From 77c14decefaf46efbc2b2227de6726b1a1bbd8cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 13:36:23 -0400 Subject: [PATCH 001/323] build(deps-dev): bump @firebase/auth-compat from 0.4.2 to 0.4.3 (#2252) Bumps [@firebase/auth-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/auth-compat) from 0.4.2 to 0.4.3. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/master/packages/auth-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/auth-compat@0.4.3/packages/auth-compat) --- updated-dependencies: - dependency-name: "@firebase/auth-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index b81b5ff560..04d3977027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "11.9.0", + "version": "11.10.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -463,14 +463,15 @@ "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" }, "@firebase/auth": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.23.2.tgz", - "integrity": "sha512-dM9iJ0R6tI1JczuGSxXmQbXAgtYie0K4WvKcuyuSTCu9V8eEDiz4tfa1sO3txsfvwg7nOY3AjoCyMYEdqZ8hdg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.0.0.tgz", + "integrity": "sha512-yQB/gCVQcLf0fBQbdkVK/qA3VY5iSXpzy1zMXSggZwEYfp8I/0PksFk6AztkzWL2c+QR6wdnIPyeXLI9x9vFgQ==", "dev": true, "requires": { "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", + "@react-native-async-storage/async-storage": "1.17.12", "node-fetch": "2.6.7", "tslib": "^2.1.0" }, @@ -487,12 +488,12 @@ } }, "@firebase/auth-compat": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.2.tgz", - "integrity": "sha512-Q30e77DWXFmXEt5dg5JbqEDpjw9y3/PcP9LslDPR7fARmAOTIY9MM6HXzm9KC+dlrKH/+p6l8g9ifJiam9mc4A==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.3.tgz", + "integrity": "sha512-M1t9nT5tBV1zQFCwO/NwxYCLGXRfLWDm6Veqai3XU7x/ItcgmLeLkkEc+hv2DlmCmgeeK0mpsW1AAe+jcUgKVw==", "dev": true, "requires": { - "@firebase/auth": "0.23.2", + "@firebase/auth": "1.0.0", "@firebase/auth-types": "0.12.0", "@firebase/component": "0.6.4", "@firebase/util": "1.9.3", @@ -1138,6 +1139,15 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "optional": true }, + "@react-native-async-storage/async-storage": { + "version": "1.17.12", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.12.tgz", + "integrity": "sha512-BXg4OxFdjPTRt+8MvN6jz4muq0/2zII3s7HeT/11e4Zeh3WCgk/BleLzUcDfVqF3OzFHUqEkSrb76d6Ndjd/Nw==", + "dev": true, + "requires": { + "merge-options": "^3.0.4" + } + }, "@rushstack/node-core-library": { "version": "3.45.5", "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.5.tgz", @@ -6596,6 +6606,15 @@ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true }, + "merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "dev": true, + "requires": { + "is-plain-obj": "^2.1.0" + } + }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", From c01007012c8908356734588c46a2e99a99d27a97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:41:47 +0000 Subject: [PATCH 002/323] build(deps): bump @types/node from 20.3.2 to 20.4.2 (#2255) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 04d3977027..25d8b6e18d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1490,9 +1490,9 @@ } }, "@types/node": { - "version": "20.3.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", - "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" + "version": "20.4.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", + "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" }, "@types/qs": { "version": "6.9.7", From f24a1a1f9d4f5a24da64c8896fd78cc3c0f3bce4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:48:05 +0000 Subject: [PATCH 003/323] build(deps): bump word-wrap from 1.2.3 to 1.2.4 (#2256) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 25d8b6e18d..265691e55f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10229,9 +10229,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==" }, "workerpool": { "version": "6.2.1", From 9ab1cf9486d75e1971680e0f6921fd52401d36e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:53:59 +0000 Subject: [PATCH 004/323] build(deps-dev): bump @microsoft/api-extractor from 7.36.1 to 7.36.3 (#2261) --- package-lock.json | 54 ++++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 265691e55f..be955a91b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -880,21 +880,21 @@ } }, "@microsoft/api-extractor": { - "version": "7.36.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.36.1.tgz", - "integrity": "sha512-2SPp1jq6wDY5IOsRLUv/4FxngslctBZJlztAJ3uWpCAwqKQG7ESdL3DhEza+StbYLtBQmu1Pk6q1Vkhl7qD/bg==", + "version": "7.36.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.36.3.tgz", + "integrity": "sha512-u0H6362AQq+r55X8drHx4npgkrCfJnMzRRHfQo8PMNKB8TcBnrTLfXhXWi+xnTM6CzlU/netEN8c4bq581Rnrg==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.27.4", + "@microsoft/api-extractor-model": "7.27.5", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.59.5", + "@rushstack/node-core-library": "3.59.6", "@rushstack/rig-package": "0.4.0", "@rushstack/ts-command-line": "4.15.1", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.22.1", - "semver": "~7.3.0", + "semver": "~7.5.4", "source-map": "~0.6.1", "typescript": "~5.0.4" }, @@ -906,9 +906,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.59.5", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.5.tgz", - "integrity": "sha512-1IpV7LufrI1EoVO8hYsb3t6L8L+yp40Sa0OaOV2CIu1zx4e6ZeVNaVIEXFgMXBKdGXkAh21MnCaIzlDNpG6ZQw==", + "version": "3.59.6", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.6.tgz", + "integrity": "sha512-bMYJwNFfWXRNUuHnsE9wMlW/mOB4jIwSUkRKtu02CwZhQdmzMsUbxE0s1xOLwTpNIwlzfW/YT7OnOHgDffLgYg==", "dev": true, "requires": { "colors": "~1.2.1", @@ -916,7 +916,7 @@ "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", - "semver": "~7.3.0", + "semver": "~7.5.4", "z-schema": "~5.0.2" } }, @@ -947,15 +947,6 @@ "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", "dev": true }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "typescript": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", @@ -965,14 +956,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.27.4.tgz", - "integrity": "sha512-HjqQFmuGPOS20rtnu+9Jj0QrqZyR59E+piUWXPMZTTn4jaZI+4UmsHSf3Id8vyueAhOBH2cgwBuRTE5R+MfSMw==", + "version": "7.27.5", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.27.5.tgz", + "integrity": "sha512-9/tBzYMJitR+o+zkPr1lQh2+e8ClcaTF6eZo7vZGDqRt2O5XmXWPbYJZmxyM3wb5at6lfJNEeGZrQXLjsQ0Nbw==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.59.5" + "@rushstack/node-core-library": "3.59.6" }, "dependencies": { "@microsoft/tsdoc": { @@ -982,9 +973,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.59.5", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.5.tgz", - "integrity": "sha512-1IpV7LufrI1EoVO8hYsb3t6L8L+yp40Sa0OaOV2CIu1zx4e6ZeVNaVIEXFgMXBKdGXkAh21MnCaIzlDNpG6ZQw==", + "version": "3.59.6", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.6.tgz", + "integrity": "sha512-bMYJwNFfWXRNUuHnsE9wMlW/mOB4jIwSUkRKtu02CwZhQdmzMsUbxE0s1xOLwTpNIwlzfW/YT7OnOHgDffLgYg==", "dev": true, "requires": { "colors": "~1.2.1", @@ -992,7 +983,7 @@ "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", - "semver": "~7.3.0", + "semver": "~7.5.4", "z-schema": "~5.0.2" } }, @@ -1001,15 +992,6 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", "dev": true - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } } } }, From d9595a9a9e8901de580cb2857908f1be8bb6f6a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:59:54 +0000 Subject: [PATCH 005/323] build(deps): bump @google-cloud/storage from 6.11.0 to 6.12.0 (#2253) --- package-lock.json | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index be955a91b1..0f51effde8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -618,9 +618,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-6.11.0.tgz", - "integrity": "sha512-p5VX5K2zLTrMXlKdS1CiQNkKpygyn7CBFm5ZvfhVj6+7QUsjWvYx9YDMkYXdarZ6JDt4cxiu451y9QUIH82ZTw==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-6.12.0.tgz", + "integrity": "sha512-78nNAY7iiZ4O/BouWMWTD/oSF2YtYgYB3GZirn0To6eBOugjXVoK+GXgUXOl+HlqbAOyHxAVXOlsj3snfbQ1dw==", "optional": true, "requires": { "@google-cloud/paginator": "^3.0.7", @@ -632,6 +632,7 @@ "duplexify": "^4.0.0", "ent": "^2.2.0", "extend": "^3.0.2", + "fast-xml-parser": "^4.2.2", "gaxios": "^5.0.0", "google-auth-library": "^8.0.1", "mime": "^3.0.0", @@ -3977,6 +3978,15 @@ "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", "optional": true }, + "fast-xml-parser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.6.tgz", + "integrity": "sha512-Xo1qV++h/Y3Ng8dphjahnYe+rGHaaNdsYOBWL9Y9GCPKpNKilJtilvWkLcI9f9X2DoKTLsZsGYAls5+JL5jfLA==", + "optional": true, + "requires": { + "strnum": "^1.0.5" + } + }, "fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -9383,6 +9393,12 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "optional": true + }, "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", From c75792fc50d3e4d44ae78a194c2d2b7fde72fead Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 18:24:28 -0400 Subject: [PATCH 006/323] build(deps-dev): bump @firebase/app-compat from 0.2.13 to 0.2.15 (#2263) Bumps [@firebase/app-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/app-compat) from 0.2.13 to 0.2.15. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/master/packages/app-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/app-compat@0.2.15/packages/app-compat) --- updated-dependencies: - dependency-name: "@firebase/app-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f51effde8..76efd950ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -432,9 +432,9 @@ } }, "@firebase/app": { - "version": "0.9.13", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.13.tgz", - "integrity": "sha512-GfiI1JxJ7ecluEmDjPzseRXk/PX31hS7+tjgBopL7XjB2hLUdR+0FTMXy2Q3/hXezypDvU6or7gVFizDESrkXw==", + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.15.tgz", + "integrity": "sha512-xxQi6mkhRjtXeFUwleSF4zU7lwEH+beNhLE7VmkzEzjEsjAS14QPQPZ35gpgSD+/NigOeho7wgEXd4C/bOkRfA==", "dev": true, "requires": { "@firebase/component": "0.6.4", @@ -445,12 +445,12 @@ } }, "@firebase/app-compat": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.13.tgz", - "integrity": "sha512-j6ANZaWjeVy5zg6X7uiqh6lM6o3n3LD1+/SJFNs9V781xyryyZWXe+tmnWNWPkP086QfJoNkWN9pMQRqSG4vMg==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.15.tgz", + "integrity": "sha512-ttEbOEtO1SSz27cRPrwXAmrqDjdQ33sQc7rqqQuSMUuPRdYCQEcYdqzpkbvqgdkzGksx2kfH4JqQ6R/hI12nDw==", "dev": true, "requires": { - "@firebase/app": "0.9.13", + "@firebase/app": "0.9.15", "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", From 61fe5aed301372d7dc566ec7b56fce8d9488952d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 22:30:00 +0000 Subject: [PATCH 007/323] build(deps-dev): bump @types/uuid from 9.0.1 to 9.0.2 (#2267) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 76efd950ce..c7e6c265e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1566,9 +1566,9 @@ "dev": true }, "@types/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", "dev": true }, "@typescript-eslint/eslint-plugin": { From cfc5130e00db2bb5d3a6396aab866532d0d5d424 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 22:36:30 +0000 Subject: [PATCH 008/323] build(deps): bump @google-cloud/firestore from 6.6.1 to 6.7.0 (#2265) --- package-lock.json | 56 ++++++++++++----------------------------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7e6c265e9..37cbbcb851 100644 --- a/package-lock.json +++ b/package-lock.json @@ -584,9 +584,9 @@ } }, "@google-cloud/firestore": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-6.6.1.tgz", - "integrity": "sha512-Z41j2h0mrgBH9qNIVmbRLqGKc6XmdJtWipeKwdnGa/bPTP1gn2SGTrYyWnpfsLMEtzKSYieHPSkAFp5kduF2RA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-6.7.0.tgz", + "integrity": "sha512-bkH2jb5KkQSUa+NAvpip9HQ+rpYhi77IaqHovWuN07adVmvNXX08gPpvPWEzoXYa/wDjEVI7LiAtCWkJJEYTNg==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -652,9 +652,9 @@ } }, "@grpc/grpc-js": { - "version": "1.8.17", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.17.tgz", - "integrity": "sha512-DGuSbtMFbaRsyffMf+VEkVu8HkSXEUfO3UyGJNtqxW9ABdtTIA+2UXAJpwbJS+xfQxuwqLUeELmL6FuZkOqPxw==", + "version": "1.8.20", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.20.tgz", + "integrity": "sha512-SPse1wE4PcIFojOISsAnrWXCBsCBwDdcDqz2SS0T8nBSxg9jwmCK70Jy7ypRn2nIspwLy3Ls5TNaKNHo+6dF8A==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.0", @@ -662,15 +662,15 @@ } }, "@grpc/proto-loader": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.7.tgz", - "integrity": "sha512-1TIeXOi8TuSCQprPItwoMymZXxWT0CPxUhkrkeCUH+D8U7QDwQ6b7SUz2MaLuWM2llT+J/TVFLmQI5KtML3BhQ==", + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.8.tgz", + "integrity": "sha512-GU12e2c8dmdXb7XUlOgYWZ2o2i+z9/VeACkxTA/zzAe2IjclC5PnVL0lpgjhrqfpDYHzM8B1TF6pqWegMYAzlA==", "optional": true, "requires": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^4.0.0", - "protobufjs": "^7.0.0", + "protobufjs": "^7.2.4", "yargs": "^17.7.2" } }, @@ -4763,9 +4763,9 @@ } }, "google-gax": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-3.6.0.tgz", - "integrity": "sha512-2fyb61vWxUonHiArRNJQmE4tx5oY1ni8VPo08fzII409vDSCWG7apDX4qNOQ2GXXT82gLBn3d3P1Dydh7pWjyw==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-3.6.1.tgz", + "integrity": "sha512-g/lcUjGcB6DSw2HxgEmCDOrI/CByOwqRvsuUvNalHUK2iPPPlmAIpbMbl62u0YufGMr8zgE3JL7th6dCb1Ry+w==", "optional": true, "requires": { "@grpc/grpc-js": "~1.8.0", @@ -4780,37 +4780,9 @@ "node-fetch": "^2.6.1", "object-hash": "^3.0.0", "proto3-json-serializer": "^1.0.0", - "protobufjs": "7.2.3", + "protobufjs": "7.2.4", "protobufjs-cli": "1.1.1", "retry-request": "^5.0.0" - }, - "dependencies": { - "long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "optional": true - }, - "protobufjs": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz", - "integrity": "sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - } - } } }, "google-p12-pem": { From 774bf1bbab4b2e628749d863d4e63f6c95ec8036 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jul 2023 22:42:51 +0000 Subject: [PATCH 009/323] build(deps-dev): bump @typescript-eslint/parser from 5.59.9 to 5.62.0 (#2264) --- package-lock.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 37cbbcb851..160dc8aec5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1590,41 +1590,41 @@ } }, "@typescript-eslint/parser": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz", - "integrity": "sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.59.9", - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/typescript-estree": "5.59.9", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz", - "integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" } }, "@typescript-eslint/types": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz", - "integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz", - "integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.9", - "@typescript-eslint/visitor-keys": "5.59.9", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1633,12 +1633,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.59.9", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz", - "integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.59.9", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" } } From 6efe5a9dff9c0048c97362609c62e37426cb1a2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 12:46:00 -0400 Subject: [PATCH 010/323] build(deps-dev): bump @firebase/auth-compat from 0.4.3 to 0.4.4 (#2273) Bumps [@firebase/auth-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/auth-compat) from 0.4.3 to 0.4.4. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/master/packages/auth-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/auth-compat@0.4.4/packages/auth-compat) --- updated-dependencies: - dependency-name: "@firebase/auth-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 160dc8aec5..a70bd55670 100644 --- a/package-lock.json +++ b/package-lock.json @@ -463,15 +463,15 @@ "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" }, "@firebase/auth": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.0.0.tgz", - "integrity": "sha512-yQB/gCVQcLf0fBQbdkVK/qA3VY5iSXpzy1zMXSggZwEYfp8I/0PksFk6AztkzWL2c+QR6wdnIPyeXLI9x9vFgQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.1.0.tgz", + "integrity": "sha512-5RJQMXG0p/tSvtqpfM8jA+heELjVCgHHASq3F7NglAa/CWUGCAE4g2F4YDPW5stDkvtKKRez0WYAWnbcuQ5P4w==", "dev": true, "requires": { "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", - "@react-native-async-storage/async-storage": "1.17.12", + "@react-native-async-storage/async-storage": "^1.18.1", "node-fetch": "2.6.7", "tslib": "^2.1.0" }, @@ -488,12 +488,12 @@ } }, "@firebase/auth-compat": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.3.tgz", - "integrity": "sha512-M1t9nT5tBV1zQFCwO/NwxYCLGXRfLWDm6Veqai3XU7x/ItcgmLeLkkEc+hv2DlmCmgeeK0mpsW1AAe+jcUgKVw==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.4.tgz", + "integrity": "sha512-B2DctJDJ05djBwebNEdC3zbKWzKdIdxpbca8u9P/NSjqaJNSFq3fhz8h8bjlS9ufSrxaQWFSJMMH3dRmx3FlEA==", "dev": true, "requires": { - "@firebase/auth": "1.0.0", + "@firebase/auth": "1.1.0", "@firebase/auth-types": "0.12.0", "@firebase/component": "0.6.4", "@firebase/util": "1.9.3", @@ -1123,9 +1123,9 @@ "optional": true }, "@react-native-async-storage/async-storage": { - "version": "1.17.12", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.17.12.tgz", - "integrity": "sha512-BXg4OxFdjPTRt+8MvN6jz4muq0/2zII3s7HeT/11e4Zeh3WCgk/BleLzUcDfVqF3OzFHUqEkSrb76d6Ndjd/Nw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.19.1.tgz", + "integrity": "sha512-5QXuGCtB+HL3VtKL2JN3+6t4qh8VXizK+aGDAv6Dqiq3MLrzgZHb4tjVgtEWMd8CcDtD/JqaAI1b6/EaYGtFIA==", "dev": true, "requires": { "merge-options": "^3.0.4" From bedf6b6ff7edce84219f7e6ae375ce9db9089698 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:54:07 +0000 Subject: [PATCH 011/323] build(deps-dev): bump nock from 13.3.1 to 13.3.2 (#2270) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a70bd55670..f9490801a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7015,9 +7015,9 @@ } }, "nock": { - "version": "13.3.1", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.1.tgz", - "integrity": "sha512-vHnopocZuI93p2ccivFyGuUfzjq2fxNyNurp7816mlT5V5HF4SzXu8lvLrVzBbNqzs+ODooZ6OksuSUNM7Njkw==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.2.tgz", + "integrity": "sha512-CwbljitiWJhF1gL83NbanhoKs1l23TDlRioNraPTZrzZIEooPemrHRj5m0FZCPkB1ecdYCSWWGcHysJgX/ngnQ==", "dev": true, "requires": { "debug": "^4.1.0", From 3d0b25f44d96d8d0210ee144806e2b1a3d783753 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:46:36 -0400 Subject: [PATCH 012/323] build(deps-dev): bump @typescript-eslint/eslint-plugin (#2282) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.60.1 to 5.62.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.62.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 76 ++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9490801a5..5adefb8af8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1572,17 +1572,17 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz", - "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.60.1", - "@typescript-eslint/type-utils": "5.60.1", - "@typescript-eslint/utils": "5.60.1", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", @@ -1645,41 +1645,41 @@ } }, "@typescript-eslint/scope-manager": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz", - "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" } }, "@typescript-eslint/type-utils": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz", - "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.60.1", - "@typescript-eslint/utils": "5.60.1", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz", - "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz", - "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/visitor-keys": "5.60.1", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1688,28 +1688,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz", - "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.60.1", - "@typescript-eslint/types": "5.60.1", - "@typescript-eslint/typescript-estree": "5.60.1", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.60.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz", - "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.60.1", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -4808,12 +4808,6 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", From 903d6291db807217d54d7535591186230184ce74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 18:52:37 +0000 Subject: [PATCH 013/323] build(deps-dev): bump @types/lodash from 4.14.195 to 4.14.197 (#2280) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5adefb8af8..23241d68f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1413,9 +1413,9 @@ "optional": true }, "@types/lodash": { - "version": "4.14.195", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", - "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "version": "4.14.197", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz", + "integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==", "dev": true }, "@types/long": { From bd8a11106c4af22d2fd46c84158d1a80e7d4828a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 18:58:19 +0000 Subject: [PATCH 014/323] build(deps-dev): bump eslint from 8.43.0 to 8.47.0 (#2279) --- package-lock.json | 122 +++++++++++++++++++++++++++++++++------------- 1 file changed, 87 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23241d68f0..646cba00a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -364,14 +370,14 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -380,6 +386,12 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -390,6 +402,23 @@ "concat-map": "0.0.1" } }, + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -402,9 +431,9 @@ } }, "@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true }, "@fastify/busboy": { @@ -3520,27 +3549,27 @@ } }, "eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -3550,7 +3579,6 @@ "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", @@ -3560,12 +3588,23 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { + "@eslint-community/regexpp": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "dev": true + }, + "acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3594,9 +3633,9 @@ "dev": true }, "eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -3604,11 +3643,22 @@ } }, "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3638,17 +3688,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "prelude-ls": { @@ -3705,6 +3755,7 @@ "version": "9.5.2", "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "optional": true, "requires": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", @@ -4705,9 +4756,9 @@ } }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -10195,7 +10246,8 @@ "word-wrap": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==" + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", + "optional": true }, "workerpool": { "version": "6.2.1", From eba78a1edf079856fdaac49b354bbbd37787a4fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:09:08 -0400 Subject: [PATCH 015/323] build(deps-dev): bump bcrypt from 5.1.0 to 5.1.1 (#2289) Bumps [bcrypt](https://github.com/kelektiv/node.bcrypt.js) from 5.1.0 to 5.1.1. - [Release notes](https://github.com/kelektiv/node.bcrypt.js/releases) - [Changelog](https://github.com/kelektiv/node.bcrypt.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/kelektiv/node.bcrypt.js/compare/v5.1.0...v5.1.1) --- updated-dependencies: - dependency-name: bcrypt dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 646cba00a7..de5240875a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -893,9 +893,9 @@ } }, "@mapbox/node-pre-gyp": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", - "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", "dev": true, "requires": { "detect-libc": "^2.0.0", @@ -2434,12 +2434,12 @@ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "bcrypt": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.0.tgz", - "integrity": "sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", "dev": true, "requires": { - "@mapbox/node-pre-gyp": "^1.0.10", + "@mapbox/node-pre-gyp": "^1.0.11", "node-addon-api": "^5.0.0" } }, @@ -3293,9 +3293,9 @@ "dev": true }, "detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", "dev": true }, "diff": { @@ -6674,9 +6674,9 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true }, "minizlib": { @@ -9447,14 +9447,14 @@ } }, "tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", "dev": true, "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" From a4ce27d879f9341535f9610b849f0eb21478224b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 18:16:26 +0000 Subject: [PATCH 016/323] build(deps-dev): bump nock from 13.3.2 to 13.3.3 (#2288) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index de5240875a..ae5762b86a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7060,9 +7060,9 @@ } }, "nock": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.2.tgz", - "integrity": "sha512-CwbljitiWJhF1gL83NbanhoKs1l23TDlRioNraPTZrzZIEooPemrHRj5m0FZCPkB1ecdYCSWWGcHysJgX/ngnQ==", + "version": "13.3.3", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.3.tgz", + "integrity": "sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==", "dev": true, "requires": { "debug": "^4.1.0", From a4019e491c9d36167853eaba056adebd0e9dfc87 Mon Sep 17 00:00:00 2001 From: pragatimodi <110490169+pragatimodi@users.noreply.github.com> Date: Thu, 7 Sep 2023 13:35:17 -0700 Subject: [PATCH 017/323] feat(auth): Add Email Privacy support in Project and Tenant config (#2198) * EmailPrivacy Config definition * Adding unit tests * Adding integration tests * api-extractor changes * trim whitespace changes * Fix typo : Update auth-config.ts * Addressing feedback * Apply suggestions from code review Co-authored-by: Kevin Cheung --------- Co-authored-by: Kevin Cheung --- etc/firebase-admin.auth.api.md | 9 ++++ src/auth/auth-config.ts | 47 +++++++++++++++++ src/auth/index.ts | 3 +- src/auth/project-config.ts | 41 ++++++++++++--- src/auth/tenant.ts | 29 +++++++++- test/integration/auth.spec.ts | 24 +++++++++ test/unit/auth/project-config.spec.ts | 40 ++++++++++++++ test/unit/auth/tenant.spec.ts | 76 ++++++++++++++++++++++++++- 8 files changed, 258 insertions(+), 11 deletions(-) diff --git a/etc/firebase-admin.auth.api.md b/etc/firebase-admin.auth.api.md index f8ae6d897a..3723abd051 100644 --- a/etc/firebase-admin.auth.api.md +++ b/etc/firebase-admin.auth.api.md @@ -238,6 +238,11 @@ export interface EmailIdentifier { email: string; } +// @public +export interface EmailPrivacyConfig { + enableImprovedEmailPrivacy?: boolean; +} + // @public export interface EmailSignInProviderConfig { enabled: boolean; @@ -363,6 +368,7 @@ export class PhoneMultiFactorInfo extends MultiFactorInfo { // @public export class ProjectConfig { + readonly emailPrivacyConfig?: EmailPrivacyConfig; get multiFactorConfig(): MultiFactorConfig | undefined; readonly passwordPolicyConfig?: PasswordPolicyConfig; get recaptchaConfig(): RecaptchaConfig | undefined; @@ -446,6 +452,7 @@ export class Tenant { // (undocumented) readonly anonymousSignInEnabled: boolean; readonly displayName?: string; + readonly emailPrivacyConfig?: EmailPrivacyConfig; get emailSignInConfig(): EmailSignInProviderConfig | undefined; get multiFactorConfig(): MultiFactorConfig | undefined; readonly passwordPolicyConfig?: PasswordPolicyConfig; @@ -500,6 +507,7 @@ export interface UpdatePhoneMultiFactorInfoRequest extends BaseUpdateMultiFactor // @public export interface UpdateProjectConfigRequest { + emailPrivacyConfig?: EmailPrivacyConfig; multiFactorConfig?: MultiFactorConfig; passwordPolicyConfig?: PasswordPolicyConfig; recaptchaConfig?: RecaptchaConfig; @@ -524,6 +532,7 @@ export interface UpdateRequest { export interface UpdateTenantRequest { anonymousSignInEnabled?: boolean; displayName?: string; + emailPrivacyConfig?: EmailPrivacyConfig; emailSignInConfig?: EmailSignInProviderConfig; multiFactorConfig?: MultiFactorConfig; passwordPolicyConfig?: PasswordPolicyConfig; diff --git a/src/auth/auth-config.ts b/src/auth/auth-config.ts index 0b54171689..28ee595c46 100644 --- a/src/auth/auth-config.ts +++ b/src/auth/auth-config.ts @@ -2279,3 +2279,50 @@ export interface CustomStrengthOptionsAuthServerConfig { minPasswordLength?: number; maxPasswordLength?: number; } + +/** + * The email privacy configuration of a project or tenant. + */ +export interface EmailPrivacyConfig { + /** + * Whether enhanced email privacy is enabled. + */ + enableImprovedEmailPrivacy?: boolean; +} + +/** + * Defines the EmailPrivacyAuthConfig class used for validation. + * + * @internal + */ +export class EmailPrivacyAuthConfig { + public static validate(options: EmailPrivacyConfig): void { + if (!validator.isNonNullObject(options)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"EmailPrivacyConfig" must be a non-null object.', + ); + } + + const validKeys = { + enableImprovedEmailPrivacy: true, + }; + + for (const key in options) { + if (!(key in validKeys)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + `"${key}" is not a valid "EmailPrivacyConfig" parameter.`, + ); + } + } + + if (typeof options.enableImprovedEmailPrivacy !== 'undefined' + && !validator.isBoolean(options.enableImprovedEmailPrivacy)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"EmailPrivacyConfig.enableImprovedEmailPrivacy" must be a valid boolean value.', + ); + } + } +} diff --git a/src/auth/index.ts b/src/auth/index.ts index 2450dd1adf..a559a706f8 100644 --- a/src/auth/index.ts +++ b/src/auth/index.ts @@ -100,8 +100,9 @@ export { UpdateRequest, TotpMultiFactorProviderConfig, PasswordPolicyConfig, - PasswordPolicyEnforcementState, + PasswordPolicyEnforcementState, CustomStrengthOptionsConfig, + EmailPrivacyConfig, } from './auth-config'; export { diff --git a/src/auth/project-config.ts b/src/auth/project-config.ts index 2748be0423..250d6549ac 100644 --- a/src/auth/project-config.ts +++ b/src/auth/project-config.ts @@ -26,6 +26,8 @@ import { PasswordPolicyAuthConfig, PasswordPolicyAuthServerConfig, PasswordPolicyConfig, + EmailPrivacyConfig, + EmailPrivacyAuthConfig, } from './auth-config'; import { deepCopy } from '../utils/deep-copy'; @@ -53,6 +55,10 @@ export interface UpdateProjectConfigRequest { * The password policy configuration to update on the project */ passwordPolicyConfig?: PasswordPolicyConfig; + /** + * The email privacy configuration to update on the project + */ + emailPrivacyConfig?: EmailPrivacyConfig; } /** @@ -63,6 +69,7 @@ export interface ProjectConfigServerResponse { mfa?: MultiFactorAuthServerConfig; recaptchaConfig?: RecaptchaConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; + emailPrivacyConfig?: EmailPrivacyConfig; } /** @@ -73,6 +80,7 @@ export interface ProjectConfigClientRequest { mfa?: MultiFactorAuthServerConfig; recaptchaConfig?: RecaptchaConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; + emailPrivacyConfig?: EmailPrivacyConfig; } /** @@ -91,7 +99,12 @@ export class ProjectConfig { * Supports only phone and TOTP. */ private readonly multiFactorConfig_?: MultiFactorConfig; - + /** + * The multi-factor auth configuration. + */ + get multiFactorConfig(): MultiFactorConfig | undefined { + return this.multiFactorConfig_; + } /** * The reCAPTCHA configuration to update on the project. * By enabling reCAPTCHA Enterprise integration, you are @@ -100,16 +113,14 @@ export class ProjectConfig { */ private readonly recaptchaConfig_?: RecaptchaAuthConfig; - /** - * The multi-factor auth configuration. - */ - get multiFactorConfig(): MultiFactorConfig | undefined { - return this.multiFactorConfig_; - } /** * The password policy configuration for the project */ public readonly passwordPolicyConfig?: PasswordPolicyConfig; + /** + * The email privacy configuration for the project + */ + public readonly emailPrivacyConfig?: EmailPrivacyConfig; /** * Validates a project config options object. Throws an error on failure. @@ -128,6 +139,7 @@ export class ProjectConfig { multiFactorConfig: true, recaptchaConfig: true, passwordPolicyConfig: true, + emailPrivacyConfig: true, } // Check for unsupported top level attributes. for (const key in request) { @@ -156,6 +168,11 @@ export class ProjectConfig { if (typeof request.passwordPolicyConfig !== 'undefined') { PasswordPolicyAuthConfig.validate(request.passwordPolicyConfig); } + + // Validate Email Privacy Config if provided. + if (typeof request.emailPrivacyConfig !== 'undefined') { + EmailPrivacyAuthConfig.validate(request.emailPrivacyConfig); + } } /** @@ -180,6 +197,9 @@ export class ProjectConfig { if (typeof configOptions.passwordPolicyConfig !== 'undefined') { request.passwordPolicyConfig = PasswordPolicyAuthConfig.buildServerRequest(configOptions.passwordPolicyConfig); } + if (typeof configOptions.emailPrivacyConfig !== 'undefined') { + request.emailPrivacyConfig = configOptions.emailPrivacyConfig; + } return request; } @@ -211,6 +231,9 @@ export class ProjectConfig { if (typeof response.passwordPolicyConfig !== 'undefined') { this.passwordPolicyConfig = new PasswordPolicyAuthConfig(response.passwordPolicyConfig); } + if (typeof response.emailPrivacyConfig !== 'undefined') { + this.emailPrivacyConfig = response.emailPrivacyConfig; + } } /** * Returns a JSON-serializable representation of this object. @@ -224,6 +247,7 @@ export class ProjectConfig { multiFactorConfig: deepCopy(this.multiFactorConfig), recaptchaConfig: this.recaptchaConfig_?.toJSON(), passwordPolicyConfig: deepCopy(this.passwordPolicyConfig), + emailPrivacyConfig: deepCopy(this.emailPrivacyConfig), }; if (typeof json.smsRegionConfig === 'undefined') { delete json.smsRegionConfig; @@ -237,6 +261,9 @@ export class ProjectConfig { if (typeof json.passwordPolicyConfig === 'undefined') { delete json.passwordPolicyConfig; } + if (typeof json.emailPrivacyConfig === 'undefined') { + delete json.emailPrivacyConfig; + } return json; } } diff --git a/src/auth/tenant.ts b/src/auth/tenant.ts index 15e941a28f..76d97f3259 100644 --- a/src/auth/tenant.ts +++ b/src/auth/tenant.ts @@ -22,8 +22,8 @@ import { EmailSignInConfig, EmailSignInConfigServerRequest, MultiFactorAuthServerConfig, MultiFactorConfig, validateTestPhoneNumbers, EmailSignInProviderConfig, MultiFactorAuthConfig, SmsRegionConfig, SmsRegionsAuthConfig, RecaptchaAuthConfig, RecaptchaConfig, - PasswordPolicyConfig, - PasswordPolicyAuthConfig, PasswordPolicyAuthServerConfig, + PasswordPolicyConfig, + PasswordPolicyAuthConfig, PasswordPolicyAuthServerConfig, EmailPrivacyConfig, EmailPrivacyAuthConfig, } from './auth-config'; /** @@ -73,6 +73,10 @@ export interface UpdateTenantRequest { * The password policy configuration for the tenant */ passwordPolicyConfig?: PasswordPolicyConfig; + /** + * The email privacy configuration for the tenant + */ + emailPrivacyConfig?: EmailPrivacyConfig; } /** @@ -90,6 +94,7 @@ export interface TenantOptionsServerRequest extends EmailSignInConfigServerReque smsRegionConfig?: SmsRegionConfig; recaptchaConfig?: RecaptchaConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; + emailPrivacyConfig?: EmailPrivacyConfig; } /** The tenant server response interface. */ @@ -104,6 +109,7 @@ export interface TenantServerResponse { smsRegionConfig?: SmsRegionConfig; recaptchaConfig? : RecaptchaConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; + emailPrivacyConfig?: EmailPrivacyConfig; } /** @@ -165,6 +171,10 @@ export class Tenant { * The password policy configuration for the tenant */ public readonly passwordPolicyConfig?: PasswordPolicyConfig; + /** + * The email privacy configuration for the tenant + */ + public readonly emailPrivacyConfig?: EmailPrivacyConfig; /** * Builds the corresponding server request for a TenantOptions object. @@ -204,6 +214,9 @@ export class Tenant { if (typeof tenantOptions.passwordPolicyConfig !== 'undefined') { request.passwordPolicyConfig = PasswordPolicyAuthConfig.buildServerRequest(tenantOptions.passwordPolicyConfig); } + if (typeof tenantOptions.emailPrivacyConfig !== 'undefined') { + request.emailPrivacyConfig = tenantOptions.emailPrivacyConfig; + } return request; } @@ -240,6 +253,7 @@ export class Tenant { smsRegionConfig: true, recaptchaConfig: true, passwordPolicyConfig: true, + emailPrivacyConfig: true, }; const label = createRequest ? 'CreateTenantRequest' : 'UpdateTenantRequest'; if (!validator.isNonNullObject(request)) { @@ -299,6 +313,10 @@ export class Tenant { // This will throw an error if invalid. PasswordPolicyAuthConfig.buildServerRequest(request.passwordPolicyConfig); } + // Validate Email Privacy Config if provided. + if (typeof request.emailPrivacyConfig !== 'undefined') { + EmailPrivacyAuthConfig.validate(request.emailPrivacyConfig); + } } /** @@ -342,6 +360,9 @@ export class Tenant { if (typeof response.passwordPolicyConfig !== 'undefined') { this.passwordPolicyConfig = new PasswordPolicyAuthConfig(response.passwordPolicyConfig); } + if (typeof response.emailPrivacyConfig !== 'undefined') { + this.emailPrivacyConfig = deepCopy(response.emailPrivacyConfig); + } } /** @@ -381,6 +402,7 @@ export class Tenant { smsRegionConfig: deepCopy(this.smsRegionConfig), recaptchaConfig: this.recaptchaConfig_?.toJSON(), passwordPolicyConfig: deepCopy(this.passwordPolicyConfig), + emailPrivacyConfig: deepCopy(this.emailPrivacyConfig), }; if (typeof json.multiFactorConfig === 'undefined') { delete json.multiFactorConfig; @@ -397,6 +419,9 @@ export class Tenant { if (typeof json.passwordPolicyConfig === 'undefined') { delete json.passwordPolicyConfig; } + if (typeof json.emailPrivacyConfig === 'undefined') { + delete json.emailPrivacyConfig; + } return json; } } diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index c88fdd8722..7b113b3156 100644 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -1283,6 +1283,9 @@ describe('admin.auth', () => { ], useAccountDefender: true, }, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + } }; const projectConfigOption2: UpdateProjectConfigRequest = { smsRegionConfig: smsRegionAllowlistOnlyConfig, @@ -1290,6 +1293,9 @@ describe('admin.auth', () => { emailPasswordEnforcementState: 'OFF', useAccountDefender: false, }, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: false, + } }; const projectConfigOptionSmsEnabledTotpDisabled: UpdateProjectConfigRequest = { smsRegionConfig: smsRegionAllowlistOnlyConfig, @@ -1309,6 +1315,9 @@ describe('admin.auth', () => { ], useAccountDefender: true, }, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; const expectedProjectConfig2: any = { smsRegionConfig: smsRegionAllowlistOnlyConfig, @@ -1323,6 +1332,7 @@ describe('admin.auth', () => { }, ], }, + emailPrivacyConfig: {}, }; const expectedProjectConfigSmsEnabledTotpDisabled: any = { smsRegionConfig: smsRegionAllowlistOnlyConfig, @@ -1337,6 +1347,7 @@ describe('admin.auth', () => { }, ], }, + emailPrivacyConfig: {}, }; it('updateProjectConfig() should resolve with the updated project config', () => { @@ -1417,6 +1428,9 @@ describe('admin.auth', () => { '+16505551234': '019287', '+16505550676': '985235', }, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; const expectedCreatedTenant: any = { displayName: 'testTenant1', @@ -1434,6 +1448,9 @@ describe('admin.auth', () => { '+16505551234': '019287', '+16505550676': '985235', }, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; const expectedUpdatedTenant: any = { displayName: 'testTenantUpdated', @@ -1459,6 +1476,7 @@ describe('admin.auth', () => { ], useAccountDefender: true, }, + emailPrivacyConfig: {}, }; const expectedUpdatedTenant2: any = { displayName: 'testTenantUpdated', @@ -1479,6 +1497,7 @@ describe('admin.auth', () => { ], useAccountDefender: false, }, + emailPrivacyConfig: {}, }; const expectedUpdatedTenantSmsEnabledTotpDisabled: any = { displayName: 'testTenantUpdated', @@ -1499,6 +1518,7 @@ describe('admin.auth', () => { ], useAccountDefender: false, }, + emailPrivacyConfig: {}, }; // https://mochajs.org/ @@ -1912,6 +1932,7 @@ describe('admin.auth', () => { multiFactorConfig: deepCopy(expectedUpdatedTenant.multiFactorConfig), testPhoneNumbers: deepCopy(expectedUpdatedTenant.testPhoneNumbers), recaptchaConfig: deepCopy(expectedUpdatedTenant.recaptchaConfig), + emailPrivacyConfig: { enableImprovedEmailPrivacy: false }, }; const updatedOptions2: UpdateTenantRequest = { emailSignInConfig: { @@ -1923,6 +1944,9 @@ describe('admin.auth', () => { testPhoneNumbers: null, smsRegionConfig: deepCopy(expectedUpdatedTenant2.smsRegionConfig), recaptchaConfig: deepCopy(expectedUpdatedTenant2.recaptchaConfig), + emailPrivacyConfig: { + enableImprovedEmailPrivacy: false, + }, }; if (authEmulatorHost) { return getAuth().tenantManager().updateTenant(createdTenantId, updatedOptions) diff --git a/test/unit/auth/project-config.spec.ts b/test/unit/auth/project-config.spec.ts index eb32cae88e..5934dd15fd 100644 --- a/test/unit/auth/project-config.spec.ts +++ b/test/unit/auth/project-config.spec.ts @@ -67,6 +67,9 @@ describe('ProjectConfig', () => { }, ], }, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; const updateProjectConfigRequest1: UpdateProjectConfigRequest = { @@ -87,6 +90,9 @@ describe('ProjectConfig', () => { maxLength: 30, }, }, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: false, + }, }; const updateProjectConfigRequest2: UpdateProjectConfigRequest = { @@ -421,6 +427,30 @@ describe('ProjectConfig', () => { ' must be greater than or equal to minLength and at max 4096.'); }); + it('should throw on null EmailPrivacyConfig attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.emailPrivacyConfig = null; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"EmailPrivacyConfig" must be a non-null object.'); + }); + + it('should throw on invalid EmailPrivacyConfig attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.emailPrivacyConfig.invalidParameter = 'invalid'; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"invalidParameter" is not a valid "EmailPrivacyConfig" parameter.'); + }); + + it('should throw on invalid enableImprovedEmailPrivacy attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.emailPrivacyConfig.enableImprovedEmailPrivacy = []; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"EmailPrivacyConfig.enableImprovedEmailPrivacy" must be a valid boolean value.'); + }); + const nonObjects = [null, NaN, 0, 1, true, false, '', 'a', [], [1, 'a'], _.noop]; nonObjects.forEach((request) => { it('should throw on invalid UpdateProjectConfigRequest:' + JSON.stringify(request), () => { @@ -505,6 +535,13 @@ describe('ProjectConfig', () => { }; expect(projectConfig.passwordPolicyConfig).to.deep.equal(expectedPasswordPolicyConfig); }); + + it('should set readonly property emailPrivacyConfig', () => { + const expectedEmailPrivacyConfig = { + enableImprovedEmailPrivacy: true, + }; + expect(projectConfig.emailPrivacyConfig).to.deep.equal(expectedEmailPrivacyConfig); + }); }); describe('toJSON()', () => { @@ -515,6 +552,7 @@ describe('ProjectConfig', () => { multiFactorConfig: deepCopy(serverResponse.mfa), recaptchaConfig: deepCopy(serverResponse.recaptchaConfig), passwordPolicyConfig: deepCopy(serverResponse.passwordPolicyConfig), + emailPrivacyConfig: deepCopy(serverResponse.emailPrivacyConfig), }); }); @@ -526,6 +564,8 @@ describe('ProjectConfig', () => { delete serverResponseOptionalCopy.recaptchaConfig?.managedRules; delete serverResponseOptionalCopy.recaptchaConfig?.useAccountDefender; delete serverResponseOptionalCopy.passwordPolicyConfig; + delete serverResponseOptionalCopy.passwordPolicyConfig; + delete serverResponseOptionalCopy.emailPrivacyConfig; expect(new ProjectConfig(serverResponseOptionalCopy).toJSON()).to.deep.equal({ recaptchaConfig: { recaptchaKeys: deepCopy(serverResponse.recaptchaConfig?.recaptchaKeys), diff --git a/test/unit/auth/tenant.spec.ts b/test/unit/auth/tenant.spec.ts index 0d4d9e8a90..e1006e47b7 100644 --- a/test/unit/auth/tenant.spec.ts +++ b/test/unit/auth/tenant.spec.ts @@ -20,7 +20,7 @@ import * as sinonChai from 'sinon-chai'; import * as chaiAsPromised from 'chai-as-promised'; import { deepCopy } from '../../../src/utils/deep-copy'; -import { EmailSignInConfig, MultiFactorAuthConfig, RecaptchaAuthConfig, +import { EmailSignInConfig, MultiFactorAuthConfig, RecaptchaAuthConfig, PasswordPolicyAuthServerConfig, PasswordPolicyConfig, } from '../../../src/auth/auth-config'; import { TenantServerResponse } from '../../../src/auth/tenant'; @@ -100,6 +100,9 @@ describe('Tenant', () => { }, smsRegionConfig: smsAllowByDefault, passwordPolicyConfig: passwordPolicyServerConfig, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; const clientRequest: UpdateTenantRequest = { @@ -126,6 +129,9 @@ describe('Tenant', () => { }, smsRegionConfig: smsAllowByDefault, passwordPolicyConfig: passwordPolicyClientConfig, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; const serverRequestWithoutMfa: TenantServerResponse = { @@ -134,6 +140,9 @@ describe('Tenant', () => { allowPasswordSignup: true, enableEmailLinkSignin: true, passwordPolicyConfig: passwordPolicyServerConfig, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; const clientRequestWithoutMfa: UpdateTenantRequest = { @@ -143,6 +152,9 @@ describe('Tenant', () => { passwordRequired: false, }, passwordPolicyConfig: passwordPolicyClientConfig, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; const clientRequestWithRecaptcha: UpdateTenantRequest = { @@ -203,6 +215,10 @@ describe('Tenant', () => { useAccountDefender: true, }, smsRegionConfig: smsAllowByDefault, + passwordPolicyConfig: passwordPolicyServerConfig, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }; describe('buildServerRequest()', () => { @@ -544,6 +560,30 @@ describe('Tenant', () => { ' must be greater than or equal to minLength and at max 4096.'); }); + it('should throw on null EmailPrivacyConfig attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequest) as any; + tenantOptionsClientRequest.emailPrivacyConfig = null; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"EmailPrivacyConfig" must be a non-null object.'); + }); + + it('should throw on invalid EmailPrivacyConfig attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequest) as any; + tenantOptionsClientRequest.emailPrivacyConfig.invalidParameter = 'invalid'; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"invalidParameter" is not a valid "EmailPrivacyConfig" parameter.'); + }); + + it('should throw on invalid enableImprovedEmailPrivacy attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequest) as any; + tenantOptionsClientRequest.emailPrivacyConfig.enableImprovedEmailPrivacy = []; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"EmailPrivacyConfig.enableImprovedEmailPrivacy" must be a valid boolean value.'); + }); + it('should not throw on valid client request object', () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha); expect(() => { @@ -915,6 +955,30 @@ describe('Tenant', () => { ' must be greater than or equal to minLength and at max 4096.'); }); + it('should throw on null EmailPrivacyConfig attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequest) as any; + tenantOptionsClientRequest.emailPrivacyConfig = null; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"EmailPrivacyConfig" must be a non-null object.'); + }); + + it('should throw on invalid EmailPrivacyConfig attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequest) as any; + tenantOptionsClientRequest.emailPrivacyConfig.invalidParameter = 'invalid'; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"invalidParameter" is not a valid "EmailPrivacyConfig" parameter.'); + }); + + it('should throw on invalid enableImprovedEmailPrivacy attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequest) as any; + tenantOptionsClientRequest.emailPrivacyConfig.enableImprovedEmailPrivacy = []; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"EmailPrivacyConfig.enableImprovedEmailPrivacy" must be a valid boolean value.'); + }); + const nonObjects = [null, NaN, 0, 1, true, false, '', 'a', [], [1, 'a'], _.noop]; nonObjects.forEach((request) => { it('should throw on invalid CreateTenantRequest:' + JSON.stringify(request), () => { @@ -1034,6 +1098,13 @@ describe('Tenant', () => { deepCopy(clientRequest.passwordPolicyConfig)); }); + it('should set readonly property emailPrivacyConfig', () => { + const expectedEmailPrivacyConfig = { + enableImprovedEmailPrivacy: true, + }; + expect(clientRequest.emailPrivacyConfig).to.deep.equal(expectedEmailPrivacyConfig); + }); + it('should throw when no tenant ID is provided', () => { const invalidOptions = deepCopy(serverRequest); // Use resource name that does not include a tenant ID. @@ -1074,6 +1145,8 @@ describe('Tenant', () => { testPhoneNumbers: deepCopy(clientRequest.testPhoneNumbers), smsRegionConfig: deepCopy(clientRequest.smsRegionConfig), recaptchaConfig: deepCopy(serverResponseWithRecaptcha.recaptchaConfig), + passwordPolicyConfig: deepCopy(clientRequest.passwordPolicyConfig), + emailPrivacyConfig: deepCopy(clientRequest.emailPrivacyConfig), }); }); @@ -1084,6 +1157,7 @@ describe('Tenant', () => { delete serverRequestCopyWithoutMfa.smsRegionConfig; delete serverRequestCopyWithoutMfa.recaptchaConfig; delete serverRequestCopyWithoutMfa.passwordPolicyConfig; + delete serverRequestCopyWithoutMfa.emailPrivacyConfig; expect(new Tenant(serverRequestCopyWithoutMfa).toJSON()).to.deep.equal({ tenantId: 'TENANT-ID', displayName: 'TENANT-DISPLAY-NAME', From 6e2fea415f5644a6d6e95dea93b2de7b27a87904 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 26 Sep 2023 14:19:31 -0400 Subject: [PATCH 018/323] Update `github.ref` value in `release.yml` (#2313) - Fixes the release workflow to match the updates to `github.ref`. - `github.ref` now returns a fully-formed value `refs/heads/...`. - See https://github.blog/changelog/2023-09-13-github-actions-updates-to-github_ref-and-github-ref/ --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 813136e4ee..c01fba6dcf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -96,7 +96,7 @@ jobs: # 3. with the label 'release:publish', and # 4. the title prefix '[chore] Release '. if: github.event.pull_request.merged && - github.ref == 'master' && + github.ref == 'refs/heads/master' && contains(github.event.pull_request.labels.*.name, 'release:publish') && startsWith(github.event.pull_request.title, '[chore] Release ') From ba27460d32206f02f602663e6e7e7176928932fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 20:08:17 +0000 Subject: [PATCH 019/323] build(deps-dev): bump eslint from 8.47.0 to 8.50.0 (#2311) --- package-lock.json | 64 +++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index ae5762b86a..6ee6d8fee7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -431,9 +431,9 @@ } }, "@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", + "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", "dev": true }, "@fastify/busboy": { @@ -704,9 +704,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -3549,16 +3549,16 @@ } }, "eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", + "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/js": "8.50.0", + "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", @@ -3594,9 +3594,9 @@ }, "dependencies": { "@eslint-community/regexpp": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", - "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.2.tgz", + "integrity": "sha512-0MGxAVt1m/ZK+LTJp/j0qF7Hz97D9O/FH9Ms3ltnyIdDD57cbb1ACIQTkbHvNXtWDv5TPq7w5Kq56+cNukbo7g==", "dev": true }, "acorn": { @@ -4256,19 +4256,20 @@ "dev": true }, "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", "dev": true, "requires": { - "flatted": "^3.1.0", + "flatted": "^3.2.7", + "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "flush-write-stream": { @@ -4756,9 +4757,9 @@ } }, "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.22.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", + "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -5973,6 +5974,12 @@ "bignumber.js": "^9.0.0" } }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -6118,6 +6125,15 @@ "safe-buffer": "^5.0.1" } }, + "keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", From 4fe5577c52853588c2d64cff1029ab51f5ccfd30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 20:15:34 +0000 Subject: [PATCH 020/323] build(deps-dev): bump @types/lodash from 4.14.197 to 4.14.199 (#2309) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6ee6d8fee7..40a768beba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1442,9 +1442,9 @@ "optional": true }, "@types/lodash": { - "version": "4.14.197", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.197.tgz", - "integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==", + "version": "4.14.199", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz", + "integrity": "sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==", "dev": true }, "@types/long": { From c8838e14d0449814fe4ee540b407326f8ebc9569 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 28 Sep 2023 18:46:54 -0400 Subject: [PATCH 021/323] [chore] Release 11.11.0 (#2315) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 446ad2cf42..68f51b1157 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "11.10.1", + "version": "11.11.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 1661adc5ee6b76b3a5e4e5eed7c5fc9687e65060 Mon Sep 17 00:00:00 2001 From: Rishabh Ajay <63163183+rishabhAjay@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:00:09 +0530 Subject: [PATCH 022/323] Bug Fix for issue #2320 (#2321) --- src/auth/auth-api-request.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index c4ba2ac811..9fd535777c 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -2084,7 +2084,7 @@ export class AuthRequestHandler extends AbstractAuthRequestHandler { * The FirebaseAuthRequestHandler constructor used to initialize an instance using a FirebaseApp. * * @param app - The app used to fetch access tokens to sign API requests. - * @constructor. + * @constructor */ constructor(app: App) { super(app); From 3af7e43f8acf5f3cae30ef8afddf336e0b7933de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 15:20:40 +0000 Subject: [PATCH 023/323] build(deps-dev): bump @types/firebase-token-generator (#2322) --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40a768beba..576846d5ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "11.10.1", + "version": "11.11.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1405,9 +1405,9 @@ } }, "@types/firebase-token-generator": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.30.tgz", - "integrity": "sha512-GcNz25MRki9ZpVfvNNrthx4t3XXjgIZ2wv729ea9F4n/1PZf4QIZlzTGoDTDeV417vmd6cPTYKUzPf4rR+qGhw==", + "version": "2.0.31", + "resolved": "https://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.31.tgz", + "integrity": "sha512-mR6GuDPxFiD7nZ3x2NddRvo42ZBS22PHHNdAWuQvqp/1LfiYshZ6PzJD2+JOyLw5ZErgmw7F8R1nfpXnvBOxGg==", "dev": true }, "@types/glob": { From 455a8f592c473271c6befebc1da5f08cfa5fc2ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 15:59:30 +0000 Subject: [PATCH 024/323] build(deps-dev): bump eslint from 8.50.0 to 8.51.0 (#2330) --- package-lock.json | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 576846d5ab..f12dfd4f5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -431,9 +431,9 @@ } }, "@eslint/js": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", - "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", + "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", "dev": true }, "@fastify/busboy": { @@ -3549,15 +3549,15 @@ } }, "eslint": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", - "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", + "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.50.0", + "@eslint/js": "8.51.0", "@humanwhocodes/config-array": "^0.11.11", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3594,9 +3594,9 @@ }, "dependencies": { "@eslint-community/regexpp": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.2.tgz", - "integrity": "sha512-0MGxAVt1m/ZK+LTJp/j0qF7Hz97D9O/FH9Ms3ltnyIdDD57cbb1ACIQTkbHvNXtWDv5TPq7w5Kq56+cNukbo7g==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", + "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", "dev": true }, "acorn": { @@ -4256,12 +4256,12 @@ "dev": true }, "flat-cache": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", - "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", "dev": true, "requires": { - "flatted": "^3.2.7", + "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" } @@ -4757,9 +4757,9 @@ } }, "globals": { - "version": "13.22.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", - "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -6126,9 +6126,9 @@ } }, "keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "requires": { "json-buffer": "3.0.1" From 1e2f906571dc7e2f8dffebf3fa442b2a1ad2d56b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 18:50:12 -0400 Subject: [PATCH 025/323] build(deps-dev): bump @babel/traverse from 7.21.4 to 7.23.2 (#2343) Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.21.4 to 7.23.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 208 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 176 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index f12dfd4f5c..21b31a745d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -120,25 +120,6 @@ "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true }, - "@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, "@babel/helper-module-imports": { "version": "7.21.4", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", @@ -297,28 +278,191 @@ } }, "@babel/traverse": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz", - "integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.4", - "@babel/types": "^7.21.4", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "requires": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + } + }, + "@babel/generator": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "dev": true, + "requires": { + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "requires": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true + }, + "@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "dev": true + }, + "@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + } + }, + "@babel/types": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, From 81925812b8d70e8dd6a69c94c024803c8f500830 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 12:50:58 -0500 Subject: [PATCH 026/323] build(deps-dev): bump @types/sinon-chai from 3.2.9 to 3.2.12 (#2366) Bumps [@types/sinon-chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon-chai) from 3.2.9 to 3.2.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sinon-chai) --- updated-dependencies: - dependency-name: "@types/sinon-chai" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 21b31a745d..5bb9055bc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1717,9 +1717,9 @@ } }, "@types/sinon-chai": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", - "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.12.tgz", + "integrity": "sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==", "dev": true, "requires": { "@types/chai": "*", From ec8b293946e749a25e9ebbebac8a72fe06d45f07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 10:43:07 -0500 Subject: [PATCH 027/323] build(deps-dev): bump @microsoft/api-extractor from 7.36.3 to 7.38.3 (#2380) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.36.3 to 7.38.3. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.38.3/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5bb9055bc9..1bf6ef3218 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1054,17 +1054,17 @@ } }, "@microsoft/api-extractor": { - "version": "7.36.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.36.3.tgz", - "integrity": "sha512-u0H6362AQq+r55X8drHx4npgkrCfJnMzRRHfQo8PMNKB8TcBnrTLfXhXWi+xnTM6CzlU/netEN8c4bq581Rnrg==", + "version": "7.38.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.3.tgz", + "integrity": "sha512-xt9iYyC5f39281j77JTA9C3ISJpW1XWkCcnw+2vM78CPnro6KhPfwQdPDfwS5JCPNuq0grm8cMdPUOPvrchDWw==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.27.5", + "@microsoft/api-extractor-model": "7.28.2", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.59.6", - "@rushstack/rig-package": "0.4.0", - "@rushstack/ts-command-line": "4.15.1", + "@rushstack/node-core-library": "3.61.0", + "@rushstack/rig-package": "0.5.1", + "@rushstack/ts-command-line": "4.17.1", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.22.1", @@ -1080,9 +1080,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.59.6", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.6.tgz", - "integrity": "sha512-bMYJwNFfWXRNUuHnsE9wMlW/mOB4jIwSUkRKtu02CwZhQdmzMsUbxE0s1xOLwTpNIwlzfW/YT7OnOHgDffLgYg==", + "version": "3.61.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.61.0.tgz", + "integrity": "sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==", "dev": true, "requires": { "colors": "~1.2.1", @@ -1095,9 +1095,9 @@ } }, "@rushstack/ts-command-line": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.1.tgz", - "integrity": "sha512-EL4jxZe5fhb1uVL/P/wQO+Z8Rc8FMiWJ1G7VgnPDvdIt5GVjRfK7vwzder1CZQiX3x0PY6uxENYLNGTFd1InRQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.17.1.tgz", + "integrity": "sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==", "dev": true, "requires": { "@types/argparse": "1.0.38", @@ -1130,14 +1130,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.27.5.tgz", - "integrity": "sha512-9/tBzYMJitR+o+zkPr1lQh2+e8ClcaTF6eZo7vZGDqRt2O5XmXWPbYJZmxyM3wb5at6lfJNEeGZrQXLjsQ0Nbw==", + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.2.tgz", + "integrity": "sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.59.6" + "@rushstack/node-core-library": "3.61.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1147,9 +1147,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.59.6", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.6.tgz", - "integrity": "sha512-bMYJwNFfWXRNUuHnsE9wMlW/mOB4jIwSUkRKtu02CwZhQdmzMsUbxE0s1xOLwTpNIwlzfW/YT7OnOHgDffLgYg==", + "version": "3.61.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.61.0.tgz", + "integrity": "sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==", "dev": true, "requires": { "colors": "~1.2.1", @@ -1354,9 +1354,9 @@ } }, "@rushstack/rig-package": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.4.0.tgz", - "integrity": "sha512-FnM1TQLJYwSiurP6aYSnansprK5l8WUK8VG38CmAaZs29ZeL1msjK0AP1VS4ejD33G0kE/2cpsPsS9jDenBMxw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.1.tgz", + "integrity": "sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==", "dev": true, "requires": { "resolve": "~1.22.1", From 746f0db2c61ebc9a5d482eaf425a37043fb213de Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 22 Nov 2023 10:32:15 -0500 Subject: [PATCH 028/323] chore(deps): bump google-cloud/firestore to 6.8.0 (#2385) --- package-lock.json | 112 +++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1bf6ef3218..70dd139f58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -757,15 +757,15 @@ } }, "@google-cloud/firestore": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-6.7.0.tgz", - "integrity": "sha512-bkH2jb5KkQSUa+NAvpip9HQ+rpYhi77IaqHovWuN07adVmvNXX08gPpvPWEzoXYa/wDjEVI7LiAtCWkJJEYTNg==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-6.8.0.tgz", + "integrity": "sha512-JRpk06SmZXLGz0pNx1x7yU3YhkUXheKgH5hbDZ4kMsdhtfV5qPLJLRI4wv69K0cZorIk+zTMOwptue7hizo0eA==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", "google-gax": "^3.5.7", - "protobufjs": "^7.0.0" + "protobufjs": "^7.2.5" } }, "@google-cloud/paginator": { @@ -825,9 +825,9 @@ } }, "@grpc/grpc-js": { - "version": "1.8.20", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.20.tgz", - "integrity": "sha512-SPse1wE4PcIFojOISsAnrWXCBsCBwDdcDqz2SS0T8nBSxg9jwmCK70Jy7ypRn2nIspwLy3Ls5TNaKNHo+6dF8A==", + "version": "1.8.21", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.21.tgz", + "integrity": "sha512-KeyQeZpxeEBSqFVTi3q2K7PiPXmgBfECc4updA1ejCLjYmoAlvvM3ZMp5ztTDUCUQmoY3CpDxvchjO1+rFkoHg==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.0", @@ -835,14 +835,13 @@ } }, "@grpc/proto-loader": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.8.tgz", - "integrity": "sha512-GU12e2c8dmdXb7XUlOgYWZ2o2i+z9/VeACkxTA/zzAe2IjclC5PnVL0lpgjhrqfpDYHzM8B1TF6pqWegMYAzlA==", + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", "optional": true, "requires": { - "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", + "long": "^5.0.0", "protobufjs": "^7.2.4", "yargs": "^17.7.2" } @@ -1028,9 +1027,9 @@ } }, "@jsdoc/salty": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.5.tgz", - "integrity": "sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.6.tgz", + "integrity": "sha512-aA+awb5yoml8TQ3CzI5Ue7sM3VMRC4l1zJJW4fgZ8OCL1wshJZhNzaf0PL85DSnOUw6QuFgeHGD/eq/xwwAF2g==", "optional": true, "requires": { "lodash": "^4.17.21" @@ -1580,9 +1579,9 @@ } }, "@types/linkify-it": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", "optional": true }, "@types/lodash": { @@ -1608,9 +1607,9 @@ } }, "@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", "optional": true }, "@types/mime": { @@ -1904,7 +1903,8 @@ "acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true }, "acorn-jsx": { "version": "5.3.2", @@ -3896,20 +3896,26 @@ "dev": true }, "espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "optional": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, "dependencies": { + "acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "optional": true + }, "eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "optional": true } } @@ -4979,6 +4985,28 @@ "protobufjs": "7.2.4", "protobufjs-cli": "1.1.1", "retry-request": "^5.0.0" + }, + "dependencies": { + "protobufjs": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", + "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", + "optional": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + } + } } }, "google-p12-pem": { @@ -6500,9 +6528,9 @@ } }, "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", "optional": true }, "loupe": { @@ -8237,9 +8265,9 @@ } }, "protobufjs": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", - "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", + "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", "optional": true, "requires": { "@protobufjs/aspromise": "^1.1.2", @@ -8254,14 +8282,6 @@ "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" - }, - "dependencies": { - "long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "optional": true - } } }, "protobufjs-cli": { @@ -10404,9 +10424,9 @@ } }, "word-wrap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", - "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "optional": true }, "workerpool": { diff --git a/package.json b/package.json index 68f51b1157..3104a01ce3 100644 --- a/package.json +++ b/package.json @@ -206,7 +206,7 @@ "uuid": "^9.0.0" }, "optionalDependencies": { - "@google-cloud/firestore": "^6.6.0", + "@google-cloud/firestore": "^6.8.0", "@google-cloud/storage": "^6.9.5" }, "devDependencies": { From e2e40ce3d3bebd4fc50af35a5644f323c44f0b01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:37:08 +0000 Subject: [PATCH 029/323] build(deps): bump jwks-rsa from 3.0.1 to 3.1.0 (#2381) --- package-lock.json | 92 +++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 70dd139f58..f154905ea9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1489,9 +1489,9 @@ "dev": true }, "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "requires": { "@types/connect": "*", "@types/node": "*" @@ -1519,17 +1519,17 @@ } }, "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "requires": { "@types/node": "*" } }, "@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "requires": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -1538,13 +1538,14 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.33", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", - "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", "requires": { "@types/node": "*", "@types/qs": "*", - "@types/range-parser": "*" + "@types/range-parser": "*", + "@types/send": "*" } }, "@types/firebase-token-generator": { @@ -1563,6 +1564,11 @@ "@types/node": "*" } }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, "@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -1613,9 +1619,9 @@ "optional": true }, "@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "@types/minimatch": { "version": "5.1.2", @@ -1650,14 +1656,14 @@ "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" }, "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" }, "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "@types/request": { "version": "2.48.8", @@ -1697,11 +1703,21 @@ "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "requires": { + "@types/http-errors": "*", "@types/mime": "*", "@types/node": "*" } @@ -6074,9 +6090,9 @@ "dev": true }, "jose": { - "version": "4.13.1", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.13.1.tgz", - "integrity": "sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==" + "version": "4.15.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", + "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==" }, "js-tokens": { "version": "4.0.0", @@ -6265,22 +6281,22 @@ } }, "jwks-rsa": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.0.1.tgz", - "integrity": "sha512-UUOZ0CVReK1QVU3rbi9bC7N5/le8ziUj0A2ef1Q0M7OPD2KvjEYizptqIxGIo6fSLYDkqBrazILS18tYuRc8gw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", "requires": { - "@types/express": "^4.17.14", - "@types/jsonwebtoken": "^9.0.0", + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", "debug": "^4.3.4", - "jose": "^4.10.4", + "jose": "^4.14.6", "limiter": "^1.1.5", - "lru-memoizer": "^2.1.4" + "lru-memoizer": "^2.2.0" }, "dependencies": { "@types/jsonwebtoken": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", - "integrity": "sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", "requires": { "@types/node": "*" } From 5297fbf93d607a1b3a54fa402696bdd76a8cba05 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 23 Nov 2023 11:37:40 -0500 Subject: [PATCH 030/323] [chore] Release 11.11.1 (#2387) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3104a01ce3..e59e2333fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "11.11.0", + "version": "11.11.1", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From e7c4258f1bd0397a0123ca4a14807c0ec518c754 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 29 Nov 2023 14:35:45 -0500 Subject: [PATCH 031/323] chore(deps): bump google-cloud/firestore and google-cloud/storage --- package-lock.json | 643 +++++++++++----------------------------------- package.json | 4 +- 2 files changed, 148 insertions(+), 499 deletions(-) diff --git a/package-lock.json b/package-lock.json index f154905ea9..990783fc67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "11.11.0", + "version": "11.11.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -264,7 +264,8 @@ "@babel/parser": { "version": "7.21.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", - "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==" + "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", + "dev": true }, "@babel/template": { "version": "7.20.7", @@ -757,21 +758,21 @@ } }, "@google-cloud/firestore": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-6.8.0.tgz", - "integrity": "sha512-JRpk06SmZXLGz0pNx1x7yU3YhkUXheKgH5hbDZ4kMsdhtfV5qPLJLRI4wv69K0cZorIk+zTMOwptue7hizo0eA==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.1.0.tgz", + "integrity": "sha512-kkTC0Sb9r2lONuFF8Tr2wFfBfk0DT1/EKcTKOhsuoXUVClv3jCqGYVPtHgQsHFjdOsubS+tx9G5D5WG+obB2DA==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", - "google-gax": "^3.5.7", + "google-gax": "^4.0.4", "protobufjs": "^7.2.5" } }, "@google-cloud/paginator": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.7.tgz", - "integrity": "sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.0.tgz", + "integrity": "sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==", "optional": true, "requires": { "arrify": "^2.0.0", @@ -779,40 +780,39 @@ } }, "@google-cloud/projectify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-3.0.0.tgz", - "integrity": "sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", "optional": true }, "@google-cloud/promisify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-3.0.1.tgz", - "integrity": "sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", "optional": true }, "@google-cloud/storage": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-6.12.0.tgz", - "integrity": "sha512-78nNAY7iiZ4O/BouWMWTD/oSF2YtYgYB3GZirn0To6eBOugjXVoK+GXgUXOl+HlqbAOyHxAVXOlsj3snfbQ1dw==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.6.0.tgz", + "integrity": "sha512-/pQl5pXePhVRvgaR+huKIlSrjEjmxv5pdMieW09Sbo7pa1I9ofQ54y7QN/z9xZ1Yj2j9znfMPAmae1F+Tt4q4g==", "optional": true, "requires": { - "@google-cloud/paginator": "^3.0.7", - "@google-cloud/projectify": "^3.0.0", - "@google-cloud/promisify": "^3.0.0", + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", "abort-controller": "^3.0.0", "async-retry": "^1.3.3", "compressible": "^2.0.12", "duplexify": "^4.0.0", "ent": "^2.2.0", - "extend": "^3.0.2", - "fast-xml-parser": "^4.2.2", - "gaxios": "^5.0.0", - "google-auth-library": "^8.0.1", + "fast-xml-parser": "^4.3.0", + "gaxios": "^6.0.2", + "google-auth-library": "^9.0.0", "mime": "^3.0.0", "mime-types": "^2.0.8", "p-limit": "^3.0.1", - "retry-request": "^5.0.0", - "teeny-request": "^8.0.0", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", "uuid": "^8.0.0" }, "dependencies": { @@ -825,12 +825,12 @@ } }, "@grpc/grpc-js": { - "version": "1.8.21", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.21.tgz", - "integrity": "sha512-KeyQeZpxeEBSqFVTi3q2K7PiPXmgBfECc4updA1ejCLjYmoAlvvM3ZMp5ztTDUCUQmoY3CpDxvchjO1+rFkoHg==", + "version": "1.9.12", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.12.tgz", + "integrity": "sha512-Um5MBuge32TS3lAKX02PGCnFM4xPT996yLgZNb5H03pn6NyJ4Iwn5YcPq6Jj9yxGRk7WOgaZFtVRH5iTdYBeUg==", "optional": true, "requires": { - "@grpc/proto-loader": "^0.7.0", + "@grpc/proto-loader": "^0.7.8", "@types/node": ">=12.12.47" } }, @@ -1026,15 +1026,6 @@ } } }, - "@jsdoc/salty": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.6.tgz", - "integrity": "sha512-aA+awb5yoml8TQ3CzI5Ue7sM3VMRC4l1zJJW4fgZ8OCL1wshJZhNzaf0PL85DSnOUw6QuFgeHGD/eq/xwwAF2g==", - "optional": true, - "requires": { - "lodash": "^4.17.21" - } - }, "@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -1500,8 +1491,7 @@ "@types/caseless": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", - "dev": true + "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" }, "@types/chai": { "version": "4.3.5", @@ -1554,16 +1544,6 @@ "integrity": "sha512-mR6GuDPxFiD7nZ3x2NddRvo42ZBS22PHHNdAWuQvqp/1LfiYshZ6PzJD2+JOyLw5ZErgmw7F8R1nfpXnvBOxGg==", "dev": true }, - "@types/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", - "optional": true, - "requires": { - "@types/minimatch": "^5.1.2", - "@types/node": "*" - } - }, "@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -1584,12 +1564,6 @@ "@types/node": "*" } }, - "@types/linkify-it": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", - "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", - "optional": true - }, "@types/lodash": { "version": "4.14.199", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz", @@ -1602,33 +1576,11 @@ "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", "optional": true }, - "@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", - "optional": true, - "requires": { - "@types/linkify-it": "*", - "@types/mdurl": "*" - } - }, - "@types/mdurl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", - "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", - "optional": true - }, "@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "optional": true - }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -1669,7 +1621,6 @@ "version": "2.48.8", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.8.tgz", "integrity": "sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==", - "dev": true, "requires": { "@types/caseless": "*", "@types/node": "*", @@ -1687,16 +1638,6 @@ "@types/request": "*" } }, - "@types/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==", - "optional": true, - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, "@types/semver": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", @@ -1750,8 +1691,7 @@ "@types/tough-cookie": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", - "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", - "dev": true + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==" }, "@types/uuid": { "version": "9.0.2", @@ -1925,7 +1865,8 @@ "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true }, "acorn-walk": { "version": "8.2.0", @@ -2281,7 +2222,8 @@ "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "arr-diff": { "version": "4.0.0", @@ -2484,8 +2426,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "atob": { "version": "2.1.2", @@ -2531,7 +2472,8 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "base": { "version": "0.11.2", @@ -2613,9 +2555,9 @@ } }, "bignumber.js": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz", - "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", "optional": true }, "binary-extensions": { @@ -2637,16 +2579,8 @@ "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "optional": true, - "requires": { - "balanced-match": "^1.0.0" - } + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true }, "braces": { "version": "3.0.2", @@ -2766,15 +2700,6 @@ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, - "catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "optional": true, - "requires": { - "lodash": "^4.17.15" - } - }, "chai": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", @@ -2812,6 +2737,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3107,7 +3033,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -3143,7 +3068,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "concat-stream": { "version": "1.6.2", @@ -3325,7 +3251,8 @@ "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true }, "default-compare": { "version": "1.0.0", @@ -3437,8 +3364,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "delegates": { "version": "1.0.0", @@ -3547,12 +3473,6 @@ "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", "optional": true }, - "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "optional": true - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3681,33 +3601,6 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "optional": true - }, - "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "optional": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "optional": true - } - } - }, "eslint": { "version": "8.51.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", @@ -3911,35 +3804,11 @@ "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", "dev": true }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "optional": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "dependencies": { - "acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", - "optional": true - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "optional": true - } - } - }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true }, "esquery": { "version": "1.5.0", @@ -3962,12 +3831,14 @@ "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true }, "event-target-shim": { "version": "5.0.1", @@ -4187,18 +4058,13 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "fast-text-encoding": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz", - "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==", - "optional": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true }, "fast-xml-parser": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.6.tgz", - "integrity": "sha512-Xo1qV++h/Y3Ng8dphjahnYe+rGHaaNdsYOBWL9Y9GCPKpNKilJtilvWkLcI9f9X2DoKTLsZsGYAls5+JL5jfLA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.2.tgz", + "integrity": "sha512-rmrXUXwbJedoXkStenj1kkljNF7ugn5ZjR9FJcwmCfcCbtOMDghPajbc+Tck6vE6F5XsDmx+Pr2le9fw8+pXBg==", "optional": true, "requires": { "strnum": "^1.0.5" @@ -4546,7 +4412,6 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -4612,7 +4477,8 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, "fsevents": { "version": "1.2.13", @@ -4673,24 +4539,45 @@ } }, "gaxios": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.0.tgz", - "integrity": "sha512-aezGIjb+/VfsJtIcHGcBSerNEDdfdHeMros+RbYbGpmonKWQCOVOes0LVZhn1lDtIgq55qq0HaxymIoae3Fl/A==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.1.1.tgz", + "integrity": "sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==", "optional": true, "requires": { "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", + "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", - "node-fetch": "^2.6.7" + "node-fetch": "^2.6.9" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "optional": true, + "requires": { + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "optional": true, + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + } } }, "gcp-metadata": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.2.0.tgz", - "integrity": "sha512-aFhhvvNycky2QyhG+dcfEdHBF0FRbYcf39s6WNHUDysKSrbJ5vuFbjydxBcmewtXeV248GP8dWT3ByPNxsyHCw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", "optional": true, "requires": { - "gaxios": "^5.0.0", + "gaxios": "^6.0.0", "json-bigint": "^1.0.0" } }, @@ -4759,19 +4646,6 @@ "assert-plus": "^1.0.0" } }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -4964,74 +4838,36 @@ } }, "google-auth-library": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.7.0.tgz", - "integrity": "sha512-1M0NG5VDIvJZEnstHbRdckLZESoJwguinwN8Dhae0j2ZKIQFIV63zxm6Fo6nM4xkgqUr2bbMtV5Dgo+Hy6oo0Q==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.2.0.tgz", + "integrity": "sha512-1oV3p0JhNEhVbj26eF3FAJcv9MXXQt4S0wcvKZaDbl4oHq5V3UJoSbsGZGQNcjoCdhW4kDSwOs11wLlHog3fgQ==", "optional": true, "requires": { - "arrify": "^2.0.0", "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^5.0.0", - "gcp-metadata": "^5.0.0", - "gtoken": "^6.1.0", - "jws": "^4.0.0", - "lru-cache": "^6.0.0" + "gaxios": "^6.0.0", + "gcp-metadata": "^6.0.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" } }, "google-gax": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-3.6.1.tgz", - "integrity": "sha512-g/lcUjGcB6DSw2HxgEmCDOrI/CByOwqRvsuUvNalHUK2iPPPlmAIpbMbl62u0YufGMr8zgE3JL7th6dCb1Ry+w==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.0.5.tgz", + "integrity": "sha512-yLoYtp4zE+8OQA74oBEbNkbzI6c95W01JSL7RqC8XERKpRvj3ytZp1dgnbA6G9aRsc8pZB25xWYBcCmrbYOEhA==", "optional": true, "requires": { - "@grpc/grpc-js": "~1.8.0", + "@grpc/grpc-js": "~1.9.6", "@grpc/proto-loader": "^0.7.0", "@types/long": "^4.0.0", - "@types/rimraf": "^3.0.2", "abort-controller": "^3.0.0", "duplexify": "^4.0.0", - "fast-text-encoding": "^1.0.3", - "google-auth-library": "^8.0.2", - "is-stream-ended": "^0.1.4", + "google-auth-library": "^9.0.0", "node-fetch": "^2.6.1", "object-hash": "^3.0.0", - "proto3-json-serializer": "^1.0.0", - "protobufjs": "7.2.4", - "protobufjs-cli": "1.1.1", - "retry-request": "^5.0.0" - }, - "dependencies": { - "protobufjs": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", - "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - } - } - } - }, - "google-p12-pem": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.1.tgz", - "integrity": "sha512-WPkN4yGtz05WZ5EhtlxNDWPhC4JIic6G8ePitwUWy4l+XPVYec+a0j0Ts47PDtW59y3RwAhUd9/h9ZZ63px6RQ==", - "optional": true, - "requires": { - "node-forge": "^1.3.1" + "proto3-json-serializer": "^2.0.0", + "protobufjs": "7.2.5", + "retry-request": "^7.0.0" } }, "gopd": { @@ -5046,7 +4882,8 @@ "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "graphemer": { "version": "1.4.0", @@ -5055,13 +4892,12 @@ "dev": true }, "gtoken": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-6.1.2.tgz", - "integrity": "sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz", + "integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==", "optional": true, "requires": { - "gaxios": "^5.0.1", - "google-p12-pem": "^4.0.0", + "gaxios": "^6.0.0", "jws": "^4.0.0" } }, @@ -5326,7 +5162,8 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "has-property-descriptors": { "version": "1.0.0", @@ -5560,6 +5397,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -5856,12 +5694,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "optional": true - }, "is-string": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", @@ -6109,44 +5941,12 @@ "argparse": "^2.0.1" } }, - "js2xmlparser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", - "optional": true, - "requires": { - "xmlcreate": "^2.0.4" - } - }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, - "jsdoc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", - "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", - "optional": true, - "requires": { - "@babel/parser": "^7.20.15", - "@jsdoc/salty": "^0.2.1", - "@types/markdown-it": "^12.2.3", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.2", - "klaw": "^3.0.0", - "markdown-it": "^12.3.2", - "markdown-it-anchor": "^8.4.1", - "marked": "^4.0.10", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "underscore": "~1.13.2" - } - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -6328,15 +6128,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, - "klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "optional": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, "last-run": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", @@ -6406,16 +6197,6 @@ "flush-write-stream": "^1.0.2" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "optional": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, "liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -6437,15 +6218,6 @@ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, - "linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", - "optional": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -6644,31 +6416,6 @@ "object-visit": "^1.0.0" } }, - "markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", - "optional": true, - "requires": { - "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, - "markdown-it-anchor": { - "version": "8.6.7", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", - "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", - "optional": true - }, - "marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "optional": true - }, "matchdep": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", @@ -6807,12 +6554,6 @@ } } }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "optional": true - }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -6863,19 +6604,11 @@ "mime-db": "1.52.0" } }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "optional": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true }, "minipass": { "version": "5.0.0", @@ -6928,7 +6661,8 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "mocha": { "version": "10.2.0", @@ -7893,20 +7627,6 @@ "wrappy": "1" } }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "optional": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, "ordered-read-streams": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", @@ -8063,7 +7783,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true }, "path-key": { "version": "3.1.1", @@ -8232,12 +7953,6 @@ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", "dev": true }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "optional": true - }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -8272,9 +7987,9 @@ "dev": true }, "proto3-json-serializer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-1.1.1.tgz", - "integrity": "sha512-AwAuY4g9nxx0u52DnSMkqqgyLHaW/XaPLtaAo3y/ZCfeaQB/g4YDH4kb8Wc/mWzWvu0YjOznVnfn373MVZZrgw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.0.tgz", + "integrity": "sha512-FB/YaNrpiPkyQNSNPilpn8qn0KdEfkgmJ9JP93PQyF/U4bAiXY5BiUdDhiDO4S48uSQ6AesklgVlrKiqZPzegw==", "optional": true, "requires": { "protobufjs": "^7.0.0" @@ -8300,24 +8015,6 @@ "long": "^5.0.0" } }, - "protobufjs-cli": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/protobufjs-cli/-/protobufjs-cli-1.1.1.tgz", - "integrity": "sha512-VPWMgIcRNyQwWUv8OLPyGQ/0lQY/QTQAVN5fh+XzfDwsVw1FZ2L3DM/bcBf8WPiRz2tNpaov9lPZfNcmNo6LXA==", - "optional": true, - "requires": { - "chalk": "^4.0.0", - "escodegen": "^1.13.0", - "espree": "^9.0.0", - "estraverse": "^5.1.0", - "glob": "^8.0.0", - "jsdoc": "^4.0.0", - "minimist": "^1.2.0", - "semver": "^7.1.2", - "tmp": "^0.2.1", - "uglify-js": "^3.7.7" - } - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -8806,15 +8503,6 @@ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", "dev": true }, - "requizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", - "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", - "optional": true, - "requires": { - "lodash": "^4.17.21" - } - }, "resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -8870,13 +8558,15 @@ "optional": true }, "retry-request": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-5.0.2.tgz", - "integrity": "sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.1.tgz", + "integrity": "sha512-ZI6vJp9rfB71mrZpw+n9p/B6HCsd7QJlSEQftZ+xfJzr3cQ9EPGKw1FF0BnViJ0fYREX6FhymBD2CARpmsFciQ==", "optional": true, "requires": { + "@types/request": "^2.48.8", "debug": "^4.1.1", - "extend": "^3.0.2" + "extend": "^3.0.2", + "teeny-request": "^9.0.0" } }, "reusify": { @@ -8889,6 +8579,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "requires": { "glob": "^7.1.3" }, @@ -8897,6 +8588,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -8906,6 +8598,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8919,6 +8612,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -9332,7 +9026,8 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true }, "source-map-resolve": { "version": "0.5.3", @@ -9604,7 +9299,8 @@ "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==" + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true }, "strnum": { "version": "1.0.5", @@ -9622,6 +9318,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -9657,14 +9354,14 @@ } }, "teeny-request": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-8.0.3.tgz", - "integrity": "sha512-jJZpA5He2y52yUhA7pyAGZlgQpcB+xLjcN0eUFxr9c8hP/H7uOXbBNVo/O0C/xVfJLJs680jvkFgVJEEvk9+ww==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", "optional": true, "requires": { "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.9", "stream-events": "^1.0.5", "uuid": "^9.0.0" } @@ -9808,15 +9505,6 @@ "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", "dev": true }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "optional": true, - "requires": { - "rimraf": "^3.0.0" - } - }, "to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", @@ -9970,15 +9658,6 @@ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", "dev": true }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "optional": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -10023,18 +9702,6 @@ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "optional": true - }, - "uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "optional": true - }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -10053,12 +9720,6 @@ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "dev": true }, - "underscore": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", - "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", - "optional": true - }, "undertaker": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", @@ -10439,12 +10100,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "optional": true - }, "workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", @@ -10478,12 +10133,6 @@ "typedarray-to-buffer": "^3.1.5" } }, - "xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "optional": true - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index e59e2333fd..fc1cfe9edd 100644 --- a/package.json +++ b/package.json @@ -206,8 +206,8 @@ "uuid": "^9.0.0" }, "optionalDependencies": { - "@google-cloud/firestore": "^6.8.0", - "@google-cloud/storage": "^6.9.5" + "@google-cloud/firestore": "^7.1.0", + "@google-cloud/storage": "^7.6.0" }, "devDependencies": { "@firebase/api-documenter": "^0.3.0", From ffae70ca88202a70299d72113bca3f906bf96a80 Mon Sep 17 00:00:00 2001 From: Pavel Jbanov Date: Thu, 30 Nov 2023 11:58:42 -0500 Subject: [PATCH 032/323] change(ml): Drop the feature to publish from an AutoML Model (#1974) * Deprecating the feature to publish from an AutoML Model * Empty-Commit to trigger CI --------- Co-authored-by: Lahiru Maramba --- etc/firebase-admin.api.md | 4 - etc/firebase-admin.machine-learning.api.md | 12 +-- src/machine-learning/index.ts | 1 - .../machine-learning-api-client.ts | 12 +-- .../machine-learning-namespace.ts | 8 -- src/machine-learning/machine-learning.ts | 16 +--- test/integration/machine-learning.spec.ts | 89 +------------------ .../machine-learning-api-client.spec.ts | 64 ------------- 8 files changed, 5 insertions(+), 201 deletions(-) diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index 816809d7e6..703c1ad5e6 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -320,10 +320,6 @@ export function machineLearning(app?: App): machineLearning.MachineLearning; // @public (undocumented) export namespace machineLearning { - // Warning: (ae-forgotten-export) The symbol "AutoMLTfliteModelOptions" needs to be exported by the entry point default-namespace.d.ts - // - // @deprecated - export type AutoMLTfliteModelOptions = AutoMLTfliteModelOptions; // Warning: (ae-forgotten-export) The symbol "GcsTfliteModelOptions" needs to be exported by the entry point default-namespace.d.ts export type GcsTfliteModelOptions = GcsTfliteModelOptions; // Warning: (ae-forgotten-export) The symbol "ListModelsOptions" needs to be exported by the entry point default-namespace.d.ts diff --git a/etc/firebase-admin.machine-learning.api.md b/etc/firebase-admin.machine-learning.api.md index b99a41523b..b6c3569de9 100644 --- a/etc/firebase-admin.machine-learning.api.md +++ b/etc/firebase-admin.machine-learning.api.md @@ -8,14 +8,6 @@ import { Agent } from 'http'; -// @public @deprecated (undocumented) -export interface AutoMLTfliteModelOptions extends ModelOptionsBase { - // (undocumented) - tfliteModel: { - automlModel: string; - }; -} - // @public (undocumented) export interface GcsTfliteModelOptions extends ModelOptionsBase { // (undocumented) @@ -74,7 +66,7 @@ export class Model { } // @public (undocumented) -export type ModelOptions = ModelOptionsBase | GcsTfliteModelOptions | AutoMLTfliteModelOptions; +export type ModelOptions = ModelOptionsBase | GcsTfliteModelOptions; // @public export interface ModelOptionsBase { @@ -86,8 +78,6 @@ export interface ModelOptionsBase { // @public export interface TFLiteModel { - // @deprecated - readonly automlModel?: string; readonly gcsTfliteUri?: string; readonly sizeBytes: number; } diff --git a/src/machine-learning/index.ts b/src/machine-learning/index.ts index e541d82b35..433832c358 100644 --- a/src/machine-learning/index.ts +++ b/src/machine-learning/index.ts @@ -31,7 +31,6 @@ export { TFLiteModel, } from './machine-learning'; export { - AutoMLTfliteModelOptions, GcsTfliteModelOptions, ListModelsOptions, ModelOptions, diff --git a/src/machine-learning/machine-learning-api-client.ts b/src/machine-learning/machine-learning-api-client.ts index cb4c32963b..7ae1c3436a 100644 --- a/src/machine-learning/machine-learning-api-client.ts +++ b/src/machine-learning/machine-learning-api-client.ts @@ -38,16 +38,7 @@ export interface GcsTfliteModelOptions extends ModelOptionsBase { }; } -/** - * @deprecated AutoMLTfliteModelOptions will be removed in the next major version. - */ -export interface AutoMLTfliteModelOptions extends ModelOptionsBase { - tfliteModel: { - automlModel: string; - }; -} - -export type ModelOptions = ModelOptionsBase | GcsTfliteModelOptions | AutoMLTfliteModelOptions; +export type ModelOptions = ModelOptionsBase | GcsTfliteModelOptions; /** * Interface representing options for listing Models. @@ -108,7 +99,6 @@ export interface ModelContent { }; readonly tfliteModel?: { readonly gcsTfliteUri?: string; - readonly automlModel?: string; readonly sizeBytes: number; }; diff --git a/src/machine-learning/machine-learning-namespace.ts b/src/machine-learning/machine-learning-namespace.ts index e02601dd60..7c5786fdbb 100644 --- a/src/machine-learning/machine-learning-namespace.ts +++ b/src/machine-learning/machine-learning-namespace.ts @@ -22,7 +22,6 @@ import { TFLiteModel as TTFLiteModel, } from './machine-learning'; import { - AutoMLTfliteModelOptions as TAutoMLTfliteModelOptions, GcsTfliteModelOptions as TGcsTfliteModelOptions, ListModelsOptions as TListModelsOptions, ModelOptions as TModelOptions, @@ -80,13 +79,6 @@ export namespace machineLearning { */ export type TFLiteModel = TTFLiteModel; - /** - * Type alias to {@link firebase-admin.machine-learning#AutoMLTfliteModelOptions}. - * - * @deprecated AutoMLTfliteModelOptions will be removed in the next major version. - */ - export type AutoMLTfliteModelOptions = TAutoMLTfliteModelOptions; - /** * Type alias to {@link firebase-admin.machine-learning#GcsTfliteModelOptions}. */ diff --git a/src/machine-learning/machine-learning.ts b/src/machine-learning/machine-learning.ts index 1db987e421..98b956c85c 100644 --- a/src/machine-learning/machine-learning.ts +++ b/src/machine-learning/machine-learning.ts @@ -40,9 +40,6 @@ export interface ListModelsResult { /** * A TensorFlow Lite Model output object - * - * One of either the `gcsTfliteUri` or `automlModel` properties will be - * defined. */ export interface TFLiteModel { /** The size of the model. */ @@ -50,13 +47,6 @@ export interface TFLiteModel { /** The URI from which the model was originally provided to Firebase. */ readonly gcsTfliteUri?: string; - /** - * The AutoML model reference from which the model was originally provided - * to Firebase. - * - * @deprecated AutoML model support will be removed in the next major version. - */ - readonly automlModel?: string; } /** @@ -400,11 +390,9 @@ export class Model { } const tmpModel = deepCopy(model); - // If tflite Model is specified, it must have a source consisting of - // oneof {gcsTfliteUri, automlModel} + // If tflite Model is specified, it must have a source of {gcsTfliteUri} if (model.tfliteModel && - !validator.isNonEmptyString(model.tfliteModel.gcsTfliteUri) && - !validator.isNonEmptyString(model.tfliteModel.automlModel)) { + !validator.isNonEmptyString(model.tfliteModel.gcsTfliteUri)) { // If we have some other source, ignore the whole tfliteModel. delete (tmpModel as any).tfliteModel; } diff --git a/test/integration/machine-learning.spec.ts b/test/integration/machine-learning.spec.ts index 900bbaa699..b44ebdc1e2 100644 --- a/test/integration/machine-learning.spec.ts +++ b/test/integration/machine-learning.spec.ts @@ -17,11 +17,10 @@ import path = require('path'); import * as chai from 'chai'; -import { projectId } from './setup'; import { Bucket } from '@google-cloud/storage'; import { getStorage } from '../../lib/storage/index'; import { - AutoMLTfliteModelOptions, GcsTfliteModelOptions, Model, ModelOptions, getMachineLearning, + GcsTfliteModelOptions, Model, ModelOptions, getMachineLearning, } from '../../lib/machine-learning/index'; const expect = chai.expect; @@ -104,31 +103,6 @@ describe('admin.machineLearning', () => { }); }); - it('creates a new Model with valid AutoML TFLite ModelFormat', function () { - // AutoML models require verification. This takes between 20 and 60 seconds - this.timeout(60000); // Allow up to 60 seconds for this test. - return getAutoMLModelReference() - .then((automlRef: string) => { - if (!automlRef) { - this.skip(); - return; - } - const modelOptions: ModelOptions = { - displayName: 'node-integ-test-create-automl', - tags: ['tagAutoml'], - tfliteModel: { automlModel: automlRef } - }; - return getMachineLearning().createModel(modelOptions) - .then((model) => { - return model.waitForUnlocked(55000) - .then(() => { - scheduleForDelete(model); - verifyModel(model, modelOptions); - }); - }); - }); - }); - it('creates a new Model with invalid ModelFormat', () => { // Upload a file to default gcs bucket const modelOptions: ModelOptions = { @@ -233,33 +207,6 @@ describe('admin.machineLearning', () => { }); }); - it('updates the automl model', function () { - // AutoML models require verification. This takes between 20 and 60 seconds - this.timeout(60000); // Allow up to 60 seconds for this test. - return createTemporaryModel({ - displayName: 'node-integ-test-update-automl' - }).then((model) => { - - return getAutoMLModelReference() - .then((automlRef: string) => { - if (!automlRef) { - this.skip(); - return; - } - const modelOptions: ModelOptions = { - tfliteModel: { automlModel: automlRef }, - }; - return getMachineLearning().updateModel(model.modelId, modelOptions) - .then((updatedModel) => { - return updatedModel.waitForUnlocked(55000) - .then(() => { - verifyModel(updatedModel, modelOptions); - }); - }); - }); - }); - }); - it('can update more than 1 field', () => { const DISPLAY_NAME = 'node-integ-test-update-3b'; const TAGS = ['node-integ-tag-1', 'node-integ-tag-2']; @@ -540,8 +487,6 @@ function verifyModel(model: Model, expectedOptions: ModelOptions): void { } if ((expectedOptions as GcsTfliteModelOptions).tfliteModel?.gcsTfliteUri !== undefined) { verifyGcsTfliteModel(model, (expectedOptions as GcsTfliteModelOptions)); - } else if ((expectedOptions as AutoMLTfliteModelOptions).tfliteModel?.automlModel !== undefined) { - verifyAutomlTfliteModel(model, (expectedOptions as AutoMLTfliteModelOptions)); } else { expect(model.validationError).to.equal('No model file has been uploaded.'); } @@ -558,35 +503,3 @@ function verifyGcsTfliteModel(model: Model, expectedOptions: GcsTfliteModelOptio expect(model.validationError).to.be.undefined; } } - -function verifyAutomlTfliteModel(model: Model, expectedOptions: AutoMLTfliteModelOptions): void { - const expectedAutomlReference = expectedOptions.tfliteModel.automlModel; - expect(model.tfliteModel!.automlModel).to.equal(expectedAutomlReference); - expect(model.validationError).to.be.undefined; - expect(model.tfliteModel!.sizeBytes).to.not.be.undefined; - expect(model.modelHash).to.not.be.undefined; -} - -function getAutoMLModelReference(): Promise { - let automl; - try { - const { AutoMlClient } = require('@google-cloud/automl').v1; - automl = new AutoMlClient(); - } - catch (error) { - // Returning an empty string will result in skipping the test. - return Promise.resolve(''); - } - - const parent = automl.locationPath(projectId, 'us-central1'); - return automl.listModels({ parent, filter:'displayName=admin_sdk_integ_test1' }) - .then(([models]: [any]) => { - let modelRef = ''; - for (const model of models) { - modelRef = model.name; - } - return modelRef; - }) - // Skip the test if anything goes wrong with listing the models. - .catch(() => ''); -} diff --git a/test/unit/machine-learning/machine-learning-api-client.spec.ts b/test/unit/machine-learning/machine-learning-api-client.spec.ts index 01f6936869..9fbb94066e 100644 --- a/test/unit/machine-learning/machine-learning-api-client.spec.ts +++ b/test/unit/machine-learning/machine-learning-api-client.spec.ts @@ -64,20 +64,6 @@ describe('MachineLearningApiClient', () => { sizeBytes: 2220022, }, }; - const MODEL_RESPONSE_AUTOML = { - name: 'projects/test-project/models/3456789', - createTime: '2020-07-15T18:12:25.123987Z', - updateTime: '2020-07-15T19:15:32.965435Z', - etag: 'etag345', - modelHash: 'modelHash345', - displayName: 'model_automl', - tags: ['tag_automl'], - state: { published: true }, - tfliteModel: { - automlModel: 'projects/65432/models/ICN123', - sizeBytes: 3330033, - }, - }; const PROJECT_ID = 'test-project'; const PROJECT_NUMBER = '1234567'; @@ -105,10 +91,6 @@ describe('MachineLearningApiClient', () => { }, done: false, }; - const OPERATION_AUTOML_RESPONSE = { - done: true, - response: MODEL_RESPONSE_AUTOML, - }; const LOCKED_MODEL_RESPONSE = { name: 'projects/test-project/models/1234567', createTime: '2020-02-07T23:45:23.288047Z', @@ -179,12 +161,6 @@ describe('MachineLearningApiClient', () => { gcsTfliteUri: 'gcsUri1', }, }; - const AUTOML_OPTIONS: ModelOptions = { - displayName: 'name3', - tfliteModel: { - automlModel: 'automlModel', - }, - }; const invalidContent: any[] = [null, undefined, {}, { tags: [] }]; invalidContent.forEach((content) => { @@ -236,19 +212,6 @@ describe('MachineLearningApiClient', () => { }); }); - it('should accept AutoML options', () => { - const stub = sinon - .stub(HttpClient.prototype, 'send') - .resolves(utils.responseFrom(OPERATION_AUTOML_RESPONSE)); - stubs.push(stub); - return apiClient.createModel(AUTOML_OPTIONS) - .then((resp) => { - expect(resp.done).to.be.true; - expect(resp.name).to.be.undefined; - expect(resp.response).to.deep.equal(MODEL_RESPONSE_AUTOML); - }); - }); - it('should resolve with error when the operation fails', () => { const stub = sinon .stub(HttpClient.prototype, 'send') @@ -302,20 +265,12 @@ describe('MachineLearningApiClient', () => { gcsTfliteUri: 'gcsUri1', }, }; - const AUTOML_OPTIONS: ModelOptions = { - displayName: 'name3', - tfliteModel: { - automlModel: 'automlModel', - }, - }; const NAME_ONLY_MASK_LIST = ['displayName']; const GCS_MASK_LIST = ['displayName', 'tfliteModel.gcsTfliteUri']; - const AUTOML_MASK_LIST = ['displayName', 'tfliteModel.automlModel']; const NAME_ONLY_UPDATE_MASK_STRING = 'updateMask=displayName'; const GCS_UPDATE_MASK_STRING = 'updateMask=displayName,tfliteModel.gcsTfliteUri'; - const AUTOML_UPDATE_MASK_STRING = 'updateMask=displayName,tfliteModel.automlModel'; const invalidOptions: any[] = [null, undefined]; invalidOptions.forEach((option) => { @@ -385,25 +340,6 @@ describe('MachineLearningApiClient', () => { }); }); - it('should resolve with the updated AutoML resource on success', () => { - const stub = sinon - .stub(HttpClient.prototype, 'send') - .resolves(utils.responseFrom(OPERATION_SUCCESS_RESPONSE)); - stubs.push(stub); - return apiClient.updateModel(MODEL_ID, AUTOML_OPTIONS, AUTOML_MASK_LIST) - .then((resp) => { - expect(resp.done).to.be.true; - expect(resp.name).to.be.undefined; - expect(resp.response).to.deep.equal(MODEL_RESPONSE); - expect(stub).to.have.been.calledOnce.and.calledWith({ - method: 'PATCH', - headers: EXPECTED_HEADERS, - url: `${BASE_URL}/projects/test-project/models/${MODEL_ID}?${AUTOML_UPDATE_MASK_STRING}`, - data: AUTOML_OPTIONS, - }); - }); - }); - it('should resolve with error when the operation fails', () => { const stub = sinon .stub(HttpClient.prototype, 'send') From b9bdb47513c8e82da270ed8bf4adc11c398fee16 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:03:58 +0000 Subject: [PATCH 033/323] build(deps-dev): bump @types/request from 2.48.8 to 2.48.12 (#2390) --- package-lock.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 990783fc67..7d772b9404 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1489,9 +1489,9 @@ } }, "@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" }, "@types/chai": { "version": "4.3.5", @@ -1618,9 +1618,9 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "@types/request": { - "version": "2.48.8", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.8.tgz", - "integrity": "sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==", + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", "requires": { "@types/caseless": "*", "@types/node": "*", @@ -1689,9 +1689,9 @@ "dev": true }, "@types/tough-cookie": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", - "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==" + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" }, "@types/uuid": { "version": "9.0.2", From bc1e522ae42528c8d74fcfbf9e85cd4ca35d43fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:10:03 +0000 Subject: [PATCH 034/323] build(deps-dev): bump @types/minimist from 1.2.2 to 1.2.5 (#2389) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d772b9404..0d3d76506b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1582,9 +1582,9 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true }, "@types/mocha": { From de0063517340597ad4c28485120f0d1943e0193c Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 4 Dec 2023 13:24:15 -0500 Subject: [PATCH 035/323] fix(firestore): Export new aggregate types (#2396) * fix(firestore): Export new aggregate types * Run api extractor --- docgen/extras/firebase-admin.firestore.md | 40 ++++++++++++----------- etc/firebase-admin.api.md | 7 ++++ etc/firebase-admin.firestore.api.md | 21 ++++++++++++ src/firestore/firestore-namespace.ts | 7 ++++ src/firestore/index.ts | 7 ++++ 5 files changed, 63 insertions(+), 19 deletions(-) diff --git a/docgen/extras/firebase-admin.firestore.md b/docgen/extras/firebase-admin.firestore.md index 49617a6367..f00750727b 100644 --- a/docgen/extras/firebase-admin.firestore.md +++ b/docgen/extras/firebase-admin.firestore.md @@ -4,30 +4,32 @@ The following externally defined APIs are re-exported from this module entry poi | Symbol | Description | | --- | --- | -| [BulkWriter](https://googleapis.dev/nodejs/firestore/latest/BulkWriter.html) | `BulkWriter` type from the `@google-cloud/firestore` package. | -| [BulkWriterOptions](https://googleapis.dev/nodejs/firestore/latest/global.html#BulkWriterOptions) | `BulkWriterOptions` type from the `@google-cloud/firestore` package. | +| [BulkWriter](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/bulkwriter) | `BulkWriter` type from the `@google-cloud/firestore` package. | +| [AggregateField](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/aggregatefield) | `AggregateField` type from the `@google-cloud/firestore` package. | +| [BulkWriterOptions](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/bulkwriter) | `BulkWriterOptions` type from the `@google-cloud/firestore` package. | | [BundleBuilder](https://googleapis.dev/nodejs/firestore/latest/BundleBuilder.html) | `BundleBuilder` type from the `@google-cloud/firestore` package. | -| [CollectionGroup](https://googleapis.dev/nodejs/firestore/latest/CollectionGroup.html) | `CollectionGroup` type from the `@google-cloud/firestore` package. | -| [CollectionReference](https://googleapis.dev/nodejs/firestore/latest/CollectionReference.html) | `CollectionReference` type from the `@google-cloud/firestore` package. | -| [DocumentChange](https://googleapis.dev/nodejs/firestore/latest/DocumentChange.html) | `DocumentChange` type from the `@google-cloud/firestore` package. | +| [CollectionGroup](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/collectiongroup) | `CollectionGroup` type from the `@google-cloud/firestore` package. | +| [CollectionReference](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/collectionreference) | `CollectionReference` type from the `@google-cloud/firestore` package. | +| [DocumentChange](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/documentchange) | `DocumentChange` type from the `@google-cloud/firestore` package. | | [DocumentData](https://googleapis.dev/nodejs/firestore/latest/global.html#DocumentData) | `DocumentData` type from the `@google-cloud/firestore` package. | -| [DocumentReference](https://googleapis.dev/nodejs/firestore/latest/DocumentReference.html) | `DocumentReference` type from the `@google-cloud/firestore` package. | -| [DocumentSnapshot](https://googleapis.dev/nodejs/firestore/latest/DocumentSnapshot.html) | `DocumentSnapshot` type from the `@google-cloud/firestore` package. | -| [FieldPath](https://googleapis.dev/nodejs/firestore/latest/FieldPath.html) | `FieldPath` type from the `@google-cloud/firestore` package. | -| [FieldValue](https://googleapis.dev/nodejs/firestore/latest/FieldValue.html) | `FieldValue` type from the `@google-cloud/firestore` package. | -| [Firestore](https://googleapis.dev/nodejs/firestore/latest/Firestore.html) | `Firestore` type from the `@google-cloud/firestore` package. | +| [DocumentReference](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/documentreference) | `DocumentReference` type from the `@google-cloud/firestore` package. | +| [DocumentSnapshot](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/documentsnapshot) | `DocumentSnapshot` type from the `@google-cloud/firestore` package. | +| [FieldPath](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/fieldpath) | `FieldPath` type from the `@google-cloud/firestore` package. | +| [FieldValue](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/fieldvalue) | `FieldValue` type from the `@google-cloud/firestore` package. | +| [Filter](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/filter) | `Filter` type from the `@google-cloud/firestore` package. | +| [Firestore](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/firestore) | `Firestore` type from the `@google-cloud/firestore` package. | | [FirestoreDataConverter](https://googleapis.dev/nodejs/firestore/latest/global.html#FirestoreDataConverter) | `FirestoreDataConverter` type from the `@google-cloud/firestore` package. | -| [GeoPoint](https://googleapis.dev/nodejs/firestore/latest/GeoPoint.html) | `GeoPoint` type from the `@google-cloud/firestore` package. | +| [GeoPoint](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/geopoint) | `GeoPoint` type from the `@google-cloud/firestore` package. | | [GrpcStatus](https://googleapis.dev/nodejs/firestore/latest/global.html#GrpcStatus) | `GrpcStatus` type from the `@google-cloud/firestore` package. | | [Precondition](https://googleapis.dev/nodejs/firestore/latest/global.html#Precondition) | `Precondition` type from the `@google-cloud/firestore` package. | -| [Query](https://googleapis.dev/nodejs/firestore/latest/Query.html) | `Query` type from the `@google-cloud/firestore` package. | -| [QueryDocumentSnapshot](https://googleapis.dev/nodejs/firestore/latest/QueryDocumentSnapshot.html) | `QueryDocumentSnapshot` type from the `@google-cloud/firestore` package. | -| [QueryPartition](https://googleapis.dev/nodejs/firestore/latest/QueryPartition.html) | `QueryPartition` type from the `@google-cloud/firestore` package. | -| [QuerySnapshot](https://googleapis.dev/nodejs/firestore/latest/QuerySnapshot.html) | `QuerySnapshot` type from the `@google-cloud/firestore` package. | +| [Query](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/query) | `Query` type from the `@google-cloud/firestore` package. | +| [QueryDocumentSnapshot](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/querydocumentsnapshot) | `QueryDocumentSnapshot` type from the `@google-cloud/firestore` package. | +| [QueryPartition](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/querypartition) | `QueryPartition` type from the `@google-cloud/firestore` package. | +| [QuerySnapshot](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/querysnapshot) | `QuerySnapshot` type from the `@google-cloud/firestore` package. | | [ReadOptions](https://googleapis.dev/nodejs/firestore/latest/global.html#ReadOptions) | `ReadOptions` type from the `@google-cloud/firestore` package. | | [SetOptions](https://googleapis.dev/nodejs/firestore/latest/global.html#SetOptions) | `SetOptions` type from the `@google-cloud/firestore` package. | -| [Timestamp](https://googleapis.dev/nodejs/firestore/latest/Timestamp.html) | `Timestamp` type from the `@google-cloud/firestore` package. | -| [Transaction](https://googleapis.dev/nodejs/firestore/latest/Transaction.html) | `Transaction` type from the `@google-cloud/firestore` package. | -| [WriteBatch](https://googleapis.dev/nodejs/firestore/latest/WriteBatch.html) | `WriteBatch` type from the `@google-cloud/firestore` package. | -| [WriteResult](https://googleapis.dev/nodejs/firestore/latest/WriteResult.html) | `WriteResult` type from the `@google-cloud/firestore` package. | +| [Timestamp](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/timestamp) | `Timestamp` type from the `@google-cloud/firestore` package. | +| [Transaction](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/transaction) | `Transaction` type from the `@google-cloud/firestore` package. | +| [WriteBatch](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/writebatch) | `WriteBatch` type from the `@google-cloud/firestore` package. | +| [WriteResult](https://cloud.google.com/nodejs/docs/reference/firestore/latest/firestore/writeresult) | `WriteResult` type from the `@google-cloud/firestore` package. | | [setLogFunction](https://googleapis.dev/nodejs/firestore/latest/global.html#setLogFunction) | `setLogFunction` function from the `@google-cloud/firestore` package. | diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index 703c1ad5e6..ceb4ff1ab4 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -243,6 +243,13 @@ export function firestore(app?: App): _firestore.Firestore; export namespace firestore { import v1beta1 = _firestore.v1beta1; import v1 = _firestore.v1; + import AggregateField = _firestore.AggregateField; + import AggregateFieldType = _firestore.AggregateFieldType; + import AggregateQuery = _firestore.AggregateQuery; + import AggregateQuerySnapshot = _firestore.AggregateQuerySnapshot; + import AggregateSpecData = _firestore.AggregateSpecData; + import AggregateSpec = _firestore.AggregateSpec; + import AggregateType = _firestore.AggregateType; import BulkWriter = _firestore.BulkWriter; import BulkWriterOptions = _firestore.BulkWriterOptions; import BundleBuilder = _firestore.BundleBuilder; diff --git a/etc/firebase-admin.firestore.api.md b/etc/firebase-admin.firestore.api.md index 960e320daf..80c0e5d9c3 100644 --- a/etc/firebase-admin.firestore.api.md +++ b/etc/firebase-admin.firestore.api.md @@ -8,6 +8,13 @@ import { AddPrefixToKeys } from '@google-cloud/firestore'; import { Agent } from 'http'; +import { AggregateField } from '@google-cloud/firestore'; +import { AggregateFieldType } from '@google-cloud/firestore'; +import { AggregateQuery } from '@google-cloud/firestore'; +import { AggregateQuerySnapshot } from '@google-cloud/firestore'; +import { AggregateSpec } from '@google-cloud/firestore'; +import { AggregateSpecData } from '@google-cloud/firestore'; +import { AggregateType } from '@google-cloud/firestore'; import { BulkWriter } from '@google-cloud/firestore'; import { BulkWriterOptions } from '@google-cloud/firestore'; import { BundleBuilder } from '@google-cloud/firestore'; @@ -53,6 +60,20 @@ import { WriteResult } from '@google-cloud/firestore'; export { AddPrefixToKeys } +export { AggregateField } + +export { AggregateFieldType } + +export { AggregateQuery } + +export { AggregateQuerySnapshot } + +export { AggregateSpec } + +export { AggregateSpecData } + +export { AggregateType } + export { BulkWriter } export { BulkWriterOptions } diff --git a/src/firestore/firestore-namespace.ts b/src/firestore/firestore-namespace.ts index 98b081d774..67733fb8f6 100644 --- a/src/firestore/firestore-namespace.ts +++ b/src/firestore/firestore-namespace.ts @@ -26,6 +26,13 @@ export namespace firestore { export import v1beta1 = _firestore.v1beta1; export import v1 = _firestore.v1; + export import AggregateField = _firestore.AggregateField; + export import AggregateFieldType = _firestore.AggregateFieldType; + export import AggregateQuery = _firestore.AggregateQuery; + export import AggregateQuerySnapshot = _firestore.AggregateQuerySnapshot; + export import AggregateSpecData = _firestore.AggregateSpecData; + export import AggregateSpec = _firestore.AggregateSpec; + export import AggregateType = _firestore.AggregateType; export import BulkWriter = _firestore.BulkWriter; export import BulkWriterOptions = _firestore.BulkWriterOptions; export import BundleBuilder = _firestore.BundleBuilder; diff --git a/src/firestore/index.ts b/src/firestore/index.ts index eafcc5367b..ff6954cefa 100644 --- a/src/firestore/index.ts +++ b/src/firestore/index.ts @@ -28,6 +28,13 @@ import { DEFAULT_DATABASE_ID } from '@google-cloud/firestore/build/src/path'; export { AddPrefixToKeys, + AggregateField, + AggregateFieldType, + AggregateQuery, + AggregateQuerySnapshot, + AggregateSpecData, + AggregateSpec, + AggregateType, BulkWriter, BulkWriterOptions, BundleBuilder, From 8b98b79aed5678b4f675245dc20d3b225f9b8160 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 14:57:04 -0500 Subject: [PATCH 036/323] build(deps-dev): bump @types/mocha from 10.0.1 to 10.0.6 (#2400) Bumps [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) from 10.0.1 to 10.0.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha) --- updated-dependencies: - dependency-name: "@types/mocha" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d3d76506b..b0eb9b720d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1588,9 +1588,9 @@ "dev": true }, "@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", + "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", "dev": true }, "@types/nock": { From 653f014a19df530a548f5edabed3f71cfd5466be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:01:57 +0000 Subject: [PATCH 037/323] build(deps-dev): bump sinon and @types/sinon (#2398) --- package-lock.json | 54 ++++++++++++++++++++++++++++++++--------------- package.json | 4 ++-- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index b0eb9b720d..45e9fde0ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1392,9 +1392,9 @@ } }, "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0" @@ -1664,9 +1664,9 @@ } }, "@types/sinon": { - "version": "10.0.14", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.14.tgz", - "integrity": "sha512-mn72up6cjaMyMuaPaa/AwKf6WtsSRysQC7wxFkCm1XcOKXPM1z+5Y4H5wjIVBz4gdAkjvZxVVfjA6ba1nHr5WQ==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.2.tgz", + "integrity": "sha512-Zt6heIGsdqERkxctIpvN5Pv3edgBrhoeb3yHyxffd4InN0AX2SVNKSrhdDZKGQICVOxWP/q4DyhpfPNMSrpIiA==", "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" @@ -1683,9 +1683,9 @@ } }, "@types/sinonjs__fake-timers": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", "dev": true }, "@types/tough-cookie": { @@ -6974,9 +6974,9 @@ "dev": true }, "nise": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", - "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", + "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", "dev": true, "requires": { "@sinonjs/commons": "^2.0.0", @@ -6994,6 +6994,26 @@ "requires": { "type-detect": "4.0.8" } + }, + "@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } + } } } }, @@ -8862,16 +8882,16 @@ "dev": true }, "sinon": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", - "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.3.0", + "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/samsam": "^8.0.0", "diff": "^5.1.0", - "nise": "^5.1.4", + "nise": "^5.1.5", "supports-color": "^7.2.0" }, "dependencies": { diff --git a/package.json b/package.json index fc1cfe9edd..fef7285063 100644 --- a/package.json +++ b/package.json @@ -226,7 +226,7 @@ "@types/nock": "^11.1.0", "@types/request": "^2.47.0", "@types/request-promise": "^4.1.41", - "@types/sinon": "^10.0.2", + "@types/sinon": "^17.0.2", "@types/sinon-chai": "^3.0.0", "@types/uuid": "^9.0.1", "@typescript-eslint/eslint-plugin": "^5.0.0", @@ -255,7 +255,7 @@ "request": "^2.75.0", "request-promise": "^4.1.1", "run-sequence": "^2.2.1", - "sinon": "^15.0.1", + "sinon": "^17.0.1", "sinon-chai": "^3.0.0", "ts-node": "^10.2.0", "typescript": "^4.6.4", From b334dca560445e907f5a77f4b9e358410a47513b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:06:29 +0000 Subject: [PATCH 038/323] build(deps-dev): bump @types/firebase-token-generator (#2399) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45e9fde0ec..d6807bc4d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1539,9 +1539,9 @@ } }, "@types/firebase-token-generator": { - "version": "2.0.31", - "resolved": "https://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.31.tgz", - "integrity": "sha512-mR6GuDPxFiD7nZ3x2NddRvo42ZBS22PHHNdAWuQvqp/1LfiYshZ6PzJD2+JOyLw5ZErgmw7F8R1nfpXnvBOxGg==", + "version": "2.0.33", + "resolved": "https://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.33.tgz", + "integrity": "sha512-FNZyTEHIE5Kq55QpVuyK7ZUJE/yoegRXalGVhbUh8+xC9pa1BUP7zspY+P5ci5SYKgoHjYQruC9gulFCn576Zw==", "dev": true }, "@types/http-errors": { From 14dea588c00ea38f027802e983a40c3ff966edf8 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 6 Dec 2023 15:03:30 -0500 Subject: [PATCH 039/323] build(deps): Bump typescript, database-compat (#2403) Upgraded @firebase/database-compat to v1.0.2 and @firebase/database-types to v1.0.0 Upgraded typescript to ^5.1.6 Upgraded @types/node to ^20.10.3 Upgraded @google-cloud/storage to ^7.7.0 --- etc/firebase-admin.storage.api.md | 4 +- package-lock.json | 2192 +++++++++++++---------------- package.json | 14 +- src/utils/api-request.ts | 4 +- test/unit/index.spec.ts | 2 +- 5 files changed, 955 insertions(+), 1261 deletions(-) diff --git a/etc/firebase-admin.storage.api.md b/etc/firebase-admin.storage.api.md index b3727679ce..ab798e8fca 100644 --- a/etc/firebase-admin.storage.api.md +++ b/etc/firebase-admin.storage.api.md @@ -8,10 +8,10 @@ import { Agent } from 'http'; import { Bucket } from '@google-cloud/storage'; -import { File } from '@google-cloud/storage'; +import { File as File_2 } from '@google-cloud/storage'; // @public -export function getDownloadURL(file: File): Promise; +export function getDownloadURL(file: File_2): Promise; // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts // diff --git a/package-lock.json b/package-lock.json index d6807bc4d0..a120760e29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,43 +21,108 @@ } }, "@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/compat-data": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", - "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", "dev": true }, "@babel/core": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", - "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", + "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.5", + "@babel/parser": "^7.23.5", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -67,28 +132,28 @@ } }, "@babel/generator": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz", - "integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", "dev": true, "requires": { - "@babel/types": "^7.21.4", + "@babel/types": "^7.23.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" } }, "@babel/helper-compilation-targets": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", - "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "requires": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "dependencies": { "lru-cache": { @@ -115,91 +180,107 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, + "@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "requires": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, "@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "requires": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.15" } }, "@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.2", - "@babel/types": "^7.21.2" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "requires": { - "@babel/types": "^7.20.2" + "@babel/types": "^7.22.5" } }, "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", "dev": true }, "@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", + "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", "dev": true, "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.5", + "@babel/types": "^7.23.5" } }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -262,219 +343,56 @@ } }, "@babel/parser": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz", - "integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "dev": true }, "@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", + "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", + "@babel/parser": "^7.23.5", + "@babel/types": "^7.23.5", "debug": "^4.1.0", "globals": "^11.1.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, - "requires": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - } - }, - "@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", - "dev": true, - "requires": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", - "dev": true - }, - "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, "@babel/types": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", - "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", + "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -509,15 +427,15 @@ } }, "@eslint-community/regexpp": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.0.tgz", - "integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true }, "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -529,56 +447,12 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } } }, "@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", + "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", "dev": true }, "@fastify/busboy": { @@ -606,9 +480,9 @@ } }, "@firebase/app": { - "version": "0.9.15", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.15.tgz", - "integrity": "sha512-xxQi6mkhRjtXeFUwleSF4zU7lwEH+beNhLE7VmkzEzjEsjAS14QPQPZ35gpgSD+/NigOeho7wgEXd4C/bOkRfA==", + "version": "0.9.25", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.25.tgz", + "integrity": "sha512-fX22gL5USXhOK21Hlh3oTeOzQZ6th6S2JrjXNEpBARmwzuUkqmVGVdsOCIFYIsLpK0dQE3o8xZnLrRg5wnzZ/g==", "dev": true, "requires": { "@firebase/component": "0.6.4", @@ -618,13 +492,18 @@ "tslib": "^2.1.0" } }, + "@firebase/app-check-interop-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz", + "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" + }, "@firebase/app-compat": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.15.tgz", - "integrity": "sha512-ttEbOEtO1SSz27cRPrwXAmrqDjdQ33sQc7rqqQuSMUuPRdYCQEcYdqzpkbvqgdkzGksx2kfH4JqQ6R/hI12nDw==", + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.25.tgz", + "integrity": "sha512-B/JtCp1FsTuzlh1tIGQpYM2AXps21/zlzpFsk5LRsROOTRhBcR2N45AyaONPFD06C0yS0Tw19foxADzHyOSC3A==", "dev": true, "requires": { - "@firebase/app": "0.9.15", + "@firebase/app": "0.9.25", "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", @@ -637,15 +516,14 @@ "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" }, "@firebase/auth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.1.0.tgz", - "integrity": "sha512-5RJQMXG0p/tSvtqpfM8jA+heELjVCgHHASq3F7NglAa/CWUGCAE4g2F4YDPW5stDkvtKKRez0WYAWnbcuQ5P4w==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.4.0.tgz", + "integrity": "sha512-SfFXZCHDbY+7oSR52NSwx0U7LjYiA+N8imloxphCf3/F+MFty/+mhdjSXGtrJYd0Gbud/qcyedfn2XnWJeIB/g==", "dev": true, "requires": { "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", - "@react-native-async-storage/async-storage": "^1.18.1", "node-fetch": "2.6.7", "tslib": "^2.1.0" }, @@ -662,12 +540,12 @@ } }, "@firebase/auth-compat": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.4.tgz", - "integrity": "sha512-B2DctJDJ05djBwebNEdC3zbKWzKdIdxpbca8u9P/NSjqaJNSFq3fhz8h8bjlS9ufSrxaQWFSJMMH3dRmx3FlEA==", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.9.tgz", + "integrity": "sha512-Fw03i7vduIciEBG4imLtA1duJbljgkfbxiBo/EuekcB+BnPxHp+e8OGMUfemPYeO7Munj6kUC9gr5DelsQkiNA==", "dev": true, "requires": { - "@firebase/auth": "1.1.0", + "@firebase/auth": "1.4.0", "@firebase/auth-types": "0.12.0", "@firebase/component": "0.6.4", "@firebase/util": "1.9.3", @@ -707,10 +585,11 @@ } }, "@firebase/database": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.14.4.tgz", - "integrity": "sha512-+Ea/IKGwh42jwdjCyzTmeZeLM3oy1h0mFPsTy6OqCWzcu/KFqRAr5Tt1HRCOBlNOdbh84JPZC47WLU18n2VbxQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.2.tgz", + "integrity": "sha512-8X6NBJgUQzDz0xQVaCISoOLINKat594N2eBbMR3Mu/MH/ei4WM+aAMlsNzngF22eljXu1SILP5G3evkyvsG3Ng==", "requires": { + "@firebase/app-check-interop-types": "0.3.0", "@firebase/auth-interop-types": "0.2.1", "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", @@ -720,22 +599,22 @@ } }, "@firebase/database-compat": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.3.4.tgz", - "integrity": "sha512-kuAW+l+sLMUKBThnvxvUZ+Q1ZrF/vFJ58iUY9kAcbX48U03nVzIF6Tmkf0p3WVQwMqiXguSgtOPIB6ZCeF+5Gg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.2.tgz", + "integrity": "sha512-09ryJnXDvuycsxn8aXBzLhBTuCos3HEnCOBWY6hosxfYlNCGnLvG8YMlbSAt5eNhf7/00B095AEfDsdrrLjxqA==", "requires": { "@firebase/component": "0.6.4", - "@firebase/database": "0.14.4", - "@firebase/database-types": "0.10.4", + "@firebase/database": "1.0.2", + "@firebase/database-types": "1.0.0", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", "tslib": "^2.1.0" } }, "@firebase/database-types": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.10.4.tgz", - "integrity": "sha512-dPySn0vJ/89ZeBac70T+2tWWPiJXWbmRygYv0smT5TfE3hDrQ09eKMF3Y+vMlTdrMWq7mUdYW5REWPSGH4kAZQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.0.tgz", + "integrity": "sha512-SjnXStoE0Q56HcFgNQ+9SsmJc0c8TqGARdI/T44KXy+Ets3r6x/ivhQozT66bMnCEjJRywYoxNurRTMlZF8VNg==", "requires": { "@firebase/app-types": "0.9.0", "@firebase/util": "1.9.3" @@ -792,9 +671,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.6.0.tgz", - "integrity": "sha512-/pQl5pXePhVRvgaR+huKIlSrjEjmxv5pdMieW09Sbo7pa1I9ofQ54y7QN/z9xZ1Yj2j9znfMPAmae1F+Tt4q4g==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.7.0.tgz", + "integrity": "sha512-EMCEY+6JiIkx7Dt8NXVGGjy1vRdSGdHkoqZoqjJw7cEBkT7ZkX0c7puedfn1MamnzW5SX4xoa2jVq5u7OWBmkQ==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", @@ -847,35 +726,14 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } } }, "@humanwhocodes/module-importer": { @@ -885,9 +743,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -903,15 +761,6 @@ "resolve-from": "^5.0.0" }, "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -991,9 +840,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true }, "@jridgewell/set-array": { @@ -1009,21 +858,13 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - } + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@mapbox/node-pre-gyp": { @@ -1041,12 +882,33 @@ "rimraf": "^3.0.2", "semver": "^7.3.5", "tar": "^6.1.11" + }, + "dependencies": { + "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" + } + }, + "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" + } + } } }, "@microsoft/api-extractor": { - "version": "7.38.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.3.tgz", - "integrity": "sha512-xt9iYyC5f39281j77JTA9C3ISJpW1XWkCcnw+2vM78CPnro6KhPfwQdPDfwS5JCPNuq0grm8cMdPUOPvrchDWw==", + "version": "7.38.4", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.4.tgz", + "integrity": "sha512-0SW3Of6os4bAYlHdiD1hJx/ygXr7vRZi92E1pREufNERH87aZ0B9Vhku/4Mj2Oxp58gyV5d18t7uZold6HCSEw==", "dev": true, "requires": { "@microsoft/api-extractor-model": "7.28.2", @@ -1096,15 +958,6 @@ "string-argv": "~0.3.1" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, "colors": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", @@ -1285,15 +1138,6 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "optional": true }, - "@react-native-async-storage/async-storage": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.19.1.tgz", - "integrity": "sha512-5QXuGCtB+HL3VtKL2JN3+6t4qh8VXizK+aGDAv6Dqiq3MLrzgZHb4tjVgtEWMd8CcDtD/JqaAI1b6/EaYGtFIA==", - "dev": true, - "requires": { - "merge-options": "^3.0.4" - } - }, "@rushstack/node-core-library": { "version": "3.45.5", "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.5.tgz", @@ -1365,15 +1209,6 @@ "string-argv": "~0.3.1" }, "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, "colors": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", @@ -1453,9 +1288,9 @@ "dev": true }, "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, "@types/argparse": { @@ -1465,18 +1300,18 @@ "dev": true }, "@types/bcrypt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", - "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", + "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", "dev": true, "requires": { "@types/node": "*" } }, "@types/bluebird": { - "version": "3.5.38", - "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.38.tgz", - "integrity": "sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==", + "version": "3.5.42", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.42.tgz", + "integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==", "dev": true }, "@types/body-parser": { @@ -1494,15 +1329,15 @@ "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" }, "@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "version": "4.3.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", + "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", "dev": true }, "@types/chai-as-promised": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", - "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", "dev": true, "requires": { "@types/chai": "*" @@ -1550,9 +1385,9 @@ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "@types/jsonwebtoken": { @@ -1565,9 +1400,9 @@ } }, "@types/lodash": { - "version": "4.14.199", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz", - "integrity": "sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg==", + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", "dev": true }, "@types/long": { @@ -1581,6 +1416,12 @@ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, "@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", @@ -1603,9 +1444,12 @@ } }, "@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" + "version": "20.10.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", + "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", + "requires": { + "undici-types": "~5.26.4" + } }, "@types/qs": { "version": "6.9.10", @@ -1629,9 +1473,9 @@ } }, "@types/request-promise": { - "version": "4.1.48", - "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.48.tgz", - "integrity": "sha512-sLsfxfwP5G3E3U64QXxKwA6ctsxZ7uKyl4I28pMj3JvV+ztWECRns73GL71KMOOJME5u1A5Vs5dkBqyiR1Zcnw==", + "version": "4.1.51", + "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.51.tgz", + "integrity": "sha512-qVcP9Fuzh9oaAh8oPxiSoWMFGnWKkJDknnij66vi09Yiy62bsSDqtd+fG5kIM9wLLgZsRP3Y6acqj9O/v2ZtRw==", "dev": true, "requires": { "@types/bluebird": "*", @@ -1639,9 +1483,9 @@ } }, "@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", "dev": true }, "@types/send": { @@ -1694,9 +1538,9 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" }, "@types/uuid": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", - "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", + "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", "dev": true }, "@typescript-eslint/eslint-plugin": { @@ -1727,49 +1571,6 @@ "@typescript-eslint/types": "5.62.0", "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - } - }, - "@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - } - } } }, "@typescript-eslint/scope-manager": { @@ -1841,6 +1642,12 @@ "eslint-visitor-keys": "^3.3.0" } }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1857,9 +1664,9 @@ } }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true }, "acorn-jsx": { @@ -1869,17 +1676,18 @@ "dev": true }, "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", "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==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "optional": true, "requires": { - "debug": "4" + "debug": "^4.3.4" } }, "aggregate-error": { @@ -2220,10 +2028,13 @@ "dev": true }, "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } }, "arr-diff": { "version": "4.0.0", @@ -2355,6 +2166,21 @@ "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true }, + "arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + } + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -2493,39 +2319,20 @@ "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "is-descriptor": "^1.0.0" } }, "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } } } @@ -2582,6 +2389,16 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -2598,15 +2415,15 @@ "dev": true }, "browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" } }, "buffer": { @@ -2667,13 +2484,14 @@ } }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" } }, "callsites": { @@ -2689,9 +2507,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001477", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001477.tgz", - "integrity": "sha512-lZim4iUHhGcy5p+Ri/G7m84hJwncj+Kz7S5aD4hoQfslKZJgt0tHc/hafVbqHC5bbhHb+mrW2JOUHkI5KH7toQ==", + "version": "1.0.30001566", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", + "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", "dev": true }, "caseless": { @@ -2701,18 +2519,18 @@ "dev": true }, "chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", "dev": true, "requires": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" } }, "chai-as-promised": { @@ -2744,10 +2562,13 @@ } }, "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "requires": { + "get-func-name": "^2.0.2" + } }, "child-process-promise": { "version": "2.2.1", @@ -2906,13 +2727,12 @@ "dev": true }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -3051,9 +2871,9 @@ "dev": true }, "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true }, "compressible": { @@ -3294,12 +3114,24 @@ "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", "dev": true }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "requires": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } @@ -3314,33 +3146,14 @@ "isobject": "^3.0.1" }, "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } } } @@ -3449,9 +3262,9 @@ } }, "electron-to-chromium": { - "version": "1.4.357", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.357.tgz", - "integrity": "sha512-UTkCbNTAcGXABmEnQrGcW4m3cG6fcyBfD4KDF0iyEAlbrGZiY9dmslyDAGOD1Kr5biN2F743Y30aRCOtau35Vw==", + "version": "1.4.605", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.605.tgz", + "integrity": "sha512-V52j+P5z6cdRqTjPR/bYNxx7ETCHIkm5VIGuyCy3CMrfSnbEpIlLnk5oHmZo7gYvDfh2TfHeanB6rawyQ23ktg==", "dev": true }, "emoji-regex": { @@ -3483,25 +3296,26 @@ } }, "es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, "requires": { "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.5", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", + "hasown": "^2.0.0", "internal-slot": "^1.0.5", "is-array-buffer": "^3.0.2", "is-callable": "^1.2.7", @@ -3509,30 +3323,34 @@ "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.12", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" + "which-typed-array": "^1.1.13" } }, "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" } }, "es-to-primitive": { @@ -3601,19 +3419,26 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, "eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", + "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.55.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3646,28 +3471,6 @@ "text-table": "^0.2.0" }, "dependencies": { - "@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", - "dev": true - }, - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3679,12 +3482,6 @@ "which": "^2.0.1" } }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, "eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -3695,23 +3492,12 @@ "estraverse": "^5.2.0" } }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3721,54 +3507,6 @@ "is-glob": "^4.0.3" } }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3788,22 +3526,25 @@ "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } } }, "eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, + "espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "requires": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -3817,6 +3558,14 @@ "dev": true, "requires": { "estraverse": "^5.1.0" + }, + "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 + } } }, "esrecurse": { @@ -3826,12 +3575,20 @@ "dev": true, "requires": { "estraverse": "^5.2.0" + }, + "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 + } } }, "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { @@ -3982,33 +3739,14 @@ "is-extendable": "^0.1.0" } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } } } @@ -4037,9 +3775,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -4288,9 +4026,9 @@ "dev": true }, "flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "requires": { "flatted": "^3.2.9", @@ -4492,21 +4230,21 @@ } }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" } }, "functional-red-black-tree": { @@ -4548,27 +4286,6 @@ "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9" - }, - "dependencies": { - "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "optional": true, - "requires": { - "debug": "^4.3.4" - } - }, - "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", - "optional": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - } } }, "gcp-metadata": { @@ -4593,20 +4310,21 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-package-type": { @@ -4646,6 +4364,20 @@ "assert-plus": "^1.0.0" } }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -4673,30 +4405,6 @@ "unique-stream": "^2.0.2" }, "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -4716,15 +4424,6 @@ "is-extglob": "^2.1.0" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -4838,15 +4537,15 @@ } }, "google-auth-library": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.2.0.tgz", - "integrity": "sha512-1oV3p0JhNEhVbj26eF3FAJcv9MXXQt4S0wcvKZaDbl4oHq5V3UJoSbsGZGQNcjoCdhW4kDSwOs11wLlHog3fgQ==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.4.1.tgz", + "integrity": "sha512-Chs7cuzDuav8W/BXOoRgSXw4u0zxYtuqAHETDR5Q6dG1RwNwz7NUKjsDDHAsBV3KkiiJBtJqjbzy1XU1L41w1g==", "optional": true, "requires": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.0.0", - "gcp-metadata": "^6.0.0", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", "gtoken": "^7.0.0", "jws": "^4.0.0" } @@ -5127,15 +4826,6 @@ "har-schema": "^2.0.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -5166,12 +4856,12 @@ "dev": true }, "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, "requires": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.2.2" } }, "has-proto": { @@ -5271,6 +4961,15 @@ } } }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -5325,6 +5024,17 @@ "@tootallnate/once": "2", "agent-base": "6", "debug": "4" + }, + "dependencies": { + "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==", + "optional": true, + "requires": { + "debug": "4" + } + } } }, "http-signature": { @@ -5339,11 +5049,12 @@ } }, "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==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "optional": true, "requires": { - "agent-base": "6", + "agent-base": "^7.0.2", "debug": "4" } }, @@ -5360,9 +5071,9 @@ "dev": true }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true }, "import-fresh": { @@ -5415,13 +5126,13 @@ "dev": true }, "internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", "dev": true, "requires": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", "side-channel": "^1.0.4" } }, @@ -5448,23 +5159,12 @@ } }, "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "hasown": "^2.0.0" } }, "is-array-buffer": { @@ -5525,32 +5225,21 @@ "dev": true }, "is-core-module": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", - "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "hasown": "^2.0.0" } }, "is-date-object": { @@ -5563,22 +5252,13 @@ } }, "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } }, "is-extendable": { @@ -5713,16 +5393,12 @@ } }, "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.11" } }, "is-typedarray": { @@ -5798,9 +5474,9 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true }, "istanbul-lib-hook": { @@ -5884,14 +5560,25 @@ } }, "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "requires": { + "semver": "^7.5.3" + } + } } }, "istanbul-lib-source-maps": { @@ -5906,9 +5593,9 @@ } }, "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -5939,6 +5626,14 @@ "dev": true, "requires": { "argparse": "^2.0.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + } } }, "jsbn": { @@ -6014,14 +5709,20 @@ } }, "jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", "requires": { "jws": "^3.2.2", - "lodash": "^4.17.21", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", "ms": "^2.1.1", - "semver": "^7.3.8" + "semver": "^7.5.4" }, "dependencies": { "jwa": { @@ -6197,6 +5898,16 @@ "flush-write-stream": "^1.0.2" } }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, "liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -6243,7 +5954,8 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "lodash._reinterpolate": { "version": "3.0.0", @@ -6274,18 +5986,53 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", "dev": true }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", @@ -6322,12 +6069,12 @@ "optional": true }, "loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "requires": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "lru-cache": { @@ -6560,15 +6307,6 @@ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true }, - "merge-options": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", - "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", - "dev": true, - "requires": { - "is-plain-obj": "^2.1.0" - } - }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6604,6 +6342,15 @@ "mime-db": "1.52.0" } }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -6715,16 +6462,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -6741,16 +6478,21 @@ "readdirp": "~3.6.0" } }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } }, "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, @@ -6871,33 +6613,6 @@ "array-union": "^2.1.0", "arrify": "^2.0.1", "minimatch": "^3.0.4" - }, - "dependencies": { - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } } }, "mute-stdout": { @@ -6918,9 +6633,9 @@ } }, "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", "dev": true, "optional": true }, @@ -7018,14 +6733,13 @@ } }, "nock": { - "version": "13.3.3", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.3.tgz", - "integrity": "sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==", + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.4.0.tgz", + "integrity": "sha512-W8NVHjO/LCTNA64yxAPHV/K47LpGYcVzgKd3Q0n6owhwvD0Dgoterc25R4rnZbckJEb6Loxz1f5QMuJpJnbSyQ==", "dev": true, "requires": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.21", "propagate": "^2.0.0" } }, @@ -7036,9 +6750,9 @@ "dev": true }, "node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "requires": { "whatwg-url": "^5.0.0" } @@ -7058,9 +6772,9 @@ } }, "node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node-version": { @@ -7139,16 +6853,6 @@ "color-convert": "^1.9.0" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -7212,15 +6916,6 @@ "strip-bom": "^3.0.0" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -7354,16 +7049,6 @@ "yargs": "^15.0.2" }, "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -7391,20 +7076,6 @@ "path-exists": "^4.0.0" } }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -7414,15 +7085,6 @@ "p-locate": "^4.1.0" } }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -7463,9 +7125,9 @@ "dev": true }, "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true }, "wrap-ansi": { @@ -7566,9 +7228,9 @@ "optional": true }, "object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, "object-keys": { @@ -7587,13 +7249,13 @@ } }, "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } @@ -7647,6 +7309,20 @@ "wrappy": "1" } }, + "optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + } + }, "ordered-read-streams": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", @@ -7973,6 +7649,12 @@ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", "dev": true }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -8112,9 +7794,9 @@ } }, "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "qs": { @@ -8369,14 +8051,14 @@ } }, "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" } }, "release-zalgo": { @@ -8524,12 +8206,12 @@ "dev": true }, "resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "requires": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -8602,41 +8284,6 @@ "dev": true, "requires": { "glob": "^7.1.3" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } } }, "run-parallel": { @@ -8757,6 +8404,26 @@ } } }, + "safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -8820,6 +8487,29 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "requires": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + } + }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -8992,33 +8682,14 @@ "is-descriptor": "^1.0.0" } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" } } } @@ -9126,9 +8797,9 @@ } }, "spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", + "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", "dev": true }, "split-string": { @@ -9147,9 +8818,9 @@ "dev": true }, "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -9232,9 +8903,9 @@ } }, "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true }, "string-width": { @@ -9248,47 +8919,47 @@ } }, "string.prototype.padend": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", - "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", + "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" } }, "string_decoder": { @@ -9360,9 +9031,9 @@ } }, "tar": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", - "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -9384,6 +9055,27 @@ "node-fetch": "^2.6.9", "stream-events": "^1.0.5", "uuid": "^9.0.0" + }, + "dependencies": { + "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==", + "optional": true, + "requires": { + "debug": "4" + } + }, + "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==", + "optional": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + } } }, "test-exclude": { @@ -9395,41 +9087,6 @@ "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } } }, "text-decoding": { @@ -9636,9 +9293,9 @@ } }, "tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "tsutils": { "version": "3.21.0", @@ -9678,6 +9335,15 @@ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", "dev": true }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -9690,6 +9356,42 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, + "typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + } + }, "typed-array-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -9717,9 +9419,9 @@ } }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", "dev": true }, "unbox-primitive": { @@ -9772,6 +9474,11 @@ "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", "dev": true }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -9847,9 +9554,9 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "requires": { "escalade": "^3.1.1", @@ -9883,9 +9590,9 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" }, "v8-compile-cache-lib": { "version": "3.0.1", @@ -9913,9 +9620,9 @@ } }, "validator": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", - "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "dev": true }, "value-or-function": { @@ -10098,17 +9805,16 @@ "dev": true }, "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", "dev": true, "requires": { "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.4", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.0" } }, "wide-align": { @@ -10181,18 +9887,6 @@ "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" - }, - "dependencies": { - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - } } }, "yargs-parser": { diff --git a/package.json b/package.json index fef7285063..5281ab42a7 100644 --- a/package.json +++ b/package.json @@ -197,9 +197,9 @@ }, "dependencies": { "@fastify/busboy": "^1.2.1", - "@firebase/database-compat": "^0.3.4", - "@firebase/database-types": "^0.10.4", - "@types/node": ">=12.12.47", + "@firebase/database-compat": "^1.0.2", + "@firebase/database-types": "^1.0.0", + "@types/node": "^20.10.3", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.0.1", "node-forge": "^1.3.1", @@ -207,7 +207,7 @@ }, "optionalDependencies": { "@google-cloud/firestore": "^7.1.0", - "@google-cloud/storage": "^7.6.0" + "@google-cloud/storage": "^7.7.0" }, "devDependencies": { "@firebase/api-documenter": "^0.3.0", @@ -229,8 +229,8 @@ "@types/sinon": "^17.0.2", "@types/sinon-chai": "^3.0.0", "@types/uuid": "^9.0.1", - "@typescript-eslint/eslint-plugin": "^5.0.0", - "@typescript-eslint/parser": "^5.0.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "bcrypt": "^5.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.0.0", @@ -258,7 +258,7 @@ "sinon": "^17.0.1", "sinon-chai": "^3.0.0", "ts-node": "^10.2.0", - "typescript": "^4.6.4", + "typescript": "5.1.6", "yargs": "^17.0.1" } } diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index 485ce3c8eb..2408e92344 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -918,8 +918,8 @@ export class ExponentialBackoffPoller extends EventEmitter { private numTries = 0; private completed = false; - private masterTimer: NodeJS.Timer; - private repollTimer: NodeJS.Timer; + private masterTimer: NodeJS.Timeout; + private repollTimer: NodeJS.Timeout; private pollCallback?: () => Promise; private resolve: (result: T) => void; diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index ffa46e7ef4..c2ce02ff3f 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -102,7 +102,7 @@ import './remote-config/remote-config-api-client.spec'; import './app-check/app-check.spec'; import './app-check/app-check-api-client-internal.spec'; import './app-check/token-generator.spec'; -import './app-check/token-verifier.spec.ts'; +import './app-check/token-verifier.spec'; // Eventarc import './eventarc/eventarc.spec'; From a8d9d422b501ca43b0e4e2e64fe982efe53db75e Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 6 Dec 2023 16:19:43 -0500 Subject: [PATCH 040/323] chore: Deprecate Node.js 14 (#2397) --- CONTRIBUTING.md | 2 +- README.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4f80791cea..eefd161066 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,7 +87,7 @@ information on using pull requests. ### Prerequisites -1. Node.js 14 or higher. +1. Node.js 16 or higher. 2. `npm` 6 or higher. 3. Google Cloud SDK ([`gcloud`](https://cloud.google.com/sdk/downloads) utility). diff --git a/README.md b/README.md index 6a1d293bee..2d466926a7 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,8 @@ requests, code review feedback, and also pull requests. ## Supported Environments -We support Node.js 14 and higher. +We support Node.js 14 and higher. However, Node.js 14 support is deprecated. We strongly encourage +you to use Node.js 16 or higher as we will drop support for Node.js 14 in the next major version. Please also note that the Admin SDK should only be used in server-side/back-end environments controlled by the app developer. From 6bde095be8d8e98f5f48eaff4cf260c8b82109bf Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 7 Dec 2023 11:02:30 -0500 Subject: [PATCH 041/323] [chore] Release 12.0.0 (#2404) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5281ab42a7..c1f12f3283 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "11.11.1", + "version": "12.0.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From efc225f8884759ac86c4831f700d02cf18e34d6d Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:36:55 -0500 Subject: [PATCH 042/323] chore: Update Firebase integration test project setup instructions. (#2395) * Update Firebase integration test project setup instructions. * fix: path to resource keys * fix: add step * fix: mirror Tech Writer review * remove quote * fix: pencil * Added service account management note. --- CONTRIBUTING.md | 126 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 37 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eefd161066..28d15bf290 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -156,43 +156,95 @@ below covers how to run the full test suite against an actual Firebase project. #### Integration Tests with an actual Firebase project -Other integration tests require an actual Firebase project. Create a new -project in the [Firebase Console](https://console.firebase.google.com), if you -do not already have one suitable for running the tests against. Then obtain the -following credentials from the project: - -1. *Service account certificate*: This can be downloaded as a JSON file from - the "Settings > Service Accounts" tab of the Firebase console. Copy the - file into the repo so it's available at `test/resources/key.json`. -2. *Web API key*: This is displayed in the "Settings > General" tab of the - console. Copy it and save to a new text file at `test/resources/apikey.txt`. - -Then set up your Firebase/Google Cloud project as follows: - -1. Enable Firestore: Go to the Firebase Console, and select "Database" from - the "Develop" menu. Click on the "Create database" button. You may choose - to set up Firestore either in the locked mode or in the test mode. -2. Enable password auth: Select "Authentication" from the "Develop" menu in - Firebase Console. Select the "Sign-in method" tab, and enable the - "Email/Password" sign-in method, including the Email link (passwordless - sign-in) option. -3. Enable the Firebase ML API: Go to the - [Google Developers Console]( - https://console.developers.google.com/apis/api/firebaseml.googleapis.com/overview) - and make sure your project is selected. If the API is not already enabled, click Enable. -4. Enable the IAM API: Go to the - [Google Cloud Console](https://console.cloud.google.com) and make - sure your Firebase/Google Cloud project is selected. Select "APIs & Services > - Dashboard" from the main menu, and click the "ENABLE APIS AND SERVICES" - button. Search for and enable the "Identity and Access Management (IAM) - API". -5. Grant your service account the 'Firebase Authentication Admin' role. This is - required to ensure that exported user records contain the password hashes of - the user accounts: - 1. Go to [Google Cloud Console / IAM & admin](https://console.cloud.google.com/iam-admin). - 2. Find your service account in the list, and click the 'pencil' icon to edit it's permissions. - 3. Click 'ADD ANOTHER ROLE' and choose 'Firebase Authentication Admin'. - 4. Click 'SAVE'. +Integration tests are executed against a real life Firebase project. If you do not already +have one suitable for running the tests against, you can create a new project in the +[Firebase Console](https://console.firebase.google.com) following the setup guide below. +If you already have a Firebase project, you'll need to obtain credentials to communicate and +authorize access to your Firebase project: + +1. Service account certificate: This allows access to your Firebase project through a service account +which is required for all integration tests. This can be downloaded as a JSON file from the +**Settings > Service Accounts** tab of the Firebase console when you click the +**Generate new private key** button. Copy the file into the repo so it's available at +`test/resources/key.json`. + > **Note:** Service accounts should be carefully managed and their keys should never be stored in publicly accessible source code or repositories. + + +2. Web API key: This allows for Auth sign-in needed for some Authentication and Tenant Management +integration tests. This is displayed in the **Settings > General** tab of the Firebase console +after enabling Authentication as described in the steps below. Copy it and save to a new text +file at `test/resources/apikey.txt`. + + +Set up your Firebase project as follows: + + +1. Enable Authentication: + 1. Go to the Firebase Console, and select **Authentication** from the **Build** menu. + 2. Click on **Get Started**. + 3. Select **Sign-in method > Add new provider > Email/Password** then enable both the + **Email/Password** and **Email link (passwordless sign-in)** options. + + +2. Enable Firestore: + 1. Go to the Firebase Console, and select **Firestore Database** from the **Build** menu. + 2. Click on the **Create database** button. You can choose to set up Firestore either in + the production mode or in the test mode. + + +3. Enable Realtime Database: + 1. Go to the Firebase Console, and select **Realtime Database** from the **Build** menu. + 2. Click on the **Create Database** button. You can choose to set up the Realtime Database + either in the locked mode or in the test mode. + + > **Note:** Integration tests are not run against the default Realtime Database reference and are + instead run against a database created at `https://{PROJECT_ID}.firebaseio.com`. + This second Realtime Database reference is created in the following steps. + + 3. In the **Data** tab click on the kebab menu (3 dots) and select **Create Database**. + 4. Enter your Project ID (Found in the **General** tab in **Account Settings**) as the + **Realtime Database reference**. Again, you can choose to set up the Realtime Database + either in the locked mode or in the test mode. + + +4. Enable Storage: + 1. Go to the Firebase Console, and select **Storage** from the **Build** menu. + 2. Click on the **Get started** button. You can choose to set up Cloud Storage + either in the production mode or in the test mode. + + +5. Enable the Firebase ML API: + 1. Go to the + [Google Cloud console | Firebase ML API](https://console.cloud.google.com/apis/api/firebaseml.googleapis.com/overview) + and make sure your project is selected. + 2. If the API is not already enabled, click **Enable**. + + +6. Enable the IAM API: + 1. Go to the [Google Cloud console](https://console.cloud.google.com) + and make sure your Firebase project is selected. + 2. Select **APIs & Services** from the main menu, and click the + **ENABLE APIS AND SERVICES** button. + 3. Search for and enable **Identity and Access Management (IAM) API** by Google Enterprise API. + + +7. Enable Tenant Management: + 1. Go to + [Google Cloud console | Identity Platform](https://console.cloud.google.com/customer-identity/) + and if it is not already enabled, click **Enable**. + 2. Then + [enable multi-tenancy](https://cloud.google.com/identity-platform/docs/multi-tenancy-quickstart#enabling_multi-tenancy) + for your project. + + +8. Ensure your service account has the **Firebase Authentication Admin** role. This is required +to ensure that exported user records contain the password hashes of the user accounts: + 1. Go to [Google Cloud console | IAM & admin](https://console.cloud.google.com/iam-admin). + 2. Find your service account in the list. If not added click the pencil icon to edit its + permissions. + 3. Click **ADD ANOTHER ROLE** and choose **Firebase Authentication Admin**. + 4. Click **SAVE**. + Finally, to run the integration test suite: From 95a48ce00c1133940f00a0ab993ced87ed14bf8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:10:11 -0500 Subject: [PATCH 043/323] build(deps): bump @types/node from 20.10.3 to 20.10.6 (#2417) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.3 to 20.10.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index a120760e29..c97b208917 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "11.11.1", + "version": "12.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1444,9 +1444,9 @@ } }, "@types/node": { - "version": "20.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", - "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", + "version": "20.10.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz", + "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==", "requires": { "undici-types": "~5.26.4" } From a35b444d248d7779c511c678311119d57516b288 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:14:20 +0000 Subject: [PATCH 044/323] build(deps): bump @fastify/busboy from 1.2.1 to 2.1.0 (#2406) --- package-lock.json | 14 +++----------- package.json | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index c97b208917..121aeb8a90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -456,12 +456,9 @@ "dev": true }, "@fastify/busboy": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz", - "integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==", - "requires": { - "text-decoding": "^1.0.0" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==" }, "@firebase/api-documenter": { "version": "0.3.0", @@ -9089,11 +9086,6 @@ "minimatch": "^3.0.4" } }, - "text-decoding": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz", - "integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==" - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", diff --git a/package.json b/package.json index c1f12f3283..c22b95edbe 100644 --- a/package.json +++ b/package.json @@ -196,7 +196,7 @@ } }, "dependencies": { - "@fastify/busboy": "^1.2.1", + "@fastify/busboy": "^2.1.0", "@firebase/database-compat": "^1.0.2", "@firebase/database-types": "^1.0.0", "@types/node": "^20.10.3", From d824c0a0adfa8f5eba1a85b0e1826aa5725a146d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:18:40 +0000 Subject: [PATCH 045/323] build(deps-dev): bump @microsoft/api-extractor from 7.38.4 to 7.39.0 (#2416) --- package-lock.json | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 121aeb8a90..bf0d86b023 100644 --- a/package-lock.json +++ b/package-lock.json @@ -903,15 +903,15 @@ } }, "@microsoft/api-extractor": { - "version": "7.38.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.38.4.tgz", - "integrity": "sha512-0SW3Of6os4bAYlHdiD1hJx/ygXr7vRZi92E1pREufNERH87aZ0B9Vhku/4Mj2Oxp58gyV5d18t7uZold6HCSEw==", + "version": "7.39.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.39.0.tgz", + "integrity": "sha512-PuXxzadgnvp+wdeZFPonssRAj/EW4Gm4s75TXzPk09h3wJ8RS3x7typf95B4vwZRrPTQBGopdUl+/vHvlPdAcg==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.2", + "@microsoft/api-extractor-model": "7.28.3", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.61.0", + "@rushstack/node-core-library": "3.62.0", "@rushstack/rig-package": "0.5.1", "@rushstack/ts-command-line": "4.17.1", "colors": "~1.2.1", @@ -919,7 +919,7 @@ "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", - "typescript": "~5.0.4" + "typescript": "5.3.3" }, "dependencies": { "@microsoft/tsdoc": { @@ -929,9 +929,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.61.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.61.0.tgz", - "integrity": "sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==", + "version": "3.62.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.62.0.tgz", + "integrity": "sha512-88aJn2h8UpSvdwuDXBv1/v1heM6GnBf3RjEy6ZPP7UnzHNCqOHA2Ut+ScYUbXcqIdfew9JlTAe3g+cnX9xQ/Aw==", "dev": true, "requires": { "colors": "~1.2.1", @@ -962,22 +962,22 @@ "dev": true }, "typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true } } }, "@microsoft/api-extractor-model": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.2.tgz", - "integrity": "sha512-vkojrM2fo3q4n4oPh4uUZdjJ2DxQ2+RnDQL/xhTWSRUNPF6P4QyrvY357HBxbnltKcYu+nNNolVqc6TIGQ73Ig==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.3.tgz", + "integrity": "sha512-wT/kB2oDbdZXITyDh2SQLzaWwTOFbV326fP0pUwNW00WeliARs0qjmXBWmGWardEzp2U3/axkO3Lboqun6vrig==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.61.0" + "@rushstack/node-core-library": "3.62.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -987,9 +987,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.61.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.61.0.tgz", - "integrity": "sha512-tdOjdErme+/YOu4gPed3sFS72GhtWCgNV9oDsHDnoLY5oDfwjKUc9Z+JOZZ37uAxcm/OCahDHfuu2ugqrfWAVQ==", + "version": "3.62.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.62.0.tgz", + "integrity": "sha512-88aJn2h8UpSvdwuDXBv1/v1heM6GnBf3RjEy6ZPP7UnzHNCqOHA2Ut+ScYUbXcqIdfew9JlTAe3g+cnX9xQ/Aw==", "dev": true, "requires": { "colors": "~1.2.1", From c38160b9ca25b236037d8bbffd063c1e9ad9ceaf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:47:07 -0500 Subject: [PATCH 046/323] build(deps): bump @types/node from 20.10.6 to 20.11.5 (#2428) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.10.6 to 20.11.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bf0d86b023..c3eaf3770b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1441,9 +1441,9 @@ } }, "@types/node": { - "version": "20.10.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz", - "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==", + "version": "20.11.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", + "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", "requires": { "undici-types": "~5.26.4" } From 7a603ded4ded3998cb8ce3a79c3af784f2899f2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:51:47 +0000 Subject: [PATCH 047/323] build(deps-dev): bump chai from 4.3.10 to 4.4.1 (#2424) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c3eaf3770b..c0d2c6a336 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2516,9 +2516,9 @@ "dev": true }, "chai": { - "version": "4.3.10", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", - "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", "dev": true, "requires": { "assertion-error": "^1.1.0", From d3871f38f000350e9bb24bdc3cb5fc3b5e618ed4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:57:02 +0000 Subject: [PATCH 048/323] build(deps-dev): bump eslint from 8.55.0 to 8.56.0 (#2422) --- package-lock.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index c0d2c6a336..0045eae073 100644 --- a/package-lock.json +++ b/package-lock.json @@ -450,9 +450,9 @@ } }, "@eslint/js": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", - "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", "dev": true }, "@fastify/busboy": { @@ -723,13 +723,13 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" } }, @@ -740,9 +740,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -3423,15 +3423,15 @@ "dev": true }, "eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", - "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.55.0", + "@eslint/js": "8.56.0", "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4493,9 +4493,9 @@ } }, "globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" From fb080683bd624a1d197dd869ebe442c85c19d5a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:10:31 -0500 Subject: [PATCH 049/323] build(deps-dev): bump @microsoft/api-extractor from 7.39.0 to 7.39.4 (#2436) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.39.0 to 7.39.4. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.39.4/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0045eae073..dbac9857bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -903,15 +903,15 @@ } }, "@microsoft/api-extractor": { - "version": "7.39.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.39.0.tgz", - "integrity": "sha512-PuXxzadgnvp+wdeZFPonssRAj/EW4Gm4s75TXzPk09h3wJ8RS3x7typf95B4vwZRrPTQBGopdUl+/vHvlPdAcg==", + "version": "7.39.4", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.39.4.tgz", + "integrity": "sha512-6YvfkpbEqRQ0UPdVBc+lOiq7VlXi9kw8U3w+RcXCFDVc/UljlXU5l9fHEyuBAW1GGO2opUe+yf9OscWhoHANhg==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.3", + "@microsoft/api-extractor-model": "7.28.7", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.62.0", + "@rushstack/node-core-library": "3.64.2", "@rushstack/rig-package": "0.5.1", "@rushstack/ts-command-line": "4.17.1", "colors": "~1.2.1", @@ -929,9 +929,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.62.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.62.0.tgz", - "integrity": "sha512-88aJn2h8UpSvdwuDXBv1/v1heM6GnBf3RjEy6ZPP7UnzHNCqOHA2Ut+ScYUbXcqIdfew9JlTAe3g+cnX9xQ/Aw==", + "version": "3.64.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.64.2.tgz", + "integrity": "sha512-n1S2VYEklONiwKpUyBq/Fym6yAsfsCXrqFabuOMcCuj4C+zW+HyaspSHXJCKqkMxfjviwe/c9+DUqvRWIvSN9Q==", "dev": true, "requires": { "colors": "~1.2.1", @@ -970,14 +970,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.3.tgz", - "integrity": "sha512-wT/kB2oDbdZXITyDh2SQLzaWwTOFbV326fP0pUwNW00WeliARs0qjmXBWmGWardEzp2U3/axkO3Lboqun6vrig==", + "version": "7.28.7", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.7.tgz", + "integrity": "sha512-4gCGGEQGHmbQmarnDcEWS2cjj0LtNuD3D6rh3ZcAyAYTkceAugAk2eyQHGdTcGX8w3qMjWCTU1TPb8xHnMM+Kg==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.62.0" + "@rushstack/node-core-library": "3.64.2" }, "dependencies": { "@microsoft/tsdoc": { @@ -987,9 +987,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.62.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.62.0.tgz", - "integrity": "sha512-88aJn2h8UpSvdwuDXBv1/v1heM6GnBf3RjEy6ZPP7UnzHNCqOHA2Ut+ScYUbXcqIdfew9JlTAe3g+cnX9xQ/Aw==", + "version": "3.64.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.64.2.tgz", + "integrity": "sha512-n1S2VYEklONiwKpUyBq/Fym6yAsfsCXrqFabuOMcCuj4C+zW+HyaspSHXJCKqkMxfjviwe/c9+DUqvRWIvSN9Q==", "dev": true, "requires": { "colors": "~1.2.1", From 69c8cbfe0d5161954d3b81aad99629f224168a14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:15:35 +0000 Subject: [PATCH 050/323] build(deps-dev): bump nock from 13.4.0 to 13.5.1 (#2434) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index dbac9857bc..8f558eddbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6730,9 +6730,9 @@ } }, "nock": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.4.0.tgz", - "integrity": "sha512-W8NVHjO/LCTNA64yxAPHV/K47LpGYcVzgKd3Q0n6owhwvD0Dgoterc25R4rnZbckJEb6Loxz1f5QMuJpJnbSyQ==", + "version": "13.5.1", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.1.tgz", + "integrity": "sha512-+s7b73fzj5KnxbKH4Oaqz07tQ8degcMilU4rrmnKvI//b0JMBU4wEXFQ8zqr+3+L4eWSfU3H/UoIVGUV0tue1Q==", "dev": true, "requires": { "debug": "^4.1.0", From 88daeb1596c02f1f1386694a4b5b27845c56843e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:21:48 +0000 Subject: [PATCH 051/323] build(deps-dev): bump @firebase/api-documenter from 0.3.0 to 0.4.0 (#2433) --- package-lock.json | 52 ++++++++++++----------------------------------- package.json | 2 +- 2 files changed, 14 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f558eddbc..9bb337ed59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -461,14 +461,14 @@ "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==" }, "@firebase/api-documenter": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/api-documenter/-/api-documenter-0.3.0.tgz", - "integrity": "sha512-NYwiuGaspPZJtHbyIwd5ns3gauPemarjIU4KNyZY2gxijkrCImgq7cQ+evnFXjytGl5skeo+JHYWBQPhxVqMiw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/api-documenter/-/api-documenter-0.4.0.tgz", + "integrity": "sha512-UUPxxj1wIAGkXBCF9UL1dhfyzM4Lcd/gMSCoJqy8o75rLqQVGB2GSBaU7I4JmQsQhIIk/nKKLiy4HM/70kEfZA==", "dev": true, "requires": { "@microsoft/tsdoc": "0.12.24", - "@rushstack/node-core-library": "3.45.5", - "@rushstack/ts-command-line": "4.11.0", + "@rushstack/node-core-library": "3.59.7", + "@rushstack/ts-command-line": "4.15.2", "api-extractor-model-me": "0.1.1", "colors": "~1.4.0", "js-yaml": "4.1.0", @@ -1136,51 +1136,25 @@ "optional": true }, "@rushstack/node-core-library": { - "version": "3.45.5", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.5.tgz", - "integrity": "sha512-KbN7Hp9vH3bD3YJfv6RnVtzzTAwGYIBl7y2HQLY4WEQqRbvE3LgI78W9l9X+cTAXCX//p0EeoiUYNTFdqJrMZg==", + "version": "3.59.7", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.7.tgz", + "integrity": "sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==", "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", - "timsort": "~0.3.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", "z-schema": "~5.0.2" }, "dependencies": { - "@types/node": { - "version": "12.20.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.24.tgz", - "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ==", - "dev": true - }, "colors": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", "dev": true - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } } } }, @@ -1195,9 +1169,9 @@ } }, "@rushstack/ts-command-line": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.11.0.tgz", - "integrity": "sha512-ptG9L0mjvJ5QtK11GsAFY+jGfsnqHDS6CY6Yw1xT7a9bhjfNYnf6UPwjV+pF6UgiucfNcMDNW9lkDLxvZKKxMg==", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz", + "integrity": "sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==", "dev": true, "requires": { "@types/argparse": "1.0.38", diff --git a/package.json b/package.json index c22b95edbe..5391d11c81 100644 --- a/package.json +++ b/package.json @@ -210,7 +210,7 @@ "@google-cloud/storage": "^7.7.0" }, "devDependencies": { - "@firebase/api-documenter": "^0.3.0", + "@firebase/api-documenter": "^0.4.0", "@firebase/app-compat": "^0.2.1", "@firebase/auth-compat": "^0.4.1", "@firebase/auth-types": "^0.12.0", From db3d5bef6f2fbfc567c87dc34f90959d64588fe3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:26:53 +0000 Subject: [PATCH 052/323] build(deps-dev): bump ts-node from 10.9.1 to 10.9.2 (#2435) --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bb337ed59..61fd1e6231 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1647,9 +1647,9 @@ "dev": true }, "acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true }, "agent-base": { @@ -9230,9 +9230,9 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", From e3217841207dfd86e71a0386bc58cbddb15af60b Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:20:40 -0500 Subject: [PATCH 053/323] [chore] Bump `@actions/core` to ^1.10.1 to remove `set-output` warning and set action to use Node 20 (#2432) * [chore] Bump `@actions/core` to ^1.10.1 to remove `set-output` warning * fix: keep mailgun version the same --- .github/actions/send-email/action.yml | 2 +- .github/actions/send-email/dist/index.js | 29334 ++++++++++++++++- .github/actions/send-email/package-lock.json | 451 +- .github/actions/send-email/package.json | 6 +- 4 files changed, 28066 insertions(+), 1727 deletions(-) diff --git a/.github/actions/send-email/action.yml b/.github/actions/send-email/action.yml index 65956f9a12..eca721b842 100644 --- a/.github/actions/send-email/action.yml +++ b/.github/actions/send-email/action.yml @@ -40,5 +40,5 @@ inputs: description: HTML body of the message. required: false runs: - using: 'node12' + using: 'node20' main: 'dist/index.js' diff --git a/.github/actions/send-email/dist/index.js b/.github/actions/send-email/dist/index.js index d1817b6db8..410dda0a18 100644 --- a/.github/actions/send-email/dist/index.js +++ b/.github/actions/send-email/dist/index.js @@ -1,2105 +1,28185 @@ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; + } + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } + } + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; + } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map + +/***/ }), + +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { + /** + * A code indicating that the action was successful + */ + ExitCode[ExitCode["Success"] = 0] = "Success"; + /** + * A code indicating that the action was a failure + */ + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); + } + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); + } + else { + command_1.issueCommand('add-path', {}, inputPath); + } + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); + } + if (options && options.trimWhitespace === false) { + return val; + } + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; + } + return inputs.map(input => input.trim()); +} +exports.getMultilineInput = getMultilineInput; +/** + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean + */ +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + } + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); +} +exports.setOutput = setOutput; +/** + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * + */ +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.notice = notice; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); + } + finally { + endGroup(); + } + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function saveState(name, value) { + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + } + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); +} +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); +} +exports.getIDToken = getIDToken; +/** + * Summary exports + */ +var summary_1 = __nccwpck_require__(1327); +Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); +/** + * @deprecated use core.summary + */ +var summary_2 = __nccwpck_require__(1327); +Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +/** + * Path exports + */ +var path_utils_1 = __nccwpck_require__(2981); +Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); +Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); +Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); +//# sourceMappingURL=core.js.map + +/***/ }), + +/***/ 717: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +// For internal use, subject to change. +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(__nccwpck_require__(7147)); +const os = __importStar(__nccwpck_require__(2037)); +const uuid_1 = __nccwpck_require__(5840); +const utils_1 = __nccwpck_require__(5278); +function issueFileCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); + } + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); + } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); +} +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; +} +exports.prepareKeyValueMessage = prepareKeyValueMessage; +//# sourceMappingURL=file-command.js.map + +/***/ }), + +/***/ 8041: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.OidcClient = void 0; +const http_client_1 = __nccwpck_require__(6255); +const auth_1 = __nccwpck_require__(5526); +const core_1 = __nccwpck_require__(2186); +class OidcClient { + static createHttpClient(allowRetry = true, maxRetry = 10) { + const requestOptions = { + allowRetries: allowRetry, + maxRetries: maxRetry + }; + return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + } + static getRequestToken() { + const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; + if (!token) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); + } + return token; + } + static getIDTokenUrl() { + const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; + if (!runtimeUrl) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); + } + return runtimeUrl; + } + static getCall(id_token_url) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const httpclient = OidcClient.createHttpClient(); + const res = yield httpclient + .getJson(id_token_url) + .catch(error => { + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.message}`); + }); + const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + if (!id_token) { + throw new Error('Response json body do not have ID Token field'); + } + return id_token; + }); + } + static getIDToken(audience) { + return __awaiter(this, void 0, void 0, function* () { + try { + // New ID Token is requested from action service + let id_token_url = OidcClient.getIDTokenUrl(); + if (audience) { + const encodedAudience = encodeURIComponent(audience); + id_token_url = `${id_token_url}&audience=${encodedAudience}`; + } + core_1.debug(`ID token url is ${id_token_url}`); + const id_token = yield OidcClient.getCall(id_token_url); + core_1.setSecret(id_token); + return id_token; + } + catch (error) { + throw new Error(`Error message: ${error.message}`); + } + }); + } +} +exports.OidcClient = OidcClient; +//# sourceMappingURL=oidc-utils.js.map + +/***/ }), + +/***/ 2981: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; +const path = __importStar(__nccwpck_require__(1017)); +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +function toPosixPath(pth) { + return pth.replace(/[\\]/g, '/'); +} +exports.toPosixPath = toPosixPath; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +function toWin32Path(pth) { + return pth.replace(/[/]/g, '\\'); +} +exports.toWin32Path = toWin32Path; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +function toPlatformPath(pth) { + return pth.replace(/[/\\]/g, path.sep); +} +exports.toPlatformPath = toPlatformPath; +//# sourceMappingURL=path-utils.js.map + +/***/ }), + +/***/ 1327: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; +const os_1 = __nccwpck_require__(2037); +const fs_1 = __nccwpck_require__(7147); +const { access, appendFile, writeFile } = fs_1.promises; +exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; +exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; +class Summary { + constructor() { + this._buffer = ''; + } + /** + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path + */ + filePath() { + return __awaiter(this, void 0, void 0, function* () { + if (this._filePath) { + return this._filePath; + } + const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; + if (!pathFromEnv) { + throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); + } + try { + yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); + } + catch (_a) { + throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); + } + this._filePath = pathFromEnv; + return this._filePath; + }); + } + /** + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element + */ + wrap(tag, content, attrs = {}) { + const htmlAttrs = Object.entries(attrs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(''); + if (!content) { + return `<${tag}${htmlAttrs}>`; + } + return `<${tag}${htmlAttrs}>${content}`; + } + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ + write(options) { + return __awaiter(this, void 0, void 0, function* () { + const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); + const filePath = yield this.filePath(); + const writeFunc = overwrite ? writeFile : appendFile; + yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); + return this.emptyBuffer(); + }); + } + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear() { + return __awaiter(this, void 0, void 0, function* () { + return this.emptyBuffer().write({ overwrite: true }); + }); + } + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify() { + return this._buffer; + } + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer() { + return this._buffer.length === 0; + } + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer() { + this._buffer = ''; + return this; + } + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text, addEOL = false) { + this._buffer += text; + return addEOL ? this.addEOL() : this; + } + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL() { + return this.addRaw(os_1.EOL); + } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code, lang) { + const attrs = Object.assign({}, (lang && { lang })); + const element = this.wrap('pre', this.wrap('code', code), attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items, ordered = false) { + const tag = ordered ? 'ol' : 'ul'; + const listItems = items.map(item => this.wrap('li', item)).join(''); + const element = this.wrap(tag, listItems); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows) { + const tableBody = rows + .map(row => { + const cells = row + .map(cell => { + if (typeof cell === 'string') { + return this.wrap('td', cell); + } + const { header, data, colspan, rowspan } = cell; + const tag = header ? 'th' : 'td'; + const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); + return this.wrap(tag, data, attrs); + }) + .join(''); + return this.wrap('tr', cells); + }) + .join(''); + const element = this.wrap('table', tableBody); + return this.addRaw(element).addEOL(); + } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label, content) { + const element = this.wrap('details', this.wrap('summary', label) + content); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src, alt, options) { + const { width, height } = options || {}; + const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); + const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text, level) { + const tag = `h${level}`; + const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) + ? tag + : 'h1'; + const element = this.wrap(allowedTag, text); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator() { + const element = this.wrap('hr', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak() { + const element = this.wrap('br', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text, cite) { + const attrs = Object.assign({}, (cite && { cite })); + const element = this.wrap('blockquote', text, attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text, href) { + const element = this.wrap('a', text, { href }); + return this.addRaw(element).addEOL(); + } +} +const _summary = new Summary(); +/** + * @deprecated use `core.summary` + */ +exports.markdownSummary = _summary; +exports.summary = _summary; +//# sourceMappingURL=summary.js.map + +/***/ }), + +/***/ 5278: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toCommandProperties = exports.toCommandValue = void 0; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; + } + else if (typeof input === 'string' || input instanceof String) { + return input; + } + return JSON.stringify(input); +} +exports.toCommandValue = toCommandValue; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +function toCommandProperties(annotationProperties) { + if (!Object.keys(annotationProperties).length) { + return {}; + } + return { + title: annotationProperties.title, + file: annotationProperties.file, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + }; +} +exports.toCommandProperties = toCommandProperties; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 5526: +/***/ (function(__unused_webpack_module, exports) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0; +class BasicCredentialHandler { + constructor(username, password) { + this.username = username; + this.password = password; + } + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.BasicCredentialHandler = BasicCredentialHandler; +class BearerCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Bearer ${this.token}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.BearerCredentialHandler = BearerCredentialHandler; +class PersonalAccessTokenCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; +//# sourceMappingURL=auth.js.map + +/***/ }), + +/***/ 6255: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +/* eslint-disable @typescript-eslint/no-explicit-any */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0; +const http = __importStar(__nccwpck_require__(3685)); +const https = __importStar(__nccwpck_require__(5687)); +const pm = __importStar(__nccwpck_require__(9835)); +const tunnel = __importStar(__nccwpck_require__(4294)); +const undici_1 = __nccwpck_require__(1773); +var HttpCodes; +(function (HttpCodes) { + HttpCodes[HttpCodes["OK"] = 200] = "OK"; + HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; + HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; + HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; + HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; + HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; + HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; + HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; + HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; + HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; + HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; + HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; + HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; + HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; + HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; + HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; + HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; + HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; + HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; + HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; + HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; + HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; + HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; + HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; + HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; + HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; + HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; +})(HttpCodes || (exports.HttpCodes = HttpCodes = {})); +var Headers; +(function (Headers) { + Headers["Accept"] = "accept"; + Headers["ContentType"] = "content-type"; +})(Headers || (exports.Headers = Headers = {})); +var MediaTypes; +(function (MediaTypes) { + MediaTypes["ApplicationJson"] = "application/json"; +})(MediaTypes || (exports.MediaTypes = MediaTypes = {})); +/** + * Returns the proxy URL, depending upon the supplied url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ +function getProxyUrl(serverUrl) { + const proxyUrl = pm.getProxyUrl(new URL(serverUrl)); + return proxyUrl ? proxyUrl.href : ''; +} +exports.getProxyUrl = getProxyUrl; +const HttpRedirectCodes = [ + HttpCodes.MovedPermanently, + HttpCodes.ResourceMoved, + HttpCodes.SeeOther, + HttpCodes.TemporaryRedirect, + HttpCodes.PermanentRedirect +]; +const HttpResponseRetryCodes = [ + HttpCodes.BadGateway, + HttpCodes.ServiceUnavailable, + HttpCodes.GatewayTimeout +]; +const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; +const ExponentialBackoffCeiling = 10; +const ExponentialBackoffTimeSlice = 5; +class HttpClientError extends Error { + constructor(message, statusCode) { + super(message); + this.name = 'HttpClientError'; + this.statusCode = statusCode; + Object.setPrototypeOf(this, HttpClientError.prototype); + } +} +exports.HttpClientError = HttpClientError; +class HttpClientResponse { + constructor(message) { + this.message = message; + } + readBody() { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + let output = Buffer.alloc(0); + this.message.on('data', (chunk) => { + output = Buffer.concat([output, chunk]); + }); + this.message.on('end', () => { + resolve(output.toString()); + }); + })); + }); + } + readBodyBuffer() { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + const chunks = []; + this.message.on('data', (chunk) => { + chunks.push(chunk); + }); + this.message.on('end', () => { + resolve(Buffer.concat(chunks)); + }); + })); + }); + } +} +exports.HttpClientResponse = HttpClientResponse; +function isHttps(requestUrl) { + const parsedUrl = new URL(requestUrl); + return parsedUrl.protocol === 'https:'; +} +exports.isHttps = isHttps; +class HttpClient { + constructor(userAgent, handlers, requestOptions) { + this._ignoreSslError = false; + this._allowRedirects = true; + this._allowRedirectDowngrade = false; + this._maxRedirects = 50; + this._allowRetries = false; + this._maxRetries = 1; + this._keepAlive = false; + this._disposed = false; + this.userAgent = userAgent; + this.handlers = handlers || []; + this.requestOptions = requestOptions; + if (requestOptions) { + if (requestOptions.ignoreSslError != null) { + this._ignoreSslError = requestOptions.ignoreSslError; + } + this._socketTimeout = requestOptions.socketTimeout; + if (requestOptions.allowRedirects != null) { + this._allowRedirects = requestOptions.allowRedirects; + } + if (requestOptions.allowRedirectDowngrade != null) { + this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; + } + if (requestOptions.maxRedirects != null) { + this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); + } + if (requestOptions.keepAlive != null) { + this._keepAlive = requestOptions.keepAlive; + } + if (requestOptions.allowRetries != null) { + this._allowRetries = requestOptions.allowRetries; + } + if (requestOptions.maxRetries != null) { + this._maxRetries = requestOptions.maxRetries; + } + } + } + options(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); + }); + } + get(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('GET', requestUrl, null, additionalHeaders || {}); + }); + } + del(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('DELETE', requestUrl, null, additionalHeaders || {}); + }); + } + post(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('POST', requestUrl, data, additionalHeaders || {}); + }); + } + patch(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('PATCH', requestUrl, data, additionalHeaders || {}); + }); + } + put(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('PUT', requestUrl, data, additionalHeaders || {}); + }); + } + head(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('HEAD', requestUrl, null, additionalHeaders || {}); + }); + } + sendStream(verb, requestUrl, stream, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request(verb, requestUrl, stream, additionalHeaders); + }); + } + /** + * Gets a typed object from an endpoint + * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise + */ + getJson(requestUrl, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + const res = yield this.get(requestUrl, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + postJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.post(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + putJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.put(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + patchJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.patch(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + /** + * Makes a raw http request. + * All other methods such as get, post, patch, and request ultimately call this. + * Prefer get, del, post and patch + */ + request(verb, requestUrl, data, headers) { + return __awaiter(this, void 0, void 0, function* () { + if (this._disposed) { + throw new Error('Client has already been disposed.'); + } + const parsedUrl = new URL(requestUrl); + let info = this._prepareRequest(verb, parsedUrl, headers); + // Only perform retries on reads since writes may not be idempotent. + const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) + ? this._maxRetries + 1 + : 1; + let numTries = 0; + let response; + do { + response = yield this.requestRaw(info, data); + // Check if it's an authentication challenge + if (response && + response.message && + response.message.statusCode === HttpCodes.Unauthorized) { + let authenticationHandler; + for (const handler of this.handlers) { + if (handler.canHandleAuthentication(response)) { + authenticationHandler = handler; + break; + } + } + if (authenticationHandler) { + return authenticationHandler.handleAuthentication(this, info, data); + } + else { + // We have received an unauthorized response but have no handlers to handle it. + // Let the response return to the caller. + return response; + } + } + let redirectsRemaining = this._maxRedirects; + while (response.message.statusCode && + HttpRedirectCodes.includes(response.message.statusCode) && + this._allowRedirects && + redirectsRemaining > 0) { + const redirectUrl = response.message.headers['location']; + if (!redirectUrl) { + // if there's no location to redirect to, we won't + break; + } + const parsedRedirectUrl = new URL(redirectUrl); + if (parsedUrl.protocol === 'https:' && + parsedUrl.protocol !== parsedRedirectUrl.protocol && + !this._allowRedirectDowngrade) { + throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); + } + // we need to finish reading the response before reassigning response + // which will leak the open socket. + yield response.readBody(); + // strip authorization header if redirected to a different hostname + if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { + for (const header in headers) { + // header names are case insensitive + if (header.toLowerCase() === 'authorization') { + delete headers[header]; + } + } + } + // let's make the request with the new redirectUrl + info = this._prepareRequest(verb, parsedRedirectUrl, headers); + response = yield this.requestRaw(info, data); + redirectsRemaining--; + } + if (!response.message.statusCode || + !HttpResponseRetryCodes.includes(response.message.statusCode)) { + // If not a retry code, return immediately instead of retrying + return response; + } + numTries += 1; + if (numTries < maxTries) { + yield response.readBody(); + yield this._performExponentialBackoff(numTries); + } + } while (numTries < maxTries); + return response; + }); + } + /** + * Needs to be called if keepAlive is set to true in request options. + */ + dispose() { + if (this._agent) { + this._agent.destroy(); + } + this._disposed = true; + } + /** + * Raw request. + * @param info + * @param data + */ + requestRaw(info, data) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => { + function callbackForResult(err, res) { + if (err) { + reject(err); + } + else if (!res) { + // If `err` is not passed, then `res` must be passed. + reject(new Error('Unknown error')); + } + else { + resolve(res); + } + } + this.requestRawWithCallback(info, data, callbackForResult); + }); + }); + } + /** + * Raw request with callback. + * @param info + * @param data + * @param onResult + */ + requestRawWithCallback(info, data, onResult) { + if (typeof data === 'string') { + if (!info.options.headers) { + info.options.headers = {}; + } + info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); + } + let callbackCalled = false; + function handleResult(err, res) { + if (!callbackCalled) { + callbackCalled = true; + onResult(err, res); + } + } + const req = info.httpModule.request(info.options, (msg) => { + const res = new HttpClientResponse(msg); + handleResult(undefined, res); + }); + let socket; + req.on('socket', sock => { + socket = sock; + }); + // If we ever get disconnected, we want the socket to timeout eventually + req.setTimeout(this._socketTimeout || 3 * 60000, () => { + if (socket) { + socket.end(); + } + handleResult(new Error(`Request timeout: ${info.options.path}`)); + }); + req.on('error', function (err) { + // err has statusCode property + // res should have headers + handleResult(err); + }); + if (data && typeof data === 'string') { + req.write(data, 'utf8'); + } + if (data && typeof data !== 'string') { + data.on('close', function () { + req.end(); + }); + data.pipe(req); + } + else { + req.end(); + } + } + /** + * Gets an http agent. This function is useful when you need an http agent that handles + * routing through a proxy server - depending upon the url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ + getAgent(serverUrl) { + const parsedUrl = new URL(serverUrl); + return this._getAgent(parsedUrl); + } + getAgentDispatcher(serverUrl) { + const parsedUrl = new URL(serverUrl); + const proxyUrl = pm.getProxyUrl(parsedUrl); + const useProxy = proxyUrl && proxyUrl.hostname; + if (!useProxy) { + return; + } + return this._getProxyAgentDispatcher(parsedUrl, proxyUrl); + } + _prepareRequest(method, requestUrl, headers) { + const info = {}; + info.parsedUrl = requestUrl; + const usingSsl = info.parsedUrl.protocol === 'https:'; + info.httpModule = usingSsl ? https : http; + const defaultPort = usingSsl ? 443 : 80; + info.options = {}; + info.options.host = info.parsedUrl.hostname; + info.options.port = info.parsedUrl.port + ? parseInt(info.parsedUrl.port) + : defaultPort; + info.options.path = + (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); + info.options.method = method; + info.options.headers = this._mergeHeaders(headers); + if (this.userAgent != null) { + info.options.headers['user-agent'] = this.userAgent; + } + info.options.agent = this._getAgent(info.parsedUrl); + // gives handlers an opportunity to participate + if (this.handlers) { + for (const handler of this.handlers) { + handler.prepareRequest(info.options); + } + } + return info; + } + _mergeHeaders(headers) { + if (this.requestOptions && this.requestOptions.headers) { + return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {})); + } + return lowercaseKeys(headers || {}); + } + _getExistingOrDefaultHeader(additionalHeaders, header, _default) { + let clientHeader; + if (this.requestOptions && this.requestOptions.headers) { + clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; + } + return additionalHeaders[header] || clientHeader || _default; + } + _getAgent(parsedUrl) { + let agent; + const proxyUrl = pm.getProxyUrl(parsedUrl); + const useProxy = proxyUrl && proxyUrl.hostname; + if (this._keepAlive && useProxy) { + agent = this._proxyAgent; + } + if (this._keepAlive && !useProxy) { + agent = this._agent; + } + // if agent is already assigned use that agent. + if (agent) { + return agent; + } + const usingSsl = parsedUrl.protocol === 'https:'; + let maxSockets = 100; + if (this.requestOptions) { + maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; + } + // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis. + if (proxyUrl && proxyUrl.hostname) { + const agentOptions = { + maxSockets, + keepAlive: this._keepAlive, + proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && { + proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` + })), { host: proxyUrl.hostname, port: proxyUrl.port }) + }; + let tunnelAgent; + const overHttps = proxyUrl.protocol === 'https:'; + if (usingSsl) { + tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; + } + else { + tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; + } + agent = tunnelAgent(agentOptions); + this._proxyAgent = agent; + } + // if reusing agent across request and tunneling agent isn't assigned create a new agent + if (this._keepAlive && !agent) { + const options = { keepAlive: this._keepAlive, maxSockets }; + agent = usingSsl ? new https.Agent(options) : new http.Agent(options); + this._agent = agent; + } + // if not using private agent and tunnel agent isn't setup then use global agent + if (!agent) { + agent = usingSsl ? https.globalAgent : http.globalAgent; + } + if (usingSsl && this._ignoreSslError) { + // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process + // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options + // we have to cast it to any and change it directly + agent.options = Object.assign(agent.options || {}, { + rejectUnauthorized: false + }); + } + return agent; + } + _getProxyAgentDispatcher(parsedUrl, proxyUrl) { + let proxyAgent; + if (this._keepAlive) { + proxyAgent = this._proxyAgentDispatcher; + } + // if agent is already assigned use that agent. + if (proxyAgent) { + return proxyAgent; + } + const usingSsl = parsedUrl.protocol === 'https:'; + proxyAgent = new undici_1.ProxyAgent(Object.assign({ uri: proxyUrl.href, pipelining: !this._keepAlive ? 0 : 1 }, ((proxyUrl.username || proxyUrl.password) && { + token: `${proxyUrl.username}:${proxyUrl.password}` + }))); + this._proxyAgentDispatcher = proxyAgent; + if (usingSsl && this._ignoreSslError) { + // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process + // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options + // we have to cast it to any and change it directly + proxyAgent.options = Object.assign(proxyAgent.options.requestTls || {}, { + rejectUnauthorized: false + }); + } + return proxyAgent; + } + _performExponentialBackoff(retryNumber) { + return __awaiter(this, void 0, void 0, function* () { + retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); + const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); + return new Promise(resolve => setTimeout(() => resolve(), ms)); + }); + } + _processResponse(res, options) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + const statusCode = res.message.statusCode || 0; + const response = { + statusCode, + result: null, + headers: {} + }; + // not found leads to null obj returned + if (statusCode === HttpCodes.NotFound) { + resolve(response); + } + // get the result from the body + function dateTimeDeserializer(key, value) { + if (typeof value === 'string') { + const a = new Date(value); + if (!isNaN(a.valueOf())) { + return a; + } + } + return value; + } + let obj; + let contents; + try { + contents = yield res.readBody(); + if (contents && contents.length > 0) { + if (options && options.deserializeDates) { + obj = JSON.parse(contents, dateTimeDeserializer); + } + else { + obj = JSON.parse(contents); + } + response.result = obj; + } + response.headers = res.message.headers; + } + catch (err) { + // Invalid resource (contents not json); leaving result obj null + } + // note that 3xx redirects are handled by the http layer. + if (statusCode > 299) { + let msg; + // if exception/error in body, attempt to get better error + if (obj && obj.message) { + msg = obj.message; + } + else if (contents && contents.length > 0) { + // it may be the case that the exception is in the body message as string + msg = contents; + } + else { + msg = `Failed request: (${statusCode})`; + } + const err = new HttpClientError(msg, statusCode); + err.result = response.result; + reject(err); + } + else { + resolve(response); + } + })); + }); + } +} +exports.HttpClient = HttpClient; +const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 9835: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.checkBypass = exports.getProxyUrl = void 0; +function getProxyUrl(reqUrl) { + const usingSsl = reqUrl.protocol === 'https:'; + if (checkBypass(reqUrl)) { + return undefined; + } + const proxyVar = (() => { + if (usingSsl) { + return process.env['https_proxy'] || process.env['HTTPS_PROXY']; + } + else { + return process.env['http_proxy'] || process.env['HTTP_PROXY']; + } + })(); + if (proxyVar) { + try { + return new URL(proxyVar); + } + catch (_a) { + if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://')) + return new URL(`http://${proxyVar}`); + } + } + else { + return undefined; + } +} +exports.getProxyUrl = getProxyUrl; +function checkBypass(reqUrl) { + if (!reqUrl.hostname) { + return false; + } + const reqHost = reqUrl.hostname; + if (isLoopbackAddress(reqHost)) { + return true; + } + const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; + if (!noProxy) { + return false; + } + // Determine the request port + let reqPort; + if (reqUrl.port) { + reqPort = Number(reqUrl.port); + } + else if (reqUrl.protocol === 'http:') { + reqPort = 80; + } + else if (reqUrl.protocol === 'https:') { + reqPort = 443; + } + // Format the request hostname and hostname with port + const upperReqHosts = [reqUrl.hostname.toUpperCase()]; + if (typeof reqPort === 'number') { + upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); + } + // Compare request host against noproxy + for (const upperNoProxyItem of noProxy + .split(',') + .map(x => x.trim().toUpperCase()) + .filter(x => x)) { + if (upperNoProxyItem === '*' || + upperReqHosts.some(x => x === upperNoProxyItem || + x.endsWith(`.${upperNoProxyItem}`) || + (upperNoProxyItem.startsWith('.') && + x.endsWith(`${upperNoProxyItem}`)))) { + return true; + } + } + return false; +} +exports.checkBypass = checkBypass; +function isLoopbackAddress(host) { + const hostLower = host.toLowerCase(); + return (hostLower === 'localhost' || + hostLower.startsWith('127.') || + hostLower.startsWith('[::1]') || + hostLower.startsWith('[0:0:0:0:0:0:0:1]')); +} +//# sourceMappingURL=proxy.js.map + +/***/ }), + +/***/ 5046: +/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) { + +/*! For license information please see mailgun.node.js.LICENSE.txt */ +!function(e,t){ true?module.exports=t():0}(this,(function(){return(()=>{var e={271:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=r(185);class AbortSignal extends o.EventTarget{constructor(){throw super(),new TypeError("AbortSignal cannot be constructed directly")}get aborted(){const e=n.get(this);if("boolean"!=typeof e)throw new TypeError("Expected 'this' to be an 'AbortSignal' object, but got "+(null===this?"null":typeof this));return e}}o.defineEventAttribute(AbortSignal.prototype,"abort");const n=new WeakMap;Object.defineProperties(AbortSignal.prototype,{aborted:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(AbortSignal.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortSignal"});class AbortController{constructor(){s.set(this,function(){const e=Object.create(AbortSignal.prototype);return o.EventTarget.call(e),n.set(e,!1),e}())}get signal(){return i(this)}abort(){var e;e=i(this),!1===n.get(e)&&(n.set(e,!0),e.dispatchEvent({type:"abort"}))}}const s=new WeakMap;function i(e){const t=s.get(e);if(null==t)throw new TypeError("Expected 'this' to be an 'AbortController' object, but got "+(null===e?"null":typeof e));return t}Object.defineProperties(AbortController.prototype,{signal:{enumerable:!0},abort:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(AbortController.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortController"}),t.AbortController=AbortController,t.AbortSignal=AbortSignal,t.default=AbortController,e.exports=AbortController,e.exports.AbortController=e.exports.default=AbortController,e.exports.AbortSignal=AbortSignal},48:function(e,t,r){"use strict";var o=(this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}})(r(475)),n=function(){function e(e){this.formData=e}return e.prototype.client=function(e){return new o.default(e,this.formData)},e}();e.exports=n},475:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){var t=this;return this.request.get("/v1/ip_pools",e).then((function(e){return t.parseIpPoolsResponse(e)}))},e.prototype.create=function(e){return this.request.post("/v1/ip_pools",e).then((function(e){return null==e?void 0:e.body}))},e.prototype.update=function(e,t){return this.request.patch("/v1/ip_pools/"+e,t).then((function(e){return null==e?void 0:e.body}))},e.prototype.delete=function(e,t){return this.request.delete("/v1/ip_pools/"+e,t).then((function(e){return null==e?void 0:e.body}))},e.prototype.parseIpPoolsResponse=function(e){return e.body.ip_pools},e}();t.default=r},345:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){var t=this;return this.request.get("/v3/ips",e).then((function(e){return t.parseIpsResponse(e)}))},e.prototype.get=function(e){var t=this;return this.request.get("/v3/ips/"+e).then((function(e){return t.parseIpsResponse(e)}))},e.prototype.parseIpsResponse=function(e){return e.body},e}();t.default=r},126:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){this.request=e,this.baseRoute="/v3/lists",this.members=t}return e.prototype.list=function(e){return this.request.get(this.baseRoute+"/pages",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get(this.baseRoute+"/"+e).then((function(e){return e.body.list}))},e.prototype.create=function(e){return this.request.postWithFD(this.baseRoute,e).then((function(e){return e.body.list}))},e.prototype.update=function(e,t){return this.request.putWithFD(this.baseRoute+"/"+e,t).then((function(e){return e.body.list}))},e.prototype.destroy=function(e){return this.request.delete(this.baseRoute+"/"+e).then((function(e){return e.body}))},e}();t.default=r},135:function(e,t){"use strict";var r=this&&this.__assign||function(){return r=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype._parseResponse=function(e){return e.body?e.body:e},e.prototype.create=function(e,t){return t.message?this.request.postWithFD("/v3/"+e+"/messages.mime",t).then(this._parseResponse):this.request.postWithFD("/v3/"+e+"/messages",t).then(this._parseResponse)},e}();t.default=r},826:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.get=function(e,t){var r={};return Array.isArray(e)?r.addresses=e.join(","):r.addresses=e,t&&(r.syntax_only=!1),this.request.get("/v3/address/parse",r).then((function(e){return e.body}))},e}();t.default=r},438:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r0&&n[n.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!n||s[1]>n[0]&&s[1]0&&(p.searchParams=n.query,delete p.query),[4,(0,l.default)((0,u.default)(this.url,t),o({method:e.toLocaleUpperCase(),headers:f,throwHttpErrors:!1,timeout:this.timeout},p))];case 1:return(null==(h=s.sent())?void 0:h.ok)?[3,6]:(null==h?void 0:h.body)&&d(h.body)?[4,(_=h.body,g=[],new Promise((function(e,t){_.on("data",(function(e){return g.push(e)})),_.on("error",t),_.on("end",(function(){return e(Buffer.concat(g).toString("utf8"))}))})))]:[3,3];case 2:return y=s.sent(),[3,5];case 3:return[4,null==h?void 0:h.json()];case 4:y=s.sent(),s.label=5;case 5:throw b=y,new c.default({status:null==h?void 0:h.status,statusText:null==h?void 0:h.statusText,body:{message:b}});case 6:return m={},[4,null==h?void 0:h.json()];case 7:return[2,(m.body=s.sent(),m.status=null==h?void 0:h.status,m)]}var _,g}))}))},e.prototype.query=function(e,t,r,n){return this.request(e,t,o({query:r},n))},e.prototype.command=function(e,t,r,n){return this.request(e,t,o({headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r},n))},e.prototype.get=function(e,t,r){return this.query("get",e,t,r)},e.prototype.head=function(e,t,r){return this.query("head",e,t,r)},e.prototype.options=function(e,t,r){return this.query("options",e,t,r)},e.prototype.post=function(e,t,r){return this.command("post",e,t,r)},e.prototype.postWithFD=function(e,t){var r=this.createFormData(t);return this.command("post",e,r,{headers:{"Content-Type":null}})},e.prototype.putWithFD=function(e,t){var r=this.createFormData(t);return this.command("put",e,r,{headers:{"Content-Type":null}})},e.prototype.createFormData=function(e){var t=function(e,t,r){var n=d(t)?t:t.data,s=function(e){if("object"!=typeof e||d(e))return{};var t=e.filename,r=e.contentType,n=e.knownLength;return o(o(o({},t?{filename:t}:{filename:"file"}),r&&{contentType:r}),n&&{knownLength:n})}(t);!function(e){return void 0!==e.getHeaders}(r)?r.append(e,n,s.filename):r.append(e,n,s)};return Object.keys(e).filter((function(t){return e[t]})).reduce((function(r,o){if("attachment"===o||"inline"===o){var n=e[o];return Array.isArray(n)?n.forEach((function(e){t(o,e,r)})):t(o,n,r),r}return Array.isArray(e[o])?e[o].forEach((function(e){r.append(o,e)})):null!=e[o]&&r.append(o,e[o]),r}),new this.formData)},e.prototype.put=function(e,t,r){return this.command("put",e,t,r)},e.prototype.patch=function(e,t,r){return this.command("patch",e,t,r)},e.prototype.delete=function(e,t,r){return this.command("delete",e,t,r)},e}();t.default=f},277:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){return this.request.get("/v3/routes",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get("/v3/routes/"+e).then((function(e){return e.body.route}))},e.prototype.create=function(e){return this.request.postWithFD("/v3/routes",e).then((function(e){return e.body.route}))},e.prototype.update=function(e,t){return this.request.putWithFD("/v3/routes/"+e,t).then((function(e){return e.body}))},e.prototype.destroy=function(e){return this.request.delete("/v3/routes/"+e).then((function(e){return e.body}))},e}();t.default=r},747:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.get=function(e){return this.request.get("/v3/address/validate",{address:e}).then((function(e){return e.body}))},e}();t.default=r},750:function(e,t,r){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var n=o(r(78)),s=function(e,t){this.id=e,this.url=t},i=function(){function e(e){this.request=e}return e.prototype._parseWebhookList=function(e){return e.body.webhooks},e.prototype._parseWebhookWithID=function(e){return function(t){var r,o=null===(r=null==t?void 0:t.body)||void 0===r?void 0:r.webhook,n=null==o?void 0:o.url;return n||(n=(null==o?void 0:o.urls)&&o.urls.length?o.urls[0]:null),new s(e,n)}},e.prototype._parseWebhookTest=function(e){return{code:e.body.code,message:e.body.message}},e.prototype.list=function(e,t){return this.request.get((0,n.default)("/v2/domains",e,"webhooks"),t).then(this._parseWebhookList)},e.prototype.get=function(e,t){return this.request.get((0,n.default)("/v2/domains",e,"webhooks",t)).then(this._parseWebhookWithID(t))},e.prototype.create=function(e,t,r,o){return void 0===o&&(o=!1),o?this.request.putWithFD((0,n.default)("/v2/domains",e,"webhooks",t,"test"),{url:r}).then(this._parseWebhookTest):this.request.postWithFD((0,n.default)("/v2/domains",e,"webhooks"),{id:t,url:r}).then(this._parseWebhookWithID(t))},e.prototype.update=function(e,t,r){return this.request.putWithFD((0,n.default)("/v2/domains",e,"webhooks",t),{url:r}).then(this._parseWebhookWithID(t))},e.prototype.destroy=function(e,t){return this.request.delete((0,n.default)("/v2/domains",e,"webhooks",t)).then(this._parseWebhookWithID(t))},e}();t.default=i},501:function(e,t,r){var o;e=r.nmd(e),function(n){var s=t,i=(e&&e.exports,"object"==typeof global&&global);i.global!==i&&i.window;var a=function(e){this.message=e};(a.prototype=new Error).name="InvalidCharacterError";var u=function(e){throw new a(e)},l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=/[\t\n\f\r ]/g,d={encode:function(e){e=String(e),/[^\0-\xFF]/.test(e)&&u("The string to be encoded contains characters outside of the Latin1 range.");for(var t,r,o,n,s=e.length%3,i="",a=-1,c=e.length-s;++a>18&63)+l.charAt(n>>12&63)+l.charAt(n>>6&63)+l.charAt(63&n);return 2==s?(t=e.charCodeAt(a)<<8,r=e.charCodeAt(++a),i+=l.charAt((n=t+r)>>10)+l.charAt(n>>4&63)+l.charAt(n<<2&63)+"="):1==s&&(n=e.charCodeAt(a),i+=l.charAt(n>>2)+l.charAt(n<<4&63)+"=="),i},decode:function(e){var t=(e=String(e).replace(c,"")).length;t%4==0&&(t=(e=e.replace(/==?$/,"")).length),(t%4==1||/[^+a-zA-Z0-9/]/.test(e))&&u("Invalid character: the string to be decoded is not correctly encoded.");for(var r,o,n=0,s="",i=-1;++i>(-2*n&6)));return s},version:"1.0.0"};void 0===(o=function(){return d}.call(t,r,t,e))||(e.exports=o)}()},175:e=>{"use strict";e.exports=function(e){if(!/^data:/i.test(e))throw new TypeError('`uri` does not appear to be a Data URI (must begin with "data:")');const t=(e=e.replace(/\r?\n/g,"")).indexOf(",");if(-1===t||t<=4)throw new TypeError("malformed data: URI");const r=e.substring(5,t).split(";");let o="",n=!1;const s=r[0]||"text/plain";let i=s;for(let e=1;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=new WeakMap,o=new WeakMap;function n(e){const t=r.get(e);return console.assert(null!=t,"'this' is expected an Event object, but got",e),t}function s(e){null==e.passiveListener?e.event.cancelable&&(e.canceled=!0,"function"==typeof e.event.preventDefault&&e.event.preventDefault()):"undefined"!=typeof console&&"function"==typeof console.error&&console.error("Unable to preventDefault inside passive event listener invocation.",e.passiveListener)}function i(e,t){r.set(this,{eventTarget:e,event:t,eventPhase:2,currentTarget:e,canceled:!1,stopped:!1,immediateStopped:!1,passiveListener:null,timeStamp:t.timeStamp||Date.now()}),Object.defineProperty(this,"isTrusted",{value:!1,enumerable:!0});const o=Object.keys(t);for(let e=0;e0){const e=new Array(arguments.length);for(let t=0;t{const{Readable:o}=r(781),n=new WeakMap;class Blob{constructor(e=[],t={}){let r=0;const o=e.map((e=>{let t;return t=e instanceof Buffer?e:ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):e instanceof ArrayBuffer?Buffer.from(e):e instanceof Blob?e:Buffer.from("string"==typeof e?e:String(e)),r+=t.length||t.size||0,t})),s=void 0===t.type?"":String(t.type).toLowerCase();n.set(this,{type:/[^\u0020-\u007E]/.test(s)?"":s,size:r,parts:o})}get size(){return n.get(this).size}get type(){return n.get(this).type}async text(){return Buffer.from(await this.arrayBuffer()).toString()}async arrayBuffer(){const e=new Uint8Array(this.size);let t=0;for await(const r of this.stream())e.set(r,t),t+=r.length;return e.buffer}stream(){return o.from(async function*(e){for(const t of e)"stream"in t?yield*t.stream():yield t}(n.get(this).parts))}slice(e=0,t=this.size,r=""){const{size:o}=this;let s=e<0?Math.max(o+e,0):Math.min(e,o),i=t<0?Math.max(o+t,0):Math.min(t,o);const a=Math.max(i-s,0),u=n.get(this).parts.values(),l=[];let c=0;for(const e of u){const t=ArrayBuffer.isView(e)?e.byteLength:e.size;if(s&&t<=s)s-=t,i-=t;else{const r=e.slice(s,Math.min(t,i));if(l.push(r),c+=ArrayBuffer.isView(r)?r.byteLength:r.size,s=0,c>=a)break}}const d=new Blob([],{type:String(r).toLowerCase()});return Object.assign(n.get(d),{size:a,parts:l}),d}get[Symbol.toStringTag](){return"Blob"}static[Symbol.hasInstance](e){return e&&"object"==typeof e&&"function"==typeof e.stream&&0===e.stream.length&&"function"==typeof e.constructor&&/^(Blob|File)$/.test(e[Symbol.toStringTag])}}Object.defineProperties(Blob.prototype,{size:{enumerable:!0},type:{enumerable:!0},slice:{enumerable:!0}}),e.exports=Blob},556:(e,t,r)=>{"use strict";const o=r(594),n=r(271);if(global.fetch||(global.fetch=(e,t)=>o(e,{highWaterMark:1e7,...t})),global.Headers||(global.Headers=o.Headers),global.Request||(global.Request=o.Request),global.Response||(global.Response=o.Response),global.AbortController||(global.AbortController=n),!global.ReadableStream)try{global.ReadableStream=r(902)}catch(e){}e.exports=r(721)},721:function(e){var t;t=function(){"use strict";const e={},t=e=>"undefined"!=typeof self&&self&&e in self?self:"undefined"!=typeof window&&window&&e in window?window:"undefined"!=typeof global&&global&&e in global?global:"undefined"!=typeof globalThis&&globalThis?globalThis:void 0,r=["Headers","Request","Response","ReadableStream","fetch","AbortController","FormData"];for(const o of r)Object.defineProperty(e,o,{get(){const e=t(o),r=e&&e[o];return"function"==typeof r?r.bind(e):r}});const o=e=>null!==e&&"object"==typeof e,n="function"==typeof e.AbortController,s="function"==typeof e.ReadableStream,i="function"==typeof e.FormData,a=(t,r)=>{const o=new e.Headers(t||{}),n=r instanceof e.Headers,s=new e.Headers(r||{});for(const[e,t]of s)n&&"undefined"===t||void 0===t?o.delete(e):o.set(e,t);return o},u=(...e)=>{let t={},r={};for(const n of e){if(Array.isArray(n))Array.isArray(t)||(t=[]),t=[...t,...n];else if(o(n)){for(let[e,r]of Object.entries(n))o(r)&&e in t&&(r=u(t[e],r)),t={...t,[e]:r};o(n.headers)&&(r=a(r,n.headers))}t.headers=r}return t},l=["get","post","put","patch","head","delete"],c={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},d=[413,429,503],f=Symbol("stop");class HTTPError extends Error{constructor(e){super(e.statusText||String(0===e.status||e.status?e.status:"Unknown response error")),this.name="HTTPError",this.response=e}}class TimeoutError extends Error{constructor(e){super("Request timed out"),this.name="TimeoutError",this.request=e}}const p=e=>new Promise((t=>setTimeout(t,e))),h=e=>l.includes(e)?e.toUpperCase():e,b={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:d},y=(e={})=>{if("number"==typeof e)return{...b,limit:e};if(e.methods&&!Array.isArray(e.methods))throw new Error("retry.methods must be an array");if(e.statusCodes&&!Array.isArray(e.statusCodes))throw new Error("retry.statusCodes must be an array");return{...b,...e,afterStatusCodes:d}},m=2147483647;class Ky{constructor(t,r={}){if(this._retryCount=0,this._input=t,this._options={credentials:this._input.credentials||"same-origin",...r,headers:a(this._input.headers,r.headers),hooks:u({beforeRequest:[],beforeRetry:[],afterResponse:[]},r.hooks),method:h(r.method||this._input.method),prefixUrl:String(r.prefixUrl||""),retry:y(r.retry),throwHttpErrors:!1!==r.throwHttpErrors,timeout:void 0===r.timeout?1e4:r.timeout,fetch:r.fetch||e.fetch},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof e.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(n&&(this.abortController=new e.AbortController,this._options.signal&&this._options.signal.addEventListener("abort",(()=>{this.abortController.abort()})),this._options.signal=this.abortController.signal),this.request=new e.Request(this._input,this._options),this._options.searchParams){const t="?"+new URLSearchParams(this._options.searchParams).toString(),r=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,t);!(i&&this._options.body instanceof e.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new e.Request(new e.Request(r,this.request),this._options)}void 0!==this._options.json&&(this._options.body=JSON.stringify(this._options.json),this.request.headers.set("content-type","application/json"),this.request=new e.Request(this.request,{body:this._options.body}));const o=async()=>{if(this._options.timeout>m)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await p(1);let t=await this._fetch();for(const r of this._options.hooks.afterResponse){const o=await r(this.request,this._options,this._decorateResponse(t.clone()));o instanceof e.Response&&(t=o)}if(this._decorateResponse(t),!t.ok&&this._options.throwHttpErrors)throw new HTTPError(t);if(this._options.onDownloadProgress){if("function"!=typeof this._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!s)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return this._stream(t.clone(),this._options.onDownloadProgress)}return t},l=this._options.retry.methods.includes(this.request.method.toLowerCase())?this._retry(o):o();for(const[e,t]of Object.entries(c))l[e]=async()=>{this.request.headers.set("accept",this.request.headers.get("accept")||t);const o=(await l).clone();if("json"===e){if(204===o.status)return"";if(r.parseJson)return r.parseJson(await o.text())}return o[e]()};return l}_calculateRetryDelay(e){if(this._retryCount++,this._retryCountthis._options.retry.maxRetryAfter?0:e}if(413===e.response.status)return 0}return.3*2**(this._retryCount-1)*1e3}return 0}_decorateResponse(e){return this._options.parseJson&&(e.json=async()=>this._options.parseJson(await e.text())),e}async _retry(e){try{return await e()}catch(t){const r=Math.min(this._calculateRetryDelay(t),m);if(0!==r&&this._retryCount>0){await p(r);for(const e of this._options.hooks.beforeRetry)if(await e({request:this.request,options:this._options,error:t,retryCount:this._retryCount})===f)return;return this._retry(e)}if(this._options.throwHttpErrors)throw t}}async _fetch(){for(const e of this._options.hooks.beforeRequest){const t=await e(this.request,this._options);if(t instanceof Request){this.request=t;break}if(t instanceof Response)return t}return!1===this._options.timeout?this._options.fetch(this.request.clone()):(e=this.request.clone(),t=this.abortController,r=this._options,new Promise(((o,n)=>{const s=setTimeout((()=>{t&&t.abort(),n(new TimeoutError(e))}),r.timeout);r.fetch(e).then(o).catch(n).then((()=>{clearTimeout(s)}))})));var e,t,r}_stream(t,r){const o=Number(t.headers.get("content-length"))||0;let n=0;return new e.Response(new e.ReadableStream({start(e){const s=t.body.getReader();r&&r({percent:0,transferredBytes:0,totalBytes:o},new Uint8Array),async function t(){const{done:i,value:a}=await s.read();i?e.close():(r&&(n+=a.byteLength,r({percent:0===o?0:n/o,transferredBytes:n,totalBytes:o},a)),e.enqueue(a),t())}()}}))}}const _=(...e)=>{for(const t of e)if((!o(t)||Array.isArray(t))&&void 0!==t)throw new TypeError("The `options` argument must be an object");return u({},...e)},g=e=>{const t=(t,r)=>new Ky(t,_(e,r));for(const r of l)t[r]=(t,o)=>new Ky(t,_(e,o,{method:r}));return t.HTTPError=HTTPError,t.TimeoutError=TimeoutError,t.create=e=>g(_(e)),t.extend=t=>g(_(e,t)),t.stop=f,t};return g()},e.exports=t()},78:e=>{function t(e){return e.replace(/[\/]+/g,"/").replace(/\/\?/g,"?").replace(/\/\#/g,"#").replace(/\:\//g,"://")}e.exports=function(){var e=[].slice.call(arguments,0).join("/");return t(e)}},113:e=>{"use strict";e.exports=__nccwpck_require__(6113)},685:e=>{"use strict";e.exports=__nccwpck_require__(3685)},687:e=>{"use strict";e.exports=__nccwpck_require__(5687)},781:e=>{"use strict";e.exports=__nccwpck_require__(2781)},310:e=>{"use strict";e.exports=__nccwpck_require__(7310)},837:e=>{"use strict";e.exports=__nccwpck_require__(3837)},796:e=>{"use strict";e.exports=__nccwpck_require__(9796)},594:(e,t,r)=>{"use strict";t=e.exports=W;const o=r(685),n=r(687),s=r(796),i=r(781),a=r(175),u=r(837),l=r(30),c=r(113),d=r(310);class FetchBaseError extends Error{constructor(e,t){super(e),Error.captureStackTrace(this,this.constructor),this.type=t}get name(){return this.constructor.name}get[Symbol.toStringTag](){return this.constructor.name}}class FetchError extends FetchBaseError{constructor(e,t,r){super(e,t),r&&(this.code=this.errno=r.code,this.erroredSysCall=r.syscall)}}const f=Symbol.toStringTag,p=e=>"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.delete&&"function"==typeof e.get&&"function"==typeof e.getAll&&"function"==typeof e.has&&"function"==typeof e.set&&"function"==typeof e.sort&&"URLSearchParams"===e[f],h=e=>"object"==typeof e&&"function"==typeof e.arrayBuffer&&"string"==typeof e.type&&"function"==typeof e.stream&&"function"==typeof e.constructor&&/^(Blob|File)$/.test(e[f]);function b(e){return"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.set&&"function"==typeof e.get&&"function"==typeof e.getAll&&"function"==typeof e.delete&&"function"==typeof e.keys&&"function"==typeof e.values&&"function"==typeof e.entries&&"function"==typeof e.constructor&&"FormData"===e[f]}const y="\r\n",m="-".repeat(2),_=Buffer.byteLength(y),g=e=>`${m}${e}${m}${y.repeat(2)}`;function v(e,t,r){let o="";return o+=`${m}${e}\r\n`,o+=`Content-Disposition: form-data; name="${t}"`,h(r)&&(o+=`; filename="${r.name}"\r\n`,o+=`Content-Type: ${r.type||"application/octet-stream"}`),`${o}${y.repeat(2)}`}const w=Symbol("Body internals");class Body{constructor(e,{size:t=0}={}){let r=null;null===e?e=null:p(e)?e=Buffer.from(e.toString()):h(e)||Buffer.isBuffer(e)||(u.types.isAnyArrayBuffer(e)?e=Buffer.from(e):ArrayBuffer.isView(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):e instanceof i||(b(e)?(r=`NodeFetchFormDataBoundary${c.randomBytes(8).toString("hex")}`,e=i.Readable.from(async function*(e,t){for(const[r,o]of e)yield v(t,r,o),h(o)?yield*o.stream():yield o,yield y;yield g(t)}(e,r))):e=Buffer.from(String(e)))),this[w]={body:e,boundary:r,disturbed:!1,error:null},this.size=t,e instanceof i&&e.on("error",(e=>{const t=e instanceof FetchBaseError?e:new FetchError(`Invalid response body while trying to fetch ${this.url}: ${e.message}`,"system",e);this[w].error=t}))}get body(){return this[w].body}get bodyUsed(){return this[w].disturbed}async arrayBuffer(){const{buffer:e,byteOffset:t,byteLength:r}=await S(this);return e.slice(t,t+r)}async blob(){const e=this.headers&&this.headers.get("content-type")||this[w].body&&this[w].body.type||"",t=await this.buffer();return new l([t],{type:e})}async json(){const e=await S(this);return JSON.parse(e.toString())}async text(){return(await S(this)).toString()}buffer(){return S(this)}}async function S(e){if(e[w].disturbed)throw new TypeError(`body used already for: ${e.url}`);if(e[w].disturbed=!0,e[w].error)throw e[w].error;let{body:t}=e;if(null===t)return Buffer.alloc(0);if(h(t)&&(t=t.stream()),Buffer.isBuffer(t))return t;if(!(t instanceof i))return Buffer.alloc(0);const r=[];let o=0;try{for await(const n of t){if(e.size>0&&o+n.length>e.size){const r=new FetchError(`content size at ${e.url} over limit: ${e.size}`,"max-size");throw t.destroy(r),r}o+=n.length,r.push(n)}}catch(t){throw t instanceof FetchBaseError?t:new FetchError(`Invalid response body while trying to fetch ${e.url}: ${t.message}`,"system",t)}if(!0!==t.readableEnded&&!0!==t._readableState.ended)throw new FetchError(`Premature close of server response while trying to fetch ${e.url}`);try{return r.every((e=>"string"==typeof e))?Buffer.from(r.join("")):Buffer.concat(r,o)}catch(t){throw new FetchError(`Could not create Buffer from response body for ${e.url}: ${t.message}`,"system",t)}}Object.defineProperties(Body.prototype,{body:{enumerable:!0},bodyUsed:{enumerable:!0},arrayBuffer:{enumerable:!0},blob:{enumerable:!0},json:{enumerable:!0},text:{enumerable:!0}});const R=(e,t)=>{let r,o,{body:n}=e;if(e.bodyUsed)throw new Error("cannot clone body after it is used");return n instanceof i&&"function"!=typeof n.getBoundary&&(r=new i.PassThrough({highWaterMark:t}),o=new i.PassThrough({highWaterMark:t}),n.pipe(r),n.pipe(o),e[w].body=r,n=o),n},T=(e,t)=>null===e?null:"string"==typeof e?"text/plain;charset=UTF-8":p(e)?"application/x-www-form-urlencoded;charset=UTF-8":h(e)?e.type||null:Buffer.isBuffer(e)||u.types.isAnyArrayBuffer(e)||ArrayBuffer.isView(e)?null:e&&"function"==typeof e.getBoundary?`multipart/form-data;boundary=${e.getBoundary()}`:b(e)?`multipart/form-data; boundary=${t[w].boundary}`:e instanceof i?null:"text/plain;charset=UTF-8",q=e=>{const{body:t}=e;return null===t?0:h(t)?t.size:Buffer.isBuffer(t)?t.length:t&&"function"==typeof t.getLengthSync?t.hasKnownLength&&t.hasKnownLength()?t.getLengthSync():null:b(t)?function(e,t){let r=0;for(const[o,n]of e)r+=Buffer.byteLength(v(t,o,n)),h(n)?r+=n.size:r+=Buffer.byteLength(String(n)),r+=_;return r+=Buffer.byteLength(g(t)),r}(e[w].boundary):null},P="function"==typeof o.validateHeaderName?o.validateHeaderName:e=>{if(!/^[\^`\-\w!#$%&'*+.|~]+$/.test(e)){const t=new TypeError(`Header name must be a valid HTTP token [${e}]`);throw Object.defineProperty(t,"code",{value:"ERR_INVALID_HTTP_TOKEN"}),t}},E="function"==typeof o.validateHeaderValue?o.validateHeaderValue:(e,t)=>{if(/[^\t\u0020-\u007E\u0080-\u00FF]/.test(t)){const t=new TypeError(`Invalid character in header content ["${e}"]`);throw Object.defineProperty(t,"code",{value:"ERR_INVALID_CHAR"}),t}};class Headers extends URLSearchParams{constructor(e){let t=[];if(e instanceof Headers){const r=e.raw();for(const[e,o]of Object.entries(r))t.push(...o.map((t=>[e,t])))}else if(null==e);else{if("object"!=typeof e||u.types.isBoxedPrimitive(e))throw new TypeError("Failed to construct 'Headers': The provided value is not of type '(sequence> or record)");{const r=e[Symbol.iterator];if(null==r)t.push(...Object.entries(e));else{if("function"!=typeof r)throw new TypeError("Header pairs must be iterable");t=[...e].map((e=>{if("object"!=typeof e||u.types.isBoxedPrimitive(e))throw new TypeError("Each header pair must be an iterable object");return[...e]})).map((e=>{if(2!==e.length)throw new TypeError("Each header pair must be a name/value tuple");return[...e]}))}}}return t=t.length>0?t.map((([e,t])=>(P(e),E(e,String(t)),[String(e).toLowerCase(),String(t)]))):void 0,super(t),new Proxy(this,{get(e,t,r){switch(t){case"append":case"set":return(e,o)=>(P(e),E(e,String(o)),URLSearchParams.prototype[t].call(r,String(e).toLowerCase(),String(o)));case"delete":case"has":case"getAll":return e=>(P(e),URLSearchParams.prototype[t].call(r,String(e).toLowerCase()));case"keys":return()=>(e.sort(),new Set(URLSearchParams.prototype.keys.call(e)).keys());default:return Reflect.get(e,t,r)}}})}get[Symbol.toStringTag](){return this.constructor.name}toString(){return Object.prototype.toString.call(this)}get(e){const t=this.getAll(e);if(0===t.length)return null;let r=t.join(", ");return/^content-encoding$/i.test(e)&&(r=r.toLowerCase()),r}forEach(e){for(const t of this.keys())e(this.get(t),t)}*values(){for(const e of this.keys())yield this.get(e)}*entries(){for(const e of this.keys())yield[e,this.get(e)]}[Symbol.iterator](){return this.entries()}raw(){return[...this.keys()].reduce(((e,t)=>(e[t]=this.getAll(t),e)),{})}[Symbol.for("nodejs.util.inspect.custom")](){return[...this.keys()].reduce(((e,t)=>{const r=this.getAll(t);return e[t]="host"===t?r[0]:r.length>1?r:r[0],e}),{})}}Object.defineProperties(Headers.prototype,["get","entries","forEach","values"].reduce(((e,t)=>(e[t]={enumerable:!0},e)),{}));const C=new Set([301,302,303,307,308]),O=e=>C.has(e),A=Symbol("Response internals");class Response extends Body{constructor(e=null,t={}){super(e,t);const r=t.status||200,o=new Headers(t.headers);if(null!==e&&!o.has("Content-Type")){const t=T(e);t&&o.append("Content-Type",t)}this[A]={url:t.url,status:r,statusText:t.statusText||"",headers:o,counter:t.counter,highWaterMark:t.highWaterMark}}get url(){return this[A].url||""}get status(){return this[A].status}get ok(){return this[A].status>=200&&this[A].status<300}get redirected(){return this[A].counter>0}get statusText(){return this[A].statusText}get headers(){return this[A].headers}get highWaterMark(){return this[A].highWaterMark}clone(){return new Response(R(this,this.highWaterMark),{url:this.url,status:this.status,statusText:this.statusText,headers:this.headers,ok:this.ok,redirected:this.redirected,size:this.size})}static redirect(e,t=302){if(!O(t))throw new RangeError('Failed to execute "redirect" on "response": Invalid status code');return new Response(null,{headers:{location:new URL(e).toString()},status:t})}get[Symbol.toStringTag](){return"Response"}}Object.defineProperties(Response.prototype,{url:{enumerable:!0},status:{enumerable:!0},ok:{enumerable:!0},redirected:{enumerable:!0},statusText:{enumerable:!0},headers:{enumerable:!0},clone:{enumerable:!0}});const j=Symbol("Request internals"),k=e=>"object"==typeof e&&"object"==typeof e[j];class Request extends Body{constructor(e,t={}){let r;k(e)?r=new URL(e.url):(r=new URL(e),e={});let o=t.method||e.method||"GET";if(o=o.toUpperCase(),(null!=t.body||k(e))&&null!==e.body&&("GET"===o||"HEAD"===o))throw new TypeError("Request with GET/HEAD method cannot have body");const n=t.body?t.body:k(e)&&null!==e.body?R(e):null;super(n,{size:t.size||e.size||0});const s=new Headers(t.headers||e.headers||{});if(null!==n&&!s.has("Content-Type")){const e=T(n,this);e&&s.append("Content-Type",e)}let i=k(e)?e.signal:null;if("signal"in t&&(i=t.signal),null!==i&&("object"!=typeof(a=i)||"AbortSignal"!==a[f]))throw new TypeError("Expected signal to be an instanceof AbortSignal");var a;this[j]={method:o,redirect:t.redirect||e.redirect||"follow",headers:s,parsedURL:r,signal:i},this.follow=void 0===t.follow?void 0===e.follow?20:e.follow:t.follow,this.compress=void 0===t.compress?void 0===e.compress||e.compress:t.compress,this.counter=t.counter||e.counter||0,this.agent=t.agent||e.agent,this.highWaterMark=t.highWaterMark||e.highWaterMark||16384,this.insecureHTTPParser=t.insecureHTTPParser||e.insecureHTTPParser||!1}get method(){return this[j].method}get url(){return d.format(this[j].parsedURL)}get headers(){return this[j].headers}get redirect(){return this[j].redirect}get signal(){return this[j].signal}clone(){return new Request(this)}get[Symbol.toStringTag](){return"Request"}}Object.defineProperties(Request.prototype,{method:{enumerable:!0},url:{enumerable:!0},headers:{enumerable:!0},redirect:{enumerable:!0},clone:{enumerable:!0},signal:{enumerable:!0}});class AbortError extends FetchBaseError{constructor(e,t="aborted"){super(e,t)}}const B=new Set(["data:","http:","https:"]);async function W(e,t){return new Promise(((r,u)=>{const l=new Request(e,t),c=(e=>{const{parsedURL:t}=e[j],r=new Headers(e[j].headers);r.has("Accept")||r.set("Accept","*/*");let o=null;if(null===e.body&&/^(post|put)$/i.test(e.method)&&(o="0"),null!==e.body){const t=q(e);"number"!=typeof t||Number.isNaN(t)||(o=String(t))}o&&r.set("Content-Length",o),r.has("User-Agent")||r.set("User-Agent","node-fetch"),e.compress&&!r.has("Accept-Encoding")&&r.set("Accept-Encoding","gzip,deflate,br");let{agent:n}=e;"function"==typeof n&&(n=n(t)),r.has("Connection")||n||r.set("Connection","close");const s=(e=>{if(e.search)return e.search;const t=e.href.length-1,r=e.hash||("#"===e.href[t]?"#":"");return"?"===e.href[t-r.length]?"?":""})(t);return{path:t.pathname+s,pathname:t.pathname,hostname:t.hostname,protocol:t.protocol,port:t.port,hash:t.hash,search:t.search,query:t.query,href:t.href,method:e.method,headers:r[Symbol.for("nodejs.util.inspect.custom")](),insecureHTTPParser:e.insecureHTTPParser,agent:n}})(l);if(!B.has(c.protocol))throw new TypeError(`node-fetch cannot load ${e}. URL scheme "${c.protocol.replace(/:$/,"")}" is not supported.`);if("data:"===c.protocol){const e=a(l.url),t=new Response(e,{headers:{"Content-Type":e.typeFull}});return void r(t)}const d=("https:"===c.protocol?n:o).request,{signal:f}=l;let p=null;const b=()=>{const e=new AbortError("The operation was aborted.");u(e),l.body&&l.body instanceof i.Readable&&l.body.destroy(e),p&&p.body&&p.body.emit("error",e)};if(f&&f.aborted)return void b();const y=()=>{b(),_()},m=d(c);f&&f.addEventListener("abort",y);const _=()=>{m.abort(),f&&f.removeEventListener("abort",y)};m.on("error",(e=>{u(new FetchError(`request to ${l.url} failed, reason: ${e.message}`,"system",e)),_()})),m.on("response",(e=>{m.setTimeout(0);const o=function(e=[]){return new Headers(e.reduce(((e,t,r,o)=>(r%2==0&&e.push(o.slice(r,r+2)),e)),[]).filter((([e,t])=>{try{return P(e),E(e,String(t)),!0}catch{return!1}})))}(e.rawHeaders);if(O(e.statusCode)){const n=o.get("Location"),s=null===n?null:new URL(n,l.url);switch(l.redirect){case"error":return u(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${l.url}`,"no-redirect")),void _();case"manual":if(null!==s)try{o.set("Location",s)}catch(e){u(e)}break;case"follow":{if(null===s)break;if(l.counter>=l.follow)return u(new FetchError(`maximum redirect reached at: ${l.url}`,"max-redirect")),void _();const o={headers:new Headers(l.headers),follow:l.follow,counter:l.counter+1,agent:l.agent,compress:l.compress,method:l.method,body:l.body,signal:l.signal,size:l.size};return 303!==e.statusCode&&l.body&&t.body instanceof i.Readable?(u(new FetchError("Cannot follow redirect with body being a readable stream","unsupported-redirect")),void _()):(303!==e.statusCode&&(301!==e.statusCode&&302!==e.statusCode||"POST"!==l.method)||(o.method="GET",o.body=void 0,o.headers.delete("content-length")),r(W(new Request(s,o))),void _())}}}e.once("end",(()=>{f&&f.removeEventListener("abort",y)}));let n=i.pipeline(e,new i.PassThrough,(e=>{u(e)}));process.version<"v12.10"&&e.on("aborted",y);const a={url:l.url,status:e.statusCode,statusText:e.statusMessage,headers:o,size:l.size,counter:l.counter,highWaterMark:l.highWaterMark},c=o.get("Content-Encoding");if(!l.compress||"HEAD"===l.method||null===c||204===e.statusCode||304===e.statusCode)return p=new Response(n,a),void r(p);const d={flush:s.Z_SYNC_FLUSH,finishFlush:s.Z_SYNC_FLUSH};if("gzip"===c||"x-gzip"===c)return n=i.pipeline(n,s.createGunzip(d),(e=>{u(e)})),p=new Response(n,a),void r(p);if("deflate"!==c&&"x-deflate"!==c){if("br"===c)return n=i.pipeline(n,s.createBrotliDecompress(),(e=>{u(e)})),p=new Response(n,a),void r(p);p=new Response(n,a),r(p)}else{i.pipeline(e,new i.PassThrough,(e=>{u(e)})).once("data",(e=>{n=8==(15&e[0])?i.pipeline(n,s.createInflate(),(e=>{u(e)})):i.pipeline(n,s.createInflateRaw(),(e=>{u(e)})),p=new Response(n,a),r(p)}))}})),((e,{body:t})=>{null===t?e.end():h(t)?t.stream().pipe(e):Buffer.isBuffer(t)?(e.write(t),e.end()):t.pipe(e)})(m,l)}))}t.AbortError=AbortError,t.FetchError=FetchError,t.Headers=Headers,t.Request=Request,t.Response=Response,t.default=W,t.isRedirect=O},902:(e,t,r)=>{"use strict";r.r(t),r.d(t,{ByteLengthQueuingStrategy:()=>ByteLengthQueuingStrategy,CountQueuingStrategy:()=>CountQueuingStrategy,ReadableByteStreamController:()=>ReadableByteStreamController,ReadableStream:()=>ReadableStream,ReadableStreamBYOBReader:()=>ReadableStreamBYOBReader,ReadableStreamBYOBRequest:()=>ReadableStreamBYOBRequest,ReadableStreamDefaultController:()=>ReadableStreamDefaultController,ReadableStreamDefaultReader:()=>ReadableStreamDefaultReader,TransformStream:()=>TransformStream,TransformStreamDefaultController:()=>TransformStreamDefaultController,WritableStream:()=>WritableStream,WritableStreamDefaultController:()=>WritableStreamDefaultController,WritableStreamDefaultWriter:()=>WritableStreamDefaultWriter});const o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol:e=>`Symbol(${e})`;function n(){}const s="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0;function i(e){return"object"==typeof e&&null!==e||"function"==typeof e}const a=n,u=Promise,l=Promise.prototype.then,c=Promise.resolve.bind(u),d=Promise.reject.bind(u);function f(e){return new u(e)}function p(e){return c(e)}function h(e){return d(e)}function b(e,t,r){return l.call(e,t,r)}function y(e,t,r){b(b(e,t,r),void 0,a)}function m(e,t){y(e,t)}function _(e,t){y(e,void 0,t)}function g(e,t,r){return b(e,t,r)}function v(e){b(e,void 0,a)}const w=(()=>{const e=s&&s.queueMicrotask;if("function"==typeof e)return e;const t=p(void 0);return e=>b(t,e)})();function S(e,t,r){if("function"!=typeof e)throw new TypeError("Argument is not a function");return Function.prototype.apply.call(e,t,r)}function R(e,t,r){try{return p(S(e,t,r))}catch(e){return h(e)}}class SimpleQueue{constructor(){this._cursor=0,this._size=0,this._front={_elements:[],_next:void 0},this._back=this._front,this._cursor=0,this._size=0}get length(){return this._size}push(e){const t=this._back;let r=t;16383===t._elements.length&&(r={_elements:[],_next:void 0}),t._elements.push(e),r!==t&&(this._back=r,t._next=r),++this._size}shift(){const e=this._front;let t=e;const r=this._cursor;let o=r+1;const n=e._elements,s=n[r];return 16384===o&&(t=e._next,o=0),--this._size,this._cursor=o,e!==t&&(this._front=t),n[r]=void 0,s}forEach(e){let t=this._cursor,r=this._front,o=r._elements;for(;!(t===o.length&&void 0===r._next||t===o.length&&(r=r._next,o=r._elements,t=0,0===o.length));)e(o[t]),++t}peek(){const e=this._front,t=this._cursor;return e._elements[t]}}function T(e,t){e._ownerReadableStream=t,t._reader=e,"readable"===t._state?C(e):"closed"===t._state?function(e){C(e),j(e)}(e):O(e,t._storedError)}function q(e,t){return pr(e._ownerReadableStream,t)}function P(e){"readable"===e._ownerReadableStream._state?A(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness")):function(e,t){O(e,t)}(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness")),e._ownerReadableStream._reader=void 0,e._ownerReadableStream=void 0}function E(e){return new TypeError("Cannot "+e+" a stream using a released reader")}function C(e){e._closedPromise=f(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r}))}function O(e,t){C(e),A(e,t)}function A(e,t){void 0!==e._closedPromise_reject&&(v(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}function j(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}const k=o("[[AbortSteps]]"),B=o("[[ErrorSteps]]"),W=o("[[CancelSteps]]"),x=o("[[PullSteps]]"),D=Number.isFinite||function(e){return"number"==typeof e&&isFinite(e)},L=Math.trunc||function(e){return e<0?Math.ceil(e):Math.floor(e)};function F(e,t){if(void 0!==e&&("object"!=typeof(r=e)&&"function"!=typeof r))throw new TypeError(`${t} is not an object.`);var r}function z(e,t){if("function"!=typeof e)throw new TypeError(`${t} is not a function.`)}function I(e,t){if(!function(e){return"object"==typeof e&&null!==e||"function"==typeof e}(e))throw new TypeError(`${t} is not an object.`)}function M(e,t,r){if(void 0===e)throw new TypeError(`Parameter ${t} is required in '${r}'.`)}function $(e,t,r){if(void 0===e)throw new TypeError(`${t} is required in '${r}'.`)}function H(e){return Number(e)}function U(e){return 0===e?0:e}function N(e,t){const r=Number.MAX_SAFE_INTEGER;let o=Number(e);if(o=U(o),!D(o))throw new TypeError(`${t} is not a finite number`);if(o=function(e){return U(L(e))}(o),o<0||o>r)throw new TypeError(`${t} is outside the accepted range of 0 to ${r}, inclusive`);return D(o)&&0!==o?o:0}function Q(e,t){if(!dr(e))throw new TypeError(`${t} is not a ReadableStream.`)}function Y(e){return new ReadableStreamDefaultReader(e)}function V(e,t){e._reader._readRequests.push(t)}function G(e,t,r){const o=e._reader._readRequests.shift();r?o._closeSteps():o._chunkSteps(t)}function J(e){return e._reader._readRequests.length}function K(e){const t=e._reader;return void 0!==t&&!!Z(t)}class ReadableStreamDefaultReader{constructor(e){if(M(e,1,"ReadableStreamDefaultReader"),Q(e,"First parameter"),fr(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");T(this,e),this._readRequests=new SimpleQueue}get closed(){return Z(this)?this._closedPromise:h(ee("closed"))}cancel(e){return Z(this)?void 0===this._ownerReadableStream?h(E("cancel")):q(this,e):h(ee("cancel"))}read(){if(!Z(this))return h(ee("read"));if(void 0===this._ownerReadableStream)return h(E("read from"));let e,t;const r=f(((r,o)=>{e=r,t=o}));return X(this,{_chunkSteps:t=>e({value:t,done:!1}),_closeSteps:()=>e({value:void 0,done:!0}),_errorSteps:e=>t(e)}),r}releaseLock(){if(!Z(this))throw ee("releaseLock");if(void 0!==this._ownerReadableStream){if(this._readRequests.length>0)throw new TypeError("Tried to release a reader lock when that reader has pending read() calls un-settled");P(this)}}}function Z(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readRequests")&&e instanceof ReadableStreamDefaultReader)}function X(e,t){const r=e._ownerReadableStream;r._disturbed=!0,"closed"===r._state?t._closeSteps():"errored"===r._state?t._errorSteps(r._storedError):r._readableStreamController[x](t)}function ee(e){return new TypeError(`ReadableStreamDefaultReader.prototype.${e} can only be used on a ReadableStreamDefaultReader`)}Object.defineProperties(ReadableStreamDefaultReader.prototype,{cancel:{enumerable:!0},read:{enumerable:!0},releaseLock:{enumerable:!0},closed:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamDefaultReader.prototype,o.toStringTag,{value:"ReadableStreamDefaultReader",configurable:!0});const te=Object.getPrototypeOf(Object.getPrototypeOf((async function*(){})).prototype);class ReadableStreamAsyncIteratorImpl{constructor(e,t){this._ongoingPromise=void 0,this._isFinished=!1,this._reader=e,this._preventCancel=t}next(){const e=()=>this._nextSteps();return this._ongoingPromise=this._ongoingPromise?g(this._ongoingPromise,e,e):e(),this._ongoingPromise}return(e){const t=()=>this._returnSteps(e);return this._ongoingPromise?g(this._ongoingPromise,t,t):t()}_nextSteps(){if(this._isFinished)return Promise.resolve({value:void 0,done:!0});const e=this._reader;if(void 0===e._ownerReadableStream)return h(E("iterate"));let t,r;const o=f(((e,o)=>{t=e,r=o}));return X(e,{_chunkSteps:e=>{this._ongoingPromise=void 0,w((()=>t({value:e,done:!1})))},_closeSteps:()=>{this._ongoingPromise=void 0,this._isFinished=!0,P(e),t({value:void 0,done:!0})},_errorSteps:t=>{this._ongoingPromise=void 0,this._isFinished=!0,P(e),r(t)}}),o}_returnSteps(e){if(this._isFinished)return Promise.resolve({value:e,done:!0});this._isFinished=!0;const t=this._reader;if(void 0===t._ownerReadableStream)return h(E("finish iterating"));if(!this._preventCancel){const r=q(t,e);return P(t),g(r,(()=>({value:e,done:!0})))}return P(t),p({value:e,done:!0})}}const re={next(){return oe(this)?this._asyncIteratorImpl.next():h(ne("next"))},return(e){return oe(this)?this._asyncIteratorImpl.return(e):h(ne("return"))}};function oe(e){if(!i(e))return!1;if(!Object.prototype.hasOwnProperty.call(e,"_asyncIteratorImpl"))return!1;try{return e._asyncIteratorImpl instanceof ReadableStreamAsyncIteratorImpl}catch(e){return!1}}function ne(e){return new TypeError(`ReadableStreamAsyncIterator.${e} can only be used on a ReadableSteamAsyncIterator`)}void 0!==te&&Object.setPrototypeOf(re,te);const se=Number.isNaN||function(e){return e!=e};function ie(e){return e.slice()}function ae(e,t,r,o,n){new Uint8Array(e).set(new Uint8Array(r,o,n),t)}function ue(e,t,r){if(e.slice)return e.slice(t,r);const o=r-t,n=new ArrayBuffer(o);return ae(n,0,e,t,o),n}function le(e){const t=ue(e.buffer,e.byteOffset,e.byteOffset+e.byteLength);return new Uint8Array(t)}function ce(e){const t=e._queue.shift();return e._queueTotalSize-=t.size,e._queueTotalSize<0&&(e._queueTotalSize=0),t.value}function de(e,t,r){if("number"!=typeof(o=r)||se(o)||o<0||r===1/0)throw new RangeError("Size must be a finite, non-NaN, non-negative number.");var o;e._queue.push({value:t,size:r}),e._queueTotalSize+=r}function fe(e){e._queue=new SimpleQueue,e._queueTotalSize=0}class ReadableStreamBYOBRequest{constructor(){throw new TypeError("Illegal constructor")}get view(){if(!he(this))throw De("view");return this._view}respond(e){if(!he(this))throw De("respond");if(M(e,1,"respond"),e=N(e,"First parameter"),void 0===this._associatedReadableByteStreamController)throw new TypeError("This BYOB request has been invalidated");this._view.buffer,Be(this._associatedReadableByteStreamController,e)}respondWithNewView(e){if(!he(this))throw De("respondWithNewView");if(M(e,1,"respondWithNewView"),!ArrayBuffer.isView(e))throw new TypeError("You can only respond with array buffer views");if(void 0===this._associatedReadableByteStreamController)throw new TypeError("This BYOB request has been invalidated");e.buffer,We(this._associatedReadableByteStreamController,e)}}Object.defineProperties(ReadableStreamBYOBRequest.prototype,{respond:{enumerable:!0},respondWithNewView:{enumerable:!0},view:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamBYOBRequest.prototype,o.toStringTag,{value:"ReadableStreamBYOBRequest",configurable:!0});class ReadableByteStreamController{constructor(){throw new TypeError("Illegal constructor")}get byobRequest(){if(!pe(this))throw Le("byobRequest");return je(this)}get desiredSize(){if(!pe(this))throw Le("desiredSize");return ke(this)}close(){if(!pe(this))throw Le("close");if(this._closeRequested)throw new TypeError("The stream has already been closed; do not close it again!");const e=this._controlledReadableByteStream._state;if("readable"!==e)throw new TypeError(`The stream (in ${e} state) is not in the readable state and cannot be closed`);Ce(this)}enqueue(e){if(!pe(this))throw Le("enqueue");if(M(e,1,"enqueue"),!ArrayBuffer.isView(e))throw new TypeError("chunk must be an array buffer view");if(0===e.byteLength)throw new TypeError("chunk must have non-zero byteLength");if(0===e.buffer.byteLength)throw new TypeError("chunk's buffer must have non-zero byteLength");if(this._closeRequested)throw new TypeError("stream is closed or draining");const t=this._controlledReadableByteStream._state;if("readable"!==t)throw new TypeError(`The stream (in ${t} state) is not in the readable state and cannot be enqueued to`);Oe(this,e)}error(e){if(!pe(this))throw Le("error");Ae(this,e)}[W](e){ye(this),fe(this);const t=this._cancelAlgorithm(e);return Ee(this),t}[x](e){const t=this._controlledReadableByteStream;if(this._queueTotalSize>0){const t=this._queue.shift();this._queueTotalSize-=t.byteLength,Se(this);const r=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return void e._chunkSteps(r)}const r=this._autoAllocateChunkSize;if(void 0!==r){let t;try{t=new ArrayBuffer(r)}catch(t){return void e._errorSteps(t)}const o={buffer:t,bufferByteLength:r,byteOffset:0,byteLength:r,bytesFilled:0,elementSize:1,viewConstructor:Uint8Array,readerType:"default"};this._pendingPullIntos.push(o)}V(t,e),be(this)}}function pe(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledReadableByteStream")&&e instanceof ReadableByteStreamController)}function he(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_associatedReadableByteStreamController")&&e instanceof ReadableStreamBYOBRequest)}function be(e){const t=function(e){const t=e._controlledReadableByteStream;if("readable"!==t._state)return!1;if(e._closeRequested)return!1;if(!e._started)return!1;if(K(t)&&J(t)>0)return!0;if(Me(t)&&Ie(t)>0)return!0;if(ke(e)>0)return!0;return!1}(e);if(!t)return;if(e._pulling)return void(e._pullAgain=!0);e._pulling=!0;y(e._pullAlgorithm(),(()=>{e._pulling=!1,e._pullAgain&&(e._pullAgain=!1,be(e))}),(t=>{Ae(e,t)}))}function ye(e){Re(e),e._pendingPullIntos=new SimpleQueue}function me(e,t){let r=!1;"closed"===e._state&&(r=!0);const o=_e(t);"default"===t.readerType?G(e,o,r):function(e,t,r){const o=e._reader._readIntoRequests.shift();r?o._closeSteps(t):o._chunkSteps(t)}(e,o,r)}function _e(e){const t=e.bytesFilled,r=e.elementSize;return new e.viewConstructor(e.buffer,e.byteOffset,t/r)}function ge(e,t,r,o){e._queue.push({buffer:t,byteOffset:r,byteLength:o}),e._queueTotalSize+=o}function ve(e,t){const r=t.elementSize,o=t.bytesFilled-t.bytesFilled%r,n=Math.min(e._queueTotalSize,t.byteLength-t.bytesFilled),s=t.bytesFilled+n,i=s-s%r;let a=n,u=!1;i>o&&(a=i-t.bytesFilled,u=!0);const l=e._queue;for(;a>0;){const r=l.peek(),o=Math.min(a,r.byteLength),n=t.byteOffset+t.bytesFilled;ae(t.buffer,n,r.buffer,r.byteOffset,o),r.byteLength===o?l.shift():(r.byteOffset+=o,r.byteLength-=o),e._queueTotalSize-=o,we(e,o,t),a-=o}return u}function we(e,t,r){r.bytesFilled+=t}function Se(e){0===e._queueTotalSize&&e._closeRequested?(Ee(e),hr(e._controlledReadableByteStream)):be(e)}function Re(e){null!==e._byobRequest&&(e._byobRequest._associatedReadableByteStreamController=void 0,e._byobRequest._view=null,e._byobRequest=null)}function Te(e){for(;e._pendingPullIntos.length>0;){if(0===e._queueTotalSize)return;const t=e._pendingPullIntos.peek();ve(e,t)&&(Pe(e),me(e._controlledReadableByteStream,t))}}function qe(e,t){const r=e._pendingPullIntos.peek();Re(e);"closed"===e._controlledReadableByteStream._state?function(e,t){const r=e._controlledReadableByteStream;if(Me(r))for(;Ie(r)>0;)me(r,Pe(e))}(e):function(e,t,r){if(we(0,t,r),r.bytesFilled0){const t=r.byteOffset+r.bytesFilled,n=ue(r.buffer,t-o,t);ge(e,n,0,n.byteLength)}r.bytesFilled-=o,me(e._controlledReadableByteStream,r),Te(e)}(e,t,r),be(e)}function Pe(e){return e._pendingPullIntos.shift()}function Ee(e){e._pullAlgorithm=void 0,e._cancelAlgorithm=void 0}function Ce(e){const t=e._controlledReadableByteStream;if(!e._closeRequested&&"readable"===t._state)if(e._queueTotalSize>0)e._closeRequested=!0;else{if(e._pendingPullIntos.length>0){if(e._pendingPullIntos.peek().bytesFilled>0){const t=new TypeError("Insufficient bytes to fill elements in the given buffer");throw Ae(e,t),t}}Ee(e),hr(t)}}function Oe(e,t){const r=e._controlledReadableByteStream;if(e._closeRequested||"readable"!==r._state)return;const o=t.buffer,n=t.byteOffset,s=t.byteLength,i=o;if(e._pendingPullIntos.length>0){const t=e._pendingPullIntos.peek();t.buffer,0,t.buffer=t.buffer}if(Re(e),K(r))if(0===J(r))ge(e,i,n,s);else{G(r,new Uint8Array(i,n,s),!1)}else Me(r)?(ge(e,i,n,s),Te(e)):ge(e,i,n,s);be(e)}function Ae(e,t){const r=e._controlledReadableByteStream;"readable"===r._state&&(ye(e),fe(e),Ee(e),br(r,t))}function je(e){if(null===e._byobRequest&&e._pendingPullIntos.length>0){const t=e._pendingPullIntos.peek(),r=new Uint8Array(t.buffer,t.byteOffset+t.bytesFilled,t.byteLength-t.bytesFilled),o=Object.create(ReadableStreamBYOBRequest.prototype);!function(e,t,r){e._associatedReadableByteStreamController=t,e._view=r}(o,e,r),e._byobRequest=o}return e._byobRequest}function ke(e){const t=e._controlledReadableByteStream._state;return"errored"===t?null:"closed"===t?0:e._strategyHWM-e._queueTotalSize}function Be(e,t){const r=e._pendingPullIntos.peek();if("closed"===e._controlledReadableByteStream._state){if(0!==t)throw new TypeError("bytesWritten must be 0 when calling respond() on a closed stream")}else{if(0===t)throw new TypeError("bytesWritten must be greater than 0 when calling respond() on a readable stream");if(r.bytesFilled+t>r.byteLength)throw new RangeError("bytesWritten out of range")}r.buffer=r.buffer,qe(e,t)}function We(e,t){const r=e._pendingPullIntos.peek();if("closed"===e._controlledReadableByteStream._state){if(0!==t.byteLength)throw new TypeError("The view's length must be 0 when calling respondWithNewView() on a closed stream")}else if(0===t.byteLength)throw new TypeError("The view's length must be greater than 0 when calling respondWithNewView() on a readable stream");if(r.byteOffset+r.bytesFilled!==t.byteOffset)throw new RangeError("The region specified by view does not match byobRequest");if(r.bufferByteLength!==t.buffer.byteLength)throw new RangeError("The buffer of view has different capacity than byobRequest");if(r.bytesFilled+t.byteLength>r.byteLength)throw new RangeError("The region specified by view is larger than byobRequest");r.buffer=t.buffer,qe(e,t.byteLength)}function xe(e,t,r,o,n,s,i){t._controlledReadableByteStream=e,t._pullAgain=!1,t._pulling=!1,t._byobRequest=null,t._queue=t._queueTotalSize=void 0,fe(t),t._closeRequested=!1,t._started=!1,t._strategyHWM=s,t._pullAlgorithm=o,t._cancelAlgorithm=n,t._autoAllocateChunkSize=i,t._pendingPullIntos=new SimpleQueue,e._readableStreamController=t;y(p(r()),(()=>{t._started=!0,be(t)}),(e=>{Ae(t,e)}))}function De(e){return new TypeError(`ReadableStreamBYOBRequest.prototype.${e} can only be used on a ReadableStreamBYOBRequest`)}function Le(e){return new TypeError(`ReadableByteStreamController.prototype.${e} can only be used on a ReadableByteStreamController`)}function Fe(e){return new ReadableStreamBYOBReader(e)}function ze(e,t){e._reader._readIntoRequests.push(t)}function Ie(e){return e._reader._readIntoRequests.length}function Me(e){const t=e._reader;return void 0!==t&&!!$e(t)}Object.defineProperties(ReadableByteStreamController.prototype,{close:{enumerable:!0},enqueue:{enumerable:!0},error:{enumerable:!0},byobRequest:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableByteStreamController.prototype,o.toStringTag,{value:"ReadableByteStreamController",configurable:!0});class ReadableStreamBYOBReader{constructor(e){if(M(e,1,"ReadableStreamBYOBReader"),Q(e,"First parameter"),fr(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");if(!pe(e._readableStreamController))throw new TypeError("Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte source");T(this,e),this._readIntoRequests=new SimpleQueue}get closed(){return $e(this)?this._closedPromise:h(Ue("closed"))}cancel(e){return $e(this)?void 0===this._ownerReadableStream?h(E("cancel")):q(this,e):h(Ue("cancel"))}read(e){if(!$e(this))return h(Ue("read"));if(!ArrayBuffer.isView(e))return h(new TypeError("view must be an array buffer view"));if(0===e.byteLength)return h(new TypeError("view must have non-zero byteLength"));if(0===e.buffer.byteLength)return h(new TypeError("view's buffer must have non-zero byteLength"));if(e.buffer,void 0===this._ownerReadableStream)return h(E("read from"));let t,r;const o=f(((e,o)=>{t=e,r=o}));return He(this,e,{_chunkSteps:e=>t({value:e,done:!1}),_closeSteps:e=>t({value:e,done:!0}),_errorSteps:e=>r(e)}),o}releaseLock(){if(!$e(this))throw Ue("releaseLock");if(void 0!==this._ownerReadableStream){if(this._readIntoRequests.length>0)throw new TypeError("Tried to release a reader lock when that reader has pending read() calls un-settled");P(this)}}}function $e(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readIntoRequests")&&e instanceof ReadableStreamBYOBReader)}function He(e,t,r){const o=e._ownerReadableStream;o._disturbed=!0,"errored"===o._state?r._errorSteps(o._storedError):function(e,t,r){const o=e._controlledReadableByteStream;let n=1;t.constructor!==DataView&&(n=t.constructor.BYTES_PER_ELEMENT);const s=t.constructor,i=t.buffer,a={buffer:i,bufferByteLength:i.byteLength,byteOffset:t.byteOffset,byteLength:t.byteLength,bytesFilled:0,elementSize:n,viewConstructor:s,readerType:"byob"};if(e._pendingPullIntos.length>0)return e._pendingPullIntos.push(a),void ze(o,r);if("closed"!==o._state){if(e._queueTotalSize>0){if(ve(e,a)){const t=_e(a);return Se(e),void r._chunkSteps(t)}if(e._closeRequested){const t=new TypeError("Insufficient bytes to fill elements in the given buffer");return Ae(e,t),void r._errorSteps(t)}}e._pendingPullIntos.push(a),ze(o,r),be(e)}else{const e=new s(a.buffer,a.byteOffset,0);r._closeSteps(e)}}(o._readableStreamController,t,r)}function Ue(e){return new TypeError(`ReadableStreamBYOBReader.prototype.${e} can only be used on a ReadableStreamBYOBReader`)}function Ne(e,t){const{highWaterMark:r}=e;if(void 0===r)return t;if(se(r)||r<0)throw new RangeError("Invalid highWaterMark");return r}function Qe(e){const{size:t}=e;return t||(()=>1)}function Ye(e,t){F(e,t);const r=null==e?void 0:e.highWaterMark,o=null==e?void 0:e.size;return{highWaterMark:void 0===r?void 0:H(r),size:void 0===o?void 0:Ve(o,`${t} has member 'size' that`)}}function Ve(e,t){return z(e,t),t=>H(e(t))}function Ge(e,t,r){return z(e,r),r=>R(e,t,[r])}function Je(e,t,r){return z(e,r),()=>R(e,t,[])}function Ke(e,t,r){return z(e,r),r=>S(e,t,[r])}function Ze(e,t,r){return z(e,r),(r,o)=>R(e,t,[r,o])}function Xe(e,t){if(!ot(e))throw new TypeError(`${t} is not a WritableStream.`)}Object.defineProperties(ReadableStreamBYOBReader.prototype,{cancel:{enumerable:!0},read:{enumerable:!0},releaseLock:{enumerable:!0},closed:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamBYOBReader.prototype,o.toStringTag,{value:"ReadableStreamBYOBReader",configurable:!0});const et="function"==typeof AbortController;class WritableStream{constructor(e={},t={}){void 0===e?e=null:I(e,"First parameter");const r=Ye(t,"Second parameter"),o=function(e,t){F(e,t);const r=null==e?void 0:e.abort,o=null==e?void 0:e.close,n=null==e?void 0:e.start,s=null==e?void 0:e.type,i=null==e?void 0:e.write;return{abort:void 0===r?void 0:Ge(r,e,`${t} has member 'abort' that`),close:void 0===o?void 0:Je(o,e,`${t} has member 'close' that`),start:void 0===n?void 0:Ke(n,e,`${t} has member 'start' that`),write:void 0===i?void 0:Ze(i,e,`${t} has member 'write' that`),type:s}}(e,"First parameter");rt(this);if(void 0!==o.type)throw new RangeError("Invalid type is specified");const n=Qe(r);!function(e,t,r,o){const n=Object.create(WritableStreamDefaultController.prototype);let s=()=>{},i=()=>p(void 0),a=()=>p(void 0),u=()=>p(void 0);void 0!==t.start&&(s=()=>t.start(n));void 0!==t.write&&(i=e=>t.write(e,n));void 0!==t.close&&(a=()=>t.close());void 0!==t.abort&&(u=e=>t.abort(e));wt(e,n,s,i,a,u,r,o)}(this,o,Ne(r,1),n)}get locked(){if(!ot(this))throw Ct("locked");return nt(this)}abort(e){return ot(this)?nt(this)?h(new TypeError("Cannot abort a stream that already has a writer")):st(this,e):h(Ct("abort"))}close(){return ot(this)?nt(this)?h(new TypeError("Cannot close a stream that already has a writer")):ct(this)?h(new TypeError("Cannot close an already-closing stream")):it(this):h(Ct("close"))}getWriter(){if(!ot(this))throw Ct("getWriter");return tt(this)}}function tt(e){return new WritableStreamDefaultWriter(e)}function rt(e){e._state="writable",e._storedError=void 0,e._writer=void 0,e._writableStreamController=void 0,e._writeRequests=new SimpleQueue,e._inFlightWriteRequest=void 0,e._closeRequest=void 0,e._inFlightCloseRequest=void 0,e._pendingAbortRequest=void 0,e._backpressure=!1}function ot(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_writableStreamController")&&e instanceof WritableStream)}function nt(e){return void 0!==e._writer}function st(e,t){var r;if("closed"===e._state||"errored"===e._state)return p(void 0);e._writableStreamController._abortReason=t,null===(r=e._writableStreamController._abortController)||void 0===r||r.abort();const o=e._state;if("closed"===o||"errored"===o)return p(void 0);if(void 0!==e._pendingAbortRequest)return e._pendingAbortRequest._promise;let n=!1;"erroring"===o&&(n=!0,t=void 0);const s=f(((r,o)=>{e._pendingAbortRequest={_promise:void 0,_resolve:r,_reject:o,_reason:t,_wasAlreadyErroring:n}}));return e._pendingAbortRequest._promise=s,n||ut(e,t),s}function it(e){const t=e._state;if("closed"===t||"errored"===t)return h(new TypeError(`The stream (in ${t} state) is not in the writable state and cannot be closed`));const r=f(((t,r)=>{const o={_resolve:t,_reject:r};e._closeRequest=o})),o=e._writer;var n;return void 0!==o&&e._backpressure&&"writable"===t&&It(o),de(n=e._writableStreamController,gt,0),Tt(n),r}function at(e,t){"writable"!==e._state?lt(e):ut(e,t)}function ut(e,t){const r=e._writableStreamController;e._state="erroring",e._storedError=t;const o=e._writer;void 0!==o&&yt(o,t),!function(e){if(void 0===e._inFlightWriteRequest&&void 0===e._inFlightCloseRequest)return!1;return!0}(e)&&r._started&<(e)}function lt(e){e._state="errored",e._writableStreamController[B]();const t=e._storedError;if(e._writeRequests.forEach((e=>{e._reject(t)})),e._writeRequests=new SimpleQueue,void 0===e._pendingAbortRequest)return void dt(e);const r=e._pendingAbortRequest;if(e._pendingAbortRequest=void 0,r._wasAlreadyErroring)return r._reject(t),void dt(e);y(e._writableStreamController[k](r._reason),(()=>{r._resolve(),dt(e)}),(t=>{r._reject(t),dt(e)}))}function ct(e){return void 0!==e._closeRequest||void 0!==e._inFlightCloseRequest}function dt(e){void 0!==e._closeRequest&&(e._closeRequest._reject(e._storedError),e._closeRequest=void 0);const t=e._writer;void 0!==t&&Wt(t,e._storedError)}function ft(e,t){const r=e._writer;void 0!==r&&t!==e._backpressure&&(t?function(e){Dt(e)}(r):It(r)),e._backpressure=t}Object.defineProperties(WritableStream.prototype,{abort:{enumerable:!0},close:{enumerable:!0},getWriter:{enumerable:!0},locked:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStream.prototype,o.toStringTag,{value:"WritableStream",configurable:!0});class WritableStreamDefaultWriter{constructor(e){if(M(e,1,"WritableStreamDefaultWriter"),Xe(e,"First parameter"),nt(e))throw new TypeError("This stream has already been locked for exclusive writing by another writer");this._ownerWritableStream=e,e._writer=this;const t=e._state;if("writable"===t)!ct(e)&&e._backpressure?Dt(this):Ft(this),kt(this);else if("erroring"===t)Lt(this,e._storedError),kt(this);else if("closed"===t)Ft(this),kt(r=this),xt(r);else{const t=e._storedError;Lt(this,t),Bt(this,t)}var r}get closed(){return pt(this)?this._closedPromise:h(At("closed"))}get desiredSize(){if(!pt(this))throw At("desiredSize");if(void 0===this._ownerWritableStream)throw jt("desiredSize");return function(e){const t=e._ownerWritableStream,r=t._state;if("errored"===r||"erroring"===r)return null;if("closed"===r)return 0;return Rt(t._writableStreamController)}(this)}get ready(){return pt(this)?this._readyPromise:h(At("ready"))}abort(e){return pt(this)?void 0===this._ownerWritableStream?h(jt("abort")):function(e,t){return st(e._ownerWritableStream,t)}(this,e):h(At("abort"))}close(){if(!pt(this))return h(At("close"));const e=this._ownerWritableStream;return void 0===e?h(jt("close")):ct(e)?h(new TypeError("Cannot close an already-closing stream")):ht(this)}releaseLock(){if(!pt(this))throw At("releaseLock");void 0!==this._ownerWritableStream&&mt(this)}write(e){return pt(this)?void 0===this._ownerWritableStream?h(jt("write to")):_t(this,e):h(At("write"))}}function pt(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_ownerWritableStream")&&e instanceof WritableStreamDefaultWriter)}function ht(e){return it(e._ownerWritableStream)}function bt(e,t){"pending"===e._closedPromiseState?Wt(e,t):function(e,t){Bt(e,t)}(e,t)}function yt(e,t){"pending"===e._readyPromiseState?zt(e,t):function(e,t){Lt(e,t)}(e,t)}function mt(e){const t=e._ownerWritableStream,r=new TypeError("Writer was released and can no longer be used to monitor the stream's closedness");yt(e,r),bt(e,r),t._writer=void 0,e._ownerWritableStream=void 0}function _t(e,t){const r=e._ownerWritableStream,o=r._writableStreamController,n=function(e,t){try{return e._strategySizeAlgorithm(t)}catch(t){return qt(e,t),1}}(o,t);if(r!==e._ownerWritableStream)return h(jt("write to"));const s=r._state;if("errored"===s)return h(r._storedError);if(ct(r)||"closed"===s)return h(new TypeError("The stream is closing or closed and cannot be written to"));if("erroring"===s)return h(r._storedError);const i=function(e){return f(((t,r)=>{const o={_resolve:t,_reject:r};e._writeRequests.push(o)}))}(r);return function(e,t,r){try{de(e,t,r)}catch(t){return void qt(e,t)}const o=e._controlledWritableStream;if(!ct(o)&&"writable"===o._state){ft(o,Pt(e))}Tt(e)}(o,t,n),i}Object.defineProperties(WritableStreamDefaultWriter.prototype,{abort:{enumerable:!0},close:{enumerable:!0},releaseLock:{enumerable:!0},write:{enumerable:!0},closed:{enumerable:!0},desiredSize:{enumerable:!0},ready:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStreamDefaultWriter.prototype,o.toStringTag,{value:"WritableStreamDefaultWriter",configurable:!0});const gt={};class WritableStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get abortReason(){if(!vt(this))throw Ot("abortReason");return this._abortReason}get signal(){if(!vt(this))throw Ot("signal");if(void 0===this._abortController)throw new TypeError("WritableStreamDefaultController.prototype.signal is not supported");return this._abortController.signal}error(e){if(!vt(this))throw Ot("error");"writable"===this._controlledWritableStream._state&&Et(this,e)}[k](e){const t=this._abortAlgorithm(e);return St(this),t}[B](){fe(this)}}function vt(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledWritableStream")&&e instanceof WritableStreamDefaultController)}function wt(e,t,r,o,n,s,i,a){t._controlledWritableStream=e,e._writableStreamController=t,t._queue=void 0,t._queueTotalSize=void 0,fe(t),t._abortReason=void 0,t._abortController=function(){if(et)return new AbortController}(),t._started=!1,t._strategySizeAlgorithm=a,t._strategyHWM=i,t._writeAlgorithm=o,t._closeAlgorithm=n,t._abortAlgorithm=s;const u=Pt(t);ft(e,u);y(p(r()),(()=>{t._started=!0,Tt(t)}),(r=>{t._started=!0,at(e,r)}))}function St(e){e._writeAlgorithm=void 0,e._closeAlgorithm=void 0,e._abortAlgorithm=void 0,e._strategySizeAlgorithm=void 0}function Rt(e){return e._strategyHWM-e._queueTotalSize}function Tt(e){const t=e._controlledWritableStream;if(!e._started)return;if(void 0!==t._inFlightWriteRequest)return;if("erroring"===t._state)return void lt(t);if(0===e._queue.length)return;const r=e._queue.peek().value;r===gt?function(e){const t=e._controlledWritableStream;(function(e){e._inFlightCloseRequest=e._closeRequest,e._closeRequest=void 0})(t),ce(e);const r=e._closeAlgorithm();St(e),y(r,(()=>{!function(e){e._inFlightCloseRequest._resolve(void 0),e._inFlightCloseRequest=void 0,"erroring"===e._state&&(e._storedError=void 0,void 0!==e._pendingAbortRequest&&(e._pendingAbortRequest._resolve(),e._pendingAbortRequest=void 0)),e._state="closed";const t=e._writer;void 0!==t&&xt(t)}(t)}),(e=>{!function(e,t){e._inFlightCloseRequest._reject(t),e._inFlightCloseRequest=void 0,void 0!==e._pendingAbortRequest&&(e._pendingAbortRequest._reject(t),e._pendingAbortRequest=void 0),at(e,t)}(t,e)}))}(e):function(e,t){const r=e._controlledWritableStream;!function(e){e._inFlightWriteRequest=e._writeRequests.shift()}(r);y(e._writeAlgorithm(t),(()=>{!function(e){e._inFlightWriteRequest._resolve(void 0),e._inFlightWriteRequest=void 0}(r);const t=r._state;if(ce(e),!ct(r)&&"writable"===t){const t=Pt(e);ft(r,t)}Tt(e)}),(t=>{"writable"===r._state&&St(e),function(e,t){e._inFlightWriteRequest._reject(t),e._inFlightWriteRequest=void 0,at(e,t)}(r,t)}))}(e,r)}function qt(e,t){"writable"===e._controlledWritableStream._state&&Et(e,t)}function Pt(e){return Rt(e)<=0}function Et(e,t){const r=e._controlledWritableStream;St(e),ut(r,t)}function Ct(e){return new TypeError(`WritableStream.prototype.${e} can only be used on a WritableStream`)}function Ot(e){return new TypeError(`WritableStreamDefaultController.prototype.${e} can only be used on a WritableStreamDefaultController`)}function At(e){return new TypeError(`WritableStreamDefaultWriter.prototype.${e} can only be used on a WritableStreamDefaultWriter`)}function jt(e){return new TypeError("Cannot "+e+" a stream using a released writer")}function kt(e){e._closedPromise=f(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r,e._closedPromiseState="pending"}))}function Bt(e,t){kt(e),Wt(e,t)}function Wt(e,t){void 0!==e._closedPromise_reject&&(v(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0,e._closedPromiseState="rejected")}function xt(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0,e._closedPromiseState="resolved")}function Dt(e){e._readyPromise=f(((t,r)=>{e._readyPromise_resolve=t,e._readyPromise_reject=r})),e._readyPromiseState="pending"}function Lt(e,t){Dt(e),zt(e,t)}function Ft(e){Dt(e),It(e)}function zt(e,t){void 0!==e._readyPromise_reject&&(v(e._readyPromise),e._readyPromise_reject(t),e._readyPromise_resolve=void 0,e._readyPromise_reject=void 0,e._readyPromiseState="rejected")}function It(e){void 0!==e._readyPromise_resolve&&(e._readyPromise_resolve(void 0),e._readyPromise_resolve=void 0,e._readyPromise_reject=void 0,e._readyPromiseState="fulfilled")}Object.defineProperties(WritableStreamDefaultController.prototype,{error:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStreamDefaultController.prototype,o.toStringTag,{value:"WritableStreamDefaultController",configurable:!0});const Mt="undefined"!=typeof DOMException?DOMException:void 0;const $t=function(e){if("function"!=typeof e&&"object"!=typeof e)return!1;try{return new e,!0}catch(e){return!1}}(Mt)?Mt:function(){const e=function(e,t){this.message=e||"",this.name=t||"Error",Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)};return e.prototype=Object.create(Error.prototype),Object.defineProperty(e.prototype,"constructor",{value:e,writable:!0,configurable:!0}),e}();function Ht(e,t,r,o,s,i){const a=Y(e),u=tt(t);e._disturbed=!0;let l=!1,c=p(void 0);return f(((d,g)=>{let w;if(void 0!==i){if(w=()=>{const r=new $t("Aborted","AbortError"),n=[];o||n.push((()=>"writable"===t._state?st(t,r):p(void 0))),s||n.push((()=>"readable"===e._state?pr(e,r):p(void 0))),C((()=>Promise.all(n.map((e=>e())))),!0,r)},i.aborted)return void w();i.addEventListener("abort",w)}var S,R,T;if(E(e,a._closedPromise,(e=>{o?O(!0,e):C((()=>st(t,e)),!0,e)})),E(t,u._closedPromise,(t=>{s?O(!0,t):C((()=>pr(e,t)),!0,t)})),S=e,R=a._closedPromise,T=()=>{r?O():C((()=>function(e){const t=e._ownerWritableStream,r=t._state;return ct(t)||"closed"===r?p(void 0):"errored"===r?h(t._storedError):ht(e)}(u)))},"closed"===S._state?T():m(R,T),ct(t)||"closed"===t._state){const t=new TypeError("the destination writable stream closed before all data could be piped to it");s?O(!0,t):C((()=>pr(e,t)),!0,t)}function q(){const e=c;return b(c,(()=>e!==c?q():void 0))}function E(e,t,r){"errored"===e._state?r(e._storedError):_(t,r)}function C(e,r,o){function n(){y(e(),(()=>A(r,o)),(e=>A(!0,e)))}l||(l=!0,"writable"!==t._state||ct(t)?n():m(q(),n))}function O(e,r){l||(l=!0,"writable"!==t._state||ct(t)?A(e,r):m(q(),(()=>A(e,r))))}function A(e,t){mt(u),P(a),void 0!==i&&i.removeEventListener("abort",w),e?g(t):d(void 0)}v(f(((e,t)=>{!function r(o){o?e():b(l?p(!0):b(u._readyPromise,(()=>f(((e,t)=>{X(a,{_chunkSteps:t=>{c=b(_t(u,t),void 0,n),e(!1)},_closeSteps:()=>e(!0),_errorSteps:t})})))),r,t)}(!1)})))}))}class ReadableStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get desiredSize(){if(!Ut(this))throw er("desiredSize");return Kt(this)}close(){if(!Ut(this))throw er("close");if(!Zt(this))throw new TypeError("The stream is not in a state that permits close");Vt(this)}enqueue(e){if(!Ut(this))throw er("enqueue");if(!Zt(this))throw new TypeError("The stream is not in a state that permits enqueue");return Gt(this,e)}error(e){if(!Ut(this))throw er("error");Jt(this,e)}[W](e){fe(this);const t=this._cancelAlgorithm(e);return Yt(this),t}[x](e){const t=this._controlledReadableStream;if(this._queue.length>0){const r=ce(this);this._closeRequested&&0===this._queue.length?(Yt(this),hr(t)):Nt(this),e._chunkSteps(r)}else V(t,e),Nt(this)}}function Ut(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledReadableStream")&&e instanceof ReadableStreamDefaultController)}function Nt(e){if(!Qt(e))return;if(e._pulling)return void(e._pullAgain=!0);e._pulling=!0;y(e._pullAlgorithm(),(()=>{e._pulling=!1,e._pullAgain&&(e._pullAgain=!1,Nt(e))}),(t=>{Jt(e,t)}))}function Qt(e){const t=e._controlledReadableStream;if(!Zt(e))return!1;if(!e._started)return!1;if(fr(t)&&J(t)>0)return!0;return Kt(e)>0}function Yt(e){e._pullAlgorithm=void 0,e._cancelAlgorithm=void 0,e._strategySizeAlgorithm=void 0}function Vt(e){if(!Zt(e))return;const t=e._controlledReadableStream;e._closeRequested=!0,0===e._queue.length&&(Yt(e),hr(t))}function Gt(e,t){if(!Zt(e))return;const r=e._controlledReadableStream;if(fr(r)&&J(r)>0)G(r,t,!1);else{let r;try{r=e._strategySizeAlgorithm(t)}catch(t){throw Jt(e,t),t}try{de(e,t,r)}catch(t){throw Jt(e,t),t}}Nt(e)}function Jt(e,t){const r=e._controlledReadableStream;"readable"===r._state&&(fe(e),Yt(e),br(r,t))}function Kt(e){const t=e._controlledReadableStream._state;return"errored"===t?null:"closed"===t?0:e._strategyHWM-e._queueTotalSize}function Zt(e){const t=e._controlledReadableStream._state;return!e._closeRequested&&"readable"===t}function Xt(e,t,r,o,n,s,i){t._controlledReadableStream=e,t._queue=void 0,t._queueTotalSize=void 0,fe(t),t._started=!1,t._closeRequested=!1,t._pullAgain=!1,t._pulling=!1,t._strategySizeAlgorithm=i,t._strategyHWM=s,t._pullAlgorithm=o,t._cancelAlgorithm=n,e._readableStreamController=t;y(p(r()),(()=>{t._started=!0,Nt(t)}),(e=>{Jt(t,e)}))}function er(e){return new TypeError(`ReadableStreamDefaultController.prototype.${e} can only be used on a ReadableStreamDefaultController`)}function tr(e,t){return pe(e._readableStreamController)?function(e){let t,r,o,n,s,i=Y(e),a=!1,u=!1,l=!1;const c=f((e=>{s=e}));function d(e){_(e._closedPromise,(t=>{e===i&&(Ae(o._readableStreamController,t),Ae(n._readableStreamController,t),u&&l||s(void 0))}))}function h(){$e(i)&&(P(i),i=Y(e),d(i));X(i,{_chunkSteps:t=>{w((()=>{a=!1;const r=t;let i=t;if(!u&&!l)try{i=le(t)}catch(t){return Ae(o._readableStreamController,t),Ae(n._readableStreamController,t),void s(pr(e,t))}u||Oe(o._readableStreamController,r),l||Oe(n._readableStreamController,i)}))},_closeSteps:()=>{a=!1,u||Ce(o._readableStreamController),l||Ce(n._readableStreamController),o._readableStreamController._pendingPullIntos.length>0&&Be(o._readableStreamController,0),n._readableStreamController._pendingPullIntos.length>0&&Be(n._readableStreamController,0),u&&l||s(void 0)},_errorSteps:()=>{a=!1}})}function b(t,r){Z(i)&&(P(i),i=Fe(e),d(i));const c=r?n:o,f=r?o:n;He(i,t,{_chunkSteps:t=>{w((()=>{a=!1;const o=r?l:u;if(r?u:l)o||We(c._readableStreamController,t);else{let r;try{r=le(t)}catch(t){return Ae(c._readableStreamController,t),Ae(f._readableStreamController,t),void s(pr(e,t))}o||We(c._readableStreamController,t),Oe(f._readableStreamController,r)}}))},_closeSteps:e=>{a=!1;const t=r?l:u,o=r?u:l;t||Ce(c._readableStreamController),o||Ce(f._readableStreamController),void 0!==e&&(t||We(c._readableStreamController,e),!o&&f._readableStreamController._pendingPullIntos.length>0&&Be(f._readableStreamController,0)),t&&o||s(void 0)},_errorSteps:()=>{a=!1}})}function y(){if(a)return p(void 0);a=!0;const e=je(o._readableStreamController);return null===e?h():b(e._view,!1),p(void 0)}function m(){if(a)return p(void 0);a=!0;const e=je(n._readableStreamController);return null===e?h():b(e._view,!0),p(void 0)}function g(o){if(u=!0,t=o,l){const o=ie([t,r]),n=pr(e,o);s(n)}return c}function v(o){if(l=!0,r=o,u){const o=ie([t,r]),n=pr(e,o);s(n)}return c}function S(){}return o=lr(S,y,g),n=lr(S,m,v),d(i),[o,n]}(e):function(e,t){const r=Y(e);let o,n,s,i,a,u=!1,l=!1,c=!1;const d=f((e=>{a=e}));function h(){if(u)return p(void 0);u=!0;return X(r,{_chunkSteps:e=>{w((()=>{u=!1;const t=e,r=e;l||Gt(s._readableStreamController,t),c||Gt(i._readableStreamController,r)}))},_closeSteps:()=>{u=!1,l||Vt(s._readableStreamController),c||Vt(i._readableStreamController),l&&c||a(void 0)},_errorSteps:()=>{u=!1}}),p(void 0)}function b(t){if(l=!0,o=t,c){const t=ie([o,n]),r=pr(e,t);a(r)}return d}function y(t){if(c=!0,n=t,l){const t=ie([o,n]),r=pr(e,t);a(r)}return d}function m(){}return s=ur(m,h,b),i=ur(m,h,y),_(r._closedPromise,(e=>{Jt(s._readableStreamController,e),Jt(i._readableStreamController,e),l&&c||a(void 0)})),[s,i]}(e)}function rr(e,t,r){return z(e,r),r=>R(e,t,[r])}function or(e,t,r){return z(e,r),r=>R(e,t,[r])}function nr(e,t,r){return z(e,r),r=>S(e,t,[r])}function sr(e,t){if("bytes"!==(e=`${e}`))throw new TypeError(`${t} '${e}' is not a valid enumeration value for ReadableStreamType`);return e}function ir(e,t){if("byob"!==(e=`${e}`))throw new TypeError(`${t} '${e}' is not a valid enumeration value for ReadableStreamReaderMode`);return e}function ar(e,t){F(e,t);const r=null==e?void 0:e.preventAbort,o=null==e?void 0:e.preventCancel,n=null==e?void 0:e.preventClose,s=null==e?void 0:e.signal;return void 0!==s&&function(e,t){if(!function(e){if("object"!=typeof e||null===e)return!1;try{return"boolean"==typeof e.aborted}catch(e){return!1}}(e))throw new TypeError(`${t} is not an AbortSignal.`)}(s,`${t} has member 'signal' that`),{preventAbort:Boolean(r),preventCancel:Boolean(o),preventClose:Boolean(n),signal:s}}Object.defineProperties(ReadableStreamDefaultController.prototype,{close:{enumerable:!0},enqueue:{enumerable:!0},error:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamDefaultController.prototype,o.toStringTag,{value:"ReadableStreamDefaultController",configurable:!0});class ReadableStream{constructor(e={},t={}){void 0===e?e=null:I(e,"First parameter");const r=Ye(t,"Second parameter"),o=function(e,t){F(e,t);const r=e,o=null==r?void 0:r.autoAllocateChunkSize,n=null==r?void 0:r.cancel,s=null==r?void 0:r.pull,i=null==r?void 0:r.start,a=null==r?void 0:r.type;return{autoAllocateChunkSize:void 0===o?void 0:N(o,`${t} has member 'autoAllocateChunkSize' that`),cancel:void 0===n?void 0:rr(n,r,`${t} has member 'cancel' that`),pull:void 0===s?void 0:or(s,r,`${t} has member 'pull' that`),start:void 0===i?void 0:nr(i,r,`${t} has member 'start' that`),type:void 0===a?void 0:sr(a,`${t} has member 'type' that`)}}(e,"First parameter");if(cr(this),"bytes"===o.type){if(void 0!==r.size)throw new RangeError("The strategy for a byte stream cannot have a size function");!function(e,t,r){const o=Object.create(ReadableByteStreamController.prototype);let n=()=>{},s=()=>p(void 0),i=()=>p(void 0);void 0!==t.start&&(n=()=>t.start(o)),void 0!==t.pull&&(s=()=>t.pull(o)),void 0!==t.cancel&&(i=e=>t.cancel(e));const a=t.autoAllocateChunkSize;if(0===a)throw new TypeError("autoAllocateChunkSize must be greater than 0");xe(e,o,n,s,i,r,a)}(this,o,Ne(r,0))}else{const e=Qe(r);!function(e,t,r,o){const n=Object.create(ReadableStreamDefaultController.prototype);let s=()=>{},i=()=>p(void 0),a=()=>p(void 0);void 0!==t.start&&(s=()=>t.start(n)),void 0!==t.pull&&(i=()=>t.pull(n)),void 0!==t.cancel&&(a=e=>t.cancel(e)),Xt(e,n,s,i,a,r,o)}(this,o,Ne(r,1),e)}}get locked(){if(!dr(this))throw yr("locked");return fr(this)}cancel(e){return dr(this)?fr(this)?h(new TypeError("Cannot cancel a stream that already has a reader")):pr(this,e):h(yr("cancel"))}getReader(e){if(!dr(this))throw yr("getReader");return void 0===function(e,t){F(e,t);const r=null==e?void 0:e.mode;return{mode:void 0===r?void 0:ir(r,`${t} has member 'mode' that`)}}(e,"First parameter").mode?Y(this):Fe(this)}pipeThrough(e,t={}){if(!dr(this))throw yr("pipeThrough");M(e,1,"pipeThrough");const r=function(e,t){F(e,t);const r=null==e?void 0:e.readable;$(r,"readable","ReadableWritablePair"),Q(r,`${t} has member 'readable' that`);const o=null==e?void 0:e.writable;return $(o,"writable","ReadableWritablePair"),Xe(o,`${t} has member 'writable' that`),{readable:r,writable:o}}(e,"First parameter"),o=ar(t,"Second parameter");if(fr(this))throw new TypeError("ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream");if(nt(r.writable))throw new TypeError("ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream");return v(Ht(this,r.writable,o.preventClose,o.preventAbort,o.preventCancel,o.signal)),r.readable}pipeTo(e,t={}){if(!dr(this))return h(yr("pipeTo"));if(void 0===e)return h("Parameter 1 is required in 'pipeTo'.");if(!ot(e))return h(new TypeError("ReadableStream.prototype.pipeTo's first argument must be a WritableStream"));let r;try{r=ar(t,"Second parameter")}catch(e){return h(e)}return fr(this)?h(new TypeError("ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream")):nt(e)?h(new TypeError("ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream")):Ht(this,e,r.preventClose,r.preventAbort,r.preventCancel,r.signal)}tee(){if(!dr(this))throw yr("tee");return ie(tr(this))}values(e){if(!dr(this))throw yr("values");return function(e,t){const r=Y(e),o=new ReadableStreamAsyncIteratorImpl(r,t),n=Object.create(re);return n._asyncIteratorImpl=o,n}(this,function(e,t){F(e,t);const r=null==e?void 0:e.preventCancel;return{preventCancel:Boolean(r)}}(e,"First parameter").preventCancel)}}function ur(e,t,r,o=1,n=(()=>1)){const s=Object.create(ReadableStream.prototype);cr(s);return Xt(s,Object.create(ReadableStreamDefaultController.prototype),e,t,r,o,n),s}function lr(e,t,r){const o=Object.create(ReadableStream.prototype);cr(o);return xe(o,Object.create(ReadableByteStreamController.prototype),e,t,r,0,void 0),o}function cr(e){e._state="readable",e._reader=void 0,e._storedError=void 0,e._disturbed=!1}function dr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readableStreamController")&&e instanceof ReadableStream)}function fr(e){return void 0!==e._reader}function pr(e,t){if(e._disturbed=!0,"closed"===e._state)return p(void 0);if("errored"===e._state)return h(e._storedError);hr(e);const r=e._reader;void 0!==r&&$e(r)&&(r._readIntoRequests.forEach((e=>{e._closeSteps(void 0)})),r._readIntoRequests=new SimpleQueue);return g(e._readableStreamController[W](t),n)}function hr(e){e._state="closed";const t=e._reader;void 0!==t&&(j(t),Z(t)&&(t._readRequests.forEach((e=>{e._closeSteps()})),t._readRequests=new SimpleQueue))}function br(e,t){e._state="errored",e._storedError=t;const r=e._reader;void 0!==r&&(A(r,t),Z(r)?(r._readRequests.forEach((e=>{e._errorSteps(t)})),r._readRequests=new SimpleQueue):(r._readIntoRequests.forEach((e=>{e._errorSteps(t)})),r._readIntoRequests=new SimpleQueue))}function yr(e){return new TypeError(`ReadableStream.prototype.${e} can only be used on a ReadableStream`)}function mr(e,t){F(e,t);const r=null==e?void 0:e.highWaterMark;return $(r,"highWaterMark","QueuingStrategyInit"),{highWaterMark:H(r)}}Object.defineProperties(ReadableStream.prototype,{cancel:{enumerable:!0},getReader:{enumerable:!0},pipeThrough:{enumerable:!0},pipeTo:{enumerable:!0},tee:{enumerable:!0},values:{enumerable:!0},locked:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStream.prototype,o.toStringTag,{value:"ReadableStream",configurable:!0}),"symbol"==typeof o.asyncIterator&&Object.defineProperty(ReadableStream.prototype,o.asyncIterator,{value:ReadableStream.prototype.values,writable:!0,configurable:!0});const _r=e=>e.byteLength;Object.defineProperty(_r,"name",{value:"size",configurable:!0});class ByteLengthQueuingStrategy{constructor(e){M(e,1,"ByteLengthQueuingStrategy"),e=mr(e,"First parameter"),this._byteLengthQueuingStrategyHighWaterMark=e.highWaterMark}get highWaterMark(){if(!vr(this))throw gr("highWaterMark");return this._byteLengthQueuingStrategyHighWaterMark}get size(){if(!vr(this))throw gr("size");return _r}}function gr(e){return new TypeError(`ByteLengthQueuingStrategy.prototype.${e} can only be used on a ByteLengthQueuingStrategy`)}function vr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_byteLengthQueuingStrategyHighWaterMark")&&e instanceof ByteLengthQueuingStrategy)}Object.defineProperties(ByteLengthQueuingStrategy.prototype,{highWaterMark:{enumerable:!0},size:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ByteLengthQueuingStrategy.prototype,o.toStringTag,{value:"ByteLengthQueuingStrategy",configurable:!0});const wr=()=>1;Object.defineProperty(wr,"name",{value:"size",configurable:!0});class CountQueuingStrategy{constructor(e){M(e,1,"CountQueuingStrategy"),e=mr(e,"First parameter"),this._countQueuingStrategyHighWaterMark=e.highWaterMark}get highWaterMark(){if(!Rr(this))throw Sr("highWaterMark");return this._countQueuingStrategyHighWaterMark}get size(){if(!Rr(this))throw Sr("size");return wr}}function Sr(e){return new TypeError(`CountQueuingStrategy.prototype.${e} can only be used on a CountQueuingStrategy`)}function Rr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_countQueuingStrategyHighWaterMark")&&e instanceof CountQueuingStrategy)}function Tr(e,t,r){return z(e,r),r=>R(e,t,[r])}function qr(e,t,r){return z(e,r),r=>S(e,t,[r])}function Pr(e,t,r){return z(e,r),(r,o)=>R(e,t,[r,o])}Object.defineProperties(CountQueuingStrategy.prototype,{highWaterMark:{enumerable:!0},size:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(CountQueuingStrategy.prototype,o.toStringTag,{value:"CountQueuingStrategy",configurable:!0});class TransformStream{constructor(e={},t={},r={}){void 0===e&&(e=null);const o=Ye(t,"Second parameter"),n=Ye(r,"Third parameter"),s=function(e,t){F(e,t);const r=null==e?void 0:e.flush,o=null==e?void 0:e.readableType,n=null==e?void 0:e.start,s=null==e?void 0:e.transform,i=null==e?void 0:e.writableType;return{flush:void 0===r?void 0:Tr(r,e,`${t} has member 'flush' that`),readableType:o,start:void 0===n?void 0:qr(n,e,`${t} has member 'start' that`),transform:void 0===s?void 0:Pr(s,e,`${t} has member 'transform' that`),writableType:i}}(e,"First parameter");if(void 0!==s.readableType)throw new RangeError("Invalid readableType specified");if(void 0!==s.writableType)throw new RangeError("Invalid writableType specified");const i=Ne(n,0),a=Qe(n),u=Ne(o,1),l=Qe(o);let c;!function(e,t,r,o,n,s){function i(){return t}function a(t){return function(e,t){const r=e._transformStreamController;if(e._backpressure){return g(e._backpressureChangePromise,(()=>{const o=e._writable;if("erroring"===o._state)throw o._storedError;return Wr(r,t)}))}return Wr(r,t)}(e,t)}function u(t){return function(e,t){return Cr(e,t),p(void 0)}(e,t)}function l(){return function(e){const t=e._readable,r=e._transformStreamController,o=r._flushAlgorithm();return kr(r),g(o,(()=>{if("errored"===t._state)throw t._storedError;Vt(t._readableStreamController)}),(r=>{throw Cr(e,r),t._storedError}))}(e)}function c(){return function(e){return Ar(e,!1),e._backpressureChangePromise}(e)}function d(t){return Or(e,t),p(void 0)}e._writable=function(e,t,r,o,n=1,s=(()=>1)){const i=Object.create(WritableStream.prototype);return rt(i),wt(i,Object.create(WritableStreamDefaultController.prototype),e,t,r,o,n,s),i}(i,a,l,u,r,o),e._readable=ur(i,c,d,n,s),e._backpressure=void 0,e._backpressureChangePromise=void 0,e._backpressureChangePromise_resolve=void 0,Ar(e,!0),e._transformStreamController=void 0}(this,f((e=>{c=e})),u,l,i,a),function(e,t){const r=Object.create(TransformStreamDefaultController.prototype);let o=e=>{try{return Br(r,e),p(void 0)}catch(e){return h(e)}},n=()=>p(void 0);void 0!==t.transform&&(o=e=>t.transform(e,r));void 0!==t.flush&&(n=()=>t.flush(r));!function(e,t,r,o){t._controlledTransformStream=e,e._transformStreamController=t,t._transformAlgorithm=r,t._flushAlgorithm=o}(e,r,o,n)}(this,s),void 0!==s.start?c(s.start(this._transformStreamController)):c(void 0)}get readable(){if(!Er(this))throw Dr("readable");return this._readable}get writable(){if(!Er(this))throw Dr("writable");return this._writable}}function Er(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_transformStreamController")&&e instanceof TransformStream)}function Cr(e,t){Jt(e._readable._readableStreamController,t),Or(e,t)}function Or(e,t){kr(e._transformStreamController),qt(e._writable._writableStreamController,t),e._backpressure&&Ar(e,!1)}function Ar(e,t){void 0!==e._backpressureChangePromise&&e._backpressureChangePromise_resolve(),e._backpressureChangePromise=f((t=>{e._backpressureChangePromise_resolve=t})),e._backpressure=t}Object.defineProperties(TransformStream.prototype,{readable:{enumerable:!0},writable:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(TransformStream.prototype,o.toStringTag,{value:"TransformStream",configurable:!0});class TransformStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get desiredSize(){if(!jr(this))throw xr("desiredSize");return Kt(this._controlledTransformStream._readable._readableStreamController)}enqueue(e){if(!jr(this))throw xr("enqueue");Br(this,e)}error(e){if(!jr(this))throw xr("error");var t;t=e,Cr(this._controlledTransformStream,t)}terminate(){if(!jr(this))throw xr("terminate");!function(e){const t=e._controlledTransformStream;Vt(t._readable._readableStreamController);const r=new TypeError("TransformStream terminated");Or(t,r)}(this)}}function jr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledTransformStream")&&e instanceof TransformStreamDefaultController)}function kr(e){e._transformAlgorithm=void 0,e._flushAlgorithm=void 0}function Br(e,t){const r=e._controlledTransformStream,o=r._readable._readableStreamController;if(!Zt(o))throw new TypeError("Readable side is not in a state that permits enqueue");try{Gt(o,t)}catch(e){throw Or(r,e),r._readable._storedError}const n=function(e){return!Qt(e)}(o);n!==r._backpressure&&Ar(r,!0)}function Wr(e,t){return g(e._transformAlgorithm(t),void 0,(t=>{throw Cr(e._controlledTransformStream,t),t}))}function xr(e){return new TypeError(`TransformStreamDefaultController.prototype.${e} can only be used on a TransformStreamDefaultController`)}function Dr(e){return new TypeError(`TransformStream.prototype.${e} can only be used on a TransformStream`)}Object.defineProperties(TransformStreamDefaultController.prototype,{enqueue:{enumerable:!0},error:{enumerable:!0},terminate:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(TransformStreamDefaultController.prototype,o.toStringTag,{value:"TransformStreamDefaultController",configurable:!0})}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var s=t[o]={id:o,loaded:!1,exports:{}};return e[o].call(s.exports,s,s.exports,r),s.loaded=!0,s.exports}return r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r(48)})()})); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,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UzhwQyxFQUF5QkUsR0FBWSxDQUNqRDFpQyxHQUFJMGlDLEVBQ0pFLFFBQVEsRUFDUm5xQyxRQUFTLElBVVYsT0FOQW9xQyxFQUFvQkgsR0FBVW5vQyxLQUFLN0IsRUFBT0QsUUFBU0MsRUFBUUEsRUFBT0QsUUFBU2dxQyxHQUczRS9wQyxFQUFPa3FDLFFBQVMsRUFHVGxxQyxFQUFPRCxlQ3ZCZmdxQyxFQUFvQnA3QixFQUFJLENBQUM1TyxFQUFTcXFDLEtBQ2pDLElBQUksSUFBSXZuQyxLQUFPdW5DLEVBQ1hMLEVBQW9CTSxFQUFFRCxFQUFZdm5DLEtBQVNrbkMsRUFBb0JNLEVBQUV0cUMsRUFBUzhDLElBQzVFekMsT0FBT0MsZUFBZU4sRUFBUzhDLEVBQUssQ0FBRXpCLFlBQVksRUFBTUwsSUFBS3FwQyxFQUFXdm5DLE1DSjNFa25DLEVBQW9CTSxFQUFJLENBQUNuK0IsRUFBS28rQixJQUFVbHFDLE9BQU9hLFVBQVU4dEIsZUFBZWx0QixLQUFLcUssRUFBS28rQixHQ0NsRlAsRUFBb0JyVCxFQUFLMzJCLElBQ0gsb0JBQVhzQixRQUEwQkEsT0FBT0MsYUFDMUNsQixPQUFPQyxlQUFlTixFQUFTc0IsT0FBT0MsWUFBYSxDQUFFaEIsTUFBTyxXQUU3REYsT0FBT0MsZUFBZU4sRUFBUyxhQUFjLENBQUVPLE9BQU8sS0NMdkR5cEMsRUFBb0JRLElBQU92cUMsSUFDMUJBLEVBQU93cUMsTUFBUSxHQUNWeHFDLEVBQU95cUMsV0FBVXpxQyxFQUFPeXFDLFNBQVcsSUFDakN6cUMsR0NBa0IrcEMsRUFBb0IsS3hDTzlDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24iLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hYm9ydC1jb250cm9sbGVyL2Rpc3QvYWJvcnQtY29udHJvbGxlci5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9jbGllbnQudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9kb21haW5zLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvZXJyb3IudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9ldmVudHMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9pcC1wb29scy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2lwcy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2xpc3RzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvbWFpbExpc3RNZW1iZXJzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvbWVzc2FnZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9wYXJzZS50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3JlcXVlc3QudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9yb3V0ZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9zdGF0cy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3N1cHByZXNzaW9ucy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3ZhbGlkYXRlLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvd2ViaG9va3MudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9iYXNlLTY0L2Jhc2U2NC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RhdGEtdXJpLXRvLWJ1ZmZlci9kaXN0L3NyYy9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2V2ZW50LXRhcmdldC1zaGltL2Rpc3QvZXZlbnQtdGFyZ2V0LXNoaW0uanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9mZXRjaC1ibG9iL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMva3ktdW5pdmVyc2FsL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMva3kvdW1kLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvdXJsLWpvaW4vbGliL3VybC1qb2luLmpzIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImNyeXB0b1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImh0dHBcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJodHRwc1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInN0cmVhbVwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInVybFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInV0aWxcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJ6bGliXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9ub2RlLWZldGNoL2Rpc3QvaW5kZXguY2pzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvd2ViLXN0cmVhbXMtcG9seWZpbGwvZGlzdC9wb255ZmlsbC5lczIwMTgubWpzIiwid2VicGFjazovL21haWxndW4vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL21haWxndW4vd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9tYWlsZ3VuL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3N0YXJ0dXAiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wibWFpbGd1blwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJtYWlsZ3VuXCJdID0gZmFjdG9yeSgpO1xufSkodGhpcywgZnVuY3Rpb24oKSB7XG5yZXR1cm4gIiwiLyoqXG4gKiBAYXV0aG9yIFRvcnUgTmFnYXNoaW1hIDxodHRwczovL2dpdGh1Yi5jb20vbXlzdGljYXRlYT5cbiAqIFNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBkaXJlY3RvcnkgZm9yIGZ1bGwgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgZXZlbnRUYXJnZXRTaGltID0gcmVxdWlyZSgnZXZlbnQtdGFyZ2V0LXNoaW0nKTtcblxuLyoqXG4gKiBUaGUgc2lnbmFsIGNsYXNzLlxuICogQHNlZSBodHRwczovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2Fib3J0c2lnbmFsXG4gKi9cbmNsYXNzIEFib3J0U2lnbmFsIGV4dGVuZHMgZXZlbnRUYXJnZXRTaGltLkV2ZW50VGFyZ2V0IHtcbiAgICAvKipcbiAgICAgKiBBYm9ydFNpZ25hbCBjYW5ub3QgYmUgY29uc3RydWN0ZWQgZGlyZWN0bHkuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBYm9ydFNpZ25hbCBjYW5ub3QgYmUgY29uc3RydWN0ZWQgZGlyZWN0bHlcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYHRydWVgIGlmIHRoaXMgYEFib3J0U2lnbmFsYCdzIGBBYm9ydENvbnRyb2xsZXJgIGhhcyBzaWduYWxlZCB0byBhYm9ydCwgYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGdldCBhYm9ydGVkKCkge1xuICAgICAgICBjb25zdCBhYm9ydGVkID0gYWJvcnRlZEZsYWdzLmdldCh0aGlzKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhYm9ydGVkICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgRXhwZWN0ZWQgJ3RoaXMnIHRvIGJlIGFuICdBYm9ydFNpZ25hbCcgb2JqZWN0LCBidXQgZ290ICR7dGhpcyA9PT0gbnVsbCA/IFwibnVsbFwiIDogdHlwZW9mIHRoaXN9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFib3J0ZWQ7XG4gICAgfVxufVxuZXZlbnRUYXJnZXRTaGltLmRlZmluZUV2ZW50QXR0cmlidXRlKEFib3J0U2lnbmFsLnByb3RvdHlwZSwgXCJhYm9ydFwiKTtcbi8qKlxuICogQ3JlYXRlIGFuIEFib3J0U2lnbmFsIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQWJvcnRTaWduYWwoKSB7XG4gICAgY29uc3Qgc2lnbmFsID0gT2JqZWN0LmNyZWF0ZShBYm9ydFNpZ25hbC5wcm90b3R5cGUpO1xuICAgIGV2ZW50VGFyZ2V0U2hpbS5FdmVudFRhcmdldC5jYWxsKHNpZ25hbCk7XG4gICAgYWJvcnRlZEZsYWdzLnNldChzaWduYWwsIGZhbHNlKTtcbiAgICByZXR1cm4gc2lnbmFsO1xufVxuLyoqXG4gKiBBYm9ydCBhIGdpdmVuIHNpZ25hbC5cbiAqL1xuZnVuY3Rpb24gYWJvcnRTaWduYWwoc2lnbmFsKSB7XG4gICAgaWYgKGFib3J0ZWRGbGFncy5nZXQoc2lnbmFsKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhYm9ydGVkRmxhZ3Muc2V0KHNpZ25hbCwgdHJ1ZSk7XG4gICAgc2lnbmFsLmRpc3BhdGNoRXZlbnQoeyB0eXBlOiBcImFib3J0XCIgfSk7XG59XG4vKipcbiAqIEFib3J0ZWQgZmxhZyBmb3IgZWFjaCBpbnN0YW5jZXMuXG4gKi9cbmNvbnN0IGFib3J0ZWRGbGFncyA9IG5ldyBXZWFrTWFwKCk7XG4vLyBQcm9wZXJ0aWVzIHNob3VsZCBiZSBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQWJvcnRTaWduYWwucHJvdG90eXBlLCB7XG4gICAgYWJvcnRlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG59KTtcbi8vIGB0b1N0cmluZygpYCBzaG91bGQgcmV0dXJuIGBcIltvYmplY3QgQWJvcnRTaWduYWxdXCJgXG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09IFwic3ltYm9sXCIpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQWJvcnRTaWduYWwucHJvdG90eXBlLCBTeW1ib2wudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogXCJBYm9ydFNpZ25hbFwiLFxuICAgIH0pO1xufVxuXG4vKipcbiAqIFRoZSBBYm9ydENvbnRyb2xsZXIuXG4gKiBAc2VlIGh0dHBzOi8vZG9tLnNwZWMud2hhdHdnLm9yZy8jYWJvcnRjb250cm9sbGVyXG4gKi9cbmNsYXNzIEFib3J0Q29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSB0aGlzIGNvbnRyb2xsZXIuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHNpZ25hbHMuc2V0KHRoaXMsIGNyZWF0ZUFib3J0U2lnbmFsKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgQWJvcnRTaWduYWxgIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBvYmplY3QuXG4gICAgICovXG4gICAgZ2V0IHNpZ25hbCgpIHtcbiAgICAgICAgcmV0dXJuIGdldFNpZ25hbCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWJvcnQgYW5kIHNpZ25hbCB0byBhbnkgb2JzZXJ2ZXJzIHRoYXQgdGhlIGFzc29jaWF0ZWQgYWN0aXZpdHkgaXMgdG8gYmUgYWJvcnRlZC5cbiAgICAgKi9cbiAgICBhYm9ydCgpIHtcbiAgICAgICAgYWJvcnRTaWduYWwoZ2V0U2lnbmFsKHRoaXMpKTtcbiAgICB9XG59XG4vKipcbiAqIEFzc29jaWF0ZWQgc2lnbmFscy5cbiAqL1xuY29uc3Qgc2lnbmFscyA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEdldCB0aGUgYXNzb2NpYXRlZCBzaWduYWwgb2YgYSBnaXZlbiBjb250cm9sbGVyLlxuICovXG5mdW5jdGlvbiBnZXRTaWduYWwoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHNpZ25hbCA9IHNpZ25hbHMuZ2V0KGNvbnRyb2xsZXIpO1xuICAgIGlmIChzaWduYWwgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBFeHBlY3RlZCAndGhpcycgdG8gYmUgYW4gJ0Fib3J0Q29udHJvbGxlcicgb2JqZWN0LCBidXQgZ290ICR7Y29udHJvbGxlciA9PT0gbnVsbCA/IFwibnVsbFwiIDogdHlwZW9mIGNvbnRyb2xsZXJ9YCk7XG4gICAgfVxuICAgIHJldHVybiBzaWduYWw7XG59XG4vLyBQcm9wZXJ0aWVzIHNob3VsZCBiZSBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQWJvcnRDb250cm9sbGVyLnByb3RvdHlwZSwge1xuICAgIHNpZ25hbDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgYWJvcnQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxufSk7XG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09IFwic3ltYm9sXCIpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQWJvcnRDb250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IFwiQWJvcnRDb250cm9sbGVyXCIsXG4gICAgfSk7XG59XG5cbmV4cG9ydHMuQWJvcnRDb250cm9sbGVyID0gQWJvcnRDb250cm9sbGVyO1xuZXhwb3J0cy5BYm9ydFNpZ25hbCA9IEFib3J0U2lnbmFsO1xuZXhwb3J0cy5kZWZhdWx0ID0gQWJvcnRDb250cm9sbGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFib3J0Q29udHJvbGxlclxubW9kdWxlLmV4cG9ydHMuQWJvcnRDb250cm9sbGVyID0gbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gQWJvcnRDb250cm9sbGVyXG5tb2R1bGUuZXhwb3J0cy5BYm9ydFNpZ25hbCA9IEFib3J0U2lnbmFsXG4vLyMgc291cmNlTWFwcGluZ1VSTD1hYm9ydC1jb250cm9sbGVyLmpzLm1hcFxuIiwiaW1wb3J0IENsaWVudCBmcm9tICcuL2xpYi9jbGllbnQnO1xuaW1wb3J0IHsgSW5wdXRGb3JtRGF0YSB9IGZyb20gJy4vbGliL2ludGVyZmFjZXMvSUZvcm1EYXRhJztcbmltcG9ydCBPcHRpb25zIGZyb20gJy4vbGliL2ludGVyZmFjZXMvT3B0aW9ucyc7XG5cbmNsYXNzIE1haWxndW4ge1xuICBwcml2YXRlIGZvcm1EYXRhOiBJbnB1dEZvcm1EYXRhXG5cbiAgY29uc3RydWN0b3IoRm9ybURhdGE6IElucHV0Rm9ybURhdGEpIHtcbiAgICB0aGlzLmZvcm1EYXRhID0gRm9ybURhdGE7XG4gIH1cblxuICBjbGllbnQob3B0aW9uczogT3B0aW9ucykgOiBDbGllbnQge1xuICAgIHJldHVybiBuZXcgQ2xpZW50KG9wdGlvbnMsIHRoaXMuZm9ybURhdGEpO1xuICB9XG59XG5cbmV4cG9ydCA9IE1haWxndW47XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQgT3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvT3B0aW9ucyc7XG5pbXBvcnQgUmVxdWVzdE9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL1JlcXVlc3RPcHRpb25zJztcblxuaW1wb3J0IERvbWFpbkNsaWVudCBmcm9tICcuL2RvbWFpbnMnO1xuaW1wb3J0IEV2ZW50Q2xpZW50IGZyb20gJy4vZXZlbnRzJztcbmltcG9ydCBTdGF0c0NsaWVudCBmcm9tICcuL3N0YXRzJztcbmltcG9ydCBTdXBwcmVzc2lvbkNsaWVudCBmcm9tICcuL3N1cHByZXNzaW9ucyc7XG5pbXBvcnQgV2ViaG9va0NsaWVudCBmcm9tICcuL3dlYmhvb2tzJztcbmltcG9ydCBNZXNzYWdlc0NsaWVudCBmcm9tICcuL21lc3NhZ2VzJztcbmltcG9ydCBSb3V0ZXNDbGllbnQgZnJvbSAnLi9yb3V0ZXMnO1xuaW1wb3J0IFZhbGlkYXRlQ2xpZW50IGZyb20gJy4vdmFsaWRhdGUnO1xuaW1wb3J0IFBhcnNlQ2xpZW50IGZyb20gJy4vcGFyc2UnO1xuaW1wb3J0IElwc0NsaWVudCBmcm9tICcuL2lwcyc7XG5pbXBvcnQgSXBQb29sc0NsaWVudCBmcm9tICcuL2lwLXBvb2xzJztcbmltcG9ydCBMaXN0c0NsaWVudCBmcm9tICcuL2xpc3RzJztcbmltcG9ydCBNYWlsTGlzdHNNZW1iZXJzIGZyb20gJy4vbWFpbExpc3RNZW1iZXJzJztcbmltcG9ydCB7IElucHV0Rm9ybURhdGEgfSBmcm9tICcuL2ludGVyZmFjZXMvSUZvcm1EYXRhJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2xpZW50IHtcbiAgcHJpdmF0ZSByZXF1ZXN0O1xuXG4gIHB1YmxpYyBkb21haW5zO1xuICBwdWJsaWMgd2ViaG9va3M7XG4gIHB1YmxpYyBldmVudHM7XG4gIHB1YmxpYyBzdGF0cztcbiAgcHVibGljIHN1cHByZXNzaW9ucztcbiAgcHVibGljIG1lc3NhZ2VzO1xuICBwdWJsaWMgcm91dGVzO1xuICBwdWJsaWMgcHVibGljX3JlcXVlc3Q7XG4gIHB1YmxpYyB2YWxpZGF0ZTtcbiAgcHVibGljIHBhcnNlO1xuICBwdWJsaWMgaXBzO1xuICBwdWJsaWMgaXBfcG9vbHM7XG4gIHB1YmxpYyBsaXN0cztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zLCBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YSkge1xuICAgIGNvbnN0IGNvbmZpZzogUmVxdWVzdE9wdGlvbnMgPSB7IC4uLm9wdGlvbnMgfSBhcyBSZXF1ZXN0T3B0aW9ucztcblxuICAgIGlmICghY29uZmlnLnVybCkge1xuICAgICAgY29uZmlnLnVybCA9ICdodHRwczovL2FwaS5tYWlsZ3VuLm5ldCc7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcudXNlcm5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFwidXNlcm5hbWVcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLmtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbWV0ZXIgXCJrZXlcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICB0aGlzLnJlcXVlc3QgPSBuZXcgUmVxdWVzdChjb25maWcsIGZvcm1EYXRhKTtcbiAgICBjb25zdCBtYWlsTGlzdHNNZW1iZXJzID0gbmV3IE1haWxMaXN0c01lbWJlcnModGhpcy5yZXF1ZXN0KTtcblxuICAgIHRoaXMuZG9tYWlucyA9IG5ldyBEb21haW5DbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLndlYmhvb2tzID0gbmV3IFdlYmhvb2tDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmV2ZW50cyA9IG5ldyBFdmVudENsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuc3RhdHMgPSBuZXcgU3RhdHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLnN1cHByZXNzaW9ucyA9IG5ldyBTdXBwcmVzc2lvbkNsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMubWVzc2FnZXMgPSBuZXcgTWVzc2FnZXNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLnJvdXRlcyA9IG5ldyBSb3V0ZXNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmlwcyA9IG5ldyBJcHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmlwX3Bvb2xzID0gbmV3IElwUG9vbHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmxpc3RzID0gbmV3IExpc3RzQ2xpZW50KHRoaXMucmVxdWVzdCwgbWFpbExpc3RzTWVtYmVycyk7XG5cbiAgICBpZiAoY29uZmlnLnB1YmxpY19rZXkpIHtcbiAgICAgIGNvbmZpZy5rZXkgPSBjb25maWcucHVibGljX2tleTtcblxuICAgICAgdGhpcy5wdWJsaWNfcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KGNvbmZpZywgZm9ybURhdGEpO1xuICAgICAgdGhpcy52YWxpZGF0ZSA9IG5ldyBWYWxpZGF0ZUNsaWVudCh0aGlzLnB1YmxpY19yZXF1ZXN0KTtcbiAgICAgIHRoaXMucGFyc2UgPSBuZXcgUGFyc2VDbGllbnQodGhpcy5wdWJsaWNfcmVxdWVzdCk7XG4gICAgfVxuICB9XG59XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCB7XG4gIERvbWFpblJlc3BvbnNlRGF0YSxcbiAgRGVzdHJveWVkRG9tYWluLFxuICBEZXN0cm95ZWREb21haW5SZXNwb25zZSxcbiAgRG9tYWluc1F1ZXJ5LFxuICBEb21haW5JbmZvLFxuICBEb21haW5MaXN0UmVzcG9uc2VEYXRhLFxuICBEb21haW5TaG9ydERhdGEsXG4gIEROU1JlY29yZFxufSBmcm9tICcuL2ludGVyZmFjZXMvRG9tYWlucyc7XG5cbmltcG9ydCBBUElSZXNwb25zZSBmcm9tICcuL2ludGVyZmFjZXMvQXBpUmVzcG9uc2UnO1xuaW1wb3J0IEFQSUVycm9yIGZyb20gJy4vZXJyb3InO1xuaW1wb3J0IEFQSUVycm9yT3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvQVBJRXJyb3JPcHRpb25zJztcblxuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcbmltcG9ydCB7XG4gIERvbWFpblRyYWNraW5nUmVzcG9uc2UsXG4gIERvbWFpblRyYWNraW5nRGF0YSxcbiAgT3BlblRyYWNraW5nSW5mbyxcbiAgQ2xpY2tUcmFja2luZ0luZm8sXG4gIFVuc3Vic2NyaWJlVHJhY2tpbmdJbmZvLFxuICBVcGRhdGVEb21haW5UcmFja2luZ1Jlc3BvbnNlLFxuICBVcGRhdGVkT3BlblRyYWNraW5nXG59IGZyb20gJy4vaW50ZXJmYWNlcy9Eb21haW5UcmFja2luZyc7XG5cbmNsYXNzIERvbWFpbiB7XG4gIG5hbWU6IHN0cmluZztcbiAgcmVxdWlyZV90bHM6IGJvb2xlYW47XG4gIHNraXBfdmVyaWZpY2F0aW9uOiBib29sZWFuO1xuICBzdGF0ZTogc3RyaW5nO1xuICB3aWxkY2FyZDogYm9vbGVhbjtcbiAgc3BhbV9hY3Rpb246IHN0cmluZztcbiAgY3JlYXRlZF9hdDogc3RyaW5nO1xuICBzbXRwX3Bhc3N3b3JkOiBzdHJpbmc7XG4gIHNtdHBfbG9naW46IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICByZWNlaXZpbmdfZG5zX3JlY29yZHM6IEROU1JlY29yZFtdIHwgbnVsbDtcbiAgc2VuZGluZ19kbnNfcmVjb3JkczogRE5TUmVjb3JkW10gfCBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IERvbWFpblNob3J0RGF0YSwgcmVjZWl2aW5nPzogRE5TUmVjb3JkW10gfCBudWxsLCBzZW5kaW5nPzogRE5TUmVjb3JkW10gfCBudWxsKSB7XG4gICAgdGhpcy5uYW1lID0gZGF0YS5uYW1lO1xuICAgIHRoaXMucmVxdWlyZV90bHMgPSBkYXRhLnJlcXVpcmVfdGxzO1xuICAgIHRoaXMuc2tpcF92ZXJpZmljYXRpb24gPSBkYXRhLnNraXBfdmVyaWZpY2F0aW9uO1xuICAgIHRoaXMuc3RhdGUgPSBkYXRhLnN0YXRlO1xuICAgIHRoaXMud2lsZGNhcmQgPSBkYXRhLndpbGRjYXJkO1xuICAgIHRoaXMuc3BhbV9hY3Rpb24gPSBkYXRhLnNwYW1fYWN0aW9uO1xuICAgIHRoaXMuY3JlYXRlZF9hdCA9IGRhdGEuY3JlYXRlZF9hdDtcbiAgICB0aGlzLnNtdHBfcGFzc3dvcmQgPSBkYXRhLnNtdHBfcGFzc3dvcmQ7XG4gICAgdGhpcy5zbXRwX2xvZ2luID0gZGF0YS5zbXRwX2xvZ2luO1xuICAgIHRoaXMudHlwZSA9IGRhdGEudHlwZTtcblxuICAgIHRoaXMucmVjZWl2aW5nX2Ruc19yZWNvcmRzID0gcmVjZWl2aW5nIHx8IG51bGw7XG4gICAgdGhpcy5zZW5kaW5nX2Ruc19yZWNvcmRzID0gc2VuZGluZyB8fCBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvbWFpbkNsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VNZXNzYWdlKHJlc3BvbnNlOiBEZXN0cm95ZWREb21haW5SZXNwb25zZSkgOiBEZXN0cm95ZWREb21haW4ge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG5cbiAgX3BhcnNlRG9tYWluTGlzdChyZXNwb25zZTogRG9tYWluTGlzdFJlc3BvbnNlRGF0YSk6IERvbWFpbltdIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBuZXcgRG9tYWluKGl0ZW0pO1xuICAgIH0pO1xuICB9XG5cbiAgX3BhcnNlRG9tYWluKHJlc3BvbnNlOiBEb21haW5SZXNwb25zZURhdGEpOiBEb21haW4ge1xuICAgIHJldHVybiBuZXcgRG9tYWluKFxuICAgICAgcmVzcG9uc2UuYm9keS5kb21haW4sXG4gICAgICByZXNwb25zZS5ib2R5LnJlY2VpdmluZ19kbnNfcmVjb3JkcyxcbiAgICAgIHJlc3BvbnNlLmJvZHkuc2VuZGluZ19kbnNfcmVjb3Jkc1xuICAgICk7XG4gIH1cblxuICBfcGFyc2VUcmFja2luZ1NldHRpbmdzKHJlc3BvbnNlOiBEb21haW5UcmFja2luZ1Jlc3BvbnNlKSA6IERvbWFpblRyYWNraW5nRGF0YSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkudHJhY2tpbmc7XG4gIH1cblxuICBfcGFyc2VUcmFja2luZ1VwZGF0ZShyZXNwb25zZTogVXBkYXRlRG9tYWluVHJhY2tpbmdSZXNwb25zZSkgOlVwZGF0ZWRPcGVuVHJhY2tpbmcge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG5cbiAgbGlzdChxdWVyeTogRG9tYWluc1F1ZXJ5KTogUHJvbWlzZTxEb21haW5bXT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjIvZG9tYWlucycsIHF1ZXJ5KVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbkxpc3QocmVzIGFzIERvbWFpbkxpc3RSZXNwb25zZURhdGEpKTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZykgOiBQcm9taXNlPERvbWFpbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KGAvdjIvZG9tYWlucy8ke2RvbWFpbn1gKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbihyZXMgYXMgRG9tYWluUmVzcG9uc2VEYXRhKSk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogRG9tYWluSW5mbykgOiBQcm9taXNlPERvbWFpbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCgnL3YyL2RvbWFpbnMnLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbihyZXMgYXMgRG9tYWluUmVzcG9uc2VEYXRhKSk7XG4gIH1cblxuICBkZXN0cm95KGRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95ZWREb21haW4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YyL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VNZXNzYWdlKHJlcyBhcyBEZXN0cm95ZWREb21haW5SZXNwb25zZSkpO1xuICB9XG5cbiAgLy8gVHJhY2tpbmdcblxuICBnZXRUcmFja2luZyhkb21haW46IHN0cmluZykgOiBQcm9taXNlPERvbWFpblRyYWNraW5nRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAndHJhY2tpbmcnKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlVHJhY2tpbmdTZXR0aW5ncyk7XG4gIH1cblxuICB1cGRhdGVUcmFja2luZyhcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgZGF0YTogT3BlblRyYWNraW5nSW5mbyB8IENsaWNrVHJhY2tpbmdJbmZvIHwgVW5zdWJzY3JpYmVUcmFja2luZ0luZm9cbiAgKTogUHJvbWlzZTxVcGRhdGVkT3BlblRyYWNraW5nPiB7XG4gICAgaWYgKCEoJ2h0bWxfZm9vdGVyJyBpbiBkYXRhKSAmJiAhKCd0ZXh0X2Zvb3RlcicgaW4gZGF0YSkgJiYgdHlwZW9mIGRhdGE/LmFjdGl2ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyBuZXcgQVBJRXJyb3IoeyBzdGF0dXM6IDQwMCwgc3RhdHVzVGV4dDogJycsIGJvZHk6IHsgbWVzc2FnZTogJ1ZhbHVlIFwiYWN0aXZlXCIgbXVzdCBjb250YWluIHN0cmluZyB2YWx1ZS4nIH0gfSBhcyBBUElFcnJvck9wdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3RyYWNraW5nJywgdHlwZSksIGRhdGEpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVRyYWNraW5nVXBkYXRlKTtcbiAgfVxuXG4gIC8vIElQc1xuXG4gIGdldElwcyhkb21haW46IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBBUElSZXNwb25zZSkgPT4gcmVzcG9uc2U/LmJvZHk/Lml0ZW1zKTtcbiAgfVxuXG4gIGFzc2lnbklwKGRvbWFpbjogc3RyaW5nLCBpcDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IGlwIH0pO1xuICB9XG5cbiAgZGVsZXRlSXAoZG9tYWluOiBzdHJpbmcsIGlwOiBzdHJpbmcpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICdpcHMnLCBpcCkpO1xuICB9XG5cbiAgbGlua0lwUG9vbChkb21haW46IHN0cmluZywgcG9vbF9pZDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IHBvb2xfaWQgfSk7XG4gIH1cblxuICB1bmxpbmtJcFBvbGwoZG9tYWluOiBzdHJpbmcsIHBvb2xfaWQ6IHN0cmluZywgaXA6IHN0cmluZyk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZSh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycsICdpcF9wb29sJyksIHsgcG9vbF9pZCwgaXAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCBBUElFcnJvck9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL0FQSUVycm9yT3B0aW9ucyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFQSUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBzdGF0dXM6IG51bWJlciB8IHN0cmluZztcbiAgc3RhY2s6IHN0cmluZztcbiAgZGV0YWlsczogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBzdGF0dXMsXG4gICAgc3RhdHVzVGV4dCxcbiAgICBtZXNzYWdlLFxuICAgIGJvZHkgPSB7fVxuICB9OiBBUElFcnJvck9wdGlvbnMpIHtcbiAgICBjb25zdCB7IG1lc3NhZ2U6IGJvZHlNZXNzYWdlLCBlcnJvciB9ID0gYm9keTtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5zdGFjayA9ICcnO1xuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgZXJyb3IgfHwgc3RhdHVzVGV4dDtcbiAgICB0aGlzLmRldGFpbHMgPSBib2R5TWVzc2FnZTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHtcbiAgRXZlbnRzTGlzdCwgRXZlbnRzUGFnZSwgRXZlbnRzUmVzcG9uc2UsIFBhZ2VzTGlzdCwgUGFnZXNMaXN0QWNjdW11bGF0b3Jcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL0V2ZW50cyc7XG5cbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV2ZW50Q2xpZW50IHtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIF9wYXJzZVBhZ2VOdW1iZXIodXJsOiBzdHJpbmcpIDogc3RyaW5nIHtcbiAgICByZXR1cm4gdXJsLnNwbGl0KCcvJykucG9wKCk7XG4gIH1cblxuICBfcGFyc2VQYWdlKGlkOiBzdHJpbmcsIHVybDogc3RyaW5nKSA6IEV2ZW50c1BhZ2Uge1xuICAgIHJldHVybiB7IGlkLCBudW1iZXI6IHRoaXMuX3BhcnNlUGFnZU51bWJlcih1cmwpLCB1cmwgfTtcbiAgfVxuXG4gIF9wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZTogRXZlbnRzUmVzcG9uc2UpIDogUGFnZXNMaXN0IHtcbiAgICBjb25zdCBwYWdlcyA9IE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmJvZHkucGFnaW5nIGFzIFBhZ2VzTGlzdCk7XG4gICAgcmV0dXJuIHBhZ2VzLnJlZHVjZShcbiAgICAgIChhY2M6IFBhZ2VzTGlzdEFjY3VtdWxhdG9yLCBlbnRyaWU6IFt1cmw6IHN0cmluZywgaWQ6IHN0cmluZ10pID0+IHtcbiAgICAgICAgY29uc3QgaWQgPSBlbnRyaWVbMF07XG4gICAgICAgIGNvbnN0IHVybCA9IGVudHJpZVsxXTtcbiAgICAgICAgYWNjW2lkXSA9IHRoaXMuX3BhcnNlUGFnZShpZCwgdXJsKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIHt9XG4gICAgKSBhcyB1bmtub3duIGFzIFBhZ2VzTGlzdDtcbiAgfVxuXG4gIF9wYXJzZUV2ZW50TGlzdChyZXNwb25zZTogRXZlbnRzUmVzcG9uc2UpIDogRXZlbnRzTGlzdCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1zOiByZXNwb25zZS5ib2R5Lml0ZW1zLFxuICAgICAgcGFnZXM6IHRoaXMuX3BhcnNlUGFnZUxpbmtzKHJlc3BvbnNlKVxuICAgIH07XG4gIH1cblxuICBnZXQoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiB7IHBhZ2U6IHN0cmluZyB9KSA6IFByb21pc2U8RXZlbnRzTGlzdD4ge1xuICAgIGxldCB1cmw7XG4gICAgY29uc3QgcXVlcnlDb3B5ID0geyAuLi5xdWVyeSB9O1xuICAgIGlmIChxdWVyeUNvcHkgJiYgcXVlcnlDb3B5LnBhZ2UpIHtcbiAgICAgIHVybCA9IHVybGpvaW4oJy92MicsIGRvbWFpbiwgJ2V2ZW50cycsIHF1ZXJ5Q29weS5wYWdlKTtcbiAgICAgIGRlbGV0ZSBxdWVyeUNvcHkucGFnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXJsID0gdXJsam9pbignL3YyJywgZG9tYWluLCAnZXZlbnRzJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybCwgcXVlcnlDb3B5KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBFdmVudHNSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VFdmVudExpc3QocmVzcG9uc2UpKTtcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5pbXBvcnQgeyBJcFBvb2wsIElwUG9vbExpc3RSZXNwb25zZSwgSXBQb29sVXBkYXRlRGF0YSB9IGZyb20gJy4vaW50ZXJmYWNlcy9JcFBvb2xzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSXBQb29sc0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBsaXN0KHF1ZXJ5OiBhbnkpOiBQcm9taXNlPElwUG9vbFtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92MS9pcF9wb29scycsIHF1ZXJ5KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBJcFBvb2xMaXN0UmVzcG9uc2UpID0+IHRoaXMucGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2UpKTtcbiAgfVxuXG4gIGNyZWF0ZShkYXRhOiB7IG5hbWU6IHN0cmluZywgZGVzY3JpcHRpb24/OiBzdHJpbmcsIGlwcz86IHN0cmluZ1tdIH0pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3QoJy92MS9pcF9wb29scycsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogeyBtZXNzYWdlOiBzdHJpbmcsIHBvb2xfaWQ6IHN0cmluZyB9IH0pID0+IHJlc3BvbnNlPy5ib2R5KTtcbiAgfVxuXG4gIHVwZGF0ZShwb29sSWQ6IHN0cmluZywgZGF0YTogSXBQb29sVXBkYXRlRGF0YSkgOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucGF0Y2goYC92MS9pcF9wb29scy8ke3Bvb2xJZH1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZT8uYm9keSk7XG4gIH1cblxuICBkZWxldGUocG9vbElkOiBzdHJpbmcsIGRhdGE6IHsgaWQ6IHN0cmluZywgcG9vbF9pZDogc3RyaW5nIH0pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YxL2lwX3Bvb2xzLyR7cG9vbElkfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogYW55IH0pID0+IHJlc3BvbnNlPy5ib2R5KTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2U6IHsgYm9keTogYW55IHwgYW55IH0pIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5pcF9wb29scztcbiAgfVxufVxuIiwiaW1wb3J0IE1nUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHsgSXBEYXRhLCBJcHNMaXN0UmVzcG9uc2VCb2R5IH0gZnJvbSAnLi9pbnRlcmZhY2VzL0lwcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIElwc0NsaWVudCB7XG4gIHJlcXVlc3Q6IE1nUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBNZ1JlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgbGlzdChxdWVyeTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9pcHMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiBJcHNMaXN0UmVzcG9uc2VCb2R5IH0pID0+IHRoaXMucGFyc2VJcHNSZXNwb25zZShyZXNwb25zZSkpO1xuICB9XG5cbiAgZ2V0KGlwOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YzL2lwcy8ke2lwfWApXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogSXBEYXRhIH0pID0+IHRoaXMucGFyc2VJcHNSZXNwb25zZShyZXNwb25zZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUlwc1Jlc3BvbnNlKHJlc3BvbnNlOiB7IGJvZHk6IElwc0xpc3RSZXNwb25zZUJvZHkgfCBJcERhdGEgfSkge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG59XG4iLCJpbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHtcbiAgTGlzdHNRdWVyeSxcbiAgQ3JlYXRlVXBkYXRlTGlzdCxcbiAgRGVzdHJveWVkTGlzdCxcbiAgTWFpbGluZ0xpc3Rcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL2xpc3RzJztcbmltcG9ydCB7IElNYWlsTGlzdHNNZW1iZXJzIH0gZnJvbSAnLi9pbnRlcmZhY2VzL21haWxMaXN0TWVtYmVycyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpc3RzQ2xpZW50IHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG4gIG1lbWJlcnM6IElNYWlsTGlzdHNNZW1iZXJzO1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QsIG1lbWJlcnM6SU1haWxMaXN0c01lbWJlcnMpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My9saXN0cyc7XG4gICAgdGhpcy5tZW1iZXJzID0gbWVtYmVycztcbiAgfVxuXG4gIGxpc3QocXVlcnk/OiBMaXN0c1F1ZXJ5KTogUHJvbWlzZTxNYWlsaW5nTGlzdFtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9L3BhZ2VzYCwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkuaXRlbXMgYXMgTWFpbGluZ0xpc3RbXSk7XG4gIH1cblxuICBnZXQobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogQ3JlYXRlVXBkYXRlTGlzdCk6IFByb21pc2U8TWFpbGluZ0xpc3Q+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodGhpcy5iYXNlUm91dGUsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICB1cGRhdGUobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsIGRhdGE6IENyZWF0ZVVwZGF0ZUxpc3QpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBkZXN0cm95KG1haWxMaXN0QWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95ZWRMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgRGVzdHJveWVkTGlzdCk7XG4gIH1cbn1cbiIsImltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQge1xuICBNYWlsTGlzdE1lbWJlcnNRdWVyeSxcbiAgSU1haWxMaXN0c01lbWJlcnMsXG4gIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVycyxcbiAgTWFpbExpc3RNZW1iZXIsXG4gIE11bHRpcGxlTWVtYmVyc0RhdGEsXG4gIE11bHRpcGxlTWVtYmVyc1JlcURhdGEsXG4gIERlbGV0ZWRNZW1iZXIsXG4gIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1JlcSxcbiAgTmV3TXVsdGlwbGVNZW1iZXJzUmVzcG9uc2Vcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL21haWxMaXN0TWVtYmVycyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1haWxMaXN0c01lbWJlcnMgaW1wbGVtZW50cyBJTWFpbExpc3RzTWVtYmVycyB7XG4gIGJhc2VSb3V0ZTogc3RyaW5nO1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My9saXN0cyc7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQW5kVXBkYXRlRGF0YShkYXRhOiBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnMpIHtcbiAgICBjb25zdCBuZXdEYXRhID0geyAuLi5kYXRhIH07XG5cbiAgICBpZiAodHlwZW9mIGRhdGEudmFycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIG5ld0RhdGEudmFycyA9IEpTT04uc3RyaW5naWZ5KG5ld0RhdGEudmFycyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkYXRhLnN1YnNjcmliZWQgPT09ICdib29sZWFuJykge1xuICAgICAgbmV3RGF0YS5zdWJzY3JpYmVkID0gZGF0YS5zdWJzY3JpYmVkID8gJ3llcycgOiAnbm8nO1xuICAgIH1cblxuICAgIHJldHVybiBuZXdEYXRhIGFzIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1JlcTtcbiAgfVxuXG4gIGxpc3RNZW1iZXJzKG1haWxMaXN0QWRkcmVzczogc3RyaW5nLCBxdWVyeT86IE1haWxMaXN0TWVtYmVyc1F1ZXJ5KTogUHJvbWlzZTxNYWlsTGlzdE1lbWJlcltdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzL3BhZ2VzYCwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkuaXRlbXMgYXMgTWFpbExpc3RNZW1iZXJbXSk7XG4gIH1cblxuICBnZXRNZW1iZXIobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsIG1haWxMaXN0TWVtYmVyQWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxNYWlsTGlzdE1lbWJlcj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVycy8ke21haWxMaXN0TWVtYmVyQWRkcmVzc31gKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5Lm1lbWJlciBhcyBNYWlsTGlzdE1lbWJlcik7XG4gIH1cblxuICBjcmVhdGVNZW1iZXIoXG4gICAgbWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsXG4gICAgZGF0YTogQ3JlYXRlVXBkYXRlTWFpbExpc3RNZW1iZXJzXG4gICk6IFByb21pc2U8TWFpbExpc3RNZW1iZXI+IHtcbiAgICBjb25zdCByZXFEYXRhID0gdGhpcy5jaGVja0FuZFVwZGF0ZURhdGEoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVyc2AsIHJlcURhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubWVtYmVyIGFzIE1haWxMaXN0TWVtYmVyKTtcbiAgfVxuXG4gIGNyZWF0ZU1lbWJlcnMoXG4gICAgbWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsXG4gICAgZGF0YTogTXVsdGlwbGVNZW1iZXJzRGF0YVxuICApOiBQcm9taXNlPE5ld011bHRpcGxlTWVtYmVyc1Jlc3BvbnNlPiB7XG4gICAgY29uc3QgbmV3RGF0YTogTXVsdGlwbGVNZW1iZXJzUmVxRGF0YSA9IHtcbiAgICAgIG1lbWJlcnM6IEFycmF5LmlzQXJyYXkoZGF0YS5tZW1iZXJzKSA/IEpTT04uc3RyaW5naWZ5KGRhdGEubWVtYmVycykgOiBkYXRhLm1lbWJlcnMsXG4gICAgICB1cHNlcnQ6IGRhdGEudXBzZXJ0XG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMuanNvbmAsIG5ld0RhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgTmV3TXVsdGlwbGVNZW1iZXJzUmVzcG9uc2UpO1xuICB9XG5cbiAgdXBkYXRlTWVtYmVyKFxuICAgIG1haWxMaXN0QWRkcmVzczogc3RyaW5nLFxuICAgIG1haWxMaXN0TWVtYmVyQWRkcmVzczogc3RyaW5nLFxuICAgIGRhdGE6IENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1xuICApOiBQcm9taXNlPE1haWxMaXN0TWVtYmVyPiB7XG4gICAgY29uc3QgcmVxRGF0YSA9IHRoaXMuY2hlY2tBbmRVcGRhdGVEYXRhKGRhdGEpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucHV0V2l0aEZEKGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVycy8ke21haWxMaXN0TWVtYmVyQWRkcmVzc31gLCByZXFEYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5Lm1lbWJlciBhcyBNYWlsTGlzdE1lbWJlcik7XG4gIH1cblxuICBkZXN0cm95TWVtYmVyKG1haWxMaXN0QWRkcmVzczogc3RyaW5nLCBtYWlsTGlzdE1lbWJlckFkZHJlc3M6IHN0cmluZykgOiBQcm9taXNlPERlbGV0ZWRNZW1iZXI+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMvJHttYWlsTGlzdE1lbWJlckFkZHJlc3N9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keSBhcyBEZWxldGVkTWVtYmVyKTtcbiAgfVxufVxuIiwiaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWVzc2FnZXNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgX3BhcnNlUmVzcG9uc2UocmVzcG9uc2U6IHsgYm9keTogYW55IH0pIHtcbiAgICBpZiAocmVzcG9uc2UuYm9keSkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlO1xuICB9XG5cbiAgY3JlYXRlKGRvbWFpbjogc3RyaW5nLCBkYXRhOiBhbnkpIHtcbiAgICBpZiAoZGF0YS5tZXNzYWdlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYC92My8ke2RvbWFpbn0vbWVzc2FnZXMubWltZWAsIGRhdGEpXG4gICAgICAgIC50aGVuKHRoaXMuX3BhcnNlUmVzcG9uc2UpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRChgL3YzLyR7ZG9tYWlufS9tZXNzYWdlc2AsIGRhdGEpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVJlc3BvbnNlKTtcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQYXJzZUNsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBnZXQoYWRkcmVzc2VzOiBzdHJpbmdbXSB8IHN0cmluZywgZW5hYmxlRG5zRXNwQ2hlY2tzOiBib29sZWFuKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7fSBhcyB7IGFkZHJlc3Nlczogc3RyaW5nLCBzeW50YXhfb25seTogYm9vbGVhbiB9O1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYWRkcmVzc2VzKSkge1xuICAgICAgcXVlcnkuYWRkcmVzc2VzID0gYWRkcmVzc2VzLmpvaW4oJywnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcXVlcnkuYWRkcmVzc2VzID0gYWRkcmVzc2VzO1xuICAgIH1cblxuICAgIGlmIChlbmFibGVEbnNFc3BDaGVja3MpIHtcbiAgICAgIHF1ZXJ5LnN5bnRheF9vbmx5ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9hZGRyZXNzL3BhcnNlJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG59XG4iLCJpbXBvcnQgTm9kZUZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5pbXBvcnQgYmFzZTY0IGZyb20gJ2Jhc2UtNjQnO1xuaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IGt5IGZyb20gJ2t5LXVuaXZlcnNhbCc7XG5pbXBvcnQgQVBJRXJyb3IgZnJvbSAnLi9lcnJvcic7XG5pbXBvcnQgUmVxdWVzdE9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL1JlcXVlc3RPcHRpb25zJztcbmltcG9ydCBBUElFcnJvck9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL0FQSUVycm9yT3B0aW9ucyc7XG5pbXBvcnQgeyBJbnB1dEZvcm1EYXRhIH0gZnJvbSAnLi9pbnRlcmZhY2VzL0lGb3JtRGF0YSc7XG5pbXBvcnQgQVBJUmVzcG9uc2UgZnJvbSAnLi9pbnRlcmZhY2VzL0FwaVJlc3BvbnNlJztcblxuY29uc3QgaXNTdHJlYW0gPSAoYXR0YWNobWVudDogYW55KSA9PiB0eXBlb2YgYXR0YWNobWVudCA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGF0dGFjaG1lbnQucGlwZSA9PT0gJ2Z1bmN0aW9uJztcblxuZnVuY3Rpb24gaXNOb2RlRm9ybURhdGEoZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEpXG4gIDogZm9ybURhdGFJbnN0YW5jZSBpcyBOb2RlRm9ybURhdGEge1xuICByZXR1cm4gKDxOb2RlRm9ybURhdGE+Zm9ybURhdGFJbnN0YW5jZSkuZ2V0SGVhZGVycyAhPT0gdW5kZWZpbmVkO1xufVxuXG5jb25zdCBnZXRBdHRhY2htZW50T3B0aW9ucyA9IChpdGVtOiBhbnkpOiB7XG4gIGZpbGVuYW1lPzogc3RyaW5nLFxuICBjb250ZW50VHlwZT86IHN0cmluZyxcbiAga25vd25MZW5ndGg/OiBudW1iZXJcbn0gPT4ge1xuICBpZiAodHlwZW9mIGl0ZW0gIT09ICdvYmplY3QnIHx8IGlzU3RyZWFtKGl0ZW0pKSByZXR1cm4ge307XG5cbiAgY29uc3Qge1xuICAgIGZpbGVuYW1lLFxuICAgIGNvbnRlbnRUeXBlLFxuICAgIGtub3duTGVuZ3RoXG4gIH0gPSBpdGVtO1xuXG4gIHJldHVybiB7XG4gICAgLi4uKGZpbGVuYW1lID8geyBmaWxlbmFtZSB9IDogeyBmaWxlbmFtZTogJ2ZpbGUnIH0pLFxuICAgIC4uLihjb250ZW50VHlwZSAmJiB7IGNvbnRlbnRUeXBlIH0pLFxuICAgIC4uLihrbm93bkxlbmd0aCAmJiB7IGtub3duTGVuZ3RoIH0pXG4gIH07XG59O1xuXG5jb25zdCBzdHJlYW1Ub1N0cmluZyA9IChzdHJlYW06IGFueSkgPT4ge1xuICBjb25zdCBjaHVua3M6IGFueSA9IFtdO1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHN0cmVhbS5vbignZGF0YScsIChjaHVuazogYW55KSA9PiBjaHVua3MucHVzaChjaHVuaykpO1xuICAgIHN0cmVhbS5vbignZXJyb3InLCByZWplY3QpO1xuICAgIHN0cmVhbS5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoJ3V0ZjgnKSkpO1xuICB9KTtcbn07XG5cbmNsYXNzIFJlcXVlc3Qge1xuICBwcml2YXRlIHVzZXJuYW1lOiBzdHJpbmc7XG4gIHByaXZhdGUga2V5OiBzdHJpbmc7XG4gIHByaXZhdGUgdXJsOiBzdHJpbmc7XG4gIHByaXZhdGUgdGltZW91dDogbnVtYmVyO1xuICBwcml2YXRlIGhlYWRlcnM6IGFueTtcbiAgcHJpdmF0ZSBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucywgZm9ybURhdGE6IElucHV0Rm9ybURhdGEpIHtcbiAgICB0aGlzLnVzZXJuYW1lID0gb3B0aW9ucy51c2VybmFtZTtcbiAgICB0aGlzLmtleSA9IG9wdGlvbnMua2V5O1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmwgYXMgc3RyaW5nO1xuICAgIHRoaXMudGltZW91dCA9IG9wdGlvbnMudGltZW91dDtcbiAgICB0aGlzLmhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnMgfHwge307XG4gICAgdGhpcy5mb3JtRGF0YSA9IGZvcm1EYXRhO1xuICB9XG5cbiAgYXN5bmMgcmVxdWVzdChtZXRob2Q6IHN0cmluZywgdXJsOiBzdHJpbmcsIGlucHV0T3B0aW9ucz86IGFueSk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBjb25zdCBvcHRpb25zID0geyAuLi5pbnB1dE9wdGlvbnMgfTtcbiAgICBjb25zdCBiYXNpYyA9IGJhc2U2NC5lbmNvZGUoYCR7dGhpcy51c2VybmFtZX06JHt0aGlzLmtleX1gKTtcbiAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgQXV0aG9yaXphdGlvbjogYEJhc2ljICR7YmFzaWN9YCxcbiAgICAgIC4uLnRoaXMuaGVhZGVycyxcbiAgICAgIC4uLm9wdGlvbnM/LmhlYWRlcnNcbiAgICB9O1xuXG4gICAgZGVsZXRlIG9wdGlvbnM/LmhlYWRlcnM7XG5cbiAgICBpZiAoIWhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddKSB7XG4gICAgICAvLyBmb3IgZm9ybS1kYXRhIGl0IHdpbGwgYmUgTnVsbCBzbyB3ZSBuZWVkIHRvIHJlbW92ZSBpdFxuICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmFtcyA9IHsgLi4ub3B0aW9ucyB9O1xuXG4gICAgaWYgKG9wdGlvbnM/LnF1ZXJ5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9wdGlvbnM/LnF1ZXJ5KS5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJhbXMuc2VhcmNoUGFyYW1zID0gb3B0aW9ucy5xdWVyeTtcbiAgICAgIGRlbGV0ZSBwYXJhbXMucXVlcnk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBreShcbiAgICAgIHVybGpvaW4odGhpcy51cmwsIHVybCksXG4gICAgICB7XG4gICAgICAgIG1ldGhvZDogbWV0aG9kLnRvTG9jYWxlVXBwZXJDYXNlKCksXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHRocm93SHR0cEVycm9yczogZmFsc2UsXG4gICAgICAgIHRpbWVvdXQ6IHRoaXMudGltZW91dCxcbiAgICAgICAgLi4ucGFyYW1zXG4gICAgICB9XG4gICAgKTtcblxuICAgIGlmICghcmVzcG9uc2U/Lm9rKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gcmVzcG9uc2U/LmJvZHkgJiYgaXNTdHJlYW0ocmVzcG9uc2UuYm9keSlcbiAgICAgICAgPyBhd2FpdCBzdHJlYW1Ub1N0cmluZyhyZXNwb25zZS5ib2R5KVxuICAgICAgICA6IGF3YWl0IHJlc3BvbnNlPy5qc29uKCk7XG5cbiAgICAgIHRocm93IG5ldyBBUElFcnJvcih7XG4gICAgICAgIHN0YXR1czogcmVzcG9uc2U/LnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogcmVzcG9uc2U/LnN0YXR1c1RleHQsXG4gICAgICAgIGJvZHk6IHsgbWVzc2FnZSB9XG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJvZHk6IGF3YWl0IHJlc3BvbnNlPy5qc29uKCksXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlPy5zdGF0dXNcbiAgICB9O1xuICB9XG5cbiAgcXVlcnkobWV0aG9kOiBzdHJpbmcsIHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zPzogYW55KSA6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IHF1ZXJ5LCAuLi5vcHRpb25zIH0pO1xuICB9XG5cbiAgY29tbWFuZChtZXRob2Q6IHN0cmluZywgdXJsOiBzdHJpbmcsIGRhdGE6IGFueSwgb3B0aW9ucz86IGFueSkgOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChtZXRob2QsIHVybCwge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSxcbiAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAuLi5vcHRpb25zXG4gICAgfSk7XG4gIH1cblxuICBnZXQodXJsOiBzdHJpbmcsIHF1ZXJ5PzogYW55LCBvcHRpb25zPzogYW55KSA6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeSgnZ2V0JywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBoZWFkKHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zOiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5KCdoZWFkJywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBvcHRpb25zKHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zOiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5KCdvcHRpb25zJywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBwb3N0KHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ3Bvc3QnLCB1cmwsIGRhdGEsIG9wdGlvbnMpO1xuICB9XG5cbiAgcG9zdFdpdGhGRCh1cmw6IHN0cmluZywgZGF0YTogYW55KTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIGNvbnN0IHBhcmFtczogYW55ID0ge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogbnVsbCB9XG4gICAgfTtcbiAgICBjb25zdCBmb3JtRGF0YSA9IHRoaXMuY3JlYXRlRm9ybURhdGEoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncG9zdCcsIHVybCwgZm9ybURhdGEsIHBhcmFtcyk7XG4gIH1cblxuICBwdXRXaXRoRkQodXJsOiBzdHJpbmcsIGRhdGE6IGFueSk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBjb25zdCBwYXJhbXM6IGFueSA9IHtcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6IG51bGwgfVxuICAgIH07XG4gICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLmNyZWF0ZUZvcm1EYXRhKGRhdGEpO1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ3B1dCcsIHVybCwgZm9ybURhdGEsIHBhcmFtcyk7XG4gIH1cblxuICBjcmVhdGVGb3JtRGF0YShkYXRhOiBhbnkpOiBOb2RlRm9ybURhdGEgfCBGb3JtRGF0YSB7XG4gICAgY29uc3QgYXBwZW5kRmlsZVRvRkQgPSAoXG4gICAgICBrZXk6IHN0cmluZyxcbiAgICAgIG9iajogYW55LFxuICAgICAgZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgICApOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IGlzU3RyZWFtRGF0YSA9IGlzU3RyZWFtKG9iaik7XG4gICAgICBjb25zdCBvYmpEYXRhID0gaXNTdHJlYW1EYXRhID8gb2JqIDogb2JqLmRhdGE7XG4gICAgICBjb25zdCBvcHRpb25zID0gZ2V0QXR0YWNobWVudE9wdGlvbnMob2JqKTtcbiAgICAgIGlmIChpc05vZGVGb3JtRGF0YShmb3JtRGF0YUluc3RhbmNlKSkge1xuICAgICAgICBmb3JtRGF0YUluc3RhbmNlLmFwcGVuZChrZXksIG9iakRhdGEsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBmb3JtRGF0YUluc3RhbmNlLmFwcGVuZChrZXksIG9iakRhdGEsIG9wdGlvbnMuZmlsZW5hbWUpO1xuICAgIH07XG5cbiAgICBjb25zdCBmb3JtRGF0YTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEgPSBPYmplY3Qua2V5cyhkYXRhKVxuICAgICAgLmZpbHRlcihmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBkYXRhW2tleV07IH0pXG4gICAgICAucmVkdWNlKChmb3JtRGF0YUFjYzogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEsIGtleSkgPT4ge1xuICAgICAgICBpZiAoa2V5ID09PSAnYXR0YWNobWVudCcgfHwga2V5ID09PSAnaW5saW5lJykge1xuICAgICAgICAgIGNvbnN0IG9iaiA9IGRhdGFba2V5XTtcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgIGFwcGVuZEZpbGVUb0ZEKGtleSwgaXRlbSwgZm9ybURhdGFBY2MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFwcGVuZEZpbGVUb0ZEKGtleSwgb2JqLCBmb3JtRGF0YUFjYyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGZvcm1EYXRhQWNjO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YVtrZXldKSkge1xuICAgICAgICAgIGRhdGFba2V5XS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtOiBhbnkpIHtcbiAgICAgICAgICAgIGZvcm1EYXRhQWNjLmFwcGVuZChrZXksIGl0ZW0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGFba2V5XSAhPSBudWxsKSB7XG4gICAgICAgICAgZm9ybURhdGFBY2MuYXBwZW5kKGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9ybURhdGFBY2M7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbmV3LWNhcFxuICAgICAgfSwgbmV3IHRoaXMuZm9ybURhdGEoKSk7XG4gICAgcmV0dXJuIGZvcm1EYXRhO1xuICB9XG5cbiAgcHV0KHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncHV0JywgdXJsLCBkYXRhLCBvcHRpb25zKTtcbiAgfVxuXG4gIHBhdGNoKHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncGF0Y2gnLCB1cmwsIGRhdGEsIG9wdGlvbnMpO1xuICB9XG5cbiAgZGVsZXRlKHVybDogc3RyaW5nLCBkYXRhPzogYW55LCBvcHRpb25zPzogYW55KTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ2RlbGV0ZScsIHVybCwgZGF0YSwgb3B0aW9ucyk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVxdWVzdDtcbiIsImltcG9ydCB7XG4gIENyZWF0ZVVwZGF0ZVJvdXRlRGF0YSwgRGVzdHJveVJvdXRlUmVzcG9uc2UsIFJvdXRlLCBSb3V0ZXNMaXN0UXVlcnksIFVwZGF0ZVJvdXRlUmVzcG9uc2Vcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL3JvdXRlcyc7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSb3V0ZXNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgbGlzdChxdWVyeTogUm91dGVzTGlzdFF1ZXJ5KTogUHJvbWlzZTxSb3V0ZVtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9yb3V0ZXMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5pdGVtcyk7XG4gIH1cblxuICBnZXQoaWQ6IHN0cmluZyk6IFByb21pc2U8Um91dGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YzL3JvdXRlcy8ke2lkfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkucm91dGUpO1xuICB9XG5cbiAgY3JlYXRlKGRhdGE6IENyZWF0ZVVwZGF0ZVJvdXRlRGF0YSk6IFByb21pc2U8Um91dGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoJy92My9yb3V0ZXMnLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5LnJvdXRlKTtcbiAgfVxuXG4gIHVwZGF0ZShpZDogc3RyaW5nLCBkYXRhOiBDcmVhdGVVcGRhdGVSb3V0ZURhdGEpOiBQcm9taXNlPFVwZGF0ZVJvdXRlUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRChgL3YzL3JvdXRlcy8ke2lkfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgZGVzdHJveShpZDogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95Um91dGVSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKGAvdjMvcm91dGVzLyR7aWR9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keSk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQgU3RhdHNPcHRpb25zIGZyb20gJy4vaW50ZXJmYWNlcy9TdGF0c09wdGlvbnMnO1xuXG5jbGFzcyBTdGF0cyB7XG4gIHN0YXJ0OiBEYXRlO1xuICBlbmQ6IERhdGU7XG4gIHJlc29sdXRpb246IHN0cmluZztcbiAgc3RhdHM6IGFueTtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBTdGF0c09wdGlvbnMpIHtcbiAgICB0aGlzLnN0YXJ0ID0gbmV3IERhdGUoZGF0YS5zdGFydCk7XG4gICAgdGhpcy5lbmQgPSBuZXcgRGF0ZShkYXRhLmVuZCk7XG4gICAgdGhpcy5yZXNvbHV0aW9uID0gZGF0YS5yZXNvbHV0aW9uO1xuICAgIHRoaXMuc3RhdHMgPSBkYXRhLnN0YXRzLm1hcChmdW5jdGlvbiAoc3RhdDogeyB0aW1lOiBzdHJpbmcgfCBEYXRlIH0pIHtcbiAgICAgIGNvbnN0IHJlcyA9IHsgLi4uc3RhdCB9O1xuICAgICAgcmVzLnRpbWUgPSBuZXcgRGF0ZShzdGF0LnRpbWUpO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGF0c0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VTdGF0cyhyZXNwb25zZTogeyBib2R5OiBTdGF0c09wdGlvbnMgfSkge1xuICAgIHJldHVybiBuZXcgU3RhdHMocmVzcG9uc2UuYm9keSk7XG4gIH1cblxuICBnZXREb21haW4oZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjMnLCBkb21haW4sICdzdGF0cy90b3RhbCcpLCBxdWVyeSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlU3RhdHMpO1xuICB9XG5cbiAgZ2V0QWNjb3VudChxdWVyeTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9zdGF0cy90b3RhbCcsIHF1ZXJ5KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VTdGF0cyk7XG4gIH1cbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHsgQm91bmNlRGF0YSwgQ29tcGxhaW50RGF0YSwgVW5zdWJzY3JpYmVEYXRhIH0gZnJvbSAnLi9pbnRlcmZhY2VzL1N1cHJlc3Npb25zJztcblxuY29uc3QgY3JlYXRlT3B0aW9ucyA9IHtcbiAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH1cbn07XG5cbmNsYXNzIEJvdW5jZSB7XG4gIHR5cGU6IHN0cmluZztcbiAgYWRkcmVzczogc3RyaW5nO1xuICBjb2RlOiBudW1iZXI7XG4gIGVycm9yOiBzdHJpbmc7XG4gIGNyZWF0ZWRfYXQ6IERhdGU7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogQm91bmNlRGF0YSkge1xuICAgIHRoaXMudHlwZSA9ICdib3VuY2VzJztcbiAgICB0aGlzLmFkZHJlc3MgPSBkYXRhLmFkZHJlc3M7XG4gICAgdGhpcy5jb2RlID0gK2RhdGEuY29kZTtcbiAgICB0aGlzLmVycm9yID0gZGF0YS5lcnJvcjtcbiAgICB0aGlzLmNyZWF0ZWRfYXQgPSBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRfYXQpO1xuICB9XG59XG5cbmNsYXNzIENvbXBsYWludCB7XG4gIHR5cGU6IHN0cmluZztcbiAgYWRkcmVzczogYW55O1xuICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IENvbXBsYWludERhdGEpIHtcbiAgICB0aGlzLnR5cGUgPSAnY29tcGxhaW50cyc7XG4gICAgdGhpcy5hZGRyZXNzID0gZGF0YS5hZGRyZXNzO1xuICAgIHRoaXMuY3JlYXRlZF9hdCA9IG5ldyBEYXRlKGRhdGEuY3JlYXRlZF9hdCk7XG4gIH1cbn1cblxuY2xhc3MgVW5zdWJzY3JpYmUge1xuICB0eXBlOiBzdHJpbmc7XG4gIGFkZHJlc3M6IHN0cmluZztcbiAgdGFnczogYW55O1xuICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IFVuc3Vic2NyaWJlRGF0YSkge1xuICAgIHRoaXMudHlwZSA9ICd1bnN1YnNjcmliZXMnO1xuICAgIHRoaXMuYWRkcmVzcyA9IGRhdGEuYWRkcmVzcztcbiAgICB0aGlzLnRhZ3MgPSBkYXRhLnRhZ3M7XG4gICAgdGhpcy5jcmVhdGVkX2F0ID0gbmV3IERhdGUoZGF0YS5jcmVhdGVkX2F0KTtcbiAgfVxufVxuXG50eXBlIFRNb2RlbCA9IHR5cGVvZiBCb3VuY2UgfCB0eXBlb2YgQ29tcGxhaW50IHwgdHlwZW9mIFVuc3Vic2NyaWJlO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdXBwcmVzc2lvbkNsaWVudCB7XG4gIHJlcXVlc3Q6IGFueTtcbiAgbW9kZWxzOiB7XG4gICAgYm91bmNlczogdHlwZW9mIEJvdW5jZTtcbiAgICBjb21wbGFpbnRzOiB0eXBlb2YgQ29tcGxhaW50O1xuICAgIHVuc3Vic2NyaWJlczogdHlwZW9mIFVuc3Vic2NyaWJlO1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMubW9kZWxzID0ge1xuICAgICAgYm91bmNlczogQm91bmNlLFxuICAgICAgY29tcGxhaW50czogQ29tcGxhaW50LFxuICAgICAgdW5zdWJzY3JpYmVzOiBVbnN1YnNjcmliZVxuICAgIH07XG4gIH1cblxuICBfcGFyc2VQYWdlKGlkOiBzdHJpbmcsIHBhZ2VVcmw6IHN0cmluZykge1xuICAgIGNvbnN0IHBhcnNlZFVybCA9IHVybC5wYXJzZShwYWdlVXJsLCB0cnVlKTtcbiAgICBjb25zdCB7IHF1ZXJ5IH0gPSBwYXJzZWRVcmw7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQsXG4gICAgICBwYWdlOiBxdWVyeS5wYWdlLFxuICAgICAgYWRkcmVzczogcXVlcnkuYWRkcmVzcyxcbiAgICAgIHVybDogcGFnZVVybFxuICAgIH07XG4gIH1cblxuICBfcGFyc2VQYWdlTGlua3MocmVzcG9uc2U6IHsgYm9keTogeyBwYWdpbmc6IGFueSB9IH0pIHtcbiAgICBjb25zdCBwYWdlcyA9IE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmJvZHkucGFnaW5nKTtcbiAgICByZXR1cm4gcGFnZXMucmVkdWNlKFxuICAgICAgKGFjYzogYW55LCBbaWQsIHBhZ2VVcmxdOiBbcGFnZVVybDogc3RyaW5nLCBpZDogc3RyaW5nXSkgPT4ge1xuICAgICAgICBhY2NbaWRdID0gdGhpcy5fcGFyc2VQYWdlKGlkLCBwYWdlVXJsKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIHt9XG4gICAgKTtcbiAgfVxuXG4gIF9wYXJzZUxpc3QocmVzcG9uc2U6IHsgYm9keTogeyBpdGVtczogYW55LCBwYWdpbmc6IGFueSB9IH0sIE1vZGVsOiBUTW9kZWwpIHtcbiAgICBjb25zdCBkYXRhID0ge30gYXMgYW55O1xuXG4gICAgZGF0YS5pdGVtcyA9IHJlc3BvbnNlLmJvZHkuaXRlbXMubWFwKChkOiBhbnkpID0+IG5ldyBNb2RlbChkKSk7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5fcGFyc2VQYWdlTGlua3MocmVzcG9uc2UpO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBfcGFyc2VJdGVtKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9LCBNb2RlbDogVE1vZGVsKSB7XG4gICAgcmV0dXJuIG5ldyBNb2RlbChyZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIGxpc3QoZG9tYWluOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IG1vZGVsID0gKHRoaXMubW9kZWxzIGFzIGFueSlbdHlwZV07XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAuZ2V0KHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlKSwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogeyBpdGVtczogYW55LCBwYWdpbmc6IGFueSB9IH0pID0+IHRoaXMuX3BhcnNlTGlzdChyZXNwb25zZSwgbW9kZWwpKTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZywgdHlwZTogc3RyaW5nLCBhZGRyZXNzOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtb2RlbCA9ICh0aGlzLm1vZGVscyBhcyBhbnkpW3R5cGVdO1xuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFxuICAgICAgLmdldCh1cmxqb2luKCd2MycsIGRvbWFpbiwgdHlwZSwgZW5jb2RlVVJJQ29tcG9uZW50KGFkZHJlc3MpKSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiBhbnkgfSkgPT4gdGhpcy5fcGFyc2VJdGVtKHJlc3BvbnNlLCBtb2RlbCkpO1xuICB9XG5cbiAgY3JlYXRlKGRvbWFpbjogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIGRhdGE6IGFueSkge1xuICAgIC8vIHN1cHBvcnRzIGFkZGluZyBtdWx0aXBsZSBzdXBwcmVzc2lvbnMgYnkgZGVmYXVsdFxuICAgIGxldCBwb3N0RGF0YTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHBvc3REYXRhID0gW2RhdGFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3N0RGF0YSA9IHsgLi4uZGF0YSB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAgIC5wb3N0KHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlKSwgcG9zdERhdGEsIGNyZWF0ZU9wdGlvbnMpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogYW55IH0pID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgZGVzdHJveShkb21haW46IHN0cmluZywgdHlwZTogc3RyaW5nLCBhZGRyZXNzOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAuZGVsZXRlKHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlLCBlbmNvZGVVUklDb21wb25lbnQoYWRkcmVzcykpKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN1cHByZXNzaW9uQ2xpZW50O1xuIiwiaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmFsaWRhdGVDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgZ2V0KGFkZHJlc3M6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvYWRkcmVzcy92YWxpZGF0ZScsIHsgYWRkcmVzcyB9KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHsgV2ViaG9va0xpc3QsIFdlYmhvb2tSZXNwb25zZSwgV2ViaG9va3NRdWVyeSB9IGZyb20gJy4vaW50ZXJmYWNlcy9XZWJob29rcyc7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5jbGFzcyBXZWJob29rIHtcbiAgaWQ6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgdXJsOiBzdHJpbmcpIHtcbiAgICB0aGlzLmlkID0gaWQ7XG4gICAgdGhpcy51cmwgPSB1cmw7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2ViaG9va0NsaWVudCB7XG4gIHJlcXVlc3Q6IGFueTtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tMaXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgd2ViaG9va3M6IFdlYmhvb2tMaXN0IH0gfSk6IFdlYmhvb2tMaXN0IHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS53ZWJob29rcztcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tXaXRoSUQoaWQ6IHN0cmluZykge1xuICAgIHJldHVybiBmdW5jdGlvbiAocmVzcG9uc2U6IFdlYmhvb2tSZXNwb25zZSk6IFdlYmhvb2sge1xuICAgICAgY29uc3Qgd2ViaG9va1Jlc3BvbnNlID0gcmVzcG9uc2U/LmJvZHk/LndlYmhvb2s7XG4gICAgICBsZXQgdXJsID0gd2ViaG9va1Jlc3BvbnNlPy51cmw7XG4gICAgICBpZiAoIXVybCkge1xuICAgICAgICB1cmwgPSB3ZWJob29rUmVzcG9uc2U/LnVybHMgJiYgd2ViaG9va1Jlc3BvbnNlLnVybHMubGVuZ3RoID8gd2ViaG9va1Jlc3BvbnNlLnVybHNbMF0gOiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBXZWJob29rKGlkLCB1cmwpO1xuICAgIH07XG4gIH1cblxuICBfcGFyc2VXZWJob29rVGVzdChyZXNwb25zZTogeyBib2R5OiB7IGNvZGU6IG51bWJlciwgbWVzc2FnZTogc3RyaW5nIH0gfSlcbiAgOiB7Y29kZTogbnVtYmVyLCBtZXNzYWdlOnN0cmluZ30ge1xuICAgIHJldHVybiB7IGNvZGU6IHJlc3BvbnNlLmJvZHkuY29kZSwgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlIH07XG4gIH1cblxuICBsaXN0KGRvbWFpbjogc3RyaW5nLCBxdWVyeTogV2ViaG9va3NRdWVyeSk6IFByb21pc2U8V2ViaG9va0xpc3Q+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJyksIHF1ZXJ5KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rTGlzdCk7XG4gIH1cblxuICBnZXQoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpOiBQcm9taXNlPFdlYmhvb2s+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJywgaWQpKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rV2l0aElEKGlkKSk7XG4gIH1cblxuICBjcmVhdGUoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcsIHVybDogc3RyaW5nLCB0ZXN0ID0gZmFsc2UpOiBQcm9taXNlPFdlYmhvb2s+IHtcbiAgICBpZiAodGVzdCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkLCAndGVzdCcpLCB7IHVybCB9KVxuICAgICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tUZXN0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycpLCB7IGlkLCB1cmwgfSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG5cbiAgdXBkYXRlKGRvbWFpbjogc3RyaW5nLCBpZDogc3RyaW5nLCB1cmw6IHN0cmluZyk6IFByb21pc2U8V2ViaG9vaz4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucHV0V2l0aEZEKHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAnd2ViaG9va3MnLCBpZCksIHsgdXJsIH0pXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tXaXRoSUQoaWQpKTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpIDogUHJvbWlzZTxXZWJob29rPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG59XG4iLCIvKiEgaHR0cHM6Ly9tdGhzLmJlL2Jhc2U2NCB2MS4wLjAgYnkgQG1hdGhpYXMgfCBNSVQgbGljZW5zZSAqL1xuOyhmdW5jdGlvbihyb290KSB7XG5cblx0Ly8gRGV0ZWN0IGZyZWUgdmFyaWFibGVzIGBleHBvcnRzYC5cblx0dmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cztcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC5cblx0dmFyIGZyZWVNb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJlxuXHRcdG1vZHVsZS5leHBvcnRzID09IGZyZWVFeHBvcnRzICYmIG1vZHVsZTtcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCwgZnJvbSBOb2RlLmpzIG9yIEJyb3dzZXJpZmllZCBjb2RlLCBhbmQgdXNlXG5cdC8vIGl0IGFzIGByb290YC5cblx0dmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcblx0aWYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsKSB7XG5cdFx0cm9vdCA9IGZyZWVHbG9iYWw7XG5cdH1cblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHR2YXIgSW52YWxpZENoYXJhY3RlckVycm9yID0gZnVuY3Rpb24obWVzc2FnZSkge1xuXHRcdHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG5cdH07XG5cdEludmFsaWRDaGFyYWN0ZXJFcnJvci5wcm90b3R5cGUgPSBuZXcgRXJyb3I7XG5cdEludmFsaWRDaGFyYWN0ZXJFcnJvci5wcm90b3R5cGUubmFtZSA9ICdJbnZhbGlkQ2hhcmFjdGVyRXJyb3InO1xuXG5cdHZhciBlcnJvciA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcblx0XHQvLyBOb3RlOiB0aGUgZXJyb3IgbWVzc2FnZXMgdXNlZCB0aHJvdWdob3V0IHRoaXMgZmlsZSBtYXRjaCB0aG9zZSB1c2VkIGJ5XG5cdFx0Ly8gdGhlIG5hdGl2ZSBgYXRvYmAvYGJ0b2FgIGltcGxlbWVudGF0aW9uIGluIENocm9taXVtLlxuXHRcdHRocm93IG5ldyBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IobWVzc2FnZSk7XG5cdH07XG5cblx0dmFyIFRBQkxFID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXHQvLyBodHRwOi8vd2hhdHdnLm9yZy9odG1sL2NvbW1vbi1taWNyb3N5bnRheGVzLmh0bWwjc3BhY2UtY2hhcmFjdGVyXG5cdHZhciBSRUdFWF9TUEFDRV9DSEFSQUNURVJTID0gL1tcXHRcXG5cXGZcXHIgXS9nO1xuXG5cdC8vIGBkZWNvZGVgIGlzIGRlc2lnbmVkIHRvIGJlIGZ1bGx5IGNvbXBhdGlibGUgd2l0aCBgYXRvYmAgYXMgZGVzY3JpYmVkIGluIHRoZVxuXHQvLyBIVE1MIFN0YW5kYXJkLiBodHRwOi8vd2hhdHdnLm9yZy9odG1sL3dlYmFwcGFwaXMuaHRtbCNkb20td2luZG93YmFzZTY0LWF0b2Jcblx0Ly8gVGhlIG9wdGltaXplZCBiYXNlNjQtZGVjb2RpbmcgYWxnb3JpdGhtIHVzZWQgaXMgYmFzZWQgb24gQGF0a+KAmXMgZXhjZWxsZW50XG5cdC8vIGltcGxlbWVudGF0aW9uLiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9hdGsvMTAyMDM5NlxuXHR2YXIgZGVjb2RlID0gZnVuY3Rpb24oaW5wdXQpIHtcblx0XHRpbnB1dCA9IFN0cmluZyhpbnB1dClcblx0XHRcdC5yZXBsYWNlKFJFR0VYX1NQQUNFX0NIQVJBQ1RFUlMsICcnKTtcblx0XHR2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXHRcdGlmIChsZW5ndGggJSA0ID09IDApIHtcblx0XHRcdGlucHV0ID0gaW5wdXQucmVwbGFjZSgvPT0/JC8sICcnKTtcblx0XHRcdGxlbmd0aCA9IGlucHV0Lmxlbmd0aDtcblx0XHR9XG5cdFx0aWYgKFxuXHRcdFx0bGVuZ3RoICUgNCA9PSAxIHx8XG5cdFx0XHQvLyBodHRwOi8vd2hhdHdnLm9yZy9DI2FscGhhbnVtZXJpYy1hc2NpaS1jaGFyYWN0ZXJzXG5cdFx0XHQvW14rYS16QS1aMC05L10vLnRlc3QoaW5wdXQpXG5cdFx0KSB7XG5cdFx0XHRlcnJvcihcblx0XHRcdFx0J0ludmFsaWQgY2hhcmFjdGVyOiB0aGUgc3RyaW5nIHRvIGJlIGRlY29kZWQgaXMgbm90IGNvcnJlY3RseSBlbmNvZGVkLidcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHZhciBiaXRDb3VudGVyID0gMDtcblx0XHR2YXIgYml0U3RvcmFnZTtcblx0XHR2YXIgYnVmZmVyO1xuXHRcdHZhciBvdXRwdXQgPSAnJztcblx0XHR2YXIgcG9zaXRpb24gPSAtMTtcblx0XHR3aGlsZSAoKytwb3NpdGlvbiA8IGxlbmd0aCkge1xuXHRcdFx0YnVmZmVyID0gVEFCTEUuaW5kZXhPZihpbnB1dC5jaGFyQXQocG9zaXRpb24pKTtcblx0XHRcdGJpdFN0b3JhZ2UgPSBiaXRDb3VudGVyICUgNCA/IGJpdFN0b3JhZ2UgKiA2NCArIGJ1ZmZlciA6IGJ1ZmZlcjtcblx0XHRcdC8vIFVubGVzcyB0aGlzIGlzIHRoZSBmaXJzdCBvZiBhIGdyb3VwIG9mIDQgY2hhcmFjdGVyc+KAplxuXHRcdFx0aWYgKGJpdENvdW50ZXIrKyAlIDQpIHtcblx0XHRcdFx0Ly8g4oCmY29udmVydCB0aGUgZmlyc3QgOCBiaXRzIHRvIGEgc2luZ2xlIEFTQ0lJIGNoYXJhY3Rlci5cblx0XHRcdFx0b3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG5cdFx0XHRcdFx0MHhGRiAmIGJpdFN0b3JhZ2UgPj4gKC0yICogYml0Q291bnRlciAmIDYpXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH07XG5cblx0Ly8gYGVuY29kZWAgaXMgZGVzaWduZWQgdG8gYmUgZnVsbHkgY29tcGF0aWJsZSB3aXRoIGBidG9hYCBhcyBkZXNjcmliZWQgaW4gdGhlXG5cdC8vIEhUTUwgU3RhbmRhcmQ6IGh0dHA6Ly93aGF0d2cub3JnL2h0bWwvd2ViYXBwYXBpcy5odG1sI2RvbS13aW5kb3diYXNlNjQtYnRvYVxuXHR2YXIgZW5jb2RlID0gZnVuY3Rpb24oaW5wdXQpIHtcblx0XHRpbnB1dCA9IFN0cmluZyhpbnB1dCk7XG5cdFx0aWYgKC9bXlxcMC1cXHhGRl0vLnRlc3QoaW5wdXQpKSB7XG5cdFx0XHQvLyBOb3RlOiBubyBuZWVkIHRvIHNwZWNpYWwtY2FzZSBhc3RyYWwgc3ltYm9scyBoZXJlLCBhcyBzdXJyb2dhdGVzIGFyZVxuXHRcdFx0Ly8gbWF0Y2hlZCwgYW5kIHRoZSBpbnB1dCBpcyBzdXBwb3NlZCB0byBvbmx5IGNvbnRhaW4gQVNDSUkgYW55d2F5LlxuXHRcdFx0ZXJyb3IoXG5cdFx0XHRcdCdUaGUgc3RyaW5nIHRvIGJlIGVuY29kZWQgY29udGFpbnMgY2hhcmFjdGVycyBvdXRzaWRlIG9mIHRoZSAnICtcblx0XHRcdFx0J0xhdGluMSByYW5nZS4nXG5cdFx0XHQpO1xuXHRcdH1cblx0XHR2YXIgcGFkZGluZyA9IGlucHV0Lmxlbmd0aCAlIDM7XG5cdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdHZhciBwb3NpdGlvbiA9IC0xO1xuXHRcdHZhciBhO1xuXHRcdHZhciBiO1xuXHRcdHZhciBjO1xuXHRcdHZhciBidWZmZXI7XG5cdFx0Ly8gTWFrZSBzdXJlIGFueSBwYWRkaW5nIGlzIGhhbmRsZWQgb3V0c2lkZSBvZiB0aGUgbG9vcC5cblx0XHR2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoIC0gcGFkZGluZztcblxuXHRcdHdoaWxlICgrK3Bvc2l0aW9uIDwgbGVuZ3RoKSB7XG5cdFx0XHQvLyBSZWFkIHRocmVlIGJ5dGVzLCBpLmUuIDI0IGJpdHMuXG5cdFx0XHRhID0gaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbikgPDwgMTY7XG5cdFx0XHRiID0gaW5wdXQuY2hhckNvZGVBdCgrK3Bvc2l0aW9uKSA8PCA4O1xuXHRcdFx0YyA9IGlucHV0LmNoYXJDb2RlQXQoKytwb3NpdGlvbik7XG5cdFx0XHRidWZmZXIgPSBhICsgYiArIGM7XG5cdFx0XHQvLyBUdXJuIHRoZSAyNCBiaXRzIGludG8gZm91ciBjaHVua3Mgb2YgNiBiaXRzIGVhY2gsIGFuZCBhcHBlbmQgdGhlXG5cdFx0XHQvLyBtYXRjaGluZyBjaGFyYWN0ZXIgZm9yIGVhY2ggb2YgdGhlbSB0byB0aGUgb3V0cHV0LlxuXHRcdFx0b3V0cHV0ICs9IChcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxOCAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxMiAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiA2ICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyICYgMHgzRilcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0aWYgKHBhZGRpbmcgPT0gMikge1xuXHRcdFx0YSA9IGlucHV0LmNoYXJDb2RlQXQocG9zaXRpb24pIDw8IDg7XG5cdFx0XHRiID0gaW5wdXQuY2hhckNvZGVBdCgrK3Bvc2l0aW9uKTtcblx0XHRcdGJ1ZmZlciA9IGEgKyBiO1xuXHRcdFx0b3V0cHV0ICs9IChcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxMCkgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoKGJ1ZmZlciA+PiA0KSAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KChidWZmZXIgPDwgMikgJiAweDNGKSArXG5cdFx0XHRcdCc9J1xuXHRcdFx0KTtcblx0XHR9IGVsc2UgaWYgKHBhZGRpbmcgPT0gMSkge1xuXHRcdFx0YnVmZmVyID0gaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbik7XG5cdFx0XHRvdXRwdXQgKz0gKFxuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDIpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KChidWZmZXIgPDwgNCkgJiAweDNGKSArXG5cdFx0XHRcdCc9PSdcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fTtcblxuXHR2YXIgYmFzZTY0ID0ge1xuXHRcdCdlbmNvZGUnOiBlbmNvZGUsXG5cdFx0J2RlY29kZSc6IGRlY29kZSxcblx0XHQndmVyc2lvbic6ICcxLjAuMCdcblx0fTtcblxuXHQvLyBTb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBzcGVjaWZpYyBjb25kaXRpb24gcGF0dGVybnNcblx0Ly8gbGlrZSB0aGUgZm9sbG93aW5nOlxuXHRpZiAoXG5cdFx0dHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiZcblx0XHRkZWZpbmUuYW1kXG5cdCkge1xuXHRcdGRlZmluZShmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBiYXNlNjQ7XG5cdFx0fSk7XG5cdH1cdGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmICFmcmVlRXhwb3J0cy5ub2RlVHlwZSkge1xuXHRcdGlmIChmcmVlTW9kdWxlKSB7IC8vIGluIE5vZGUuanMgb3IgUmluZ29KUyB2MC44LjArXG5cdFx0XHRmcmVlTW9kdWxlLmV4cG9ydHMgPSBiYXNlNjQ7XG5cdFx0fSBlbHNlIHsgLy8gaW4gTmFyd2hhbCBvciBSaW5nb0pTIHYwLjcuMC1cblx0XHRcdGZvciAodmFyIGtleSBpbiBiYXNlNjQpIHtcblx0XHRcdFx0YmFzZTY0Lmhhc093blByb3BlcnR5KGtleSkgJiYgKGZyZWVFeHBvcnRzW2tleV0gPSBiYXNlNjRba2V5XSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgeyAvLyBpbiBSaGlubyBvciBhIHdlYiBicm93c2VyXG5cdFx0cm9vdC5iYXNlNjQgPSBiYXNlNjQ7XG5cdH1cblxufSh0aGlzKSk7XG4iLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogUmV0dXJucyBhIGBCdWZmZXJgIGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIGRhdGEgVVJJIGB1cmlgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmkgRGF0YSBVUkkgdG8gdHVybiBpbnRvIGEgQnVmZmVyIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtCdWZmZXJ9IEJ1ZmZlciBpbnN0YW5jZSBmcm9tIERhdGEgVVJJXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBkYXRhVXJpVG9CdWZmZXIodXJpKSB7XG4gICAgaWYgKCEvXmRhdGE6L2kudGVzdCh1cmkpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2B1cmlgIGRvZXMgbm90IGFwcGVhciB0byBiZSBhIERhdGEgVVJJIChtdXN0IGJlZ2luIHdpdGggXCJkYXRhOlwiKScpO1xuICAgIH1cbiAgICAvLyBzdHJpcCBuZXdsaW5lc1xuICAgIHVyaSA9IHVyaS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKTtcbiAgICAvLyBzcGxpdCB0aGUgVVJJIHVwIGludG8gdGhlIFwibWV0YWRhdGFcIiBhbmQgdGhlIFwiZGF0YVwiIHBvcnRpb25zXG4gICAgY29uc3QgZmlyc3RDb21tYSA9IHVyaS5pbmRleE9mKCcsJyk7XG4gICAgaWYgKGZpcnN0Q29tbWEgPT09IC0xIHx8IGZpcnN0Q29tbWEgPD0gNCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtYWxmb3JtZWQgZGF0YTogVVJJJyk7XG4gICAgfVxuICAgIC8vIHJlbW92ZSB0aGUgXCJkYXRhOlwiIHNjaGVtZSBhbmQgcGFyc2UgdGhlIG1ldGFkYXRhXG4gICAgY29uc3QgbWV0YSA9IHVyaS5zdWJzdHJpbmcoNSwgZmlyc3RDb21tYSkuc3BsaXQoJzsnKTtcbiAgICBsZXQgY2hhcnNldCA9ICcnO1xuICAgIGxldCBiYXNlNjQgPSBmYWxzZTtcbiAgICBjb25zdCB0eXBlID0gbWV0YVswXSB8fCAndGV4dC9wbGFpbic7XG4gICAgbGV0IHR5cGVGdWxsID0gdHlwZTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IG1ldGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKG1ldGFbaV0gPT09ICdiYXNlNjQnKSB7XG4gICAgICAgICAgICBiYXNlNjQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdHlwZUZ1bGwgKz0gYDske21ldGFbaV19YDtcbiAgICAgICAgICAgIGlmIChtZXRhW2ldLmluZGV4T2YoJ2NoYXJzZXQ9JykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBjaGFyc2V0ID0gbWV0YVtpXS5zdWJzdHJpbmcoOCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gZGVmYXVsdHMgdG8gVVMtQVNDSUkgb25seSBpZiB0eXBlIGlzIG5vdCBwcm92aWRlZFxuICAgIGlmICghbWV0YVswXSAmJiAhY2hhcnNldC5sZW5ndGgpIHtcbiAgICAgICAgdHlwZUZ1bGwgKz0gJztjaGFyc2V0PVVTLUFTQ0lJJztcbiAgICAgICAgY2hhcnNldCA9ICdVUy1BU0NJSSc7XG4gICAgfVxuICAgIC8vIGdldCB0aGUgZW5jb2RlZCBkYXRhIHBvcnRpb24gYW5kIGRlY29kZSBVUkktZW5jb2RlZCBjaGFyc1xuICAgIGNvbnN0IGVuY29kaW5nID0gYmFzZTY0ID8gJ2Jhc2U2NCcgOiAnYXNjaWknO1xuICAgIGNvbnN0IGRhdGEgPSB1bmVzY2FwZSh1cmkuc3Vic3RyaW5nKGZpcnN0Q29tbWEgKyAxKSk7XG4gICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oZGF0YSwgZW5jb2RpbmcpO1xuICAgIC8vIHNldCBgLnR5cGVgIGFuZCBgLnR5cGVGdWxsYCBwcm9wZXJ0aWVzIHRvIE1JTUUgdHlwZVxuICAgIGJ1ZmZlci50eXBlID0gdHlwZTtcbiAgICBidWZmZXIudHlwZUZ1bGwgPSB0eXBlRnVsbDtcbiAgICAvLyBzZXQgdGhlIGAuY2hhcnNldGAgcHJvcGVydHlcbiAgICBidWZmZXIuY2hhcnNldCA9IGNoYXJzZXQ7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbn1cbm1vZHVsZS5leHBvcnRzID0gZGF0YVVyaVRvQnVmZmVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiLyoqXG4gKiBAYXV0aG9yIFRvcnUgTmFnYXNoaW1hIDxodHRwczovL2dpdGh1Yi5jb20vbXlzdGljYXRlYT5cbiAqIEBjb3B5cmlnaHQgMjAxNSBUb3J1IE5hZ2FzaGltYS4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBkaXJlY3RvcnkgZm9yIGZ1bGwgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFByaXZhdGVEYXRhXG4gKiBAcHJvcGVydHkge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0LlxuICogQHByb3BlcnR5IHt7dHlwZTpzdHJpbmd9fSBldmVudCBUaGUgb3JpZ2luYWwgZXZlbnQgb2JqZWN0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGV2ZW50UGhhc2UgVGhlIGN1cnJlbnQgZXZlbnQgcGhhc2UuXG4gKiBAcHJvcGVydHkge0V2ZW50VGFyZ2V0fG51bGx9IGN1cnJlbnRUYXJnZXQgVGhlIGN1cnJlbnQgZXZlbnQgdGFyZ2V0LlxuICogQHByb3BlcnR5IHtib29sZWFufSBjYW5jZWxlZCBUaGUgZmxhZyB0byBwcmV2ZW50IGRlZmF1bHQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHN0b3BwZWQgVGhlIGZsYWcgdG8gc3RvcCBwcm9wYWdhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gaW1tZWRpYXRlU3RvcHBlZCBUaGUgZmxhZyB0byBzdG9wIHByb3BhZ2F0aW9uIGltbWVkaWF0ZWx5LlxuICogQHByb3BlcnR5IHtGdW5jdGlvbnxudWxsfSBwYXNzaXZlTGlzdGVuZXIgVGhlIGxpc3RlbmVyIGlmIHRoZSBjdXJyZW50IGxpc3RlbmVyIGlzIHBhc3NpdmUuIE90aGVyd2lzZSB0aGlzIGlzIG51bGwuXG4gKiBAcHJvcGVydHkge251bWJlcn0gdGltZVN0YW1wIFRoZSB1bml4IHRpbWUuXG4gKiBAcHJpdmF0ZVxuICovXG5cbi8qKlxuICogUHJpdmF0ZSBkYXRhIGZvciBldmVudCB3cmFwcGVycy5cbiAqIEB0eXBlIHtXZWFrTWFwPEV2ZW50LCBQcml2YXRlRGF0YT59XG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBwcml2YXRlRGF0YSA9IG5ldyBXZWFrTWFwKCk7XG5cbi8qKlxuICogQ2FjaGUgZm9yIHdyYXBwZXIgY2xhc3Nlcy5cbiAqIEB0eXBlIHtXZWFrTWFwPE9iamVjdCwgRnVuY3Rpb24+fVxuICogQHByaXZhdGVcbiAqL1xuY29uc3Qgd3JhcHBlcnMgPSBuZXcgV2Vha01hcCgpO1xuXG4vKipcbiAqIEdldCBwcml2YXRlIGRhdGEuXG4gKiBAcGFyYW0ge0V2ZW50fSBldmVudCBUaGUgZXZlbnQgb2JqZWN0IHRvIGdldCBwcml2YXRlIGRhdGEuXG4gKiBAcmV0dXJucyB7UHJpdmF0ZURhdGF9IFRoZSBwcml2YXRlIGRhdGEgb2YgdGhlIGV2ZW50LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcGQoZXZlbnQpIHtcbiAgICBjb25zdCByZXR2ID0gcHJpdmF0ZURhdGEuZ2V0KGV2ZW50KTtcbiAgICBjb25zb2xlLmFzc2VydChcbiAgICAgICAgcmV0diAhPSBudWxsLFxuICAgICAgICBcIid0aGlzJyBpcyBleHBlY3RlZCBhbiBFdmVudCBvYmplY3QsIGJ1dCBnb3RcIixcbiAgICAgICAgZXZlbnRcbiAgICApO1xuICAgIHJldHVybiByZXR2XG59XG5cbi8qKlxuICogaHR0cHM6Ly9kb20uc3BlYy53aGF0d2cub3JnLyNzZXQtdGhlLWNhbmNlbGVkLWZsYWdcbiAqIEBwYXJhbSBkYXRhIHtQcml2YXRlRGF0YX0gcHJpdmF0ZSBkYXRhLlxuICovXG5mdW5jdGlvbiBzZXRDYW5jZWxGbGFnKGRhdGEpIHtcbiAgICBpZiAoZGF0YS5wYXNzaXZlTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUuZXJyb3IgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgXCJVbmFibGUgdG8gcHJldmVudERlZmF1bHQgaW5zaWRlIHBhc3NpdmUgZXZlbnQgbGlzdGVuZXIgaW52b2NhdGlvbi5cIixcbiAgICAgICAgICAgICAgICBkYXRhLnBhc3NpdmVMaXN0ZW5lclxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCFkYXRhLmV2ZW50LmNhbmNlbGFibGUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgZGF0YS5jYW5jZWxlZCA9IHRydWU7XG4gICAgaWYgKHR5cGVvZiBkYXRhLmV2ZW50LnByZXZlbnREZWZhdWx0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgZGF0YS5ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZG9tLnNwZWMud2hhdHdnLm9yZy8jaW50ZXJmYWNlLWV2ZW50XG4gKiBAcHJpdmF0ZVxuICovXG4vKipcbiAqIFRoZSBldmVudCB3cmFwcGVyLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0IG9mIHRoaXMgZGlzcGF0Y2hpbmcuXG4gKiBAcGFyYW0ge0V2ZW50fHt0eXBlOnN0cmluZ319IGV2ZW50IFRoZSBvcmlnaW5hbCBldmVudCB0byB3cmFwLlxuICovXG5mdW5jdGlvbiBFdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICBwcml2YXRlRGF0YS5zZXQodGhpcywge1xuICAgICAgICBldmVudFRhcmdldCxcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIGV2ZW50UGhhc2U6IDIsXG4gICAgICAgIGN1cnJlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxuICAgICAgICBjYW5jZWxlZDogZmFsc2UsXG4gICAgICAgIHN0b3BwZWQ6IGZhbHNlLFxuICAgICAgICBpbW1lZGlhdGVTdG9wcGVkOiBmYWxzZSxcbiAgICAgICAgcGFzc2l2ZUxpc3RlbmVyOiBudWxsLFxuICAgICAgICB0aW1lU3RhbXA6IGV2ZW50LnRpbWVTdGFtcCB8fCBEYXRlLm5vdygpLFxuICAgIH0pO1xuXG4gICAgLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jVW5mb3JnZWFibGVcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJpc1RydXN0ZWRcIiwgeyB2YWx1ZTogZmFsc2UsIGVudW1lcmFibGU6IHRydWUgfSk7XG5cbiAgICAvLyBEZWZpbmUgYWNjZXNzb3JzXG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGV2ZW50KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgaWYgKCEoa2V5IGluIHRoaXMpKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCBkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3Ioa2V5KSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIFNob3VsZCBiZSBlbnVtZXJhYmxlLCBidXQgY2xhc3MgbWV0aG9kcyBhcmUgbm90IGVudW1lcmFibGUuXG5FdmVudC5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuZXZlbnQudHlwZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdGFyZ2V0IG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge0V2ZW50VGFyZ2V0fVxuICAgICAqL1xuICAgIGdldCB0YXJnZXQoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5ldmVudFRhcmdldFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdGFyZ2V0IG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge0V2ZW50VGFyZ2V0fVxuICAgICAqL1xuICAgIGdldCBjdXJyZW50VGFyZ2V0KCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuY3VycmVudFRhcmdldFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7RXZlbnRUYXJnZXRbXX0gVGhlIGNvbXBvc2VkIHBhdGggb2YgdGhpcyBldmVudC5cbiAgICAgKi9cbiAgICBjb21wb3NlZFBhdGgoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUYXJnZXQgPSBwZCh0aGlzKS5jdXJyZW50VGFyZ2V0O1xuICAgICAgICBpZiAoY3VycmVudFRhcmdldCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gW11cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2N1cnJlbnRUYXJnZXRdXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENvbnN0YW50IG9mIE5PTkUuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgTk9ORSgpIHtcbiAgICAgICAgcmV0dXJuIDBcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQ0FQVFVSSU5HX1BIQVNFLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0IENBUFRVUklOR19QSEFTRSgpIHtcbiAgICAgICAgcmV0dXJuIDFcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQVRfVEFSR0VULlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0IEFUX1RBUkdFVCgpIHtcbiAgICAgICAgcmV0dXJuIDJcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQlVCQkxJTkdfUEhBU0UuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgQlVCQkxJTkdfUEhBU0UoKSB7XG4gICAgICAgIHJldHVybiAzXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldCBldmVudFBoYXNlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuZXZlbnRQaGFzZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTdG9wIGV2ZW50IGJ1YmJsaW5nLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHN0b3BQcm9wYWdhdGlvbigpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHBkKHRoaXMpO1xuXG4gICAgICAgIGRhdGEuc3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YS5ldmVudC5zdG9wUHJvcGFnYXRpb24gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgZGF0YS5ldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTdG9wIGV2ZW50IGJ1YmJsaW5nLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHBkKHRoaXMpO1xuXG4gICAgICAgIGRhdGEuc3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGRhdGEuaW1tZWRpYXRlU3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YS5ldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgZGF0YS5ldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBiZSBidWJibGluZy5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgYnViYmxlcygpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4ocGQodGhpcykuZXZlbnQuYnViYmxlcylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIGZsYWcgdG8gYmUgY2FuY2VsYWJsZS5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgY2FuY2VsYWJsZSgpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4ocGQodGhpcykuZXZlbnQuY2FuY2VsYWJsZSlcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2FuY2VsIHRoaXMgZXZlbnQuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIHNldENhbmNlbEZsYWcocGQodGhpcykpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBpbmRpY2F0ZSBjYW5jZWxsYXRpb24gc3RhdGUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRQcmV2ZW50ZWQoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5jYW5jZWxlZFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBiZSBjb21wb3NlZC5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgY29tcG9zZWQoKSB7XG4gICAgICAgIHJldHVybiBCb29sZWFuKHBkKHRoaXMpLmV2ZW50LmNvbXBvc2VkKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdW5peCB0aW1lIG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgdGltZVN0YW1wKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykudGltZVN0YW1wXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7RXZlbnRUYXJnZXR9XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgc3JjRWxlbWVudCgpIHtcbiAgICAgICAgcmV0dXJuIHBkKHRoaXMpLmV2ZW50VGFyZ2V0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBmbGFnIHRvIHN0b3AgZXZlbnQgYnViYmxpbmcuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgY2FuY2VsQnViYmxlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuc3RvcHBlZFxuICAgIH0sXG4gICAgc2V0IGNhbmNlbEJ1YmJsZSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhID0gcGQodGhpcyk7XG5cbiAgICAgICAgZGF0YS5zdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhLmV2ZW50LmNhbmNlbEJ1YmJsZSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgICAgIGRhdGEuZXZlbnQuY2FuY2VsQnViYmxlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBpbmRpY2F0ZSBjYW5jZWxsYXRpb24gc3RhdGUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgcmV0dXJuVmFsdWUoKSB7XG4gICAgICAgIHJldHVybiAhcGQodGhpcykuY2FuY2VsZWRcbiAgICB9LFxuICAgIHNldCByZXR1cm5WYWx1ZSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICBzZXRDYW5jZWxGbGFnKHBkKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIHRoaXMgZXZlbnQgb2JqZWN0LiBCdXQgZG8gbm90aGluZyB1bmRlciBldmVudCBkaXNwYXRjaGluZy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtidWJibGVzPWZhbHNlXSBUaGUgZmxhZyB0byBiZSBwb3NzaWJsZSB0byBidWJibGUgdXAuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY2FuY2VsYWJsZT1mYWxzZV0gVGhlIGZsYWcgdG8gYmUgcG9zc2libGUgdG8gY2FuY2VsLlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgaW5pdEV2ZW50KCkge1xuICAgICAgICAvLyBEbyBub3RoaW5nLlxuICAgIH0sXG59O1xuXG4vLyBgY29uc3RydWN0b3JgIGlzIG5vdCBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50LnByb3RvdHlwZSwgXCJjb25zdHJ1Y3RvclwiLCB7XG4gICAgdmFsdWU6IEV2ZW50LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB3cml0YWJsZTogdHJ1ZSxcbn0pO1xuXG4vLyBFbnN1cmUgYGV2ZW50IGluc3RhbmNlb2Ygd2luZG93LkV2ZW50YCBpcyBgdHJ1ZWAuXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB0eXBlb2Ygd2luZG93LkV2ZW50ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEV2ZW50LnByb3RvdHlwZSwgd2luZG93LkV2ZW50LnByb3RvdHlwZSk7XG5cbiAgICAvLyBNYWtlIGFzc29jaWF0aW9uIGZvciB3cmFwcGVycy5cbiAgICB3cmFwcGVycy5zZXQod2luZG93LkV2ZW50LnByb3RvdHlwZSwgRXZlbnQpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgcHJvcGVydHkgZGVzY3JpcHRvciB0byByZWRpcmVjdCBhIGdpdmVuIHByb3BlcnR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBQcm9wZXJ0eSBuYW1lIHRvIGRlZmluZSBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICogQHJldHVybnMge1Byb3BlcnR5RGVzY3JpcHRvcn0gVGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgdG8gcmVkaXJlY3QgdGhlIHByb3BlcnR5LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lUmVkaXJlY3REZXNjcmlwdG9yKGtleSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgIHJldHVybiBwZCh0aGlzKS5ldmVudFtrZXldXG4gICAgICAgIH0sXG4gICAgICAgIHNldCh2YWx1ZSkge1xuICAgICAgICAgICAgcGQodGhpcykuZXZlbnRba2V5XSA9IHZhbHVlO1xuICAgICAgICB9LFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgcHJvcGVydHkgZGVzY3JpcHRvciB0byBjYWxsIGEgZ2l2ZW4gbWV0aG9kIHByb3BlcnR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBQcm9wZXJ0eSBuYW1lIHRvIGRlZmluZSBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICogQHJldHVybnMge1Byb3BlcnR5RGVzY3JpcHRvcn0gVGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgdG8gY2FsbCB0aGUgbWV0aG9kIHByb3BlcnR5LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lQ2FsbERlc2NyaXB0b3Ioa2V5KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWUoKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHBkKHRoaXMpLmV2ZW50O1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50W2tleV0uYXBwbHkoZXZlbnQsIGFyZ3VtZW50cylcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIH1cbn1cblxuLyoqXG4gKiBEZWZpbmUgbmV3IHdyYXBwZXIgY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBCYXNlRXZlbnQgVGhlIGJhc2Ugd3JhcHBlciBjbGFzcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90byBUaGUgcHJvdG90eXBlIG9mIHRoZSBvcmlnaW5hbCBldmVudC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gVGhlIGRlZmluZWQgd3JhcHBlciBjbGFzcy5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZVdyYXBwZXIoQmFzZUV2ZW50LCBwcm90bykge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhwcm90byk7XG4gICAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCYXNlRXZlbnRcbiAgICB9XG5cbiAgICAvKiogQ3VzdG9tRXZlbnQgKi9cbiAgICBmdW5jdGlvbiBDdXN0b21FdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICAgICAgQmFzZUV2ZW50LmNhbGwodGhpcywgZXZlbnRUYXJnZXQsIGV2ZW50KTtcbiAgICB9XG5cbiAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VFdmVudC5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHsgdmFsdWU6IEN1c3RvbUV2ZW50LCBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlIH0sXG4gICAgfSk7XG5cbiAgICAvLyBEZWZpbmUgYWNjZXNzb3JzLlxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICBjb25zdCBrZXkgPSBrZXlzW2ldO1xuICAgICAgICBpZiAoIShrZXkgaW4gQmFzZUV2ZW50LnByb3RvdHlwZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3RvLCBrZXkpO1xuICAgICAgICAgICAgY29uc3QgaXNGdW5jID0gdHlwZW9mIGRlc2NyaXB0b3IudmFsdWUgPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcbiAgICAgICAgICAgICAgICBDdXN0b21FdmVudC5wcm90b3R5cGUsXG4gICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgIGlzRnVuY1xuICAgICAgICAgICAgICAgICAgICA/IGRlZmluZUNhbGxEZXNjcmlwdG9yKGtleSlcbiAgICAgICAgICAgICAgICAgICAgOiBkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3Ioa2V5KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBDdXN0b21FdmVudFxufVxuXG4vKipcbiAqIEdldCB0aGUgd3JhcHBlciBjbGFzcyBvZiBhIGdpdmVuIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90byBUaGUgcHJvdG90eXBlIG9mIHRoZSBvcmlnaW5hbCBldmVudCB0byBnZXQgaXRzIHdyYXBwZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFRoZSB3cmFwcGVyIGNsYXNzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0V3JhcHBlcihwcm90bykge1xuICAgIGlmIChwcm90byA9PSBudWxsIHx8IHByb3RvID09PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgICAgIHJldHVybiBFdmVudFxuICAgIH1cblxuICAgIGxldCB3cmFwcGVyID0gd3JhcHBlcnMuZ2V0KHByb3RvKTtcbiAgICBpZiAod3JhcHBlciA9PSBudWxsKSB7XG4gICAgICAgIHdyYXBwZXIgPSBkZWZpbmVXcmFwcGVyKGdldFdyYXBwZXIoT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKSksIHByb3RvKTtcbiAgICAgICAgd3JhcHBlcnMuc2V0KHByb3RvLCB3cmFwcGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIHdyYXBwZXJcbn1cblxuLyoqXG4gKiBXcmFwIGEgZ2l2ZW4gZXZlbnQgdG8gbWFuYWdlbWVudCBhIGRpc3BhdGNoaW5nLlxuICogQHBhcmFtIHtFdmVudFRhcmdldH0gZXZlbnRUYXJnZXQgVGhlIGV2ZW50IHRhcmdldCBvZiB0aGlzIGRpc3BhdGNoaW5nLlxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFRoZSBldmVudCB0byB3cmFwLlxuICogQHJldHVybnMge0V2ZW50fSBUaGUgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHdyYXBFdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICBjb25zdCBXcmFwcGVyID0gZ2V0V3JhcHBlcihPYmplY3QuZ2V0UHJvdG90eXBlT2YoZXZlbnQpKTtcbiAgICByZXR1cm4gbmV3IFdyYXBwZXIoZXZlbnRUYXJnZXQsIGV2ZW50KVxufVxuXG4vKipcbiAqIEdldCB0aGUgaW1tZWRpYXRlU3RvcHBlZCBmbGFnIG9mIGEgZ2l2ZW4gZXZlbnQuXG4gKiBAcGFyYW0ge0V2ZW50fSBldmVudCBUaGUgZXZlbnQgdG8gZ2V0LlxuICogQHJldHVybnMge2Jvb2xlYW59IFRoZSBmbGFnIHRvIHN0b3AgcHJvcGFnYXRpb24gaW1tZWRpYXRlbHkuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBpc1N0b3BwZWQoZXZlbnQpIHtcbiAgICByZXR1cm4gcGQoZXZlbnQpLmltbWVkaWF0ZVN0b3BwZWRcbn1cblxuLyoqXG4gKiBTZXQgdGhlIGN1cnJlbnQgZXZlbnQgcGhhc2Ugb2YgYSBnaXZlbiBldmVudC5cbiAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IFRoZSBldmVudCB0byBzZXQgY3VycmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZXZlbnRQaGFzZSBOZXcgZXZlbnQgcGhhc2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNldEV2ZW50UGhhc2UoZXZlbnQsIGV2ZW50UGhhc2UpIHtcbiAgICBwZChldmVudCkuZXZlbnRQaGFzZSA9IGV2ZW50UGhhc2U7XG59XG5cbi8qKlxuICogU2V0IHRoZSBjdXJyZW50IHRhcmdldCBvZiBhIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIHNldCBjdXJyZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8bnVsbH0gY3VycmVudFRhcmdldCBOZXcgY3VycmVudCB0YXJnZXQuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNldEN1cnJlbnRUYXJnZXQoZXZlbnQsIGN1cnJlbnRUYXJnZXQpIHtcbiAgICBwZChldmVudCkuY3VycmVudFRhcmdldCA9IGN1cnJlbnRUYXJnZXQ7XG59XG5cbi8qKlxuICogU2V0IGEgcGFzc2l2ZSBsaXN0ZW5lciBvZiBhIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIHNldCBjdXJyZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gcGFzc2l2ZUxpc3RlbmVyIE5ldyBwYXNzaXZlIGxpc3RlbmVyLlxuICogQHJldHVybnMge3ZvaWR9XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzZXRQYXNzaXZlTGlzdGVuZXIoZXZlbnQsIHBhc3NpdmVMaXN0ZW5lcikge1xuICAgIHBkKGV2ZW50KS5wYXNzaXZlTGlzdGVuZXIgPSBwYXNzaXZlTGlzdGVuZXI7XG59XG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gTGlzdGVuZXJOb2RlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBsaXN0ZW5lclxuICogQHByb3BlcnR5IHsxfDJ8M30gbGlzdGVuZXJUeXBlXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHBhc3NpdmVcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gb25jZVxuICogQHByb3BlcnR5IHtMaXN0ZW5lck5vZGV8bnVsbH0gbmV4dFxuICogQHByaXZhdGVcbiAqL1xuXG4vKipcbiAqIEB0eXBlIHtXZWFrTWFwPG9iamVjdCwgTWFwPHN0cmluZywgTGlzdGVuZXJOb2RlPj59XG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBsaXN0ZW5lcnNNYXAgPSBuZXcgV2Vha01hcCgpO1xuXG4vLyBMaXN0ZW5lciB0eXBlc1xuY29uc3QgQ0FQVFVSRSA9IDE7XG5jb25zdCBCVUJCTEUgPSAyO1xuY29uc3QgQVRUUklCVVRFID0gMztcblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gdmFsdWUgaXMgYW4gb2JqZWN0IG9yIG5vdC5cbiAqIEBwYXJhbSB7YW55fSB4IFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGFuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QoeCkge1xuICAgIHJldHVybiB4ICE9PSBudWxsICYmIHR5cGVvZiB4ID09PSBcIm9iamVjdFwiIC8vZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxufVxuXG4vKipcbiAqIEdldCBsaXN0ZW5lcnMuXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0IHRvIGdldC5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBMaXN0ZW5lck5vZGU+fSBUaGUgbGlzdGVuZXJzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2ZW50VGFyZ2V0KSB7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gbGlzdGVuZXJzTWFwLmdldChldmVudFRhcmdldCk7XG4gICAgaWYgKGxpc3RlbmVycyA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBcIid0aGlzJyBpcyBleHBlY3RlZCBhbiBFdmVudFRhcmdldCBvYmplY3QsIGJ1dCBnb3QgYW5vdGhlciB2YWx1ZS5cIlxuICAgICAgICApXG4gICAgfVxuICAgIHJldHVybiBsaXN0ZW5lcnNcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yIHRoZSBldmVudCBhdHRyaWJ1dGUgb2YgYSBnaXZlbiBldmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gZ2V0IHByb3BlcnR5IGRlc2NyaXB0b3IuXG4gKiBAcmV0dXJucyB7UHJvcGVydHlEZXNjcmlwdG9yfSBUaGUgcHJvcGVydHkgZGVzY3JpcHRvci5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvcihldmVudE5hbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGxpc3RlbmVycy5nZXQoZXZlbnROYW1lKTtcbiAgICAgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5saXN0ZW5lclR5cGUgPT09IEFUVFJJQlVURSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5saXN0ZW5lclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfSxcblxuICAgICAgICBzZXQobGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09IFwiZnVuY3Rpb25cIiAmJiAhaXNPYmplY3QobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBudWxsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG5cbiAgICAgICAgICAgIC8vIFRyYXZlcnNlIHRvIHRoZSB0YWlsIHdoaWxlIHJlbW92aW5nIG9sZCB2YWx1ZS5cbiAgICAgICAgICAgIGxldCBwcmV2ID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmxpc3RlbmVyVHlwZSA9PT0gQVRUUklCVVRFKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBvbGQgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHQgPSBub2RlLm5leHQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobm9kZS5uZXh0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5kZWxldGUoZXZlbnROYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYgPSBub2RlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCBuZXcgdmFsdWUuXG4gICAgICAgICAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdOb2RlID0ge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcixcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJUeXBlOiBBVFRSSUJVVEUsXG4gICAgICAgICAgICAgICAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbmV4dDogbnVsbCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zZXQoZXZlbnROYW1lLCBuZXdOb2RlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIH1cbn1cblxuLyoqXG4gKiBEZWZpbmUgYW4gZXZlbnQgYXR0cmlidXRlIChlLmcuIGBldmVudFRhcmdldC5vbmNsaWNrYCkuXG4gKiBAcGFyYW0ge09iamVjdH0gZXZlbnRUYXJnZXRQcm90b3R5cGUgVGhlIGV2ZW50IHRhcmdldCBwcm90b3R5cGUgdG8gZGVmaW5lIGFuIGV2ZW50IGF0dHJiaXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byBkZWZpbmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gZGVmaW5lRXZlbnRBdHRyaWJ1dGUoZXZlbnRUYXJnZXRQcm90b3R5cGUsIGV2ZW50TmFtZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcbiAgICAgICAgZXZlbnRUYXJnZXRQcm90b3R5cGUsXG4gICAgICAgIGBvbiR7ZXZlbnROYW1lfWAsXG4gICAgICAgIGRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvcihldmVudE5hbWUpXG4gICAgKTtcbn1cblxuLyoqXG4gKiBEZWZpbmUgYSBjdXN0b20gRXZlbnRUYXJnZXQgd2l0aCBldmVudCBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gZXZlbnROYW1lcyBFdmVudCBuYW1lcyBmb3IgZXZlbnQgYXR0cmlidXRlcy5cbiAqIEByZXR1cm5zIHtFdmVudFRhcmdldH0gVGhlIGN1c3RvbSBFdmVudFRhcmdldC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KGV2ZW50TmFtZXMpIHtcbiAgICAvKiogQ3VzdG9tRXZlbnRUYXJnZXQgKi9cbiAgICBmdW5jdGlvbiBDdXN0b21FdmVudFRhcmdldCgpIHtcbiAgICAgICAgRXZlbnRUYXJnZXQuY2FsbCh0aGlzKTtcbiAgICB9XG5cbiAgICBDdXN0b21FdmVudFRhcmdldC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEV2ZW50VGFyZ2V0LnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgICAgdmFsdWU6IEN1c3RvbUV2ZW50VGFyZ2V0LFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgZGVmaW5lRXZlbnRBdHRyaWJ1dGUoQ3VzdG9tRXZlbnRUYXJnZXQucHJvdG90eXBlLCBldmVudE5hbWVzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gQ3VzdG9tRXZlbnRUYXJnZXRcbn1cblxuLyoqXG4gKiBFdmVudFRhcmdldC5cbiAqXG4gKiAtIFRoaXMgaXMgY29uc3RydWN0b3IgaWYgbm8gYXJndW1lbnRzLlxuICogLSBUaGlzIGlzIGEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhIEN1c3RvbUV2ZW50VGFyZ2V0IGNvbnN0cnVjdG9yIGlmIHRoZXJlIGFyZSBhcmd1bWVudHMuXG4gKlxuICogRm9yIGV4YW1wbGU6XG4gKlxuICogICAgIGNsYXNzIEEgZXh0ZW5kcyBFdmVudFRhcmdldCB7fVxuICogICAgIGNsYXNzIEIgZXh0ZW5kcyBFdmVudFRhcmdldChcIm1lc3NhZ2VcIikge31cbiAqICAgICBjbGFzcyBDIGV4dGVuZHMgRXZlbnRUYXJnZXQoXCJtZXNzYWdlXCIsIFwiZXJyb3JcIikge31cbiAqICAgICBjbGFzcyBEIGV4dGVuZHMgRXZlbnRUYXJnZXQoW1wibWVzc2FnZVwiLCBcImVycm9yXCJdKSB7fVxuICovXG5mdW5jdGlvbiBFdmVudFRhcmdldCgpIHtcbiAgICAvKmVzbGludC1kaXNhYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBFdmVudFRhcmdldCkge1xuICAgICAgICBsaXN0ZW5lcnNNYXAuc2V0KHRoaXMsIG5ldyBNYXAoKSk7XG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBBcnJheS5pc0FycmF5KGFyZ3VtZW50c1swXSkpIHtcbiAgICAgICAgcmV0dXJuIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KGFyZ3VtZW50c1swXSlcbiAgICB9XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdHlwZXNbaV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KHR5cGVzKVxuICAgIH1cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpXG4gICAgLyplc2xpbnQtZW5hYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG59XG5cbi8vIFNob3VsZCBiZSBlbnVtZXJhYmxlLCBidXQgY2xhc3MgbWV0aG9kcyBhcmUgbm90IGVudW1lcmFibGUuXG5FdmVudFRhcmdldC5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogQWRkIGEgZ2l2ZW4gbGlzdGVuZXIgdG8gdGhpcyBldmVudCB0YXJnZXQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byBhZGQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHRvIGFkZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW58e2NhcHR1cmU/OmJvb2xlYW4scGFzc2l2ZT86Ym9vbGVhbixvbmNlPzpib29sZWFufX0gW29wdGlvbnNdIFRoZSBvcHRpb25zIGZvciB0aGlzIGxpc3RlbmVyLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIGFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgICAgICBpZiAobGlzdGVuZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gXCJmdW5jdGlvblwiICYmICFpc09iamVjdChsaXN0ZW5lcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInbGlzdGVuZXInIHNob3VsZCBiZSBhIGZ1bmN0aW9uIG9yIGFuIG9iamVjdC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IGdldExpc3RlbmVycyh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9uc0lzT2JqID0gaXNPYmplY3Qob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGNhcHR1cmUgPSBvcHRpb25zSXNPYmpcbiAgICAgICAgICAgID8gQm9vbGVhbihvcHRpb25zLmNhcHR1cmUpXG4gICAgICAgICAgICA6IEJvb2xlYW4ob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyVHlwZSA9IGNhcHR1cmUgPyBDQVBUVVJFIDogQlVCQkxFO1xuICAgICAgICBjb25zdCBuZXdOb2RlID0ge1xuICAgICAgICAgICAgbGlzdGVuZXIsXG4gICAgICAgICAgICBsaXN0ZW5lclR5cGUsXG4gICAgICAgICAgICBwYXNzaXZlOiBvcHRpb25zSXNPYmogJiYgQm9vbGVhbihvcHRpb25zLnBhc3NpdmUpLFxuICAgICAgICAgICAgb25jZTogb3B0aW9uc0lzT2JqICYmIEJvb2xlYW4ob3B0aW9ucy5vbmNlKSxcbiAgICAgICAgICAgIG5leHQ6IG51bGwsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0IGl0IGFzIHRoZSBmaXJzdCBub2RlIGlmIHRoZSBmaXJzdCBub2RlIGlzIG51bGwuXG4gICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbmV3Tm9kZSk7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyYXZlcnNlIHRvIHRoZSB0YWlsIHdoaWxlIGNoZWNraW5nIGR1cGxpY2F0aW9uLi5cbiAgICAgICAgbGV0IHByZXYgPSBudWxsO1xuICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgbm9kZS5saXN0ZW5lciA9PT0gbGlzdGVuZXIgJiZcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyVHlwZSA9PT0gbGlzdGVuZXJUeXBlXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAvLyBTaG91bGQgaWdub3JlIGR1cGxpY2F0aW9uLlxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJldiA9IG5vZGU7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGl0LlxuICAgICAgICBwcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBnaXZlbiBsaXN0ZW5lciBmcm9tIHRoaXMgZXZlbnQgdGFyZ2V0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gcmVtb3ZlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufHtjYXB0dXJlPzpib29sZWFuLHBhc3NpdmU/OmJvb2xlYW4sb25jZT86Ym9vbGVhbn19IFtvcHRpb25zXSBUaGUgb3B0aW9ucyBmb3IgdGhpcyBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGlzdGVuZXJzID0gZ2V0TGlzdGVuZXJzKHRoaXMpO1xuICAgICAgICBjb25zdCBjYXB0dXJlID0gaXNPYmplY3Qob3B0aW9ucylcbiAgICAgICAgICAgID8gQm9vbGVhbihvcHRpb25zLmNhcHR1cmUpXG4gICAgICAgICAgICA6IEJvb2xlYW4ob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyVHlwZSA9IGNhcHR1cmUgPyBDQVBUVVJFIDogQlVCQkxFO1xuXG4gICAgICAgIGxldCBwcmV2ID0gbnVsbDtcbiAgICAgICAgbGV0IG5vZGUgPSBsaXN0ZW5lcnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyID09PSBsaXN0ZW5lciAmJlxuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXJUeXBlID09PSBsaXN0ZW5lclR5cGVcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IG5vZGUubmV4dDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUubmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwcmV2ID0gbm9kZTtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRGlzcGF0Y2ggYSBnaXZlbiBldmVudC5cbiAgICAgKiBAcGFyYW0ge0V2ZW50fHt0eXBlOnN0cmluZ319IGV2ZW50IFRoZSBldmVudCB0byBkaXNwYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYGZhbHNlYCBpZiBjYW5jZWxlZC5cbiAgICAgKi9cbiAgICBkaXNwYXRjaEV2ZW50KGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudCA9PSBudWxsIHx8IHR5cGVvZiBldmVudC50eXBlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImV2ZW50LnR5cGVcIiBzaG91bGQgYmUgYSBzdHJpbmcuJylcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIGxpc3RlbmVycyBhcmVuJ3QgcmVnaXN0ZXJlZCwgdGVybWluYXRlLlxuICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG4gICAgICAgIGNvbnN0IGV2ZW50TmFtZSA9IGV2ZW50LnR5cGU7XG4gICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2luY2Ugd2UgY2Fubm90IHJld3JpdGUgc2V2ZXJhbCBwcm9wZXJ0aWVzLCBzbyB3cmFwIG9iamVjdC5cbiAgICAgICAgY29uc3Qgd3JhcHBlZEV2ZW50ID0gd3JhcEV2ZW50KHRoaXMsIGV2ZW50KTtcblxuICAgICAgICAvLyBUaGlzIGRvZXNuJ3QgcHJvY2VzcyBjYXB0dXJpbmcgcGhhc2UgYW5kIGJ1YmJsaW5nIHBoYXNlLlxuICAgICAgICAvLyBUaGlzIGlzbid0IHBhcnRpY2lwYXRpbmcgaW4gYSB0cmVlLlxuICAgICAgICBsZXQgcHJldiA9IG51bGw7XG4gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGlzIGxpc3RlbmVyIGlmIGl0J3Mgb25jZVxuICAgICAgICAgICAgaWYgKG5vZGUub25jZSkge1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IG5vZGUubmV4dDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUubmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmV2ID0gbm9kZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2FsbCB0aGlzIGxpc3RlbmVyXG4gICAgICAgICAgICBzZXRQYXNzaXZlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgd3JhcHBlZEV2ZW50LFxuICAgICAgICAgICAgICAgIG5vZGUucGFzc2l2ZSA/IG5vZGUubGlzdGVuZXIgOiBudWxsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBub2RlLmxpc3RlbmVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyLmNhbGwodGhpcywgd3JhcHBlZEV2ZW50KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlLmVycm9yID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXJUeXBlICE9PSBBVFRSSUJVVEUgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2Ygbm9kZS5saXN0ZW5lci5oYW5kbGVFdmVudCA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyLmhhbmRsZUV2ZW50KHdyYXBwZWRFdmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEJyZWFrIGlmIGBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb25gIHdhcyBjYWxsZWQuXG4gICAgICAgICAgICBpZiAoaXNTdG9wcGVkKHdyYXBwZWRFdmVudCkpIHtcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICB9XG4gICAgICAgIHNldFBhc3NpdmVMaXN0ZW5lcih3cmFwcGVkRXZlbnQsIG51bGwpO1xuICAgICAgICBzZXRFdmVudFBoYXNlKHdyYXBwZWRFdmVudCwgMCk7XG4gICAgICAgIHNldEN1cnJlbnRUYXJnZXQod3JhcHBlZEV2ZW50LCBudWxsKTtcblxuICAgICAgICByZXR1cm4gIXdyYXBwZWRFdmVudC5kZWZhdWx0UHJldmVudGVkXG4gICAgfSxcbn07XG5cbi8vIGBjb25zdHJ1Y3RvcmAgaXMgbm90IGVudW1lcmFibGUuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRUYXJnZXQucHJvdG90eXBlLCBcImNvbnN0cnVjdG9yXCIsIHtcbiAgICB2YWx1ZTogRXZlbnRUYXJnZXQsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxufSk7XG5cbi8vIEVuc3VyZSBgZXZlbnRUYXJnZXQgaW5zdGFuY2VvZiB3aW5kb3cuRXZlbnRUYXJnZXRgIGlzIGB0cnVlYC5cbmlmIChcbiAgICB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgdHlwZW9mIHdpbmRvdy5FdmVudFRhcmdldCAhPT0gXCJ1bmRlZmluZWRcIlxuKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEV2ZW50VGFyZ2V0LnByb3RvdHlwZSwgd2luZG93LkV2ZW50VGFyZ2V0LnByb3RvdHlwZSk7XG59XG5cbmV4cG9ydHMuZGVmaW5lRXZlbnRBdHRyaWJ1dGUgPSBkZWZpbmVFdmVudEF0dHJpYnV0ZTtcbmV4cG9ydHMuRXZlbnRUYXJnZXQgPSBFdmVudFRhcmdldDtcbmV4cG9ydHMuZGVmYXVsdCA9IEV2ZW50VGFyZ2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50VGFyZ2V0XG5tb2R1bGUuZXhwb3J0cy5FdmVudFRhcmdldCA9IG1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IEV2ZW50VGFyZ2V0XG5tb2R1bGUuZXhwb3J0cy5kZWZpbmVFdmVudEF0dHJpYnV0ZSA9IGRlZmluZUV2ZW50QXR0cmlidXRlXG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC10YXJnZXQtc2hpbS5qcy5tYXBcbiIsImNvbnN0IHtSZWFkYWJsZX0gPSByZXF1aXJlKCdzdHJlYW0nKTtcblxuLyoqXG4gKiBAdHlwZSB7V2Vha01hcDxCbG9iLCB7dHlwZTogc3RyaW5nLCBzaXplOiBudW1iZXIsIHBhcnRzOiAoQmxvYiB8IEJ1ZmZlcilbXSB9Pn1cbiAqL1xuY29uc3Qgd20gPSBuZXcgV2Vha01hcCgpO1xuXG5hc3luYyBmdW5jdGlvbiAqIHJlYWQocGFydHMpIHtcblx0Zm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG5cdFx0aWYgKCdzdHJlYW0nIGluIHBhcnQpIHtcblx0XHRcdHlpZWxkICogcGFydC5zdHJlYW0oKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0eWllbGQgcGFydDtcblx0XHR9XG5cdH1cbn1cblxuY2xhc3MgQmxvYiB7XG5cdC8qKlxuXHQgKiBUaGUgQmxvYigpIGNvbnN0cnVjdG9yIHJldHVybnMgYSBuZXcgQmxvYiBvYmplY3QuIFRoZSBjb250ZW50XG5cdCAqIG9mIHRoZSBibG9iIGNvbnNpc3RzIG9mIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoZSB2YWx1ZXMgZ2l2ZW5cblx0ICogaW4gdGhlIHBhcmFtZXRlciBhcnJheS5cblx0ICpcblx0ICogQHBhcmFtIHsoQXJyYXlCdWZmZXJMaWtlIHwgQXJyYXlCdWZmZXJWaWV3IHwgQmxvYiB8IEJ1ZmZlciB8IHN0cmluZylbXX0gYmxvYlBhcnRzXG5cdCAqIEBwYXJhbSB7eyB0eXBlPzogc3RyaW5nIH19IFtvcHRpb25zXVxuXHQgKi9cblx0Y29uc3RydWN0b3IoYmxvYlBhcnRzID0gW10sIG9wdGlvbnMgPSB7fSkge1xuXHRcdGxldCBzaXplID0gMDtcblxuXHRcdGNvbnN0IHBhcnRzID0gYmxvYlBhcnRzLm1hcChlbGVtZW50ID0+IHtcblx0XHRcdGxldCBidWZmZXI7XG5cdFx0XHRpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuXHRcdFx0XHRidWZmZXIgPSBlbGVtZW50O1xuXHRcdFx0fSBlbHNlIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcoZWxlbWVudCkpIHtcblx0XHRcdFx0YnVmZmVyID0gQnVmZmVyLmZyb20oZWxlbWVudC5idWZmZXIsIGVsZW1lbnQuYnl0ZU9mZnNldCwgZWxlbWVudC5ieXRlTGVuZ3RoKTtcblx0XHRcdH0gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG5cdFx0XHRcdGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGVsZW1lbnQpO1xuXHRcdFx0fSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgQmxvYikge1xuXHRcdFx0XHRidWZmZXIgPSBlbGVtZW50O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YnVmZmVyID0gQnVmZmVyLmZyb20odHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnID8gZWxlbWVudCA6IFN0cmluZyhlbGVtZW50KSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL2V4cGxpY2l0LWxlbmd0aC1jaGVja1xuXHRcdFx0c2l6ZSArPSBidWZmZXIubGVuZ3RoIHx8IGJ1ZmZlci5zaXplIHx8IDA7XG5cdFx0XHRyZXR1cm4gYnVmZmVyO1xuXHRcdH0pO1xuXG5cdFx0Y29uc3QgdHlwZSA9IG9wdGlvbnMudHlwZSA9PT0gdW5kZWZpbmVkID8gJycgOiBTdHJpbmcob3B0aW9ucy50eXBlKS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0d20uc2V0KHRoaXMsIHtcblx0XHRcdHR5cGU6IC9bXlxcdTAwMjAtXFx1MDA3RV0vLnRlc3QodHlwZSkgPyAnJyA6IHR5cGUsXG5cdFx0XHRzaXplLFxuXHRcdFx0cGFydHNcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgQmxvYiBpbnRlcmZhY2UncyBzaXplIHByb3BlcnR5IHJldHVybnMgdGhlXG5cdCAqIHNpemUgb2YgdGhlIEJsb2IgaW4gYnl0ZXMuXG5cdCAqL1xuXHRnZXQgc2l6ZSgpIHtcblx0XHRyZXR1cm4gd20uZ2V0KHRoaXMpLnNpemU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHR5cGUgcHJvcGVydHkgb2YgYSBCbG9iIG9iamVjdCByZXR1cm5zIHRoZSBNSU1FIHR5cGUgb2YgdGhlIGZpbGUuXG5cdCAqL1xuXHRnZXQgdHlwZSgpIHtcblx0XHRyZXR1cm4gd20uZ2V0KHRoaXMpLnR5cGU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHRleHQoKSBtZXRob2QgaW4gdGhlIEJsb2IgaW50ZXJmYWNlIHJldHVybnMgYSBQcm9taXNlXG5cdCAqIHRoYXQgcmVzb2x2ZXMgd2l0aCBhIHN0cmluZyBjb250YWluaW5nIHRoZSBjb250ZW50cyBvZlxuXHQgKiB0aGUgYmxvYiwgaW50ZXJwcmV0ZWQgYXMgVVRGLTguXG5cdCAqXG5cdCAqIEByZXR1cm4ge1Byb21pc2U8c3RyaW5nPn1cblx0ICovXG5cdGFzeW5jIHRleHQoKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5mcm9tKGF3YWl0IHRoaXMuYXJyYXlCdWZmZXIoKSkudG9TdHJpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYXJyYXlCdWZmZXIoKSBtZXRob2QgaW4gdGhlIEJsb2IgaW50ZXJmYWNlIHJldHVybnMgYVxuXHQgKiBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgY29udGVudHMgb2YgdGhlIGJsb2IgYXNcblx0ICogYmluYXJ5IGRhdGEgY29udGFpbmVkIGluIGFuIEFycmF5QnVmZmVyLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5QnVmZmVyPn1cblx0ICovXG5cdGFzeW5jIGFycmF5QnVmZmVyKCkge1xuXHRcdGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLnNpemUpO1xuXHRcdGxldCBvZmZzZXQgPSAwO1xuXHRcdGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgdGhpcy5zdHJlYW0oKSkge1xuXHRcdFx0ZGF0YS5zZXQoY2h1bmssIG9mZnNldCk7XG5cdFx0XHRvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuXHRcdH1cblxuXHRcdHJldHVybiBkYXRhLmJ1ZmZlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgQmxvYiBpbnRlcmZhY2UncyBzdHJlYW0oKSBtZXRob2QgaXMgZGlmZmVyZW5jZSBmcm9tIG5hdGl2ZVxuXHQgKiBhbmQgdXNlcyBub2RlIHN0cmVhbXMgaW5zdGVhZCBvZiB3aGF0d2cgc3RyZWFtcy5cblx0ICpcblx0ICogQHJldHVybnMge1JlYWRhYmxlfSBOb2RlIHJlYWRhYmxlIHN0cmVhbVxuXHQgKi9cblx0c3RyZWFtKCkge1xuXHRcdHJldHVybiBSZWFkYWJsZS5mcm9tKHJlYWQod20uZ2V0KHRoaXMpLnBhcnRzKSk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIEJsb2IgaW50ZXJmYWNlJ3Mgc2xpY2UoKSBtZXRob2QgY3JlYXRlcyBhbmQgcmV0dXJucyBhXG5cdCAqIG5ldyBCbG9iIG9iamVjdCB3aGljaCBjb250YWlucyBkYXRhIGZyb20gYSBzdWJzZXQgb2YgdGhlXG5cdCAqIGJsb2Igb24gd2hpY2ggaXQncyBjYWxsZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnRdXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kXVxuXHQgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVdXG5cdCAqL1xuXHRzbGljZShzdGFydCA9IDAsIGVuZCA9IHRoaXMuc2l6ZSwgdHlwZSA9ICcnKSB7XG5cdFx0Y29uc3Qge3NpemV9ID0gdGhpcztcblxuXHRcdGxldCByZWxhdGl2ZVN0YXJ0ID0gc3RhcnQgPCAwID8gTWF0aC5tYXgoc2l6ZSArIHN0YXJ0LCAwKSA6IE1hdGgubWluKHN0YXJ0LCBzaXplKTtcblx0XHRsZXQgcmVsYXRpdmVFbmQgPSBlbmQgPCAwID8gTWF0aC5tYXgoc2l6ZSArIGVuZCwgMCkgOiBNYXRoLm1pbihlbmQsIHNpemUpO1xuXG5cdFx0Y29uc3Qgc3BhbiA9IE1hdGgubWF4KHJlbGF0aXZlRW5kIC0gcmVsYXRpdmVTdGFydCwgMCk7XG5cdFx0Y29uc3QgcGFydHMgPSB3bS5nZXQodGhpcykucGFydHMudmFsdWVzKCk7XG5cdFx0Y29uc3QgYmxvYlBhcnRzID0gW107XG5cdFx0bGV0IGFkZGVkID0gMDtcblxuXHRcdGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuXHRcdFx0Y29uc3Qgc2l6ZSA9IEFycmF5QnVmZmVyLmlzVmlldyhwYXJ0KSA/IHBhcnQuYnl0ZUxlbmd0aCA6IHBhcnQuc2l6ZTtcblx0XHRcdGlmIChyZWxhdGl2ZVN0YXJ0ICYmIHNpemUgPD0gcmVsYXRpdmVTdGFydCkge1xuXHRcdFx0XHQvLyBTa2lwIHRoZSBiZWdpbm5pbmcgYW5kIGNoYW5nZSB0aGUgcmVsYXRpdmVcblx0XHRcdFx0Ly8gc3RhcnQgJiBlbmQgcG9zaXRpb24gYXMgd2Ugc2tpcCB0aGUgdW53YW50ZWQgcGFydHNcblx0XHRcdFx0cmVsYXRpdmVTdGFydCAtPSBzaXplO1xuXHRcdFx0XHRyZWxhdGl2ZUVuZCAtPSBzaXplO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3QgY2h1bmsgPSBwYXJ0LnNsaWNlKHJlbGF0aXZlU3RhcnQsIE1hdGgubWluKHNpemUsIHJlbGF0aXZlRW5kKSk7XG5cdFx0XHRcdGJsb2JQYXJ0cy5wdXNoKGNodW5rKTtcblx0XHRcdFx0YWRkZWQgKz0gQXJyYXlCdWZmZXIuaXNWaWV3KGNodW5rKSA/IGNodW5rLmJ5dGVMZW5ndGggOiBjaHVuay5zaXplO1xuXHRcdFx0XHRyZWxhdGl2ZVN0YXJ0ID0gMDsgLy8gQWxsIG5leHQgc2VxdWVudGFsIHBhcnRzIHNob3VsZCBzdGFydCBhdCAwXG5cblx0XHRcdFx0Ly8gZG9uJ3QgYWRkIHRoZSBvdmVyZmxvdyB0byBuZXcgYmxvYlBhcnRzXG5cdFx0XHRcdGlmIChhZGRlZCA+PSBzcGFuKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRjb25zdCBibG9iID0gbmV3IEJsb2IoW10sIHt0eXBlOiBTdHJpbmcodHlwZSkudG9Mb3dlckNhc2UoKX0pO1xuXHRcdE9iamVjdC5hc3NpZ24od20uZ2V0KGJsb2IpLCB7c2l6ZTogc3BhbiwgcGFydHM6IGJsb2JQYXJ0c30pO1xuXG5cdFx0cmV0dXJuIGJsb2I7XG5cdH1cblxuXHRnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG5cdFx0cmV0dXJuICdCbG9iJztcblx0fVxuXG5cdHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXShvYmplY3QpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0b2JqZWN0ICYmXG5cdFx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdFx0dHlwZW9mIG9iamVjdC5zdHJlYW0gPT09ICdmdW5jdGlvbicgJiZcblx0XHRcdG9iamVjdC5zdHJlYW0ubGVuZ3RoID09PSAwICYmXG5cdFx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0XHQvXihCbG9ifEZpbGUpJC8udGVzdChvYmplY3RbU3ltYm9sLnRvU3RyaW5nVGFnXSlcblx0XHQpO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJsb2IucHJvdG90eXBlLCB7XG5cdHNpemU6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0dHlwZToge2VudW1lcmFibGU6IHRydWV9LFxuXHRzbGljZToge2VudW1lcmFibGU6IHRydWV9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBCbG9iO1xuIiwiJ3VzZSBzdHJpY3QnO1xuY29uc3QgZmV0Y2ggPSByZXF1aXJlKCdub2RlLWZldGNoJyk7XG5jb25zdCBBYm9ydENvbnRyb2xsZXIgPSByZXF1aXJlKCdhYm9ydC1jb250cm9sbGVyJyk7XG5cbmNvbnN0IFRFTl9NRUdBQllURVMgPSAxMDAwICogMTAwMCAqIDEwO1xuXG5pZiAoIWdsb2JhbC5mZXRjaCkge1xuXHRnbG9iYWwuZmV0Y2ggPSAodXJsLCBvcHRpb25zKSA9PiBmZXRjaCh1cmwsIHtoaWdoV2F0ZXJNYXJrOiBURU5fTUVHQUJZVEVTLCAuLi5vcHRpb25zfSk7XG59XG5cbmlmICghZ2xvYmFsLkhlYWRlcnMpIHtcblx0Z2xvYmFsLkhlYWRlcnMgPSBmZXRjaC5IZWFkZXJzO1xufVxuXG5pZiAoIWdsb2JhbC5SZXF1ZXN0KSB7XG5cdGdsb2JhbC5SZXF1ZXN0ID0gZmV0Y2guUmVxdWVzdDtcbn1cblxuaWYgKCFnbG9iYWwuUmVzcG9uc2UpIHtcblx0Z2xvYmFsLlJlc3BvbnNlID0gZmV0Y2guUmVzcG9uc2U7XG59XG5cbmlmICghZ2xvYmFsLkFib3J0Q29udHJvbGxlcikge1xuXHRnbG9iYWwuQWJvcnRDb250cm9sbGVyID0gQWJvcnRDb250cm9sbGVyO1xufVxuXG5pZiAoIWdsb2JhbC5SZWFkYWJsZVN0cmVhbSkge1xuXHR0cnkge1xuXHRcdGdsb2JhbC5SZWFkYWJsZVN0cmVhbSA9IHJlcXVpcmUoJ3dlYi1zdHJlYW1zLXBvbHlmaWxsL3BvbnlmaWxsL2VzMjAxOCcpO1xuXHR9IGNhdGNoIChfKSB7fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ2t5L3VtZCcpO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuXHR0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuXHQoZ2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwua3kgPSBmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cblx0LyohIE1JVCBMaWNlbnNlIMKpIFNpbmRyZSBTb3JodXMgKi9cblxuXHRjb25zdCBnbG9iYWxzID0ge307XG5cblx0Y29uc3QgZ2V0R2xvYmFsID0gcHJvcGVydHkgPT4ge1xuXHRcdC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5cdFx0aWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmICYmIHByb3BlcnR5IGluIHNlbGYpIHtcblx0XHRcdHJldHVybiBzZWxmO1xuXHRcdH1cblxuXHRcdC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdyAmJiBwcm9wZXJ0eSBpbiB3aW5kb3cpIHtcblx0XHRcdHJldHVybiB3aW5kb3c7XG5cdFx0fVxuXG5cdFx0aWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbCAmJiBwcm9wZXJ0eSBpbiBnbG9iYWwpIHtcblx0XHRcdHJldHVybiBnbG9iYWw7XG5cdFx0fVxuXG5cdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbFRoaXMpIHtcblx0XHRcdHJldHVybiBnbG9iYWxUaGlzO1xuXHRcdH1cblx0fTtcblxuXHRjb25zdCBnbG9iYWxQcm9wZXJ0aWVzID0gW1xuXHRcdCdIZWFkZXJzJyxcblx0XHQnUmVxdWVzdCcsXG5cdFx0J1Jlc3BvbnNlJyxcblx0XHQnUmVhZGFibGVTdHJlYW0nLFxuXHRcdCdmZXRjaCcsXG5cdFx0J0Fib3J0Q29udHJvbGxlcicsXG5cdFx0J0Zvcm1EYXRhJ1xuXHRdO1xuXG5cdGZvciAoY29uc3QgcHJvcGVydHkgb2YgZ2xvYmFsUHJvcGVydGllcykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxzLCBwcm9wZXJ0eSwge1xuXHRcdFx0Z2V0KCkge1xuXHRcdFx0XHRjb25zdCBnbG9iYWxPYmplY3QgPSBnZXRHbG9iYWwocHJvcGVydHkpO1xuXHRcdFx0XHRjb25zdCB2YWx1ZSA9IGdsb2JhbE9iamVjdCAmJiBnbG9iYWxPYmplY3RbcHJvcGVydHldO1xuXHRcdFx0XHRyZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gdmFsdWUuYmluZChnbG9iYWxPYmplY3QpIDogdmFsdWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRjb25zdCBpc09iamVjdCA9IHZhbHVlID0+IHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCc7XG5cdGNvbnN0IHN1cHBvcnRzQWJvcnRDb250cm9sbGVyID0gdHlwZW9mIGdsb2JhbHMuQWJvcnRDb250cm9sbGVyID09PSAnZnVuY3Rpb24nO1xuXHRjb25zdCBzdXBwb3J0c1N0cmVhbXMgPSB0eXBlb2YgZ2xvYmFscy5SZWFkYWJsZVN0cmVhbSA9PT0gJ2Z1bmN0aW9uJztcblx0Y29uc3Qgc3VwcG9ydHNGb3JtRGF0YSA9IHR5cGVvZiBnbG9iYWxzLkZvcm1EYXRhID09PSAnZnVuY3Rpb24nO1xuXG5cdGNvbnN0IG1lcmdlSGVhZGVycyA9IChzb3VyY2UxLCBzb3VyY2UyKSA9PiB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gbmV3IGdsb2JhbHMuSGVhZGVycyhzb3VyY2UxIHx8IHt9KTtcblx0XHRjb25zdCBpc0hlYWRlcnNJbnN0YW5jZSA9IHNvdXJjZTIgaW5zdGFuY2VvZiBnbG9iYWxzLkhlYWRlcnM7XG5cdFx0Y29uc3Qgc291cmNlID0gbmV3IGdsb2JhbHMuSGVhZGVycyhzb3VyY2UyIHx8IHt9KTtcblxuXHRcdGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHNvdXJjZSkge1xuXHRcdFx0aWYgKChpc0hlYWRlcnNJbnN0YW5jZSAmJiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmVzdWx0LmRlbGV0ZShrZXkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmVzdWx0LnNldChrZXksIHZhbHVlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9O1xuXG5cdGNvbnN0IGRlZXBNZXJnZSA9ICguLi5zb3VyY2VzKSA9PiB7XG5cdFx0bGV0IHJldHVyblZhbHVlID0ge307XG5cdFx0bGV0IGhlYWRlcnMgPSB7fTtcblxuXHRcdGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcblx0XHRcdGlmIChBcnJheS5pc0FycmF5KHNvdXJjZSkpIHtcblx0XHRcdFx0aWYgKCEoQXJyYXkuaXNBcnJheShyZXR1cm5WYWx1ZSkpKSB7XG5cdFx0XHRcdFx0cmV0dXJuVmFsdWUgPSBbXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVyblZhbHVlID0gWy4uLnJldHVyblZhbHVlLCAuLi5zb3VyY2VdO1xuXHRcdFx0fSBlbHNlIGlmIChpc09iamVjdChzb3VyY2UpKSB7XG5cdFx0XHRcdGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhzb3VyY2UpKSB7XG5cdFx0XHRcdFx0aWYgKGlzT2JqZWN0KHZhbHVlKSAmJiAoa2V5IGluIHJldHVyblZhbHVlKSkge1xuXHRcdFx0XHRcdFx0dmFsdWUgPSBkZWVwTWVyZ2UocmV0dXJuVmFsdWVba2V5XSwgdmFsdWUpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVyblZhbHVlID0gey4uLnJldHVyblZhbHVlLCBba2V5XTogdmFsdWV9O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGlzT2JqZWN0KHNvdXJjZS5oZWFkZXJzKSkge1xuXHRcdFx0XHRcdGhlYWRlcnMgPSBtZXJnZUhlYWRlcnMoaGVhZGVycywgc291cmNlLmhlYWRlcnMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVyblZhbHVlLmhlYWRlcnMgPSBoZWFkZXJzO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXR1cm5WYWx1ZTtcblx0fTtcblxuXHRjb25zdCByZXF1ZXN0TWV0aG9kcyA9IFtcblx0XHQnZ2V0Jyxcblx0XHQncG9zdCcsXG5cdFx0J3B1dCcsXG5cdFx0J3BhdGNoJyxcblx0XHQnaGVhZCcsXG5cdFx0J2RlbGV0ZSdcblx0XTtcblxuXHRjb25zdCByZXNwb25zZVR5cGVzID0ge1xuXHRcdGpzb246ICdhcHBsaWNhdGlvbi9qc29uJyxcblx0XHR0ZXh0OiAndGV4dC8qJyxcblx0XHRmb3JtRGF0YTogJ211bHRpcGFydC9mb3JtLWRhdGEnLFxuXHRcdGFycmF5QnVmZmVyOiAnKi8qJyxcblx0XHRibG9iOiAnKi8qJ1xuXHR9O1xuXG5cdGNvbnN0IHJldHJ5TWV0aG9kcyA9IFtcblx0XHQnZ2V0Jyxcblx0XHQncHV0Jyxcblx0XHQnaGVhZCcsXG5cdFx0J2RlbGV0ZScsXG5cdFx0J29wdGlvbnMnLFxuXHRcdCd0cmFjZSdcblx0XTtcblxuXHRjb25zdCByZXRyeVN0YXR1c0NvZGVzID0gW1xuXHRcdDQwOCxcblx0XHQ0MTMsXG5cdFx0NDI5LFxuXHRcdDUwMCxcblx0XHQ1MDIsXG5cdFx0NTAzLFxuXHRcdDUwNFxuXHRdO1xuXG5cdGNvbnN0IHJldHJ5QWZ0ZXJTdGF0dXNDb2RlcyA9IFtcblx0XHQ0MTMsXG5cdFx0NDI5LFxuXHRcdDUwM1xuXHRdO1xuXG5cdGNvbnN0IHN0b3AgPSBTeW1ib2woJ3N0b3AnKTtcblxuXHRjbGFzcyBIVFRQRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdFx0Y29uc3RydWN0b3IocmVzcG9uc2UpIHtcblx0XHRcdC8vIFNldCB0aGUgbWVzc2FnZSB0byB0aGUgc3RhdHVzIHRleHQsIHN1Y2ggYXMgVW5hdXRob3JpemVkLFxuXHRcdFx0Ly8gd2l0aCBzb21lIGZhbGxiYWNrcy4gVGhpcyBtZXNzYWdlIHNob3VsZCBuZXZlciBiZSB1bmRlZmluZWQuXG5cdFx0XHRzdXBlcihcblx0XHRcdFx0cmVzcG9uc2Uuc3RhdHVzVGV4dCB8fFxuXHRcdFx0XHRTdHJpbmcoXG5cdFx0XHRcdFx0KHJlc3BvbnNlLnN0YXR1cyA9PT0gMCB8fCByZXNwb25zZS5zdGF0dXMpID9cblx0XHRcdFx0XHRcdHJlc3BvbnNlLnN0YXR1cyA6ICdVbmtub3duIHJlc3BvbnNlIGVycm9yJ1xuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdFx0dGhpcy5uYW1lID0gJ0hUVFBFcnJvcic7XG5cdFx0XHR0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG5cdFx0fVxuXHR9XG5cblx0Y2xhc3MgVGltZW91dEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRcdGNvbnN0cnVjdG9yKHJlcXVlc3QpIHtcblx0XHRcdHN1cGVyKCdSZXF1ZXN0IHRpbWVkIG91dCcpO1xuXHRcdFx0dGhpcy5uYW1lID0gJ1RpbWVvdXRFcnJvcic7XG5cdFx0XHR0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuXHRcdH1cblx0fVxuXG5cdGNvbnN0IGRlbGF5ID0gbXMgPT4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG5cblx0Ly8gYFByb21pc2UucmFjZSgpYCB3b3JrYXJvdW5kICgjOTEpXG5cdGNvbnN0IHRpbWVvdXQgPSAocmVxdWVzdCwgYWJvcnRDb250cm9sbGVyLCBvcHRpb25zKSA9PlxuXHRcdG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRcdGNvbnN0IHRpbWVvdXRJRCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRpZiAoYWJvcnRDb250cm9sbGVyKSB7XG5cdFx0XHRcdFx0YWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZWplY3QobmV3IFRpbWVvdXRFcnJvcihyZXF1ZXN0KSk7XG5cdFx0XHR9LCBvcHRpb25zLnRpbWVvdXQpO1xuXG5cdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBwcm9taXNlL3ByZWZlci1hd2FpdC10by10aGVuICovXG5cdFx0XHRvcHRpb25zLmZldGNoKHJlcXVlc3QpXG5cdFx0XHRcdC50aGVuKHJlc29sdmUpXG5cdFx0XHRcdC5jYXRjaChyZWplY3QpXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHRjbGVhclRpbWVvdXQodGltZW91dElEKTtcblx0XHRcdFx0fSk7XG5cdFx0XHQvKiBlc2xpbnQtZW5hYmxlIHByb21pc2UvcHJlZmVyLWF3YWl0LXRvLXRoZW4gKi9cblx0XHR9KTtcblxuXHRjb25zdCBub3JtYWxpemVSZXF1ZXN0TWV0aG9kID0gaW5wdXQgPT4gcmVxdWVzdE1ldGhvZHMuaW5jbHVkZXMoaW5wdXQpID8gaW5wdXQudG9VcHBlckNhc2UoKSA6IGlucHV0O1xuXG5cdGNvbnN0IGRlZmF1bHRSZXRyeU9wdGlvbnMgPSB7XG5cdFx0bGltaXQ6IDIsXG5cdFx0bWV0aG9kczogcmV0cnlNZXRob2RzLFxuXHRcdHN0YXR1c0NvZGVzOiByZXRyeVN0YXR1c0NvZGVzLFxuXHRcdGFmdGVyU3RhdHVzQ29kZXM6IHJldHJ5QWZ0ZXJTdGF0dXNDb2Rlc1xuXHR9O1xuXG5cdGNvbnN0IG5vcm1hbGl6ZVJldHJ5T3B0aW9ucyA9IChyZXRyeSA9IHt9KSA9PiB7XG5cdFx0aWYgKHR5cGVvZiByZXRyeSA9PT0gJ251bWJlcicpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdC4uLmRlZmF1bHRSZXRyeU9wdGlvbnMsXG5cdFx0XHRcdGxpbWl0OiByZXRyeVxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAocmV0cnkubWV0aG9kcyAmJiAhQXJyYXkuaXNBcnJheShyZXRyeS5tZXRob2RzKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdyZXRyeS5tZXRob2RzIG11c3QgYmUgYW4gYXJyYXknKTtcblx0XHR9XG5cblx0XHRpZiAocmV0cnkuc3RhdHVzQ29kZXMgJiYgIUFycmF5LmlzQXJyYXkocmV0cnkuc3RhdHVzQ29kZXMpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ3JldHJ5LnN0YXR1c0NvZGVzIG11c3QgYmUgYW4gYXJyYXknKTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0Li4uZGVmYXVsdFJldHJ5T3B0aW9ucyxcblx0XHRcdC4uLnJldHJ5LFxuXHRcdFx0YWZ0ZXJTdGF0dXNDb2RlczogcmV0cnlBZnRlclN0YXR1c0NvZGVzXG5cdFx0fTtcblx0fTtcblxuXHQvLyBUaGUgbWF4aW11bSB2YWx1ZSBvZiBhIDMyYml0IGludCAoc2VlIGlzc3VlICMxMTcpXG5cdGNvbnN0IG1heFNhZmVUaW1lb3V0ID0gMjE0NzQ4MzY0NztcblxuXHRjbGFzcyBLeSB7XG5cdFx0Y29uc3RydWN0b3IoaW5wdXQsIG9wdGlvbnMgPSB7fSkge1xuXHRcdFx0dGhpcy5fcmV0cnlDb3VudCA9IDA7XG5cdFx0XHR0aGlzLl9pbnB1dCA9IGlucHV0O1xuXHRcdFx0dGhpcy5fb3B0aW9ucyA9IHtcblx0XHRcdFx0Ly8gVE9ETzogY3JlZGVudGlhbHMgY2FuIGJlIHJlbW92ZWQgd2hlbiB0aGUgc3BlYyBjaGFuZ2UgaXMgaW1wbGVtZW50ZWQgaW4gYWxsIGJyb3dzZXJzLiBDb250ZXh0OiBodHRwczovL3d3dy5jaHJvbWVzdGF0dXMuY29tL2ZlYXR1cmUvNDUzOTQ3MzMxMjM1MDIwOFxuXHRcdFx0XHRjcmVkZW50aWFsczogdGhpcy5faW5wdXQuY3JlZGVudGlhbHMgfHwgJ3NhbWUtb3JpZ2luJyxcblx0XHRcdFx0Li4ub3B0aW9ucyxcblx0XHRcdFx0aGVhZGVyczogbWVyZ2VIZWFkZXJzKHRoaXMuX2lucHV0LmhlYWRlcnMsIG9wdGlvbnMuaGVhZGVycyksXG5cdFx0XHRcdGhvb2tzOiBkZWVwTWVyZ2Uoe1xuXHRcdFx0XHRcdGJlZm9yZVJlcXVlc3Q6IFtdLFxuXHRcdFx0XHRcdGJlZm9yZVJldHJ5OiBbXSxcblx0XHRcdFx0XHRhZnRlclJlc3BvbnNlOiBbXVxuXHRcdFx0XHR9LCBvcHRpb25zLmhvb2tzKSxcblx0XHRcdFx0bWV0aG9kOiBub3JtYWxpemVSZXF1ZXN0TWV0aG9kKG9wdGlvbnMubWV0aG9kIHx8IHRoaXMuX2lucHV0Lm1ldGhvZCksXG5cdFx0XHRcdHByZWZpeFVybDogU3RyaW5nKG9wdGlvbnMucHJlZml4VXJsIHx8ICcnKSxcblx0XHRcdFx0cmV0cnk6IG5vcm1hbGl6ZVJldHJ5T3B0aW9ucyhvcHRpb25zLnJldHJ5KSxcblx0XHRcdFx0dGhyb3dIdHRwRXJyb3JzOiBvcHRpb25zLnRocm93SHR0cEVycm9ycyAhPT0gZmFsc2UsXG5cdFx0XHRcdHRpbWVvdXQ6IHR5cGVvZiBvcHRpb25zLnRpbWVvdXQgPT09ICd1bmRlZmluZWQnID8gMTAwMDAgOiBvcHRpb25zLnRpbWVvdXQsXG5cdFx0XHRcdGZldGNoOiBvcHRpb25zLmZldGNoIHx8IGdsb2JhbHMuZmV0Y2hcblx0XHRcdH07XG5cblx0XHRcdGlmICh0eXBlb2YgdGhpcy5faW5wdXQgIT09ICdzdHJpbmcnICYmICEodGhpcy5faW5wdXQgaW5zdGFuY2VvZiBVUkwgfHwgdGhpcy5faW5wdXQgaW5zdGFuY2VvZiBnbG9iYWxzLlJlcXVlc3QpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2BpbnB1dGAgbXVzdCBiZSBhIHN0cmluZywgVVJMLCBvciBSZXF1ZXN0Jyk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnByZWZpeFVybCAmJiB0eXBlb2YgdGhpcy5faW5wdXQgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdGlmICh0aGlzLl9pbnB1dC5zdGFydHNXaXRoKCcvJykpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ2BpbnB1dGAgbXVzdCBub3QgYmVnaW4gd2l0aCBhIHNsYXNoIHdoZW4gdXNpbmcgYHByZWZpeFVybGAnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICghdGhpcy5fb3B0aW9ucy5wcmVmaXhVcmwuZW5kc1dpdGgoJy8nKSkge1xuXHRcdFx0XHRcdHRoaXMuX29wdGlvbnMucHJlZml4VXJsICs9ICcvJztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMuX2lucHV0ID0gdGhpcy5fb3B0aW9ucy5wcmVmaXhVcmwgKyB0aGlzLl9pbnB1dDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHN1cHBvcnRzQWJvcnRDb250cm9sbGVyKSB7XG5cdFx0XHRcdHRoaXMuYWJvcnRDb250cm9sbGVyID0gbmV3IGdsb2JhbHMuQWJvcnRDb250cm9sbGVyKCk7XG5cdFx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnNpZ25hbCkge1xuXHRcdFx0XHRcdHRoaXMuX29wdGlvbnMuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5hYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMuX29wdGlvbnMuc2lnbmFsID0gdGhpcy5hYm9ydENvbnRyb2xsZXIuc2lnbmFsO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnJlcXVlc3QgPSBuZXcgZ2xvYmFscy5SZXF1ZXN0KHRoaXMuX2lucHV0LCB0aGlzLl9vcHRpb25zKTtcblxuXHRcdFx0aWYgKHRoaXMuX29wdGlvbnMuc2VhcmNoUGFyYW1zKSB7XG5cdFx0XHRcdGNvbnN0IHNlYXJjaFBhcmFtcyA9ICc/JyArIG5ldyBVUkxTZWFyY2hQYXJhbXModGhpcy5fb3B0aW9ucy5zZWFyY2hQYXJhbXMpLnRvU3RyaW5nKCk7XG5cdFx0XHRcdGNvbnN0IHVybCA9IHRoaXMucmVxdWVzdC51cmwucmVwbGFjZSgvKD86XFw/Lio/KT8oPz0jfCQpLywgc2VhcmNoUGFyYW1zKTtcblxuXHRcdFx0XHQvLyBUbyBwcm92aWRlIGNvcnJlY3QgZm9ybSBib3VuZGFyeSwgQ29udGVudC1UeXBlIGhlYWRlciBzaG91bGQgYmUgZGVsZXRlZCBlYWNoIHRpbWUgd2hlbiBuZXcgUmVxdWVzdCBpbnN0YW50aWF0ZWQgZnJvbSBhbm90aGVyIG9uZVxuXHRcdFx0XHRpZiAoKChzdXBwb3J0c0Zvcm1EYXRhICYmIHRoaXMuX29wdGlvbnMuYm9keSBpbnN0YW5jZW9mIGdsb2JhbHMuRm9ybURhdGEpIHx8IHRoaXMuX29wdGlvbnMuYm9keSBpbnN0YW5jZW9mIFVSTFNlYXJjaFBhcmFtcykgJiYgISh0aGlzLl9vcHRpb25zLmhlYWRlcnMgJiYgdGhpcy5fb3B0aW9ucy5oZWFkZXJzWydjb250ZW50LXR5cGUnXSkpIHtcblx0XHRcdFx0XHR0aGlzLnJlcXVlc3QuaGVhZGVycy5kZWxldGUoJ2NvbnRlbnQtdHlwZScpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5yZXF1ZXN0ID0gbmV3IGdsb2JhbHMuUmVxdWVzdChuZXcgZ2xvYmFscy5SZXF1ZXN0KHVybCwgdGhpcy5yZXF1ZXN0KSwgdGhpcy5fb3B0aW9ucyk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLmpzb24gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHR0aGlzLl9vcHRpb25zLmJvZHkgPSBKU09OLnN0cmluZ2lmeSh0aGlzLl9vcHRpb25zLmpzb24pO1xuXHRcdFx0XHR0aGlzLnJlcXVlc3QuaGVhZGVycy5zZXQoJ2NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cdFx0XHRcdHRoaXMucmVxdWVzdCA9IG5ldyBnbG9iYWxzLlJlcXVlc3QodGhpcy5yZXF1ZXN0LCB7Ym9keTogdGhpcy5fb3B0aW9ucy5ib2R5fSk7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IGZuID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aW1lb3V0ID4gbWF4U2FmZVRpbWVvdXQpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVGhlIFxcYHRpbWVvdXRcXGAgb3B0aW9uIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gJHttYXhTYWZlVGltZW91dH1gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGF3YWl0IGRlbGF5KDEpO1xuXHRcdFx0XHRsZXQgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9mZXRjaCgpO1xuXG5cdFx0XHRcdGZvciAoY29uc3QgaG9vayBvZiB0aGlzLl9vcHRpb25zLmhvb2tzLmFmdGVyUmVzcG9uc2UpIHtcblx0XHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuXHRcdFx0XHRcdGNvbnN0IG1vZGlmaWVkUmVzcG9uc2UgPSBhd2FpdCBob29rKFxuXHRcdFx0XHRcdFx0dGhpcy5yZXF1ZXN0LFxuXHRcdFx0XHRcdFx0dGhpcy5fb3B0aW9ucyxcblx0XHRcdFx0XHRcdHRoaXMuX2RlY29yYXRlUmVzcG9uc2UocmVzcG9uc2UuY2xvbmUoKSlcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0aWYgKG1vZGlmaWVkUmVzcG9uc2UgaW5zdGFuY2VvZiBnbG9iYWxzLlJlc3BvbnNlKSB7XG5cdFx0XHRcdFx0XHRyZXNwb25zZSA9IG1vZGlmaWVkUmVzcG9uc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5fZGVjb3JhdGVSZXNwb25zZShyZXNwb25zZSk7XG5cblx0XHRcdFx0aWYgKCFyZXNwb25zZS5vayAmJiB0aGlzLl9vcHRpb25zLnRocm93SHR0cEVycm9ycykge1xuXHRcdFx0XHRcdHRocm93IG5ldyBIVFRQRXJyb3IocmVzcG9uc2UpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSWYgYG9uRG93bmxvYWRQcm9ncmVzc2AgaXMgcGFzc2VkLCBpdCB1c2VzIHRoZSBzdHJlYW0gQVBJIGludGVybmFsbHlcblx0XHRcdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRcdFx0aWYgKHRoaXMuX29wdGlvbnMub25Eb3dubG9hZFByb2dyZXNzKSB7XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLl9vcHRpb25zLm9uRG93bmxvYWRQcm9ncmVzcyAhPT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGBvbkRvd25sb2FkUHJvZ3Jlc3NgIG9wdGlvbiBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIXN1cHBvcnRzU3RyZWFtcykge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCdTdHJlYW1zIGFyZSBub3Qgc3VwcG9ydGVkIGluIHlvdXIgZW52aXJvbm1lbnQuIGBSZWFkYWJsZVN0cmVhbWAgaXMgbWlzc2luZy4nKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5fc3RyZWFtKHJlc3BvbnNlLmNsb25lKCksIHRoaXMuX29wdGlvbnMub25Eb3dubG9hZFByb2dyZXNzKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiByZXNwb25zZTtcblx0XHRcdH07XG5cblx0XHRcdGNvbnN0IGlzUmV0cmlhYmxlTWV0aG9kID0gdGhpcy5fb3B0aW9ucy5yZXRyeS5tZXRob2RzLmluY2x1ZGVzKHRoaXMucmVxdWVzdC5tZXRob2QudG9Mb3dlckNhc2UoKSk7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBpc1JldHJpYWJsZU1ldGhvZCA/IHRoaXMuX3JldHJ5KGZuKSA6IGZuKCk7XG5cblx0XHRcdGZvciAoY29uc3QgW3R5cGUsIG1pbWVUeXBlXSBvZiBPYmplY3QuZW50cmllcyhyZXNwb25zZVR5cGVzKSkge1xuXHRcdFx0XHRyZXN1bHRbdHlwZV0gPSBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5yZXF1ZXN0LmhlYWRlcnMuc2V0KCdhY2NlcHQnLCB0aGlzLnJlcXVlc3QuaGVhZGVycy5nZXQoJ2FjY2VwdCcpIHx8IG1pbWVUeXBlKTtcblxuXHRcdFx0XHRcdGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IHJlc3VsdCkuY2xvbmUoKTtcblxuXHRcdFx0XHRcdGlmICh0eXBlID09PSAnanNvbicpIHtcblx0XHRcdFx0XHRcdGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDIwNCkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gJyc7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmIChvcHRpb25zLnBhcnNlSnNvbikge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gb3B0aW9ucy5wYXJzZUpzb24oYXdhaXQgcmVzcG9uc2UudGV4dCgpKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gcmVzcG9uc2VbdHlwZV0oKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cblx0XHRfY2FsY3VsYXRlUmV0cnlEZWxheShlcnJvcikge1xuXHRcdFx0dGhpcy5fcmV0cnlDb3VudCsrO1xuXG5cdFx0XHRpZiAodGhpcy5fcmV0cnlDb3VudCA8IHRoaXMuX29wdGlvbnMucmV0cnkubGltaXQgJiYgIShlcnJvciBpbnN0YW5jZW9mIFRpbWVvdXRFcnJvcikpIHtcblx0XHRcdFx0aWYgKGVycm9yIGluc3RhbmNlb2YgSFRUUEVycm9yKSB7XG5cdFx0XHRcdFx0aWYgKCF0aGlzLl9vcHRpb25zLnJldHJ5LnN0YXR1c0NvZGVzLmluY2x1ZGVzKGVycm9yLnJlc3BvbnNlLnN0YXR1cykpIHtcblx0XHRcdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGNvbnN0IHJldHJ5QWZ0ZXIgPSBlcnJvci5yZXNwb25zZS5oZWFkZXJzLmdldCgnUmV0cnktQWZ0ZXInKTtcblx0XHRcdFx0XHRpZiAocmV0cnlBZnRlciAmJiB0aGlzLl9vcHRpb25zLnJldHJ5LmFmdGVyU3RhdHVzQ29kZXMuaW5jbHVkZXMoZXJyb3IucmVzcG9uc2Uuc3RhdHVzKSkge1xuXHRcdFx0XHRcdFx0bGV0IGFmdGVyID0gTnVtYmVyKHJldHJ5QWZ0ZXIpO1xuXHRcdFx0XHRcdFx0aWYgKE51bWJlci5pc05hTihhZnRlcikpIHtcblx0XHRcdFx0XHRcdFx0YWZ0ZXIgPSBEYXRlLnBhcnNlKHJldHJ5QWZ0ZXIpIC0gRGF0ZS5ub3coKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGFmdGVyICo9IDEwMDA7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmICh0eXBlb2YgdGhpcy5fb3B0aW9ucy5yZXRyeS5tYXhSZXRyeUFmdGVyICE9PSAndW5kZWZpbmVkJyAmJiBhZnRlciA+IHRoaXMuX29wdGlvbnMucmV0cnkubWF4UmV0cnlBZnRlcikge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIGFmdGVyO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmIChlcnJvci5yZXNwb25zZS5zdGF0dXMgPT09IDQxMykge1xuXHRcdFx0XHRcdFx0cmV0dXJuIDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29uc3QgQkFDS09GRl9GQUNUT1IgPSAwLjM7XG5cdFx0XHRcdHJldHVybiBCQUNLT0ZGX0ZBQ1RPUiAqICgyICoqICh0aGlzLl9yZXRyeUNvdW50IC0gMSkpICogMTAwMDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0X2RlY29yYXRlUmVzcG9uc2UocmVzcG9uc2UpIHtcblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnBhcnNlSnNvbikge1xuXHRcdFx0XHRyZXNwb25zZS5qc29uID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9vcHRpb25zLnBhcnNlSnNvbihhd2FpdCByZXNwb25zZS50ZXh0KCkpO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzcG9uc2U7XG5cdFx0fVxuXG5cdFx0YXN5bmMgX3JldHJ5KGZuKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRyZXR1cm4gYXdhaXQgZm4oKTtcblx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdGNvbnN0IG1zID0gTWF0aC5taW4odGhpcy5fY2FsY3VsYXRlUmV0cnlEZWxheShlcnJvciksIG1heFNhZmVUaW1lb3V0KTtcblx0XHRcdFx0aWYgKG1zICE9PSAwICYmIHRoaXMuX3JldHJ5Q291bnQgPiAwKSB7XG5cdFx0XHRcdFx0YXdhaXQgZGVsYXkobXMpO1xuXG5cdFx0XHRcdFx0Zm9yIChjb25zdCBob29rIG9mIHRoaXMuX29wdGlvbnMuaG9va3MuYmVmb3JlUmV0cnkpIHtcblx0XHRcdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG5cdFx0XHRcdFx0XHRjb25zdCBob29rUmVzdWx0ID0gYXdhaXQgaG9vayh7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3Q6IHRoaXMucmVxdWVzdCxcblx0XHRcdFx0XHRcdFx0b3B0aW9uczogdGhpcy5fb3B0aW9ucyxcblx0XHRcdFx0XHRcdFx0ZXJyb3IsXG5cdFx0XHRcdFx0XHRcdHJldHJ5Q291bnQ6IHRoaXMuX3JldHJ5Q291bnRcblx0XHRcdFx0XHRcdH0pO1xuXG5cdFx0XHRcdFx0XHQvLyBJZiBgc3RvcGAgaXMgcmV0dXJuZWQgZnJvbSB0aGUgaG9vaywgdGhlIHJldHJ5IHByb2Nlc3MgaXMgc3RvcHBlZFxuXHRcdFx0XHRcdFx0aWYgKGhvb2tSZXN1bHQgPT09IHN0b3ApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9yZXRyeShmbik7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aHJvd0h0dHBFcnJvcnMpIHtcblx0XHRcdFx0XHR0aHJvdyBlcnJvcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGFzeW5jIF9mZXRjaCgpIHtcblx0XHRcdGZvciAoY29uc3QgaG9vayBvZiB0aGlzLl9vcHRpb25zLmhvb2tzLmJlZm9yZVJlcXVlc3QpIHtcblx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3Bcblx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgaG9vayh0aGlzLnJlcXVlc3QsIHRoaXMuX29wdGlvbnMpO1xuXG5cdFx0XHRcdGlmIChyZXN1bHQgaW5zdGFuY2VvZiBSZXF1ZXN0KSB7XG5cdFx0XHRcdFx0dGhpcy5yZXF1ZXN0ID0gcmVzdWx0O1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKHJlc3VsdCBpbnN0YW5jZW9mIFJlc3BvbnNlKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aW1lb3V0ID09PSBmYWxzZSkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5fb3B0aW9ucy5mZXRjaCh0aGlzLnJlcXVlc3QuY2xvbmUoKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aW1lb3V0KHRoaXMucmVxdWVzdC5jbG9uZSgpLCB0aGlzLmFib3J0Q29udHJvbGxlciwgdGhpcy5fb3B0aW9ucyk7XG5cdFx0fVxuXG5cdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRfc3RyZWFtKHJlc3BvbnNlLCBvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcblx0XHRcdGNvbnN0IHRvdGFsQnl0ZXMgPSBOdW1iZXIocmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJykpIHx8IDA7XG5cdFx0XHRsZXQgdHJhbnNmZXJyZWRCeXRlcyA9IDA7XG5cblx0XHRcdHJldHVybiBuZXcgZ2xvYmFscy5SZXNwb25zZShcblx0XHRcdFx0bmV3IGdsb2JhbHMuUmVhZGFibGVTdHJlYW0oe1xuXHRcdFx0XHRcdHN0YXJ0KGNvbnRyb2xsZXIpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG5cblx0XHRcdFx0XHRcdGlmIChvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcblx0XHRcdFx0XHRcdFx0b25Eb3dubG9hZFByb2dyZXNzKHtwZXJjZW50OiAwLCB0cmFuc2ZlcnJlZEJ5dGVzOiAwLCB0b3RhbEJ5dGVzfSwgbmV3IFVpbnQ4QXJyYXkoKSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGFzeW5jIGZ1bmN0aW9uIHJlYWQoKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IHtkb25lLCB2YWx1ZX0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuXHRcdFx0XHRcdFx0XHRpZiAoZG9uZSkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnRyb2xsZXIuY2xvc2UoKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRpZiAob25Eb3dubG9hZFByb2dyZXNzKSB7XG5cdFx0XHRcdFx0XHRcdFx0dHJhbnNmZXJyZWRCeXRlcyArPSB2YWx1ZS5ieXRlTGVuZ3RoO1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHBlcmNlbnQgPSB0b3RhbEJ5dGVzID09PSAwID8gMCA6IHRyYW5zZmVycmVkQnl0ZXMgLyB0b3RhbEJ5dGVzO1xuXHRcdFx0XHRcdFx0XHRcdG9uRG93bmxvYWRQcm9ncmVzcyh7cGVyY2VudCwgdHJhbnNmZXJyZWRCeXRlcywgdG90YWxCeXRlc30sIHZhbHVlKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGNvbnRyb2xsZXIuZW5xdWV1ZSh2YWx1ZSk7XG5cdFx0XHRcdFx0XHRcdHJlYWQoKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmVhZCgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cblx0Y29uc3QgdmFsaWRhdGVBbmRNZXJnZSA9ICguLi5zb3VyY2VzKSA9PiB7XG5cdFx0Zm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykge1xuXHRcdFx0aWYgKCghaXNPYmplY3Qoc291cmNlKSB8fCBBcnJheS5pc0FycmF5KHNvdXJjZSkpICYmIHR5cGVvZiBzb3VyY2UgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBgb3B0aW9uc2AgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3QnKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZGVlcE1lcmdlKHt9LCAuLi5zb3VyY2VzKTtcblx0fTtcblxuXHRjb25zdCBjcmVhdGVJbnN0YW5jZSA9IGRlZmF1bHRzID0+IHtcblx0XHRjb25zdCBreSA9IChpbnB1dCwgb3B0aW9ucykgPT4gbmV3IEt5KGlucHV0LCB2YWxpZGF0ZUFuZE1lcmdlKGRlZmF1bHRzLCBvcHRpb25zKSk7XG5cblx0XHRmb3IgKGNvbnN0IG1ldGhvZCBvZiByZXF1ZXN0TWV0aG9kcykge1xuXHRcdFx0a3lbbWV0aG9kXSA9IChpbnB1dCwgb3B0aW9ucykgPT4gbmV3IEt5KGlucHV0LCB2YWxpZGF0ZUFuZE1lcmdlKGRlZmF1bHRzLCBvcHRpb25zLCB7bWV0aG9kfSkpO1xuXHRcdH1cblxuXHRcdGt5LkhUVFBFcnJvciA9IEhUVFBFcnJvcjtcblx0XHRreS5UaW1lb3V0RXJyb3IgPSBUaW1lb3V0RXJyb3I7XG5cdFx0a3kuY3JlYXRlID0gbmV3RGVmYXVsdHMgPT4gY3JlYXRlSW5zdGFuY2UodmFsaWRhdGVBbmRNZXJnZShuZXdEZWZhdWx0cykpO1xuXHRcdGt5LmV4dGVuZCA9IG5ld0RlZmF1bHRzID0+IGNyZWF0ZUluc3RhbmNlKHZhbGlkYXRlQW5kTWVyZ2UoZGVmYXVsdHMsIG5ld0RlZmF1bHRzKSk7XG5cdFx0a3kuc3RvcCA9IHN0b3A7XG5cblx0XHRyZXR1cm4ga3k7XG5cdH07XG5cblx0dmFyIGluZGV4ID0gY3JlYXRlSW5zdGFuY2UoKTtcblxuXHRyZXR1cm4gaW5kZXg7XG5cbn0pKSk7XG4iLCJmdW5jdGlvbiBub3JtYWxpemUgKHN0cikge1xuICByZXR1cm4gc3RyXG4gICAgICAgICAgLnJlcGxhY2UoL1tcXC9dKy9nLCAnLycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcL1xcPy9nLCAnPycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcL1xcIy9nLCAnIycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcOlxcLy9nLCAnOi8vJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgam9pbmVkID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApLmpvaW4oJy8nKTtcbiAgcmV0dXJuIG5vcm1hbGl6ZShqb2luZWQpO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjcnlwdG9cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJodHRwc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJzdHJlYW1cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidXJsXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInV0aWxcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiemxpYlwiKTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZldGNoO1xuXG5jb25zdCBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xuY29uc3QgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpO1xuY29uc3QgemxpYiA9IHJlcXVpcmUoJ3psaWInKTtcbmNvbnN0IFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xuY29uc3QgZGF0YVVyaVRvQnVmZmVyID0gcmVxdWlyZSgnZGF0YS11cmktdG8tYnVmZmVyJyk7XG5jb25zdCB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuY29uc3QgQmxvYiA9IHJlcXVpcmUoJ2ZldGNoLWJsb2InKTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5cbmNsYXNzIEZldGNoQmFzZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRjb25zdHJ1Y3RvcihtZXNzYWdlLCB0eXBlKSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0Ly8gSGlkZSBjdXN0b20gZXJyb3IgaW1wbGVtZW50YXRpb24gZGV0YWlscyBmcm9tIGVuZC11c2Vyc1xuXHRcdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpO1xuXG5cdFx0dGhpcy50eXBlID0gdHlwZTtcblx0fVxuXG5cdGdldCBuYW1lKCkge1xuXHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG5cdH1cblxuXHRnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG5cdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IubmFtZTtcblx0fVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHt7IGFkZHJlc3M/OiBzdHJpbmcsIGNvZGU6IHN0cmluZywgZGVzdD86IHN0cmluZywgZXJybm86IG51bWJlciwgaW5mbz86IG9iamVjdCwgbWVzc2FnZTogc3RyaW5nLCBwYXRoPzogc3RyaW5nLCBwb3J0PzogbnVtYmVyLCBzeXNjYWxsOiBzdHJpbmd9fSBTeXN0ZW1FcnJvclxuKi9cblxuLyoqXG4gKiBGZXRjaEVycm9yIGludGVyZmFjZSBmb3Igb3BlcmF0aW9uYWwgZXJyb3JzXG4gKi9cbmNsYXNzIEZldGNoRXJyb3IgZXh0ZW5kcyBGZXRjaEJhc2VFcnJvciB7XG5cdC8qKlxuXHQgKiBAcGFyYW0gIHtzdHJpbmd9IG1lc3NhZ2UgLSAgICAgIEVycm9yIG1lc3NhZ2UgZm9yIGh1bWFuXG5cdCAqIEBwYXJhbSAge3N0cmluZ30gW3R5cGVdIC0gICAgICAgIEVycm9yIHR5cGUgZm9yIG1hY2hpbmVcblx0ICogQHBhcmFtICB7U3lzdGVtRXJyb3J9IFtzeXN0ZW1FcnJvcl0gLSBGb3IgTm9kZS5qcyBzeXN0ZW0gZXJyb3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHR5cGUsIHN5c3RlbUVycm9yKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgdHlwZSk7XG5cdFx0Ly8gV2hlbiBlcnIudHlwZSBpcyBgc3lzdGVtYCwgZXJyLmVycm9yZWRTeXNDYWxsIGNvbnRhaW5zIHN5c3RlbSBlcnJvciBhbmQgZXJyLmNvZGUgY29udGFpbnMgc3lzdGVtIGVycm9yIGNvZGVcblx0XHRpZiAoc3lzdGVtRXJyb3IpIHtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1tdWx0aS1hc3NpZ25cblx0XHRcdHRoaXMuY29kZSA9IHRoaXMuZXJybm8gPSBzeXN0ZW1FcnJvci5jb2RlO1xuXHRcdFx0dGhpcy5lcnJvcmVkU3lzQ2FsbCA9IHN5c3RlbUVycm9yLnN5c2NhbGw7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogSXMuanNcbiAqXG4gKiBPYmplY3QgdHlwZSBjaGVja3MuXG4gKi9cblxuY29uc3QgTkFNRSA9IFN5bWJvbC50b1N0cmluZ1RhZztcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIFVSTFNlYXJjaFBhcmFtcyBvYmplY3RcbiAqIHJlZjogaHR0cHM6Ly9naXRodWIuY29tL25vZGUtZmV0Y2gvbm9kZS1mZXRjaC9pc3N1ZXMvMjk2I2lzc3VlY29tbWVudC0zMDc1OTgxNDNcbiAqXG4gKiBAcGFyYW0gIHsqfSBvYmpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGlzVVJMU2VhcmNoUGFyYW1ldGVycyA9IG9iamVjdCA9PiB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmFwcGVuZCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZGVsZXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5nZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmdldEFsbCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuaGFzID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5zZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnNvcnQgPT09ICdmdW5jdGlvbicgJiZcblx0XHRvYmplY3RbTkFNRV0gPT09ICdVUkxTZWFyY2hQYXJhbXMnXG5cdCk7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGBvYmplY3RgIGlzIGEgVzNDIGBCbG9iYCBvYmplY3QgKHdoaWNoIGBGaWxlYCBpbmhlcml0cyBmcm9tKVxuICpcbiAqIEBwYXJhbSAgeyp9IG9ialxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuY29uc3QgaXNCbG9iID0gb2JqZWN0ID0+IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuYXJyYXlCdWZmZXIgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnR5cGUgPT09ICdzdHJpbmcnICYmXG5cdFx0dHlwZW9mIG9iamVjdC5zdHJlYW0gPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0L14oQmxvYnxGaWxlKSQvLnRlc3Qob2JqZWN0W05BTUVdKVxuXHQpO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIHNwZWMtY29tcGxpYW50IGBGb3JtRGF0YWAgb2JqZWN0XG4gKlxuICogQHBhcmFtIHsqfSBvYmplY3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzRm9ybURhdGEob2JqZWN0KSB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmFwcGVuZCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3Quc2V0ID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5nZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmdldEFsbCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZGVsZXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5rZXlzID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC52YWx1ZXMgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmVudHJpZXMgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0b2JqZWN0W05BTUVdID09PSAnRm9ybURhdGEnXG5cdCk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYW4gaW5zdGFuY2Ugb2YgQWJvcnRTaWduYWwuXG4gKlxuICogQHBhcmFtICB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBpc0Fib3J0U2lnbmFsID0gb2JqZWN0ID0+IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdG9iamVjdFtOQU1FXSA9PT0gJ0Fib3J0U2lnbmFsJ1xuXHQpO1xufTtcblxuY29uc3QgY2FycmlhZ2UgPSAnXFxyXFxuJztcbmNvbnN0IGRhc2hlcyA9ICctJy5yZXBlYXQoMik7XG5jb25zdCBjYXJyaWFnZUxlbmd0aCA9IEJ1ZmZlci5ieXRlTGVuZ3RoKGNhcnJpYWdlKTtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRhcnlcbiAqL1xuY29uc3QgZ2V0Rm9vdGVyID0gYm91bmRhcnkgPT4gYCR7ZGFzaGVzfSR7Ym91bmRhcnl9JHtkYXNoZXN9JHtjYXJyaWFnZS5yZXBlYXQoMil9YDtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRhcnlcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0geyp9IGZpZWxkXG4gKlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBnZXRIZWFkZXIoYm91bmRhcnksIG5hbWUsIGZpZWxkKSB7XG5cdGxldCBoZWFkZXIgPSAnJztcblxuXHRoZWFkZXIgKz0gYCR7ZGFzaGVzfSR7Ym91bmRhcnl9JHtjYXJyaWFnZX1gO1xuXHRoZWFkZXIgKz0gYENvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT1cIiR7bmFtZX1cImA7XG5cblx0aWYgKGlzQmxvYihmaWVsZCkpIHtcblx0XHRoZWFkZXIgKz0gYDsgZmlsZW5hbWU9XCIke2ZpZWxkLm5hbWV9XCIke2NhcnJpYWdlfWA7XG5cdFx0aGVhZGVyICs9IGBDb250ZW50LVR5cGU6ICR7ZmllbGQudHlwZSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJ31gO1xuXHR9XG5cblx0cmV0dXJuIGAke2hlYWRlcn0ke2NhcnJpYWdlLnJlcGVhdCgyKX1gO1xufVxuXG4vKipcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuY29uc3QgZ2V0Qm91bmRhcnkgPSAoKSA9PiBjcnlwdG8ucmFuZG9tQnl0ZXMoOCkudG9TdHJpbmcoJ2hleCcpO1xuXG4vKipcbiAqIEBwYXJhbSB7Rm9ybURhdGF9IGZvcm1cbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZGFyeVxuICovXG5hc3luYyBmdW5jdGlvbiAqIGZvcm1EYXRhSXRlcmF0b3IoZm9ybSwgYm91bmRhcnkpIHtcblx0Zm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIGZvcm0pIHtcblx0XHR5aWVsZCBnZXRIZWFkZXIoYm91bmRhcnksIG5hbWUsIHZhbHVlKTtcblxuXHRcdGlmIChpc0Jsb2IodmFsdWUpKSB7XG5cdFx0XHR5aWVsZCAqIHZhbHVlLnN0cmVhbSgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR5aWVsZCB2YWx1ZTtcblx0XHR9XG5cblx0XHR5aWVsZCBjYXJyaWFnZTtcblx0fVxuXG5cdHlpZWxkIGdldEZvb3Rlcihib3VuZGFyeSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtGb3JtRGF0YX0gZm9ybVxuICogQHBhcmFtIHtzdHJpbmd9IGJvdW5kYXJ5XG4gKi9cbmZ1bmN0aW9uIGdldEZvcm1EYXRhTGVuZ3RoKGZvcm0sIGJvdW5kYXJ5KSB7XG5cdGxldCBsZW5ndGggPSAwO1xuXG5cdGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBmb3JtKSB7XG5cdFx0bGVuZ3RoICs9IEJ1ZmZlci5ieXRlTGVuZ3RoKGdldEhlYWRlcihib3VuZGFyeSwgbmFtZSwgdmFsdWUpKTtcblxuXHRcdGlmIChpc0Jsb2IodmFsdWUpKSB7XG5cdFx0XHRsZW5ndGggKz0gdmFsdWUuc2l6ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGVuZ3RoICs9IEJ1ZmZlci5ieXRlTGVuZ3RoKFN0cmluZyh2YWx1ZSkpO1xuXHRcdH1cblxuXHRcdGxlbmd0aCArPSBjYXJyaWFnZUxlbmd0aDtcblx0fVxuXG5cdGxlbmd0aCArPSBCdWZmZXIuYnl0ZUxlbmd0aChnZXRGb290ZXIoYm91bmRhcnkpKTtcblxuXHRyZXR1cm4gbGVuZ3RoO1xufVxuXG5jb25zdCBJTlRFUk5BTFMgPSBTeW1ib2woJ0JvZHkgaW50ZXJuYWxzJyk7XG5cbi8qKlxuICogQm9keSBtaXhpblxuICpcbiAqIFJlZjogaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2JvZHlcbiAqXG4gKiBAcGFyYW0gICBTdHJlYW0gIGJvZHkgIFJlYWRhYmxlIHN0cmVhbVxuICogQHBhcmFtICAgT2JqZWN0ICBvcHRzICBSZXNwb25zZSBvcHRpb25zXG4gKiBAcmV0dXJuICBWb2lkXG4gKi9cbmNsYXNzIEJvZHkge1xuXHRjb25zdHJ1Y3Rvcihib2R5LCB7XG5cdFx0c2l6ZSA9IDBcblx0fSA9IHt9KSB7XG5cdFx0bGV0IGJvdW5kYXJ5ID0gbnVsbDtcblxuXHRcdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0XHQvLyBCb2R5IGlzIHVuZGVmaW5lZCBvciBudWxsXG5cdFx0XHRib2R5ID0gbnVsbDtcblx0XHR9IGVsc2UgaWYgKGlzVVJMU2VhcmNoUGFyYW1ldGVycyhib2R5KSkge1xuXHRcdC8vIEJvZHkgaXMgYSBVUkxTZWFyY2hQYXJhbXNcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5LnRvU3RyaW5nKCkpO1xuXHRcdH0gZWxzZSBpZiAoaXNCbG9iKGJvZHkpKSA7IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSkgOyBlbHNlIGlmICh1dGlsLnR5cGVzLmlzQW55QXJyYXlCdWZmZXIoYm9keSkpIHtcblx0XHRcdC8vIEJvZHkgaXMgQXJyYXlCdWZmZXJcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5KTtcblx0XHR9IGVsc2UgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhib2R5KSkge1xuXHRcdFx0Ly8gQm9keSBpcyBBcnJheUJ1ZmZlclZpZXdcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5LmJ1ZmZlciwgYm9keS5ieXRlT2Zmc2V0LCBib2R5LmJ5dGVMZW5ndGgpO1xuXHRcdH0gZWxzZSBpZiAoYm9keSBpbnN0YW5jZW9mIFN0cmVhbSkgOyBlbHNlIGlmIChpc0Zvcm1EYXRhKGJvZHkpKSB7XG5cdFx0XHQvLyBCb2R5IGlzIGFuIGluc3RhbmNlIG9mIGZvcm1kYXRhLW5vZGVcblx0XHRcdGJvdW5kYXJ5ID0gYE5vZGVGZXRjaEZvcm1EYXRhQm91bmRhcnkke2dldEJvdW5kYXJ5KCl9YDtcblx0XHRcdGJvZHkgPSBTdHJlYW0uUmVhZGFibGUuZnJvbShmb3JtRGF0YUl0ZXJhdG9yKGJvZHksIGJvdW5kYXJ5KSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIE5vbmUgb2YgdGhlIGFib3ZlXG5cdFx0XHQvLyBjb2VyY2UgdG8gc3RyaW5nIHRoZW4gYnVmZmVyXG5cdFx0XHRib2R5ID0gQnVmZmVyLmZyb20oU3RyaW5nKGJvZHkpKTtcblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMU10gPSB7XG5cdFx0XHRib2R5LFxuXHRcdFx0Ym91bmRhcnksXG5cdFx0XHRkaXN0dXJiZWQ6IGZhbHNlLFxuXHRcdFx0ZXJyb3I6IG51bGxcblx0XHR9O1xuXHRcdHRoaXMuc2l6ZSA9IHNpemU7XG5cblx0XHRpZiAoYm9keSBpbnN0YW5jZW9mIFN0cmVhbSkge1xuXHRcdFx0Ym9keS5vbignZXJyb3InLCBlcnIgPT4ge1xuXHRcdFx0XHRjb25zdCBlcnJvciA9IGVyciBpbnN0YW5jZW9mIEZldGNoQmFzZUVycm9yID9cblx0XHRcdFx0XHRlcnIgOlxuXHRcdFx0XHRcdG5ldyBGZXRjaEVycm9yKGBJbnZhbGlkIHJlc3BvbnNlIGJvZHkgd2hpbGUgdHJ5aW5nIHRvIGZldGNoICR7dGhpcy51cmx9OiAke2Vyci5tZXNzYWdlfWAsICdzeXN0ZW0nLCBlcnIpO1xuXHRcdFx0XHR0aGlzW0lOVEVSTkFMU10uZXJyb3IgPSBlcnJvcjtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdGdldCBib2R5KCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMU10uYm9keTtcblx0fVxuXG5cdGdldCBib2R5VXNlZCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFNdLmRpc3R1cmJlZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWNvZGUgcmVzcG9uc2UgYXMgQXJyYXlCdWZmZXJcblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMgYXJyYXlCdWZmZXIoKSB7XG5cdFx0Y29uc3Qge2J1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aH0gPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gYnVmZmVyLnNsaWNlKGJ5dGVPZmZzZXQsIGJ5dGVPZmZzZXQgKyBieXRlTGVuZ3RoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm4gcmF3IHJlc3BvbnNlIGFzIEJsb2Jcblx0ICpcblx0ICogQHJldHVybiBQcm9taXNlXG5cdCAqL1xuXHRhc3luYyBibG9iKCkge1xuXHRcdGNvbnN0IGN0ID0gKHRoaXMuaGVhZGVycyAmJiB0aGlzLmhlYWRlcnMuZ2V0KCdjb250ZW50LXR5cGUnKSkgfHwgKHRoaXNbSU5URVJOQUxTXS5ib2R5ICYmIHRoaXNbSU5URVJOQUxTXS5ib2R5LnR5cGUpIHx8ICcnO1xuXHRcdGNvbnN0IGJ1ZiA9IGF3YWl0IHRoaXMuYnVmZmVyKCk7XG5cblx0XHRyZXR1cm4gbmV3IEJsb2IoW2J1Zl0sIHtcblx0XHRcdHR5cGU6IGN0XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIGpzb25cblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMganNvbigpIHtcblx0XHRjb25zdCBidWZmZXIgPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gSlNPTi5wYXJzZShidWZmZXIudG9TdHJpbmcoKSk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIHRleHRcblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMgdGV4dCgpIHtcblx0XHRjb25zdCBidWZmZXIgPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIGJ1ZmZlciAobm9uLXNwZWMgYXBpKVxuXHQgKlxuXHQgKiBAcmV0dXJuICBQcm9taXNlXG5cdCAqL1xuXHRidWZmZXIoKSB7XG5cdFx0cmV0dXJuIGNvbnN1bWVCb2R5KHRoaXMpO1xuXHR9XG59XG5cbi8vIEluIGJyb3dzZXJzLCBhbGwgcHJvcGVydGllcyBhcmUgZW51bWVyYWJsZS5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJvZHkucHJvdG90eXBlLCB7XG5cdGJvZHk6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0Ym9keVVzZWQ6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0YXJyYXlCdWZmZXI6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0YmxvYjoge2VudW1lcmFibGU6IHRydWV9LFxuXHRqc29uOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHRleHQ6IHtlbnVtZXJhYmxlOiB0cnVlfVxufSk7XG5cbi8qKlxuICogQ29uc3VtZSBhbmQgY29udmVydCBhbiBlbnRpcmUgQm9keSB0byBhIEJ1ZmZlci5cbiAqXG4gKiBSZWY6IGh0dHBzOi8vZmV0Y2guc3BlYy53aGF0d2cub3JnLyNjb25jZXB0LWJvZHktY29uc3VtZS1ib2R5XG4gKlxuICogQHJldHVybiBQcm9taXNlXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvbnN1bWVCb2R5KGRhdGEpIHtcblx0aWYgKGRhdGFbSU5URVJOQUxTXS5kaXN0dXJiZWQpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBib2R5IHVzZWQgYWxyZWFkeSBmb3I6ICR7ZGF0YS51cmx9YCk7XG5cdH1cblxuXHRkYXRhW0lOVEVSTkFMU10uZGlzdHVyYmVkID0gdHJ1ZTtcblxuXHRpZiAoZGF0YVtJTlRFUk5BTFNdLmVycm9yKSB7XG5cdFx0dGhyb3cgZGF0YVtJTlRFUk5BTFNdLmVycm9yO1xuXHR9XG5cblx0bGV0IHtib2R5fSA9IGRhdGE7XG5cblx0Ly8gQm9keSBpcyBudWxsXG5cdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5hbGxvYygwKTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgYmxvYlxuXHRpZiAoaXNCbG9iKGJvZHkpKSB7XG5cdFx0Ym9keSA9IGJvZHkuc3RyZWFtKCk7XG5cdH1cblxuXHQvLyBCb2R5IGlzIGJ1ZmZlclxuXHRpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSB7XG5cdFx0cmV0dXJuIGJvZHk7XG5cdH1cblxuXHQvKiBjOCBpZ25vcmUgbmV4dCAzICovXG5cdGlmICghKGJvZHkgaW5zdGFuY2VvZiBTdHJlYW0pKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5hbGxvYygwKTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgc3RyZWFtXG5cdC8vIGdldCByZWFkeSB0byBhY3R1YWxseSBjb25zdW1lIHRoZSBib2R5XG5cdGNvbnN0IGFjY3VtID0gW107XG5cdGxldCBhY2N1bUJ5dGVzID0gMDtcblxuXHR0cnkge1xuXHRcdGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgYm9keSkge1xuXHRcdFx0aWYgKGRhdGEuc2l6ZSA+IDAgJiYgYWNjdW1CeXRlcyArIGNodW5rLmxlbmd0aCA+IGRhdGEuc2l6ZSkge1xuXHRcdFx0XHRjb25zdCBlcnIgPSBuZXcgRmV0Y2hFcnJvcihgY29udGVudCBzaXplIGF0ICR7ZGF0YS51cmx9IG92ZXIgbGltaXQ6ICR7ZGF0YS5zaXplfWAsICdtYXgtc2l6ZScpO1xuXHRcdFx0XHRib2R5LmRlc3Ryb3koZXJyKTtcblx0XHRcdFx0dGhyb3cgZXJyO1xuXHRcdFx0fVxuXG5cdFx0XHRhY2N1bUJ5dGVzICs9IGNodW5rLmxlbmd0aDtcblx0XHRcdGFjY3VtLnB1c2goY2h1bmspO1xuXHRcdH1cblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRpZiAoZXJyb3IgaW5zdGFuY2VvZiBGZXRjaEJhc2VFcnJvcikge1xuXHRcdFx0dGhyb3cgZXJyb3I7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIE90aGVyIGVycm9ycywgc3VjaCBhcyBpbmNvcnJlY3QgY29udGVudC1lbmNvZGluZ1xuXHRcdFx0dGhyb3cgbmV3IEZldGNoRXJyb3IoYEludmFsaWQgcmVzcG9uc2UgYm9keSB3aGlsZSB0cnlpbmcgdG8gZmV0Y2ggJHtkYXRhLnVybH06ICR7ZXJyb3IubWVzc2FnZX1gLCAnc3lzdGVtJywgZXJyb3IpO1xuXHRcdH1cblx0fVxuXG5cdGlmIChib2R5LnJlYWRhYmxlRW5kZWQgPT09IHRydWUgfHwgYm9keS5fcmVhZGFibGVTdGF0ZS5lbmRlZCA9PT0gdHJ1ZSkge1xuXHRcdHRyeSB7XG5cdFx0XHRpZiAoYWNjdW0uZXZlcnkoYyA9PiB0eXBlb2YgYyA9PT0gJ3N0cmluZycpKSB7XG5cdFx0XHRcdHJldHVybiBCdWZmZXIuZnJvbShhY2N1bS5qb2luKCcnKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBCdWZmZXIuY29uY2F0KGFjY3VtLCBhY2N1bUJ5dGVzKTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhyb3cgbmV3IEZldGNoRXJyb3IoYENvdWxkIG5vdCBjcmVhdGUgQnVmZmVyIGZyb20gcmVzcG9uc2UgYm9keSBmb3IgJHtkYXRhLnVybH06ICR7ZXJyb3IubWVzc2FnZX1gLCAnc3lzdGVtJywgZXJyb3IpO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHR0aHJvdyBuZXcgRmV0Y2hFcnJvcihgUHJlbWF0dXJlIGNsb3NlIG9mIHNlcnZlciByZXNwb25zZSB3aGlsZSB0cnlpbmcgdG8gZmV0Y2ggJHtkYXRhLnVybH1gKTtcblx0fVxufVxuXG4vKipcbiAqIENsb25lIGJvZHkgZ2l2ZW4gUmVzL1JlcSBpbnN0YW5jZVxuICpcbiAqIEBwYXJhbSAgIE1peGVkICAgaW5zdGFuY2UgICAgICAgUmVzcG9uc2Ugb3IgUmVxdWVzdCBpbnN0YW5jZVxuICogQHBhcmFtICAgU3RyaW5nICBoaWdoV2F0ZXJNYXJrICBoaWdoV2F0ZXJNYXJrIGZvciBib3RoIFBhc3NUaHJvdWdoIGJvZHkgc3RyZWFtc1xuICogQHJldHVybiAgTWl4ZWRcbiAqL1xuY29uc3QgY2xvbmUgPSAoaW5zdGFuY2UsIGhpZ2hXYXRlck1hcmspID0+IHtcblx0bGV0IHAxO1xuXHRsZXQgcDI7XG5cdGxldCB7Ym9keX0gPSBpbnN0YW5jZTtcblxuXHQvLyBEb24ndCBhbGxvdyBjbG9uaW5nIGEgdXNlZCBib2R5XG5cdGlmIChpbnN0YW5jZS5ib2R5VXNlZCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignY2Fubm90IGNsb25lIGJvZHkgYWZ0ZXIgaXQgaXMgdXNlZCcpO1xuXHR9XG5cblx0Ly8gQ2hlY2sgdGhhdCBib2R5IGlzIGEgc3RyZWFtIGFuZCBub3QgZm9ybS1kYXRhIG9iamVjdFxuXHQvLyBub3RlOiB3ZSBjYW4ndCBjbG9uZSB0aGUgZm9ybS1kYXRhIG9iamVjdCB3aXRob3V0IGhhdmluZyBpdCBhcyBhIGRlcGVuZGVuY3lcblx0aWYgKChib2R5IGluc3RhbmNlb2YgU3RyZWFtKSAmJiAodHlwZW9mIGJvZHkuZ2V0Qm91bmRhcnkgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0Ly8gVGVlIGluc3RhbmNlIGJvZHlcblx0XHRwMSA9IG5ldyBTdHJlYW0uUGFzc1Rocm91Z2goe2hpZ2hXYXRlck1hcmt9KTtcblx0XHRwMiA9IG5ldyBTdHJlYW0uUGFzc1Rocm91Z2goe2hpZ2hXYXRlck1hcmt9KTtcblx0XHRib2R5LnBpcGUocDEpO1xuXHRcdGJvZHkucGlwZShwMik7XG5cdFx0Ly8gU2V0IGluc3RhbmNlIGJvZHkgdG8gdGVlZCBib2R5IGFuZCByZXR1cm4gdGhlIG90aGVyIHRlZWQgYm9keVxuXHRcdGluc3RhbmNlW0lOVEVSTkFMU10uYm9keSA9IHAxO1xuXHRcdGJvZHkgPSBwMjtcblx0fVxuXG5cdHJldHVybiBib2R5O1xufTtcblxuLyoqXG4gKiBQZXJmb3JtcyB0aGUgb3BlcmF0aW9uIFwiZXh0cmFjdCBhIGBDb250ZW50LVR5cGVgIHZhbHVlIGZyb20gfG9iamVjdHxcIiBhc1xuICogc3BlY2lmaWVkIGluIHRoZSBzcGVjaWZpY2F0aW9uOlxuICogaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2NvbmNlcHQtYm9keWluaXQtZXh0cmFjdFxuICpcbiAqIFRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IGluc3RhbmNlLmJvZHkgaXMgcHJlc2VudC5cbiAqXG4gKiBAcGFyYW0ge2FueX0gYm9keSBBbnkgb3B0aW9ucy5ib2R5IGlucHV0XG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH1cbiAqL1xuY29uc3QgZXh0cmFjdENvbnRlbnRUeXBlID0gKGJvZHksIHJlcXVlc3QpID0+IHtcblx0Ly8gQm9keSBpcyBudWxsIG9yIHVuZGVmaW5lZFxuXHRpZiAoYm9keSA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBzdHJpbmdcblx0aWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuXHRcdHJldHVybiAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jztcblx0fVxuXG5cdC8vIEJvZHkgaXMgYSBVUkxTZWFyY2hQYXJhbXNcblx0aWYgKGlzVVJMU2VhcmNoUGFyYW1ldGVycyhib2R5KSkge1xuXHRcdHJldHVybiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9VVRGLTgnO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBibG9iXG5cdGlmIChpc0Jsb2IoYm9keSkpIHtcblx0XHRyZXR1cm4gYm9keS50eXBlIHx8IG51bGw7XG5cdH1cblxuXHQvLyBCb2R5IGlzIGEgQnVmZmVyIChCdWZmZXIsIEFycmF5QnVmZmVyIG9yIEFycmF5QnVmZmVyVmlldylcblx0aWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSB8fCB1dGlsLnR5cGVzLmlzQW55QXJyYXlCdWZmZXIoYm9keSkgfHwgQXJyYXlCdWZmZXIuaXNWaWV3KGJvZHkpKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvLyBEZXRlY3QgZm9ybSBkYXRhIGlucHV0IGZyb20gZm9ybS1kYXRhIG1vZHVsZVxuXHRpZiAoYm9keSAmJiB0eXBlb2YgYm9keS5nZXRCb3VuZGFyeSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdHJldHVybiBgbXVsdGlwYXJ0L2Zvcm0tZGF0YTtib3VuZGFyeT0ke2JvZHkuZ2V0Qm91bmRhcnkoKX1gO1xuXHR9XG5cblx0aWYgKGlzRm9ybURhdGEoYm9keSkpIHtcblx0XHRyZXR1cm4gYG11bHRpcGFydC9mb3JtLWRhdGE7IGJvdW5kYXJ5PSR7cmVxdWVzdFtJTlRFUk5BTFNdLmJvdW5kYXJ5fWA7XG5cdH1cblxuXHQvLyBCb2R5IGlzIHN0cmVhbSAtIGNhbid0IHJlYWxseSBkbyBtdWNoIGFib3V0IHRoaXNcblx0aWYgKGJvZHkgaW5zdGFuY2VvZiBTdHJlYW0pIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIEJvZHkgY29uc3RydWN0b3IgZGVmYXVsdHMgb3RoZXIgdGhpbmdzIHRvIHN0cmluZ1xuXHRyZXR1cm4gJ3RleHQvcGxhaW47Y2hhcnNldD1VVEYtOCc7XG59O1xuXG4vKipcbiAqIFRoZSBGZXRjaCBTdGFuZGFyZCB0cmVhdHMgdGhpcyBhcyBpZiBcInRvdGFsIGJ5dGVzXCIgaXMgYSBwcm9wZXJ0eSBvbiB0aGUgYm9keS5cbiAqIEZvciB1cywgd2UgaGF2ZSB0byBleHBsaWNpdGx5IGdldCBpdCB3aXRoIGEgZnVuY3Rpb24uXG4gKlxuICogcmVmOiBodHRwczovL2ZldGNoLnNwZWMud2hhdHdnLm9yZy8jY29uY2VwdC1ib2R5LXRvdGFsLWJ5dGVzXG4gKlxuICogQHBhcmFtIHthbnl9IG9iai5ib2R5IEJvZHkgb2JqZWN0IGZyb20gdGhlIEJvZHkgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVsbH1cbiAqL1xuY29uc3QgZ2V0VG90YWxCeXRlcyA9IHJlcXVlc3QgPT4ge1xuXHRjb25zdCB7Ym9keX0gPSByZXF1ZXN0O1xuXG5cdC8vIEJvZHkgaXMgbnVsbCBvciB1bmRlZmluZWRcblx0aWYgKGJvZHkgPT09IG51bGwpIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXG5cdC8vIEJvZHkgaXMgQmxvYlxuXHRpZiAoaXNCbG9iKGJvZHkpKSB7XG5cdFx0cmV0dXJuIGJvZHkuc2l6ZTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgQnVmZmVyXG5cdGlmIChCdWZmZXIuaXNCdWZmZXIoYm9keSkpIHtcblx0XHRyZXR1cm4gYm9keS5sZW5ndGg7XG5cdH1cblxuXHQvLyBEZXRlY3QgZm9ybSBkYXRhIGlucHV0IGZyb20gZm9ybS1kYXRhIG1vZHVsZVxuXHRpZiAoYm9keSAmJiB0eXBlb2YgYm9keS5nZXRMZW5ndGhTeW5jID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0cmV0dXJuIGJvZHkuaGFzS25vd25MZW5ndGggJiYgYm9keS5oYXNLbm93bkxlbmd0aCgpID8gYm9keS5nZXRMZW5ndGhTeW5jKCkgOiBudWxsO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBhIHNwZWMtY29tcGxpYW50IGZvcm0tZGF0YVxuXHRpZiAoaXNGb3JtRGF0YShib2R5KSkge1xuXHRcdHJldHVybiBnZXRGb3JtRGF0YUxlbmd0aChyZXF1ZXN0W0lOVEVSTkFMU10uYm91bmRhcnkpO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBzdHJlYW1cblx0cmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIFdyaXRlIGEgQm9keSB0byBhIE5vZGUuanMgV3JpdGFibGVTdHJlYW0gKGUuZy4gaHR0cC5SZXF1ZXN0KSBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtTdHJlYW0uV3JpdGFibGV9IGRlc3QgVGhlIHN0cmVhbSB0byB3cml0ZSB0by5cbiAqIEBwYXJhbSBvYmouYm9keSBCb2R5IG9iamVjdCBmcm9tIHRoZSBCb2R5IGluc3RhbmNlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmNvbnN0IHdyaXRlVG9TdHJlYW0gPSAoZGVzdCwge2JvZHl9KSA9PiB7XG5cdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0Ly8gQm9keSBpcyBudWxsXG5cdFx0ZGVzdC5lbmQoKTtcblx0fSBlbHNlIGlmIChpc0Jsb2IoYm9keSkpIHtcblx0XHQvLyBCb2R5IGlzIEJsb2Jcblx0XHRib2R5LnN0cmVhbSgpLnBpcGUoZGVzdCk7XG5cdH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSB7XG5cdFx0Ly8gQm9keSBpcyBidWZmZXJcblx0XHRkZXN0LndyaXRlKGJvZHkpO1xuXHRcdGRlc3QuZW5kKCk7XG5cdH0gZWxzZSB7XG5cdFx0Ly8gQm9keSBpcyBzdHJlYW1cblx0XHRib2R5LnBpcGUoZGVzdCk7XG5cdH1cbn07XG5cbi8qKlxuICogSGVhZGVycy5qc1xuICpcbiAqIEhlYWRlcnMgY2xhc3Mgb2ZmZXJzIGNvbnZlbmllbnQgaGVscGVyc1xuICovXG5cbmNvbnN0IHZhbGlkYXRlSGVhZGVyTmFtZSA9IHR5cGVvZiBodHRwLnZhbGlkYXRlSGVhZGVyTmFtZSA9PT0gJ2Z1bmN0aW9uJyA/XG5cdGh0dHAudmFsaWRhdGVIZWFkZXJOYW1lIDpcblx0bmFtZSA9PiB7XG5cdFx0aWYgKCEvXltcXF5gXFwtXFx3ISMkJSYnKisufH5dKyQvLnRlc3QobmFtZSkpIHtcblx0XHRcdGNvbnN0IGVyciA9IG5ldyBUeXBlRXJyb3IoYEhlYWRlciBuYW1lIG11c3QgYmUgYSB2YWxpZCBIVFRQIHRva2VuIFske25hbWV9XWApO1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGVyciwgJ2NvZGUnLCB7dmFsdWU6ICdFUlJfSU5WQUxJRF9IVFRQX1RPS0VOJ30pO1xuXHRcdFx0dGhyb3cgZXJyO1xuXHRcdH1cblx0fTtcblxuY29uc3QgdmFsaWRhdGVIZWFkZXJWYWx1ZSA9IHR5cGVvZiBodHRwLnZhbGlkYXRlSGVhZGVyVmFsdWUgPT09ICdmdW5jdGlvbicgP1xuXHRodHRwLnZhbGlkYXRlSGVhZGVyVmFsdWUgOlxuXHQobmFtZSwgdmFsdWUpID0+IHtcblx0XHRpZiAoL1teXFx0XFx1MDAyMC1cXHUwMDdFXFx1MDA4MC1cXHUwMEZGXS8udGVzdCh2YWx1ZSkpIHtcblx0XHRcdGNvbnN0IGVyciA9IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgY2hhcmFjdGVyIGluIGhlYWRlciBjb250ZW50IFtcIiR7bmFtZX1cIl1gKTtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlcnIsICdjb2RlJywge3ZhbHVlOiAnRVJSX0lOVkFMSURfQ0hBUid9KTtcblx0XHRcdHRocm93IGVycjtcblx0XHR9XG5cdH07XG5cbi8qKlxuICogQHR5cGVkZWYge0hlYWRlcnMgfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHwgSXRlcmFibGU8cmVhZG9ubHkgW3N0cmluZywgc3RyaW5nXT4gfCBJdGVyYWJsZTxJdGVyYWJsZTxzdHJpbmc+Pn0gSGVhZGVyc0luaXRcbiAqL1xuXG4vKipcbiAqIFRoaXMgRmV0Y2ggQVBJIGludGVyZmFjZSBhbGxvd3MgeW91IHRvIHBlcmZvcm0gdmFyaW91cyBhY3Rpb25zIG9uIEhUVFAgcmVxdWVzdCBhbmQgcmVzcG9uc2UgaGVhZGVycy5cbiAqIFRoZXNlIGFjdGlvbnMgaW5jbHVkZSByZXRyaWV2aW5nLCBzZXR0aW5nLCBhZGRpbmcgdG8sIGFuZCByZW1vdmluZy5cbiAqIEEgSGVhZGVycyBvYmplY3QgaGFzIGFuIGFzc29jaWF0ZWQgaGVhZGVyIGxpc3QsIHdoaWNoIGlzIGluaXRpYWxseSBlbXB0eSBhbmQgY29uc2lzdHMgb2YgemVybyBvciBtb3JlIG5hbWUgYW5kIHZhbHVlIHBhaXJzLlxuICogWW91IGNhbiBhZGQgdG8gdGhpcyB1c2luZyBtZXRob2RzIGxpa2UgYXBwZW5kKCkgKHNlZSBFeGFtcGxlcy4pXG4gKiBJbiBhbGwgbWV0aG9kcyBvZiB0aGlzIGludGVyZmFjZSwgaGVhZGVyIG5hbWVzIGFyZSBtYXRjaGVkIGJ5IGNhc2UtaW5zZW5zaXRpdmUgYnl0ZSBzZXF1ZW5jZS5cbiAqXG4gKi9cbmNsYXNzIEhlYWRlcnMgZXh0ZW5kcyBVUkxTZWFyY2hQYXJhbXMge1xuXHQvKipcblx0ICogSGVhZGVycyBjbGFzc1xuXHQgKlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQHBhcmFtIHtIZWFkZXJzSW5pdH0gW2luaXRdIC0gUmVzcG9uc2UgaGVhZGVyc1xuXHQgKi9cblx0Y29uc3RydWN0b3IoaW5pdCkge1xuXHRcdC8vIFZhbGlkYXRlIGFuZCBub3JtYWxpemUgaW5pdCBvYmplY3QgaW4gW25hbWUsIHZhbHVlKHMpXVtdXG5cdFx0LyoqIEB0eXBlIHtzdHJpbmdbXVtdfSAqL1xuXHRcdGxldCByZXN1bHQgPSBbXTtcblx0XHRpZiAoaW5pdCBpbnN0YW5jZW9mIEhlYWRlcnMpIHtcblx0XHRcdGNvbnN0IHJhdyA9IGluaXQucmF3KCk7XG5cdFx0XHRmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZXNdIG9mIE9iamVjdC5lbnRyaWVzKHJhdykpIHtcblx0XHRcdFx0cmVzdWx0LnB1c2goLi4udmFsdWVzLm1hcCh2YWx1ZSA9PiBbbmFtZSwgdmFsdWVdKSk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChpbml0ID09IG51bGwpIDsgZWxzZSBpZiAodHlwZW9mIGluaXQgPT09ICdvYmplY3QnICYmICF1dGlsLnR5cGVzLmlzQm94ZWRQcmltaXRpdmUoaW5pdCkpIHtcblx0XHRcdGNvbnN0IG1ldGhvZCA9IGluaXRbU3ltYm9sLml0ZXJhdG9yXTtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lcS1udWxsLCBlcWVxZXFcblx0XHRcdGlmIChtZXRob2QgPT0gbnVsbCkge1xuXHRcdFx0XHQvLyBSZWNvcmQ8Qnl0ZVN0cmluZywgQnl0ZVN0cmluZz5cblx0XHRcdFx0cmVzdWx0LnB1c2goLi4uT2JqZWN0LmVudHJpZXMoaW5pdCkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKHR5cGVvZiBtZXRob2QgIT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdIZWFkZXIgcGFpcnMgbXVzdCBiZSBpdGVyYWJsZScpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU2VxdWVuY2U8c2VxdWVuY2U8Qnl0ZVN0cmluZz4+XG5cdFx0XHRcdC8vIE5vdGU6IHBlciBzcGVjIHdlIGhhdmUgdG8gZmlyc3QgZXhoYXVzdCB0aGUgbGlzdHMgdGhlbiBwcm9jZXNzIHRoZW1cblx0XHRcdFx0cmVzdWx0ID0gWy4uLmluaXRdXG5cdFx0XHRcdFx0Lm1hcChwYWlyID0+IHtcblx0XHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdFx0dHlwZW9mIHBhaXIgIT09ICdvYmplY3QnIHx8IHV0aWwudHlwZXMuaXNCb3hlZFByaW1pdGl2ZShwYWlyKVxuXHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0VhY2ggaGVhZGVyIHBhaXIgbXVzdCBiZSBhbiBpdGVyYWJsZSBvYmplY3QnKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIFsuLi5wYWlyXTtcblx0XHRcdFx0XHR9KS5tYXAocGFpciA9PiB7XG5cdFx0XHRcdFx0XHRpZiAocGFpci5sZW5ndGggIT09IDIpIHtcblx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRWFjaCBoZWFkZXIgcGFpciBtdXN0IGJlIGEgbmFtZS92YWx1ZSB0dXBsZScpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXR1cm4gWy4uLnBhaXJdO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdGYWlsZWQgdG8gY29uc3RydWN0IFxcJ0hlYWRlcnNcXCc6IFRoZSBwcm92aWRlZCB2YWx1ZSBpcyBub3Qgb2YgdHlwZSBcXCcoc2VxdWVuY2U8c2VxdWVuY2U8Qnl0ZVN0cmluZz4+IG9yIHJlY29yZDxCeXRlU3RyaW5nLCBCeXRlU3RyaW5nPiknKTtcblx0XHR9XG5cblx0XHQvLyBWYWxpZGF0ZSBhbmQgbG93ZXJjYXNlXG5cdFx0cmVzdWx0ID1cblx0XHRcdHJlc3VsdC5sZW5ndGggPiAwID9cblx0XHRcdFx0cmVzdWx0Lm1hcCgoW25hbWUsIHZhbHVlXSkgPT4ge1xuXHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyTmFtZShuYW1lKTtcblx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlclZhbHVlKG5hbWUsIFN0cmluZyh2YWx1ZSkpO1xuXHRcdFx0XHRcdHJldHVybiBbU3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKCksIFN0cmluZyh2YWx1ZSldO1xuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdHVuZGVmaW5lZDtcblxuXHRcdHN1cGVyKHJlc3VsdCk7XG5cblx0XHQvLyBSZXR1cm5pbmcgYSBQcm94eSB0aGF0IHdpbGwgbG93ZXJjYXNlIGtleSBuYW1lcywgdmFsaWRhdGUgcGFyYW1ldGVycyBhbmQgc29ydCBrZXlzXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0cnVjdG9yLXJldHVyblxuXHRcdHJldHVybiBuZXcgUHJveHkodGhpcywge1xuXHRcdFx0Z2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpIHtcblx0XHRcdFx0c3dpdGNoIChwKSB7XG5cdFx0XHRcdFx0Y2FzZSAnYXBwZW5kJzpcblx0XHRcdFx0XHRjYXNlICdzZXQnOlxuXHRcdFx0XHRcdFx0cmV0dXJuIChuYW1lLCB2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlck5hbWUobmFtZSk7XG5cdFx0XHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyVmFsdWUobmFtZSwgU3RyaW5nKHZhbHVlKSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlW3BdLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0cmVjZWl2ZXIsXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKCksXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKHZhbHVlKVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdGNhc2UgJ2RlbGV0ZSc6XG5cdFx0XHRcdFx0Y2FzZSAnaGFzJzpcblx0XHRcdFx0XHRjYXNlICdnZXRBbGwnOlxuXHRcdFx0XHRcdFx0cmV0dXJuIG5hbWUgPT4ge1xuXHRcdFx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlck5hbWUobmFtZSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlW3BdLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0cmVjZWl2ZXIsXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKClcblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRjYXNlICdrZXlzJzpcblx0XHRcdFx0XHRcdHJldHVybiAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRhcmdldC5zb3J0KCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBuZXcgU2V0KFVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGUua2V5cy5jYWxsKHRhcmdldCkpLmtleXMoKTtcblx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0cmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvKiBjOCBpZ25vcmUgbmV4dCAqL1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0IFtTeW1ib2wudG9TdHJpbmdUYWddKCkge1xuXHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG5cdH1cblxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRoaXMpO1xuXHR9XG5cblx0Z2V0KG5hbWUpIHtcblx0XHRjb25zdCB2YWx1ZXMgPSB0aGlzLmdldEFsbChuYW1lKTtcblx0XHRpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0bGV0IHZhbHVlID0gdmFsdWVzLmpvaW4oJywgJyk7XG5cdFx0aWYgKC9eY29udGVudC1lbmNvZGluZyQvaS50ZXN0KG5hbWUpKSB7XG5cdFx0XHR2YWx1ZSA9IHZhbHVlLnRvTG93ZXJDYXNlKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9XG5cblx0Zm9yRWFjaChjYWxsYmFjaykge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0Y2FsbGJhY2sodGhpcy5nZXQobmFtZSksIG5hbWUpO1xuXHRcdH1cblx0fVxuXG5cdCogdmFsdWVzKCkge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0eWllbGQgdGhpcy5nZXQobmFtZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEB0eXBlIHsoKSA9PiBJdGVyYWJsZUl0ZXJhdG9yPFtzdHJpbmcsIHN0cmluZ10+fVxuXHQgKi9cblx0KiBlbnRyaWVzKCkge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0eWllbGQgW25hbWUsIHRoaXMuZ2V0KG5hbWUpXTtcblx0XHR9XG5cdH1cblxuXHRbU3ltYm9sLml0ZXJhdG9yXSgpIHtcblx0XHRyZXR1cm4gdGhpcy5lbnRyaWVzKCk7XG5cdH1cblxuXHQvKipcblx0ICogTm9kZS1mZXRjaCBub24tc3BlYyBtZXRob2Rcblx0ICogcmV0dXJuaW5nIGFsbCBoZWFkZXJzIGFuZCB0aGVpciB2YWx1ZXMgYXMgYXJyYXlcblx0ICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHN0cmluZ1tdPn1cblx0ICovXG5cdHJhdygpIHtcblx0XHRyZXR1cm4gWy4uLnRoaXMua2V5cygpXS5yZWR1Y2UoKHJlc3VsdCwga2V5KSA9PiB7XG5cdFx0XHRyZXN1bHRba2V5XSA9IHRoaXMuZ2V0QWxsKGtleSk7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0sIHt9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGb3IgYmV0dGVyIGNvbnNvbGUubG9nKGhlYWRlcnMpIGFuZCBhbHNvIHRvIGNvbnZlcnQgSGVhZGVycyBpbnRvIE5vZGUuanMgUmVxdWVzdCBjb21wYXRpYmxlIGZvcm1hdFxuXHQgKi9cblx0W1N5bWJvbC5mb3IoJ25vZGVqcy51dGlsLmluc3BlY3QuY3VzdG9tJyldKCkge1xuXHRcdHJldHVybiBbLi4udGhpcy5rZXlzKCldLnJlZHVjZSgocmVzdWx0LCBrZXkpID0+IHtcblx0XHRcdGNvbnN0IHZhbHVlcyA9IHRoaXMuZ2V0QWxsKGtleSk7XG5cdFx0XHQvLyBIdHRwLnJlcXVlc3QoKSBvbmx5IHN1cHBvcnRzIHN0cmluZyBhcyBIb3N0IGhlYWRlci5cblx0XHRcdC8vIFRoaXMgaGFjayBtYWtlcyBzcGVjaWZ5aW5nIGN1c3RvbSBIb3N0IGhlYWRlciBwb3NzaWJsZS5cblx0XHRcdGlmIChrZXkgPT09ICdob3N0Jykge1xuXHRcdFx0XHRyZXN1bHRba2V5XSA9IHZhbHVlc1swXTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJlc3VsdFtrZXldID0gdmFsdWVzLmxlbmd0aCA+IDEgPyB2YWx1ZXMgOiB2YWx1ZXNbMF07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fSwge30pO1xuXHR9XG59XG5cbi8qKlxuICogUmUtc2hhcGluZyBvYmplY3QgZm9yIFdlYiBJREwgdGVzdHNcbiAqIE9ubHkgbmVlZCB0byBkbyBpdCBmb3Igb3ZlcnJpZGRlbiBtZXRob2RzXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFxuXHRIZWFkZXJzLnByb3RvdHlwZSxcblx0WydnZXQnLCAnZW50cmllcycsICdmb3JFYWNoJywgJ3ZhbHVlcyddLnJlZHVjZSgocmVzdWx0LCBwcm9wZXJ0eSkgPT4ge1xuXHRcdHJlc3VsdFtwcm9wZXJ0eV0gPSB7ZW51bWVyYWJsZTogdHJ1ZX07XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSwge30pXG4pO1xuXG4vKipcbiAqIENyZWF0ZSBhIEhlYWRlcnMgb2JqZWN0IGZyb20gYW4gaHR0cC5JbmNvbWluZ01lc3NhZ2UucmF3SGVhZGVycywgaWdub3JpbmcgdGhvc2UgdGhhdCBkb1xuICogbm90IGNvbmZvcm0gdG8gSFRUUCBncmFtbWFyIHByb2R1Y3Rpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoJ2h0dHAnKS5JbmNvbWluZ01lc3NhZ2VbJ3Jhd0hlYWRlcnMnXX0gaGVhZGVyc1xuICovXG5mdW5jdGlvbiBmcm9tUmF3SGVhZGVycyhoZWFkZXJzID0gW10pIHtcblx0cmV0dXJuIG5ldyBIZWFkZXJzKFxuXHRcdGhlYWRlcnNcblx0XHRcdC8vIFNwbGl0IGludG8gcGFpcnNcblx0XHRcdC5yZWR1Y2UoKHJlc3VsdCwgdmFsdWUsIGluZGV4LCBhcnJheSkgPT4ge1xuXHRcdFx0XHRpZiAoaW5kZXggJSAyID09PSAwKSB7XG5cdFx0XHRcdFx0cmVzdWx0LnB1c2goYXJyYXkuc2xpY2UoaW5kZXgsIGluZGV4ICsgMikpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH0sIFtdKVxuXHRcdFx0LmZpbHRlcigoW25hbWUsIHZhbHVlXSkgPT4ge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyTmFtZShuYW1lKTtcblx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlclZhbHVlKG5hbWUsIFN0cmluZyh2YWx1ZSkpO1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cblx0KTtcbn1cblxuY29uc3QgcmVkaXJlY3RTdGF0dXMgPSBuZXcgU2V0KFszMDEsIDMwMiwgMzAzLCAzMDcsIDMwOF0pO1xuXG4vKipcbiAqIFJlZGlyZWN0IGNvZGUgbWF0Y2hpbmdcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gY29kZSAtIFN0YXR1cyBjb2RlXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBpc1JlZGlyZWN0ID0gY29kZSA9PiB7XG5cdHJldHVybiByZWRpcmVjdFN0YXR1cy5oYXMoY29kZSk7XG59O1xuXG4vKipcbiAqIFJlc3BvbnNlLmpzXG4gKlxuICogUmVzcG9uc2UgY2xhc3MgcHJvdmlkZXMgY29udGVudCBkZWNvZGluZ1xuICovXG5cbmNvbnN0IElOVEVSTkFMUyQxID0gU3ltYm9sKCdSZXNwb25zZSBpbnRlcm5hbHMnKTtcblxuLyoqXG4gKiBSZXNwb25zZSBjbGFzc1xuICpcbiAqIEBwYXJhbSAgIFN0cmVhbSAgYm9keSAgUmVhZGFibGUgc3RyZWFtXG4gKiBAcGFyYW0gICBPYmplY3QgIG9wdHMgIFJlc3BvbnNlIG9wdGlvbnNcbiAqIEByZXR1cm4gIFZvaWRcbiAqL1xuY2xhc3MgUmVzcG9uc2UgZXh0ZW5kcyBCb2R5IHtcblx0Y29uc3RydWN0b3IoYm9keSA9IG51bGwsIG9wdGlvbnMgPSB7fSkge1xuXHRcdHN1cGVyKGJvZHksIG9wdGlvbnMpO1xuXG5cdFx0Y29uc3Qgc3RhdHVzID0gb3B0aW9ucy5zdGF0dXMgfHwgMjAwO1xuXHRcdGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyhvcHRpb25zLmhlYWRlcnMpO1xuXG5cdFx0aWYgKGJvZHkgIT09IG51bGwgJiYgIWhlYWRlcnMuaGFzKCdDb250ZW50LVR5cGUnKSkge1xuXHRcdFx0Y29uc3QgY29udGVudFR5cGUgPSBleHRyYWN0Q29udGVudFR5cGUoYm9keSk7XG5cdFx0XHRpZiAoY29udGVudFR5cGUpIHtcblx0XHRcdFx0aGVhZGVycy5hcHBlbmQoJ0NvbnRlbnQtVHlwZScsIGNvbnRlbnRUeXBlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMUyQxXSA9IHtcblx0XHRcdHVybDogb3B0aW9ucy51cmwsXG5cdFx0XHRzdGF0dXMsXG5cdFx0XHRzdGF0dXNUZXh0OiBvcHRpb25zLnN0YXR1c1RleHQgfHwgJycsXG5cdFx0XHRoZWFkZXJzLFxuXHRcdFx0Y291bnRlcjogb3B0aW9ucy5jb3VudGVyLFxuXHRcdFx0aGlnaFdhdGVyTWFyazogb3B0aW9ucy5oaWdoV2F0ZXJNYXJrXG5cdFx0fTtcblx0fVxuXG5cdGdldCB1cmwoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLnVybCB8fCAnJztcblx0fVxuXG5cdGdldCBzdGF0dXMoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLnN0YXR1cztcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZW5pZW5jZSBwcm9wZXJ0eSByZXByZXNlbnRpbmcgaWYgdGhlIHJlcXVlc3QgZW5kZWQgbm9ybWFsbHlcblx0ICovXG5cdGdldCBvaygpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uc3RhdHVzID49IDIwMCAmJiB0aGlzW0lOVEVSTkFMUyQxXS5zdGF0dXMgPCAzMDA7XG5cdH1cblxuXHRnZXQgcmVkaXJlY3RlZCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uY291bnRlciA+IDA7XG5cdH1cblxuXHRnZXQgc3RhdHVzVGV4dCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uc3RhdHVzVGV4dDtcblx0fVxuXG5cdGdldCBoZWFkZXJzKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQxXS5oZWFkZXJzO1xuXHR9XG5cblx0Z2V0IGhpZ2hXYXRlck1hcmsoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLmhpZ2hXYXRlck1hcms7XG5cdH1cblxuXHQvKipcblx0ICogQ2xvbmUgdGhpcyByZXNwb25zZVxuXHQgKlxuXHQgKiBAcmV0dXJuICBSZXNwb25zZVxuXHQgKi9cblx0Y2xvbmUoKSB7XG5cdFx0cmV0dXJuIG5ldyBSZXNwb25zZShjbG9uZSh0aGlzLCB0aGlzLmhpZ2hXYXRlck1hcmspLCB7XG5cdFx0XHR1cmw6IHRoaXMudXJsLFxuXHRcdFx0c3RhdHVzOiB0aGlzLnN0YXR1cyxcblx0XHRcdHN0YXR1c1RleHQ6IHRoaXMuc3RhdHVzVGV4dCxcblx0XHRcdGhlYWRlcnM6IHRoaXMuaGVhZGVycyxcblx0XHRcdG9rOiB0aGlzLm9rLFxuXHRcdFx0cmVkaXJlY3RlZDogdGhpcy5yZWRpcmVjdGVkLFxuXHRcdFx0c2l6ZTogdGhpcy5zaXplXG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IHVybCAgICBUaGUgVVJMIHRoYXQgdGhlIG5ldyByZXNwb25zZSBpcyB0byBvcmlnaW5hdGUgZnJvbS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXR1cyBBbiBvcHRpb25hbCBzdGF0dXMgY29kZSBmb3IgdGhlIHJlc3BvbnNlIChlLmcuLCAzMDIuKVxuXHQgKiBAcmV0dXJucyB7UmVzcG9uc2V9ICAgIEEgUmVzcG9uc2Ugb2JqZWN0LlxuXHQgKi9cblx0c3RhdGljIHJlZGlyZWN0KHVybCwgc3RhdHVzID0gMzAyKSB7XG5cdFx0aWYgKCFpc1JlZGlyZWN0KHN0YXR1cykpIHtcblx0XHRcdHRocm93IG5ldyBSYW5nZUVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSBcInJlZGlyZWN0XCIgb24gXCJyZXNwb25zZVwiOiBJbnZhbGlkIHN0YXR1cyBjb2RlJyk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBSZXNwb25zZShudWxsLCB7XG5cdFx0XHRoZWFkZXJzOiB7XG5cdFx0XHRcdGxvY2F0aW9uOiBuZXcgVVJMKHVybCkudG9TdHJpbmcoKVxuXHRcdFx0fSxcblx0XHRcdHN0YXR1c1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0IFtTeW1ib2wudG9TdHJpbmdUYWddKCkge1xuXHRcdHJldHVybiAnUmVzcG9uc2UnO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlc3BvbnNlLnByb3RvdHlwZSwge1xuXHR1cmw6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0c3RhdHVzOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdG9rOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHJlZGlyZWN0ZWQ6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0c3RhdHVzVGV4dDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRoZWFkZXJzOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdGNsb25lOiB7ZW51bWVyYWJsZTogdHJ1ZX1cbn0pO1xuXG5jb25zdCBnZXRTZWFyY2ggPSBwYXJzZWRVUkwgPT4ge1xuXHRpZiAocGFyc2VkVVJMLnNlYXJjaCkge1xuXHRcdHJldHVybiBwYXJzZWRVUkwuc2VhcmNoO1xuXHR9XG5cblx0Y29uc3QgbGFzdE9mZnNldCA9IHBhcnNlZFVSTC5ocmVmLmxlbmd0aCAtIDE7XG5cdGNvbnN0IGhhc2ggPSBwYXJzZWRVUkwuaGFzaCB8fCAocGFyc2VkVVJMLmhyZWZbbGFzdE9mZnNldF0gPT09ICcjJyA/ICcjJyA6ICcnKTtcblx0cmV0dXJuIHBhcnNlZFVSTC5ocmVmW2xhc3RPZmZzZXQgLSBoYXNoLmxlbmd0aF0gPT09ICc/JyA/ICc/JyA6ICcnO1xufTtcblxuY29uc3QgSU5URVJOQUxTJDIgPSBTeW1ib2woJ1JlcXVlc3QgaW50ZXJuYWxzJyk7XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYW4gaW5zdGFuY2Ugb2YgUmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gIHsqfSBvYmpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGlzUmVxdWVzdCA9IG9iamVjdCA9PiB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0W0lOVEVSTkFMUyQyXSA9PT0gJ29iamVjdCdcblx0KTtcbn07XG5cbi8qKlxuICogUmVxdWVzdCBjbGFzc1xuICpcbiAqIEBwYXJhbSAgIE1peGVkICAgaW5wdXQgIFVybCBvciBSZXF1ZXN0IGluc3RhbmNlXG4gKiBAcGFyYW0gICBPYmplY3QgIGluaXQgICBDdXN0b20gb3B0aW9uc1xuICogQHJldHVybiAgVm9pZFxuICovXG5jbGFzcyBSZXF1ZXN0IGV4dGVuZHMgQm9keSB7XG5cdGNvbnN0cnVjdG9yKGlucHV0LCBpbml0ID0ge30pIHtcblx0XHRsZXQgcGFyc2VkVVJMO1xuXG5cdFx0Ly8gTm9ybWFsaXplIGlucHV0IGFuZCBmb3JjZSBVUkwgdG8gYmUgZW5jb2RlZCBhcyBVVEYtOCAoaHR0cHM6Ly9naXRodWIuY29tL25vZGUtZmV0Y2gvbm9kZS1mZXRjaC9pc3N1ZXMvMjQ1KVxuXHRcdGlmIChpc1JlcXVlc3QoaW5wdXQpKSB7XG5cdFx0XHRwYXJzZWRVUkwgPSBuZXcgVVJMKGlucHV0LnVybCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBhcnNlZFVSTCA9IG5ldyBVUkwoaW5wdXQpO1xuXHRcdFx0aW5wdXQgPSB7fTtcblx0XHR9XG5cblx0XHRsZXQgbWV0aG9kID0gaW5pdC5tZXRob2QgfHwgaW5wdXQubWV0aG9kIHx8ICdHRVQnO1xuXHRcdG1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVxLW51bGwsIGVxZXFlcVxuXHRcdGlmICgoKGluaXQuYm9keSAhPSBudWxsIHx8IGlzUmVxdWVzdChpbnB1dCkpICYmIGlucHV0LmJvZHkgIT09IG51bGwpICYmXG5cdFx0XHQobWV0aG9kID09PSAnR0VUJyB8fCBtZXRob2QgPT09ICdIRUFEJykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlcXVlc3Qgd2l0aCBHRVQvSEVBRCBtZXRob2QgY2Fubm90IGhhdmUgYm9keScpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGlucHV0Qm9keSA9IGluaXQuYm9keSA/XG5cdFx0XHRpbml0LmJvZHkgOlxuXHRcdFx0KGlzUmVxdWVzdChpbnB1dCkgJiYgaW5wdXQuYm9keSAhPT0gbnVsbCA/XG5cdFx0XHRcdGNsb25lKGlucHV0KSA6XG5cdFx0XHRcdG51bGwpO1xuXG5cdFx0c3VwZXIoaW5wdXRCb2R5LCB7XG5cdFx0XHRzaXplOiBpbml0LnNpemUgfHwgaW5wdXQuc2l6ZSB8fCAwXG5cdFx0fSk7XG5cblx0XHRjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoaW5pdC5oZWFkZXJzIHx8IGlucHV0LmhlYWRlcnMgfHwge30pO1xuXG5cdFx0aWYgKGlucHV0Qm9keSAhPT0gbnVsbCAmJiAhaGVhZGVycy5oYXMoJ0NvbnRlbnQtVHlwZScpKSB7XG5cdFx0XHRjb25zdCBjb250ZW50VHlwZSA9IGV4dHJhY3RDb250ZW50VHlwZShpbnB1dEJvZHksIHRoaXMpO1xuXHRcdFx0aWYgKGNvbnRlbnRUeXBlKSB7XG5cdFx0XHRcdGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCBjb250ZW50VHlwZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0bGV0IHNpZ25hbCA9IGlzUmVxdWVzdChpbnB1dCkgP1xuXHRcdFx0aW5wdXQuc2lnbmFsIDpcblx0XHRcdG51bGw7XG5cdFx0aWYgKCdzaWduYWwnIGluIGluaXQpIHtcblx0XHRcdHNpZ25hbCA9IGluaXQuc2lnbmFsO1xuXHRcdH1cblxuXHRcdGlmIChzaWduYWwgIT09IG51bGwgJiYgIWlzQWJvcnRTaWduYWwoc2lnbmFsKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgc2lnbmFsIHRvIGJlIGFuIGluc3RhbmNlb2YgQWJvcnRTaWduYWwnKTtcblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMUyQyXSA9IHtcblx0XHRcdG1ldGhvZCxcblx0XHRcdHJlZGlyZWN0OiBpbml0LnJlZGlyZWN0IHx8IGlucHV0LnJlZGlyZWN0IHx8ICdmb2xsb3cnLFxuXHRcdFx0aGVhZGVycyxcblx0XHRcdHBhcnNlZFVSTCxcblx0XHRcdHNpZ25hbFxuXHRcdH07XG5cblx0XHQvLyBOb2RlLWZldGNoLW9ubHkgb3B0aW9uc1xuXHRcdHRoaXMuZm9sbG93ID0gaW5pdC5mb2xsb3cgPT09IHVuZGVmaW5lZCA/IChpbnB1dC5mb2xsb3cgPT09IHVuZGVmaW5lZCA/IDIwIDogaW5wdXQuZm9sbG93KSA6IGluaXQuZm9sbG93O1xuXHRcdHRoaXMuY29tcHJlc3MgPSBpbml0LmNvbXByZXNzID09PSB1bmRlZmluZWQgPyAoaW5wdXQuY29tcHJlc3MgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBpbnB1dC5jb21wcmVzcykgOiBpbml0LmNvbXByZXNzO1xuXHRcdHRoaXMuY291bnRlciA9IGluaXQuY291bnRlciB8fCBpbnB1dC5jb3VudGVyIHx8IDA7XG5cdFx0dGhpcy5hZ2VudCA9IGluaXQuYWdlbnQgfHwgaW5wdXQuYWdlbnQ7XG5cdFx0dGhpcy5oaWdoV2F0ZXJNYXJrID0gaW5pdC5oaWdoV2F0ZXJNYXJrIHx8IGlucHV0LmhpZ2hXYXRlck1hcmsgfHwgMTYzODQ7XG5cdFx0dGhpcy5pbnNlY3VyZUhUVFBQYXJzZXIgPSBpbml0Lmluc2VjdXJlSFRUUFBhcnNlciB8fCBpbnB1dC5pbnNlY3VyZUhUVFBQYXJzZXIgfHwgZmFsc2U7XG5cdH1cblxuXHRnZXQgbWV0aG9kKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQyXS5tZXRob2Q7XG5cdH1cblxuXHRnZXQgdXJsKCkge1xuXHRcdHJldHVybiB1cmwuZm9ybWF0KHRoaXNbSU5URVJOQUxTJDJdLnBhcnNlZFVSTCk7XG5cdH1cblxuXHRnZXQgaGVhZGVycygpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMl0uaGVhZGVycztcblx0fVxuXG5cdGdldCByZWRpcmVjdCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMl0ucmVkaXJlY3Q7XG5cdH1cblxuXHRnZXQgc2lnbmFsKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQyXS5zaWduYWw7XG5cdH1cblxuXHQvKipcblx0ICogQ2xvbmUgdGhpcyByZXF1ZXN0XG5cdCAqXG5cdCAqIEByZXR1cm4gIFJlcXVlc3Rcblx0ICovXG5cdGNsb25lKCkge1xuXHRcdHJldHVybiBuZXcgUmVxdWVzdCh0aGlzKTtcblx0fVxuXG5cdGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcblx0XHRyZXR1cm4gJ1JlcXVlc3QnO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlcXVlc3QucHJvdG90eXBlLCB7XG5cdG1ldGhvZDoge2VudW1lcmFibGU6IHRydWV9LFxuXHR1cmw6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0aGVhZGVyczoge2VudW1lcmFibGU6IHRydWV9LFxuXHRyZWRpcmVjdDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRjbG9uZToge2VudW1lcmFibGU6IHRydWV9LFxuXHRzaWduYWw6IHtlbnVtZXJhYmxlOiB0cnVlfVxufSk7XG5cbi8qKlxuICogQ29udmVydCBhIFJlcXVlc3QgdG8gTm9kZS5qcyBodHRwIHJlcXVlc3Qgb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0gICBSZXF1ZXN0ICBBIFJlcXVlc3QgaW5zdGFuY2VcbiAqIEByZXR1cm4gIE9iamVjdCAgIFRoZSBvcHRpb25zIG9iamVjdCB0byBiZSBwYXNzZWQgdG8gaHR0cC5yZXF1ZXN0XG4gKi9cbmNvbnN0IGdldE5vZGVSZXF1ZXN0T3B0aW9ucyA9IHJlcXVlc3QgPT4ge1xuXHRjb25zdCB7cGFyc2VkVVJMfSA9IHJlcXVlc3RbSU5URVJOQUxTJDJdO1xuXHRjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMocmVxdWVzdFtJTlRFUk5BTFMkMl0uaGVhZGVycyk7XG5cblx0Ly8gRmV0Y2ggc3RlcCAxLjNcblx0aWYgKCFoZWFkZXJzLmhhcygnQWNjZXB0JykpIHtcblx0XHRoZWFkZXJzLnNldCgnQWNjZXB0JywgJyovKicpO1xuXHR9XG5cblx0Ly8gSFRUUC1uZXR3b3JrLW9yLWNhY2hlIGZldGNoIHN0ZXBzIDIuNC0yLjdcblx0bGV0IGNvbnRlbnRMZW5ndGhWYWx1ZSA9IG51bGw7XG5cdGlmIChyZXF1ZXN0LmJvZHkgPT09IG51bGwgJiYgL14ocG9zdHxwdXQpJC9pLnRlc3QocmVxdWVzdC5tZXRob2QpKSB7XG5cdFx0Y29udGVudExlbmd0aFZhbHVlID0gJzAnO1xuXHR9XG5cblx0aWYgKHJlcXVlc3QuYm9keSAhPT0gbnVsbCkge1xuXHRcdGNvbnN0IHRvdGFsQnl0ZXMgPSBnZXRUb3RhbEJ5dGVzKHJlcXVlc3QpO1xuXHRcdC8vIFNldCBDb250ZW50LUxlbmd0aCBpZiB0b3RhbEJ5dGVzIGlzIGEgbnVtYmVyICh0aGF0IGlzIG5vdCBOYU4pXG5cdFx0aWYgKHR5cGVvZiB0b3RhbEJ5dGVzID09PSAnbnVtYmVyJyAmJiAhTnVtYmVyLmlzTmFOKHRvdGFsQnl0ZXMpKSB7XG5cdFx0XHRjb250ZW50TGVuZ3RoVmFsdWUgPSBTdHJpbmcodG90YWxCeXRlcyk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGNvbnRlbnRMZW5ndGhWYWx1ZSkge1xuXHRcdGhlYWRlcnMuc2V0KCdDb250ZW50LUxlbmd0aCcsIGNvbnRlbnRMZW5ndGhWYWx1ZSk7XG5cdH1cblxuXHQvLyBIVFRQLW5ldHdvcmstb3ItY2FjaGUgZmV0Y2ggc3RlcCAyLjExXG5cdGlmICghaGVhZGVycy5oYXMoJ1VzZXItQWdlbnQnKSkge1xuXHRcdGhlYWRlcnMuc2V0KCdVc2VyLUFnZW50JywgJ25vZGUtZmV0Y2gnKTtcblx0fVxuXG5cdC8vIEhUVFAtbmV0d29yay1vci1jYWNoZSBmZXRjaCBzdGVwIDIuMTVcblx0aWYgKHJlcXVlc3QuY29tcHJlc3MgJiYgIWhlYWRlcnMuaGFzKCdBY2NlcHQtRW5jb2RpbmcnKSkge1xuXHRcdGhlYWRlcnMuc2V0KCdBY2NlcHQtRW5jb2RpbmcnLCAnZ3ppcCxkZWZsYXRlLGJyJyk7XG5cdH1cblxuXHRsZXQge2FnZW50fSA9IHJlcXVlc3Q7XG5cdGlmICh0eXBlb2YgYWdlbnQgPT09ICdmdW5jdGlvbicpIHtcblx0XHRhZ2VudCA9IGFnZW50KHBhcnNlZFVSTCk7XG5cdH1cblxuXHRpZiAoIWhlYWRlcnMuaGFzKCdDb25uZWN0aW9uJykgJiYgIWFnZW50KSB7XG5cdFx0aGVhZGVycy5zZXQoJ0Nvbm5lY3Rpb24nLCAnY2xvc2UnKTtcblx0fVxuXG5cdC8vIEhUVFAtbmV0d29yayBmZXRjaCBzdGVwIDQuMlxuXHQvLyBjaHVua2VkIGVuY29kaW5nIGlzIGhhbmRsZWQgYnkgTm9kZS5qc1xuXG5cdGNvbnN0IHNlYXJjaCA9IGdldFNlYXJjaChwYXJzZWRVUkwpO1xuXG5cdC8vIE1hbnVhbGx5IHNwcmVhZCB0aGUgVVJMIG9iamVjdCBpbnN0ZWFkIG9mIHNwcmVhZCBzeW50YXhcblx0Y29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG5cdFx0cGF0aDogcGFyc2VkVVJMLnBhdGhuYW1lICsgc2VhcmNoLFxuXHRcdHBhdGhuYW1lOiBwYXJzZWRVUkwucGF0aG5hbWUsXG5cdFx0aG9zdG5hbWU6IHBhcnNlZFVSTC5ob3N0bmFtZSxcblx0XHRwcm90b2NvbDogcGFyc2VkVVJMLnByb3RvY29sLFxuXHRcdHBvcnQ6IHBhcnNlZFVSTC5wb3J0LFxuXHRcdGhhc2g6IHBhcnNlZFVSTC5oYXNoLFxuXHRcdHNlYXJjaDogcGFyc2VkVVJMLnNlYXJjaCxcblx0XHRxdWVyeTogcGFyc2VkVVJMLnF1ZXJ5LFxuXHRcdGhyZWY6IHBhcnNlZFVSTC5ocmVmLFxuXHRcdG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG5cdFx0aGVhZGVyczogaGVhZGVyc1tTeW1ib2wuZm9yKCdub2RlanMudXRpbC5pbnNwZWN0LmN1c3RvbScpXSgpLFxuXHRcdGluc2VjdXJlSFRUUFBhcnNlcjogcmVxdWVzdC5pbnNlY3VyZUhUVFBQYXJzZXIsXG5cdFx0YWdlbnRcblx0fTtcblxuXHRyZXR1cm4gcmVxdWVzdE9wdGlvbnM7XG59O1xuXG4vKipcbiAqIEFib3J0RXJyb3IgaW50ZXJmYWNlIGZvciBjYW5jZWxsZWQgcmVxdWVzdHNcbiAqL1xuY2xhc3MgQWJvcnRFcnJvciBleHRlbmRzIEZldGNoQmFzZUVycm9yIHtcblx0Y29uc3RydWN0b3IobWVzc2FnZSwgdHlwZSA9ICdhYm9ydGVkJykge1xuXHRcdHN1cGVyKG1lc3NhZ2UsIHR5cGUpO1xuXHR9XG59XG5cbi8qKlxuICogSW5kZXguanNcbiAqXG4gKiBhIHJlcXVlc3QgQVBJIGNvbXBhdGlibGUgd2l0aCB3aW5kb3cuZmV0Y2hcbiAqXG4gKiBBbGwgc3BlYyBhbGdvcml0aG0gc3RlcCBudW1iZXJzIGFyZSBiYXNlZCBvbiBodHRwczovL2ZldGNoLnNwZWMud2hhdHdnLm9yZy9jb21taXQtc25hcHNob3RzL2FlNzE2ODIyY2IzYTYxODQzMjI2Y2QwOTBlZWZjNjU4OTQ0NmMxZDIvLlxuICovXG5cbmNvbnN0IHN1cHBvcnRlZFNjaGVtYXMgPSBuZXcgU2V0KFsnZGF0YTonLCAnaHR0cDonLCAnaHR0cHM6J10pO1xuXG4vKipcbiAqIEZldGNoIGZ1bmN0aW9uXG4gKlxuICogQHBhcmFtICAge3N0cmluZyB8IFVSTCB8IGltcG9ydCgnLi9yZXF1ZXN0JykuZGVmYXVsdH0gdXJsIC0gQWJzb2x1dGUgdXJsIG9yIFJlcXVlc3QgaW5zdGFuY2VcbiAqIEBwYXJhbSAgIHsqfSBbb3B0aW9uc19dIC0gRmV0Y2ggb3B0aW9uc1xuICogQHJldHVybiAge1Byb21pc2U8aW1wb3J0KCcuL3Jlc3BvbnNlJykuZGVmYXVsdD59XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZldGNoKHVybCwgb3B0aW9uc18pIHtcblx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHQvLyBCdWlsZCByZXF1ZXN0IG9iamVjdFxuXHRcdGNvbnN0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdCh1cmwsIG9wdGlvbnNfKTtcblx0XHRjb25zdCBvcHRpb25zID0gZ2V0Tm9kZVJlcXVlc3RPcHRpb25zKHJlcXVlc3QpO1xuXHRcdGlmICghc3VwcG9ydGVkU2NoZW1hcy5oYXMob3B0aW9ucy5wcm90b2NvbCkpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYG5vZGUtZmV0Y2ggY2Fubm90IGxvYWQgJHt1cmx9LiBVUkwgc2NoZW1lIFwiJHtvcHRpb25zLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpfVwiIGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG5cdFx0fVxuXG5cdFx0aWYgKG9wdGlvbnMucHJvdG9jb2wgPT09ICdkYXRhOicpIHtcblx0XHRcdGNvbnN0IGRhdGEgPSBkYXRhVXJpVG9CdWZmZXIocmVxdWVzdC51cmwpO1xuXHRcdFx0Y29uc3QgcmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UoZGF0YSwge2hlYWRlcnM6IHsnQ29udGVudC1UeXBlJzogZGF0YS50eXBlRnVsbH19KTtcblx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFdyYXAgaHR0cC5yZXF1ZXN0IGludG8gZmV0Y2hcblx0XHRjb25zdCBzZW5kID0gKG9wdGlvbnMucHJvdG9jb2wgPT09ICdodHRwczonID8gaHR0cHMgOiBodHRwKS5yZXF1ZXN0O1xuXHRcdGNvbnN0IHtzaWduYWx9ID0gcmVxdWVzdDtcblx0XHRsZXQgcmVzcG9uc2UgPSBudWxsO1xuXG5cdFx0Y29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdFx0XHRjb25zdCBlcnJvciA9IG5ldyBBYm9ydEVycm9yKCdUaGUgb3BlcmF0aW9uIHdhcyBhYm9ydGVkLicpO1xuXHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdGlmIChyZXF1ZXN0LmJvZHkgJiYgcmVxdWVzdC5ib2R5IGluc3RhbmNlb2YgU3RyZWFtLlJlYWRhYmxlKSB7XG5cdFx0XHRcdHJlcXVlc3QuYm9keS5kZXN0cm95KGVycm9yKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCFyZXNwb25zZSB8fCAhcmVzcG9uc2UuYm9keSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHJlc3BvbnNlLmJvZHkuZW1pdCgnZXJyb3InLCBlcnJvcik7XG5cdFx0fTtcblxuXHRcdGlmIChzaWduYWwgJiYgc2lnbmFsLmFib3J0ZWQpIHtcblx0XHRcdGFib3J0KCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgYWJvcnRBbmRGaW5hbGl6ZSA9ICgpID0+IHtcblx0XHRcdGFib3J0KCk7XG5cdFx0XHRmaW5hbGl6ZSgpO1xuXHRcdH07XG5cblx0XHQvLyBTZW5kIHJlcXVlc3Rcblx0XHRjb25zdCByZXF1ZXN0XyA9IHNlbmQob3B0aW9ucyk7XG5cblx0XHRpZiAoc2lnbmFsKSB7XG5cdFx0XHRzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFuZEZpbmFsaXplKTtcblx0XHR9XG5cblx0XHRjb25zdCBmaW5hbGl6ZSA9ICgpID0+IHtcblx0XHRcdHJlcXVlc3RfLmFib3J0KCk7XG5cdFx0XHRpZiAoc2lnbmFsKSB7XG5cdFx0XHRcdHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0QW5kRmluYWxpemUpO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRyZXF1ZXN0Xy5vbignZXJyb3InLCBlcnIgPT4ge1xuXHRcdFx0cmVqZWN0KG5ldyBGZXRjaEVycm9yKGByZXF1ZXN0IHRvICR7cmVxdWVzdC51cmx9IGZhaWxlZCwgcmVhc29uOiAke2Vyci5tZXNzYWdlfWAsICdzeXN0ZW0nLCBlcnIpKTtcblx0XHRcdGZpbmFsaXplKCk7XG5cdFx0fSk7XG5cblx0XHRyZXF1ZXN0Xy5vbigncmVzcG9uc2UnLCByZXNwb25zZV8gPT4ge1xuXHRcdFx0cmVxdWVzdF8uc2V0VGltZW91dCgwKTtcblx0XHRcdGNvbnN0IGhlYWRlcnMgPSBmcm9tUmF3SGVhZGVycyhyZXNwb25zZV8ucmF3SGVhZGVycyk7XG5cblx0XHRcdC8vIEhUVFAgZmV0Y2ggc3RlcCA1XG5cdFx0XHRpZiAoaXNSZWRpcmVjdChyZXNwb25zZV8uc3RhdHVzQ29kZSkpIHtcblx0XHRcdFx0Ly8gSFRUUCBmZXRjaCBzdGVwIDUuMlxuXHRcdFx0XHRjb25zdCBsb2NhdGlvbiA9IGhlYWRlcnMuZ2V0KCdMb2NhdGlvbicpO1xuXG5cdFx0XHRcdC8vIEhUVFAgZmV0Y2ggc3RlcCA1LjNcblx0XHRcdFx0Y29uc3QgbG9jYXRpb25VUkwgPSBsb2NhdGlvbiA9PT0gbnVsbCA/IG51bGwgOiBuZXcgVVJMKGxvY2F0aW9uLCByZXF1ZXN0LnVybCk7XG5cblx0XHRcdFx0Ly8gSFRUUCBmZXRjaCBzdGVwIDUuNVxuXHRcdFx0XHRzd2l0Y2ggKHJlcXVlc3QucmVkaXJlY3QpIHtcblx0XHRcdFx0XHRjYXNlICdlcnJvcic6XG5cdFx0XHRcdFx0XHRyZWplY3QobmV3IEZldGNoRXJyb3IoYHVyaSByZXF1ZXN0ZWQgcmVzcG9uZHMgd2l0aCBhIHJlZGlyZWN0LCByZWRpcmVjdCBtb2RlIGlzIHNldCB0byBlcnJvcjogJHtyZXF1ZXN0LnVybH1gLCAnbm8tcmVkaXJlY3QnKSk7XG5cdFx0XHRcdFx0XHRmaW5hbGl6ZSgpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdGNhc2UgJ21hbnVhbCc6XG5cdFx0XHRcdFx0XHQvLyBOb2RlLWZldGNoLXNwZWNpZmljIHN0ZXA6IG1ha2UgbWFudWFsIHJlZGlyZWN0IGEgYml0IGVhc2llciB0byB1c2UgYnkgc2V0dGluZyB0aGUgTG9jYXRpb24gaGVhZGVyIHZhbHVlIHRvIHRoZSByZXNvbHZlZCBVUkwuXG5cdFx0XHRcdFx0XHRpZiAobG9jYXRpb25VUkwgIT09IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGNvcnJ1cHRlZCBoZWFkZXJcblx0XHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0XHRoZWFkZXJzLnNldCgnTG9jYXRpb24nLCBsb2NhdGlvblVSTCk7XG5cdFx0XHRcdFx0XHRcdFx0LyogYzggaWdub3JlIG5leHQgMyAqL1xuXHRcdFx0XHRcdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnZm9sbG93Jzoge1xuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDJcblx0XHRcdFx0XHRcdGlmIChsb2NhdGlvblVSTCA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDVcblx0XHRcdFx0XHRcdGlmIChyZXF1ZXN0LmNvdW50ZXIgPj0gcmVxdWVzdC5mb2xsb3cpIHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KG5ldyBGZXRjaEVycm9yKGBtYXhpbXVtIHJlZGlyZWN0IHJlYWNoZWQgYXQ6ICR7cmVxdWVzdC51cmx9YCwgJ21heC1yZWRpcmVjdCcpKTtcblx0XHRcdFx0XHRcdFx0ZmluYWxpemUoKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgNiAoY291bnRlciBpbmNyZW1lbnQpXG5cdFx0XHRcdFx0XHQvLyBDcmVhdGUgYSBuZXcgUmVxdWVzdCBvYmplY3QuXG5cdFx0XHRcdFx0XHRjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcblx0XHRcdFx0XHRcdFx0aGVhZGVyczogbmV3IEhlYWRlcnMocmVxdWVzdC5oZWFkZXJzKSxcblx0XHRcdFx0XHRcdFx0Zm9sbG93OiByZXF1ZXN0LmZvbGxvdyxcblx0XHRcdFx0XHRcdFx0Y291bnRlcjogcmVxdWVzdC5jb3VudGVyICsgMSxcblx0XHRcdFx0XHRcdFx0YWdlbnQ6IHJlcXVlc3QuYWdlbnQsXG5cdFx0XHRcdFx0XHRcdGNvbXByZXNzOiByZXF1ZXN0LmNvbXByZXNzLFxuXHRcdFx0XHRcdFx0XHRtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuXHRcdFx0XHRcdFx0XHRib2R5OiByZXF1ZXN0LmJvZHksXG5cdFx0XHRcdFx0XHRcdHNpZ25hbDogcmVxdWVzdC5zaWduYWwsXG5cdFx0XHRcdFx0XHRcdHNpemU6IHJlcXVlc3Quc2l6ZVxuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDlcblx0XHRcdFx0XHRcdGlmIChyZXNwb25zZV8uc3RhdHVzQ29kZSAhPT0gMzAzICYmIHJlcXVlc3QuYm9keSAmJiBvcHRpb25zXy5ib2R5IGluc3RhbmNlb2YgU3RyZWFtLlJlYWRhYmxlKSB7XG5cdFx0XHRcdFx0XHRcdHJlamVjdChuZXcgRmV0Y2hFcnJvcignQ2Fubm90IGZvbGxvdyByZWRpcmVjdCB3aXRoIGJvZHkgYmVpbmcgYSByZWFkYWJsZSBzdHJlYW0nLCAndW5zdXBwb3J0ZWQtcmVkaXJlY3QnKSk7XG5cdFx0XHRcdFx0XHRcdGZpbmFsaXplKCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDExXG5cdFx0XHRcdFx0XHRpZiAocmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwMyB8fCAoKHJlc3BvbnNlXy5zdGF0dXNDb2RlID09PSAzMDEgfHwgcmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwMikgJiYgcmVxdWVzdC5tZXRob2QgPT09ICdQT1NUJykpIHtcblx0XHRcdFx0XHRcdFx0cmVxdWVzdE9wdGlvbnMubWV0aG9kID0gJ0dFVCc7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RPcHRpb25zLmJvZHkgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RPcHRpb25zLmhlYWRlcnMuZGVsZXRlKCdjb250ZW50LWxlbmd0aCcpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgMTVcblx0XHRcdFx0XHRcdHJlc29sdmUoZmV0Y2gobmV3IFJlcXVlc3QobG9jYXRpb25VUkwsIHJlcXVlc3RPcHRpb25zKSkpO1xuXHRcdFx0XHRcdFx0ZmluYWxpemUoKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gRG8gbm90aGluZ1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFByZXBhcmUgcmVzcG9uc2Vcblx0XHRcdHJlc3BvbnNlXy5vbmNlKCdlbmQnLCAoKSA9PiB7XG5cdFx0XHRcdGlmIChzaWduYWwpIHtcblx0XHRcdFx0XHRzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFuZEZpbmFsaXplKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGxldCBib2R5ID0gU3RyZWFtLnBpcGVsaW5lKHJlc3BvbnNlXywgbmV3IFN0cmVhbS5QYXNzVGhyb3VnaCgpLCBlcnJvciA9PiB7XG5cdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHR9KTtcblx0XHRcdC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvcHVsbC8yOTM3NlxuXHRcdFx0aWYgKHByb2Nlc3MudmVyc2lvbiA8ICd2MTIuMTAnKSB7XG5cdFx0XHRcdHJlc3BvbnNlXy5vbignYWJvcnRlZCcsIGFib3J0QW5kRmluYWxpemUpO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCByZXNwb25zZU9wdGlvbnMgPSB7XG5cdFx0XHRcdHVybDogcmVxdWVzdC51cmwsXG5cdFx0XHRcdHN0YXR1czogcmVzcG9uc2VfLnN0YXR1c0NvZGUsXG5cdFx0XHRcdHN0YXR1c1RleHQ6IHJlc3BvbnNlXy5zdGF0dXNNZXNzYWdlLFxuXHRcdFx0XHRoZWFkZXJzLFxuXHRcdFx0XHRzaXplOiByZXF1ZXN0LnNpemUsXG5cdFx0XHRcdGNvdW50ZXI6IHJlcXVlc3QuY291bnRlcixcblx0XHRcdFx0aGlnaFdhdGVyTWFyazogcmVxdWVzdC5oaWdoV2F0ZXJNYXJrXG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBIVFRQLW5ldHdvcmsgZmV0Y2ggc3RlcCAxMi4xLjEuM1xuXHRcdFx0Y29uc3QgY29kaW5ncyA9IGhlYWRlcnMuZ2V0KCdDb250ZW50LUVuY29kaW5nJyk7XG5cblx0XHRcdC8vIEhUVFAtbmV0d29yayBmZXRjaCBzdGVwIDEyLjEuMS40OiBoYW5kbGUgY29udGVudCBjb2RpbmdzXG5cblx0XHRcdC8vIGluIGZvbGxvd2luZyBzY2VuYXJpb3Mgd2UgaWdub3JlIGNvbXByZXNzaW9uIHN1cHBvcnRcblx0XHRcdC8vIDEuIGNvbXByZXNzaW9uIHN1cHBvcnQgaXMgZGlzYWJsZWRcblx0XHRcdC8vIDIuIEhFQUQgcmVxdWVzdFxuXHRcdFx0Ly8gMy4gbm8gQ29udGVudC1FbmNvZGluZyBoZWFkZXJcblx0XHRcdC8vIDQuIG5vIGNvbnRlbnQgcmVzcG9uc2UgKDIwNClcblx0XHRcdC8vIDUuIGNvbnRlbnQgbm90IG1vZGlmaWVkIHJlc3BvbnNlICgzMDQpXG5cdFx0XHRpZiAoIXJlcXVlc3QuY29tcHJlc3MgfHwgcmVxdWVzdC5tZXRob2QgPT09ICdIRUFEJyB8fCBjb2RpbmdzID09PSBudWxsIHx8IHJlc3BvbnNlXy5zdGF0dXNDb2RlID09PSAyMDQgfHwgcmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwNCkge1xuXHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgTm9kZSB2Nitcblx0XHRcdC8vIEJlIGxlc3Mgc3RyaWN0IHdoZW4gZGVjb2RpbmcgY29tcHJlc3NlZCByZXNwb25zZXMsIHNpbmNlIHNvbWV0aW1lc1xuXHRcdFx0Ly8gc2VydmVycyBzZW5kIHNsaWdodGx5IGludmFsaWQgcmVzcG9uc2VzIHRoYXQgYXJlIHN0aWxsIGFjY2VwdGVkXG5cdFx0XHQvLyBieSBjb21tb24gYnJvd3NlcnMuXG5cdFx0XHQvLyBBbHdheXMgdXNpbmcgWl9TWU5DX0ZMVVNIIGlzIHdoYXQgY1VSTCBkb2VzLlxuXHRcdFx0Y29uc3QgemxpYk9wdGlvbnMgPSB7XG5cdFx0XHRcdGZsdXNoOiB6bGliLlpfU1lOQ19GTFVTSCxcblx0XHRcdFx0ZmluaXNoRmx1c2g6IHpsaWIuWl9TWU5DX0ZMVVNIXG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBGb3IgZ3ppcFxuXHRcdFx0aWYgKGNvZGluZ3MgPT09ICdnemlwJyB8fCBjb2RpbmdzID09PSAneC1nemlwJykge1xuXHRcdFx0XHRib2R5ID0gU3RyZWFtLnBpcGVsaW5lKGJvZHksIHpsaWIuY3JlYXRlR3VuemlwKHpsaWJPcHRpb25zKSwgZXJyb3IgPT4ge1xuXHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgZGVmbGF0ZVxuXHRcdFx0aWYgKGNvZGluZ3MgPT09ICdkZWZsYXRlJyB8fCBjb2RpbmdzID09PSAneC1kZWZsYXRlJykge1xuXHRcdFx0XHQvLyBIYW5kbGUgdGhlIGluZmFtb3VzIHJhdyBkZWZsYXRlIHJlc3BvbnNlIGZyb20gb2xkIHNlcnZlcnNcblx0XHRcdFx0Ly8gYSBoYWNrIGZvciBvbGQgSUlTIGFuZCBBcGFjaGUgc2VydmVyc1xuXHRcdFx0XHRjb25zdCByYXcgPSBTdHJlYW0ucGlwZWxpbmUocmVzcG9uc2VfLCBuZXcgU3RyZWFtLlBhc3NUaHJvdWdoKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmF3Lm9uY2UoJ2RhdGEnLCBjaHVuayA9PiB7XG5cdFx0XHRcdFx0Ly8gU2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzc1MTk4Mjhcblx0XHRcdFx0XHRpZiAoKGNodW5rWzBdICYgMHgwRikgPT09IDB4MDgpIHtcblx0XHRcdFx0XHRcdGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUoYm9keSwgemxpYi5jcmVhdGVJbmZsYXRlKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRib2R5ID0gU3RyZWFtLnBpcGVsaW5lKGJvZHksIHpsaWIuY3JlYXRlSW5mbGF0ZVJhdygpLCBlcnJvciA9PiB7XG5cdFx0XHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgYnJcblx0XHRcdGlmIChjb2RpbmdzID09PSAnYnInKSB7XG5cdFx0XHRcdGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUoYm9keSwgemxpYi5jcmVhdGVCcm90bGlEZWNvbXByZXNzKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UoYm9keSwgcmVzcG9uc2VPcHRpb25zKTtcblx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3RoZXJ3aXNlLCB1c2UgcmVzcG9uc2UgYXMtaXNcblx0XHRcdHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKGJvZHksIHJlc3BvbnNlT3B0aW9ucyk7XG5cdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHR9KTtcblxuXHRcdHdyaXRlVG9TdHJlYW0ocmVxdWVzdF8sIHJlcXVlc3QpO1xuXHR9KTtcbn1cblxuZXhwb3J0cy5BYm9ydEVycm9yID0gQWJvcnRFcnJvcjtcbmV4cG9ydHMuRmV0Y2hFcnJvciA9IEZldGNoRXJyb3I7XG5leHBvcnRzLkhlYWRlcnMgPSBIZWFkZXJzO1xuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcbmV4cG9ydHMuUmVzcG9uc2UgPSBSZXNwb25zZTtcbmV4cG9ydHMuZGVmYXVsdCA9IGZldGNoO1xuZXhwb3J0cy5pc1JlZGlyZWN0ID0gaXNSZWRpcmVjdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmNqcy5tYXBcbiIsIi8qKlxuICogd2ViLXN0cmVhbXMtcG9seWZpbGwgdjMuMS4xXG4gKi9cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5zeW1ib2xcIiAvPlxuY29uc3QgU3ltYm9sUG9seWZpbGwgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID9cbiAgICBTeW1ib2wgOlxuICAgIGRlc2NyaXB0aW9uID0+IGBTeW1ib2woJHtkZXNjcmlwdGlvbn0pYDtcblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZG9tXCIgLz5cbmZ1bmN0aW9uIG5vb3AoKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGdldEdsb2JhbHMoKSB7XG4gICAgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdztcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIGdsb2JhbDtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmNvbnN0IGdsb2JhbHMgPSBnZXRHbG9iYWxzKCk7XG5cbmZ1bmN0aW9uIHR5cGVJc09iamVjdCh4KSB7XG4gICAgcmV0dXJuICh0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCkgfHwgdHlwZW9mIHggPT09ICdmdW5jdGlvbic7XG59XG5jb25zdCByZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24gPSBub29wO1xuXG5jb25zdCBvcmlnaW5hbFByb21pc2UgPSBQcm9taXNlO1xuY29uc3Qgb3JpZ2luYWxQcm9taXNlVGhlbiA9IFByb21pc2UucHJvdG90eXBlLnRoZW47XG5jb25zdCBvcmlnaW5hbFByb21pc2VSZXNvbHZlID0gUHJvbWlzZS5yZXNvbHZlLmJpbmQob3JpZ2luYWxQcm9taXNlKTtcbmNvbnN0IG9yaWdpbmFsUHJvbWlzZVJlamVjdCA9IFByb21pc2UucmVqZWN0LmJpbmQob3JpZ2luYWxQcm9taXNlKTtcbmZ1bmN0aW9uIG5ld1Byb21pc2UoZXhlY3V0b3IpIHtcbiAgICByZXR1cm4gbmV3IG9yaWdpbmFsUHJvbWlzZShleGVjdXRvcik7XG59XG5mdW5jdGlvbiBwcm9taXNlUmVzb2x2ZWRXaXRoKHZhbHVlKSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsUHJvbWlzZVJlc29sdmUodmFsdWUpO1xufVxuZnVuY3Rpb24gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFzb24pIHtcbiAgICByZXR1cm4gb3JpZ2luYWxQcm9taXNlUmVqZWN0KHJlYXNvbik7XG59XG5mdW5jdGlvbiBQZXJmb3JtUHJvbWlzZVRoZW4ocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAvLyBUaGVyZSBkb2Vzbid0IGFwcGVhciB0byBiZSBhbnkgd2F5IHRvIGNvcnJlY3RseSBlbXVsYXRlIHRoZSBiZWhhdmlvdXIgZnJvbSBKYXZhU2NyaXB0LCBzbyB0aGlzIGlzIGp1c3QgYW5cbiAgICAvLyBhcHByb3hpbWF0aW9uLlxuICAgIHJldHVybiBvcmlnaW5hbFByb21pc2VUaGVuLmNhbGwocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpO1xufVxuZnVuY3Rpb24gdXBvblByb21pc2UocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICBQZXJmb3JtUHJvbWlzZVRoZW4oUGVyZm9ybVByb21pc2VUaGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSwgdW5kZWZpbmVkLCByZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24pO1xufVxuZnVuY3Rpb24gdXBvbkZ1bGZpbGxtZW50KHByb21pc2UsIG9uRnVsZmlsbGVkKSB7XG4gICAgdXBvblByb21pc2UocHJvbWlzZSwgb25GdWxmaWxsZWQpO1xufVxuZnVuY3Rpb24gdXBvblJlamVjdGlvbihwcm9taXNlLCBvblJlamVjdGVkKSB7XG4gICAgdXBvblByb21pc2UocHJvbWlzZSwgdW5kZWZpbmVkLCBvblJlamVjdGVkKTtcbn1cbmZ1bmN0aW9uIHRyYW5zZm9ybVByb21pc2VXaXRoKHByb21pc2UsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcikge1xuICAgIHJldHVybiBQZXJmb3JtUHJvbWlzZVRoZW4ocHJvbWlzZSwgZnVsZmlsbG1lbnRIYW5kbGVyLCByZWplY3Rpb25IYW5kbGVyKTtcbn1cbmZ1bmN0aW9uIHNldFByb21pc2VJc0hhbmRsZWRUb1RydWUocHJvbWlzZSkge1xuICAgIFBlcmZvcm1Qcm9taXNlVGhlbihwcm9taXNlLCB1bmRlZmluZWQsIHJldGhyb3dBc3NlcnRpb25FcnJvclJlamVjdGlvbik7XG59XG5jb25zdCBxdWV1ZU1pY3JvdGFzayA9ICgoKSA9PiB7XG4gICAgY29uc3QgZ2xvYmFsUXVldWVNaWNyb3Rhc2sgPSBnbG9iYWxzICYmIGdsb2JhbHMucXVldWVNaWNyb3Rhc2s7XG4gICAgaWYgKHR5cGVvZiBnbG9iYWxRdWV1ZU1pY3JvdGFzayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gZ2xvYmFsUXVldWVNaWNyb3Rhc2s7XG4gICAgfVxuICAgIGNvbnN0IHJlc29sdmVkUHJvbWlzZSA9IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICByZXR1cm4gKGZuKSA9PiBQZXJmb3JtUHJvbWlzZVRoZW4ocmVzb2x2ZWRQcm9taXNlLCBmbik7XG59KSgpO1xuZnVuY3Rpb24gcmVmbGVjdENhbGwoRiwgViwgYXJncykge1xuICAgIGlmICh0eXBlb2YgRiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBpcyBub3QgYSBmdW5jdGlvbicpO1xuICAgIH1cbiAgICByZXR1cm4gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoRiwgViwgYXJncyk7XG59XG5mdW5jdGlvbiBwcm9taXNlQ2FsbChGLCBWLCBhcmdzKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgocmVmbGVjdENhbGwoRiwgViwgYXJncykpO1xuICAgIH1cbiAgICBjYXRjaCAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgodmFsdWUpO1xuICAgIH1cbn1cblxuLy8gT3JpZ2luYWwgZnJvbSBDaHJvbWl1bVxuLy8gaHR0cHM6Ly9jaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYy8rLzBhZWU0NDM0YTRkYmE0MmE0MmFiYWVhOWJmYmMwY2QxOTZhNjNiYzEvdGhpcmRfcGFydHkvYmxpbmsvcmVuZGVyZXIvY29yZS9zdHJlYW1zL1NpbXBsZVF1ZXVlLmpzXG5jb25zdCBRVUVVRV9NQVhfQVJSQVlfU0laRSA9IDE2Mzg0O1xuLyoqXG4gKiBTaW1wbGUgcXVldWUgc3RydWN0dXJlLlxuICpcbiAqIEF2b2lkcyBzY2FsYWJpbGl0eSBpc3N1ZXMgd2l0aCB1c2luZyBhIHBhY2tlZCBhcnJheSBkaXJlY3RseSBieSB1c2luZ1xuICogbXVsdGlwbGUgYXJyYXlzIGluIGEgbGlua2VkIGxpc3QgYW5kIGtlZXBpbmcgdGhlIGFycmF5IHNpemUgYm91bmRlZC5cbiAqL1xuY2xhc3MgU2ltcGxlUXVldWUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLl9jdXJzb3IgPSAwO1xuICAgICAgICB0aGlzLl9zaXplID0gMDtcbiAgICAgICAgLy8gX2Zyb250IGFuZCBfYmFjayBhcmUgYWx3YXlzIGRlZmluZWQuXG4gICAgICAgIHRoaXMuX2Zyb250ID0ge1xuICAgICAgICAgICAgX2VsZW1lbnRzOiBbXSxcbiAgICAgICAgICAgIF9uZXh0OiB1bmRlZmluZWRcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fYmFjayA9IHRoaXMuX2Zyb250O1xuICAgICAgICAvLyBUaGUgY3Vyc29yIGlzIHVzZWQgdG8gYXZvaWQgY2FsbGluZyBBcnJheS5zaGlmdCgpLlxuICAgICAgICAvLyBJdCBjb250YWlucyB0aGUgaW5kZXggb2YgdGhlIGZyb250IGVsZW1lbnQgb2YgdGhlIGFycmF5IGluc2lkZSB0aGVcbiAgICAgICAgLy8gZnJvbnQtbW9zdCBub2RlLiBJdCBpcyBhbHdheXMgaW4gdGhlIHJhbmdlIFswLCBRVUVVRV9NQVhfQVJSQVlfU0laRSkuXG4gICAgICAgIHRoaXMuX2N1cnNvciA9IDA7XG4gICAgICAgIC8vIFdoZW4gdGhlcmUgaXMgb25seSBvbmUgbm9kZSwgc2l6ZSA9PT0gZWxlbWVudHMubGVuZ3RoIC0gY3Vyc29yLlxuICAgICAgICB0aGlzLl9zaXplID0gMDtcbiAgICB9XG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpemU7XG4gICAgfVxuICAgIC8vIEZvciBleGNlcHRpb24gc2FmZXR5LCB0aGlzIG1ldGhvZCBpcyBzdHJ1Y3R1cmVkIGluIG9yZGVyOlxuICAgIC8vIDEuIFJlYWQgc3RhdGVcbiAgICAvLyAyLiBDYWxjdWxhdGUgcmVxdWlyZWQgc3RhdGUgbXV0YXRpb25zXG4gICAgLy8gMy4gUGVyZm9ybSBzdGF0ZSBtdXRhdGlvbnNcbiAgICBwdXNoKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3Qgb2xkQmFjayA9IHRoaXMuX2JhY2s7XG4gICAgICAgIGxldCBuZXdCYWNrID0gb2xkQmFjaztcbiAgICAgICAgaWYgKG9sZEJhY2suX2VsZW1lbnRzLmxlbmd0aCA9PT0gUVVFVUVfTUFYX0FSUkFZX1NJWkUgLSAxKSB7XG4gICAgICAgICAgICBuZXdCYWNrID0ge1xuICAgICAgICAgICAgICAgIF9lbGVtZW50czogW10sXG4gICAgICAgICAgICAgICAgX25leHQ6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBwdXNoKCkgaXMgdGhlIG11dGF0aW9uIG1vc3QgbGlrZWx5IHRvIHRocm93IGFuIGV4Y2VwdGlvbiwgc28gaXRcbiAgICAgICAgLy8gZ29lcyBmaXJzdC5cbiAgICAgICAgb2xkQmFjay5fZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgaWYgKG5ld0JhY2sgIT09IG9sZEJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuX2JhY2sgPSBuZXdCYWNrO1xuICAgICAgICAgICAgb2xkQmFjay5fbmV4dCA9IG5ld0JhY2s7XG4gICAgICAgIH1cbiAgICAgICAgKyt0aGlzLl9zaXplO1xuICAgIH1cbiAgICAvLyBMaWtlIHB1c2goKSwgc2hpZnQoKSBmb2xsb3dzIHRoZSByZWFkIC0+IGNhbGN1bGF0ZSAtPiBtdXRhdGUgcGF0dGVybiBmb3JcbiAgICAvLyBleGNlcHRpb24gc2FmZXR5LlxuICAgIHNoaWZ0KCkgeyAvLyBtdXN0IG5vdCBiZSBjYWxsZWQgb24gYW4gZW1wdHkgcXVldWVcbiAgICAgICAgY29uc3Qgb2xkRnJvbnQgPSB0aGlzLl9mcm9udDtcbiAgICAgICAgbGV0IG5ld0Zyb250ID0gb2xkRnJvbnQ7XG4gICAgICAgIGNvbnN0IG9sZEN1cnNvciA9IHRoaXMuX2N1cnNvcjtcbiAgICAgICAgbGV0IG5ld0N1cnNvciA9IG9sZEN1cnNvciArIDE7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gb2xkRnJvbnQuX2VsZW1lbnRzO1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gZWxlbWVudHNbb2xkQ3Vyc29yXTtcbiAgICAgICAgaWYgKG5ld0N1cnNvciA9PT0gUVVFVUVfTUFYX0FSUkFZX1NJWkUpIHtcbiAgICAgICAgICAgIG5ld0Zyb250ID0gb2xkRnJvbnQuX25leHQ7XG4gICAgICAgICAgICBuZXdDdXJzb3IgPSAwO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vIG11dGF0aW9ucyBiZWZvcmUgdGhpcyBwb2ludC5cbiAgICAgICAgLS10aGlzLl9zaXplO1xuICAgICAgICB0aGlzLl9jdXJzb3IgPSBuZXdDdXJzb3I7XG4gICAgICAgIGlmIChvbGRGcm9udCAhPT0gbmV3RnJvbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2Zyb250ID0gbmV3RnJvbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUGVybWl0IHNoaWZ0ZWQgZWxlbWVudCB0byBiZSBnYXJiYWdlIGNvbGxlY3RlZC5cbiAgICAgICAgZWxlbWVudHNbb2xkQ3Vyc29yXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICAgIC8vIFRoZSB0cmlja3kgdGhpbmcgYWJvdXQgZm9yRWFjaCgpIGlzIHRoYXQgaXQgY2FuIGJlIGNhbGxlZFxuICAgIC8vIHJlLWVudHJhbnRseS4gVGhlIHF1ZXVlIG1heSBiZSBtdXRhdGVkIGluc2lkZSB0aGUgY2FsbGJhY2suIEl0IGlzIGVhc3kgdG9cbiAgICAvLyBzZWUgdGhhdCBwdXNoKCkgd2l0aGluIHRoZSBjYWxsYmFjayBoYXMgbm8gbmVnYXRpdmUgZWZmZWN0cyBzaW5jZSB0aGUgZW5kXG4gICAgLy8gb2YgdGhlIHF1ZXVlIGlzIGNoZWNrZWQgZm9yIG9uIGV2ZXJ5IGl0ZXJhdGlvbi4gSWYgc2hpZnQoKSBpcyBjYWxsZWRcbiAgICAvLyByZXBlYXRlZGx5IHdpdGhpbiB0aGUgY2FsbGJhY2sgdGhlbiB0aGUgbmV4dCBpdGVyYXRpb24gbWF5IHJldHVybiBhblxuICAgIC8vIGVsZW1lbnQgdGhhdCBoYXMgYmVlbiByZW1vdmVkLiBJbiB0aGlzIGNhc2UgdGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkXG4gICAgLy8gd2l0aCB1bmRlZmluZWQgdmFsdWVzIHVudGlsIHdlIGVpdGhlciBcImNhdGNoIHVwXCIgd2l0aCBlbGVtZW50cyB0aGF0IHN0aWxsXG4gICAgLy8gZXhpc3Qgb3IgcmVhY2ggdGhlIGJhY2sgb2YgdGhlIHF1ZXVlLlxuICAgIGZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgbGV0IGkgPSB0aGlzLl9jdXJzb3I7XG4gICAgICAgIGxldCBub2RlID0gdGhpcy5fZnJvbnQ7XG4gICAgICAgIGxldCBlbGVtZW50cyA9IG5vZGUuX2VsZW1lbnRzO1xuICAgICAgICB3aGlsZSAoaSAhPT0gZWxlbWVudHMubGVuZ3RoIHx8IG5vZGUuX25leHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKGkgPT09IGVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLl9uZXh0O1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzID0gbm9kZS5fZWxlbWVudHM7XG4gICAgICAgICAgICAgICAgaSA9IDA7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYWxsYmFjayhlbGVtZW50c1tpXSk7XG4gICAgICAgICAgICArK2k7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gUmV0dXJuIHRoZSBlbGVtZW50IHRoYXQgd291bGQgYmUgcmV0dXJuZWQgaWYgc2hpZnQoKSB3YXMgY2FsbGVkIG5vdyxcbiAgICAvLyB3aXRob3V0IG1vZGlmeWluZyB0aGUgcXVldWUuXG4gICAgcGVlaygpIHsgLy8gbXVzdCBub3QgYmUgY2FsbGVkIG9uIGFuIGVtcHR5IHF1ZXVlXG4gICAgICAgIGNvbnN0IGZyb250ID0gdGhpcy5fZnJvbnQ7XG4gICAgICAgIGNvbnN0IGN1cnNvciA9IHRoaXMuX2N1cnNvcjtcbiAgICAgICAgcmV0dXJuIGZyb250Ll9lbGVtZW50c1tjdXJzb3JdO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZShyZWFkZXIsIHN0cmVhbSkge1xuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9IHN0cmVhbTtcbiAgICBzdHJlYW0uX3JlYWRlciA9IHJlYWRlcjtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ3JlYWRhYmxlJykge1xuICAgICAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZChyZWFkZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZChyZWFkZXIsIHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbn1cbi8vIEEgY2xpZW50IG9mIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciBhbmQgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyIG1heSB1c2UgdGhlc2UgZnVuY3Rpb25zIGRpcmVjdGx5IHRvIGJ5cGFzcyBzdGF0ZVxuLy8gY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNDYW5jZWwocmVhZGVyLCByZWFzb24pIHtcbiAgICBjb25zdCBzdHJlYW0gPSByZWFkZXIuX293bmVyUmVhZGFibGVTdHJlYW07XG4gICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKSB7XG4gICAgaWYgKHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbS5fc3RhdGUgPT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCBuZXcgVHlwZUVycm9yKGBSZWFkZXIgd2FzIHJlbGVhc2VkIGFuZCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgdG8gbW9uaXRvciB0aGUgc3RyZWFtJ3MgY2xvc2VkbmVzc2ApKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzZXRUb1JlamVjdGVkKHJlYWRlciwgbmV3IFR5cGVFcnJvcihgUmVhZGVyIHdhcyByZWxlYXNlZCBhbmQgY2FuIG5vIGxvbmdlciBiZSB1c2VkIHRvIG1vbml0b3IgdGhlIHN0cmVhbSdzIGNsb3NlZG5lc3NgKSk7XG4gICAgfVxuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbS5fcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9IHVuZGVmaW5lZDtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSByZWFkZXJzLlxuZnVuY3Rpb24gcmVhZGVyTG9ja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCAnICsgbmFtZSArICcgYSBzdHJlYW0gdXNpbmcgYSByZWxlYXNlZCByZWFkZXInKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIuXG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKSB7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlID0gbmV3UHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHJlamVjdDtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQocmVhZGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKTtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlamVjdChyZWFkZXIsIHJlYXNvbik7XG59XG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHJlYWRlcikge1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZShyZWFkZXIpO1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzb2x2ZShyZWFkZXIpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCByZWFzb24pIHtcbiAgICBpZiAocmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShyZWFkZXIuX2Nsb3NlZFByb21pc2UpO1xuICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QocmVhc29uKTtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQocmVhZGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHJlYWRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzb2x2ZShyZWFkZXIpIHtcbiAgICBpZiAocmVhZGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbn1cblxuY29uc3QgQWJvcnRTdGVwcyA9IFN5bWJvbFBvbHlmaWxsKCdbW0Fib3J0U3RlcHNdXScpO1xuY29uc3QgRXJyb3JTdGVwcyA9IFN5bWJvbFBvbHlmaWxsKCdbW0Vycm9yU3RlcHNdXScpO1xuY29uc3QgQ2FuY2VsU3RlcHMgPSBTeW1ib2xQb2x5ZmlsbCgnW1tDYW5jZWxTdGVwc11dJyk7XG5jb25zdCBQdWxsU3RlcHMgPSBTeW1ib2xQb2x5ZmlsbCgnW1tQdWxsU3RlcHNdXScpO1xuXG4vLy8gPHJlZmVyZW5jZSBsaWI9XCJlczIwMTUuY29yZVwiIC8+XG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9OdW1iZXIvaXNGaW5pdGUjUG9seWZpbGxcbmNvbnN0IE51bWJlcklzRmluaXRlID0gTnVtYmVyLmlzRmluaXRlIHx8IGZ1bmN0aW9uICh4KSB7XG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZSh4KTtcbn07XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5jb3JlXCIgLz5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL01hdGgvdHJ1bmMjUG9seWZpbGxcbmNvbnN0IE1hdGhUcnVuYyA9IE1hdGgudHJ1bmMgfHwgZnVuY3Rpb24gKHYpIHtcbiAgICByZXR1cm4gdiA8IDAgPyBNYXRoLmNlaWwodikgOiBNYXRoLmZsb29yKHYpO1xufTtcblxuLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jaWRsLWRpY3Rpb25hcmllc1xuZnVuY3Rpb24gaXNEaWN0aW9uYXJ5KHgpIHtcbiAgICByZXR1cm4gdHlwZW9mIHggPT09ICdvYmplY3QnIHx8IHR5cGVvZiB4ID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gYXNzZXJ0RGljdGlvbmFyeShvYmosIGNvbnRleHQpIHtcbiAgICBpZiAob2JqICE9PSB1bmRlZmluZWQgJiYgIWlzRGljdGlvbmFyeShvYmopKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGFuIG9iamVjdC5gKTtcbiAgICB9XG59XG4vLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNpZGwtY2FsbGJhY2stZnVuY3Rpb25zXG5mdW5jdGlvbiBhc3NlcnRGdW5jdGlvbih4LCBjb250ZXh0KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGEgZnVuY3Rpb24uYCk7XG4gICAgfVxufVxuLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jaWRsLW9iamVjdFxuZnVuY3Rpb24gaXNPYmplY3QoeCkge1xuICAgIHJldHVybiAodHlwZW9mIHggPT09ICdvYmplY3QnICYmIHggIT09IG51bGwpIHx8IHR5cGVvZiB4ID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gYXNzZXJ0T2JqZWN0KHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGFuIG9iamVjdC5gKTtcbiAgICB9XG59XG5mdW5jdGlvbiBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHgsIHBvc2l0aW9uLCBjb250ZXh0KSB7XG4gICAgaWYgKHggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBQYXJhbWV0ZXIgJHtwb3NpdGlvbn0gaXMgcmVxdWlyZWQgaW4gJyR7Y29udGV4dH0nLmApO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGFzc2VydFJlcXVpcmVkRmllbGQoeCwgZmllbGQsIGNvbnRleHQpIHtcbiAgICBpZiAoeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7ZmllbGR9IGlzIHJlcXVpcmVkIGluICcke2NvbnRleHR9Jy5gKTtcbiAgICB9XG59XG4vLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNpZGwtdW5yZXN0cmljdGVkLWRvdWJsZVxuZnVuY3Rpb24gY29udmVydFVucmVzdHJpY3RlZERvdWJsZSh2YWx1ZSkge1xuICAgIHJldHVybiBOdW1iZXIodmFsdWUpO1xufVxuZnVuY3Rpb24gY2Vuc29yTmVnYXRpdmVaZXJvKHgpIHtcbiAgICByZXR1cm4geCA9PT0gMCA/IDAgOiB4O1xufVxuZnVuY3Rpb24gaW50ZWdlclBhcnQoeCkge1xuICAgIHJldHVybiBjZW5zb3JOZWdhdGl2ZVplcm8oTWF0aFRydW5jKHgpKTtcbn1cbi8vIGh0dHBzOi8vaGV5Y2FtLmdpdGh1Yi5pby93ZWJpZGwvI2lkbC11bnNpZ25lZC1sb25nLWxvbmdcbmZ1bmN0aW9uIGNvbnZlcnRVbnNpZ25lZExvbmdMb25nV2l0aEVuZm9yY2VSYW5nZSh2YWx1ZSwgY29udGV4dCkge1xuICAgIGNvbnN0IGxvd2VyQm91bmQgPSAwO1xuICAgIGNvbnN0IHVwcGVyQm91bmQgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICBsZXQgeCA9IE51bWJlcih2YWx1ZSk7XG4gICAgeCA9IGNlbnNvck5lZ2F0aXZlWmVybyh4KTtcbiAgICBpZiAoIU51bWJlcklzRmluaXRlKHgpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGEgZmluaXRlIG51bWJlcmApO1xuICAgIH1cbiAgICB4ID0gaW50ZWdlclBhcnQoeCk7XG4gICAgaWYgKHggPCBsb3dlckJvdW5kIHx8IHggPiB1cHBlckJvdW5kKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgb3V0c2lkZSB0aGUgYWNjZXB0ZWQgcmFuZ2Ugb2YgJHtsb3dlckJvdW5kfSB0byAke3VwcGVyQm91bmR9LCBpbmNsdXNpdmVgKTtcbiAgICB9XG4gICAgaWYgKCFOdW1iZXJJc0Zpbml0ZSh4KSB8fCB4ID09PSAwKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvLyBUT0RPIFVzZSBCaWdJbnQgaWYgc3VwcG9ydGVkP1xuICAgIC8vIGxldCB4QmlnSW50ID0gQmlnSW50KGludGVnZXJQYXJ0KHgpKTtcbiAgICAvLyB4QmlnSW50ID0gQmlnSW50LmFzVWludE4oNjQsIHhCaWdJbnQpO1xuICAgIC8vIHJldHVybiBOdW1iZXIoeEJpZ0ludCk7XG4gICAgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGFzc2VydFJlYWRhYmxlU3RyZWFtKHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0oeCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYSBSZWFkYWJsZVN0cmVhbS5gKTtcbiAgICB9XG59XG5cbi8vIEFic3RyYWN0IG9wZXJhdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbS5cbmZ1bmN0aW9uIEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKSB7XG4gICAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKTtcbn1cbi8vIFJlYWRhYmxlU3RyZWFtIEFQSSBleHBvc2VkIGZvciBjb250cm9sbGVycy5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtQWRkUmVhZFJlcXVlc3Qoc3RyZWFtLCByZWFkUmVxdWVzdCkge1xuICAgIHN0cmVhbS5fcmVhZGVyLl9yZWFkUmVxdWVzdHMucHVzaChyZWFkUmVxdWVzdCk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUZ1bGZpbGxSZWFkUmVxdWVzdChzdHJlYW0sIGNodW5rLCBkb25lKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgY29uc3QgcmVhZFJlcXVlc3QgPSByZWFkZXIuX3JlYWRSZXF1ZXN0cy5zaGlmdCgpO1xuICAgIGlmIChkb25lKSB7XG4gICAgICAgIHJlYWRSZXF1ZXN0Ll9jbG9zZVN0ZXBzKCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZWFkUmVxdWVzdC5fY2h1bmtTdGVwcyhjaHVuayk7XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSB7XG4gICAgcmV0dXJuIHN0cmVhbS5fcmVhZGVyLl9yZWFkUmVxdWVzdHMubGVuZ3RoO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1IYXNEZWZhdWx0UmVhZGVyKHN0cmVhbSkge1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5fcmVhZGVyO1xuICAgIGlmIChyZWFkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBBIGRlZmF1bHQgcmVhZGVyIHZlbmRlZCBieSBhIHtAbGluayBSZWFkYWJsZVN0cmVhbX0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIge1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHN0cmVhbSwgMSwgJ1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcicpO1xuICAgICAgICBhc3NlcnRSZWFkYWJsZVN0cmVhbShzdHJlYW0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKElzUmVhZGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhpcyBzdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBsb2NrZWQgZm9yIGV4Y2x1c2l2ZSByZWFkaW5nIGJ5IGFub3RoZXIgcmVhZGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZSh0aGlzLCBzdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBzdHJlYW0gYmVjb21lcyBjbG9zZWQsXG4gICAgICogb3IgcmVqZWN0ZWQgaWYgdGhlIHN0cmVhbSBldmVyIGVycm9ycyBvciB0aGUgcmVhZGVyJ3MgbG9jayBpcyByZWxlYXNlZCBiZWZvcmUgdGhlIHN0cmVhbSBmaW5pc2hlcyBjbG9zaW5nLlxuICAgICAqL1xuICAgIGdldCBjbG9zZWQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdjbG9zZWQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb3NlZFByb21pc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSByZWFkZXIgaXMgYWN0aXZlLCBiZWhhdmVzIHRoZSBzYW1lIGFzIHtAbGluayBSZWFkYWJsZVN0cmVhbS5jYW5jZWwgfCBzdHJlYW0uY2FuY2VsKHJlYXNvbil9LlxuICAgICAqL1xuICAgIGNhbmNlbChyZWFzb24gPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2NhbmNlbCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFkZXJMb2NrRXhjZXB0aW9uKCdjYW5jZWwnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbCh0aGlzLCByZWFzb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGFsbG93cyBhY2Nlc3MgdG8gdGhlIG5leHQgY2h1bmsgZnJvbSB0aGUgc3RyZWFtJ3MgaW50ZXJuYWwgcXVldWUsIGlmIGF2YWlsYWJsZS5cbiAgICAgKlxuICAgICAqIElmIHJlYWRpbmcgYSBjaHVuayBjYXVzZXMgdGhlIHF1ZXVlIHRvIGJlY29tZSBlbXB0eSwgbW9yZSBkYXRhIHdpbGwgYmUgcHVsbGVkIGZyb20gdGhlIHVuZGVybHlpbmcgc291cmNlLlxuICAgICAqL1xuICAgIHJlYWQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lclJlYWRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHJlYWRlckxvY2tFeGNlcHRpb24oJ3JlYWQgZnJvbScpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzb2x2ZVByb21pc2U7XG4gICAgICAgIGxldCByZWplY3RQcm9taXNlO1xuICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3UHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgICAgICAgICByZWplY3RQcm9taXNlID0gcmVqZWN0O1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVhZFJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pLFxuICAgICAgICAgICAgX2Nsb3NlU3RlcHM6ICgpID0+IHJlc29sdmVQcm9taXNlKHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9KSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiBlID0+IHJlamVjdFByb21pc2UoZSlcbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZCh0aGlzLCByZWFkUmVxdWVzdCk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlcyB0aGUgcmVhZGVyJ3MgbG9jayBvbiB0aGUgY29ycmVzcG9uZGluZyBzdHJlYW0uIEFmdGVyIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmVhZGVyIGlzIG5vIGxvbmdlciBhY3RpdmUuXG4gICAgICogSWYgdGhlIGFzc29jaWF0ZWQgc3RyZWFtIGlzIGVycm9yZWQgd2hlbiB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJlYWRlciB3aWxsIGFwcGVhciBlcnJvcmVkIGluIHRoZSBzYW1lIHdheVxuICAgICAqIGZyb20gbm93IG9uOyBvdGhlcndpc2UsIHRoZSByZWFkZXIgd2lsbCBhcHBlYXIgY2xvc2VkLlxuICAgICAqXG4gICAgICogQSByZWFkZXIncyBsb2NrIGNhbm5vdCBiZSByZWxlYXNlZCB3aGlsZSBpdCBzdGlsbCBoYXMgYSBwZW5kaW5nIHJlYWQgcmVxdWVzdCwgaS5lLiwgaWYgYSBwcm9taXNlIHJldHVybmVkIGJ5XG4gICAgICogdGhlIHJlYWRlcidzIHtAbGluayBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIucmVhZCB8IHJlYWQoKX0gbWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gc2V0dGxlZC4gQXR0ZW1wdGluZyB0b1xuICAgICAqIGRvIHNvIHdpbGwgdGhyb3cgYSBgVHlwZUVycm9yYCBhbmQgbGVhdmUgdGhlIHJlYWRlciBsb2NrZWQgdG8gdGhlIHN0cmVhbS5cbiAgICAgKi9cbiAgICByZWxlYXNlTG9jaygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdFJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlbGVhc2VMb2NrJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yZWFkUmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVHJpZWQgdG8gcmVsZWFzZSBhIHJlYWRlciBsb2NrIHdoZW4gdGhhdCByZWFkZXIgaGFzIHBlbmRpbmcgcmVhZCgpIGNhbGxzIHVuLXNldHRsZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHRoaXMpO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUsIHtcbiAgICBjYW5jZWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlYWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlbGVhc2VMb2NrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBjbG9zZWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9XG59KTtcbmlmICh0eXBlb2YgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgcmVhZGVycy5cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfcmVhZFJlcXVlc3RzJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4geCBpbnN0YW5jZW9mIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQocmVhZGVyLCByZWFkUmVxdWVzdCkge1xuICAgIGNvbnN0IHN0cmVhbSA9IHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbTtcbiAgICBzdHJlYW0uX2Rpc3R1cmJlZCA9IHRydWU7XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJlYWRSZXF1ZXN0Ll9jbG9zZVN0ZXBzKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZWFkUmVxdWVzdC5fZXJyb3JTdGVwcyhzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHN0cmVhbS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpO1xuICAgIH1cbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIuXG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyYCk7XG59XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxOC5hc3luY2l0ZXJhYmxlXCIgLz5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvbiAqL1xuY29uc3QgQXN5bmNJdGVyYXRvclByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoYXN5bmMgZnVuY3Rpb24qICgpIHsgfSkucHJvdG90eXBlKTtcblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZXMyMDE4LmFzeW5jaXRlcmFibGVcIiAvPlxuY2xhc3MgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9ySW1wbCB7XG4gICAgY29uc3RydWN0b3IocmVhZGVyLCBwcmV2ZW50Q2FuY2VsKSB7XG4gICAgICAgIHRoaXMuX29uZ29pbmdQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9pc0ZpbmlzaGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3JlYWRlciA9IHJlYWRlcjtcbiAgICAgICAgdGhpcy5fcHJldmVudENhbmNlbCA9IHByZXZlbnRDYW5jZWw7XG4gICAgfVxuICAgIG5leHQoKSB7XG4gICAgICAgIGNvbnN0IG5leHRTdGVwcyA9ICgpID0+IHRoaXMuX25leHRTdGVwcygpO1xuICAgICAgICB0aGlzLl9vbmdvaW5nUHJvbWlzZSA9IHRoaXMuX29uZ29pbmdQcm9taXNlID9cbiAgICAgICAgICAgIHRyYW5zZm9ybVByb21pc2VXaXRoKHRoaXMuX29uZ29pbmdQcm9taXNlLCBuZXh0U3RlcHMsIG5leHRTdGVwcykgOlxuICAgICAgICAgICAgbmV4dFN0ZXBzKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9vbmdvaW5nUHJvbWlzZTtcbiAgICB9XG4gICAgcmV0dXJuKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHJldHVyblN0ZXBzID0gKCkgPT4gdGhpcy5fcmV0dXJuU3RlcHModmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fb25nb2luZ1Byb21pc2UgP1xuICAgICAgICAgICAgdHJhbnNmb3JtUHJvbWlzZVdpdGgodGhpcy5fb25nb2luZ1Byb21pc2UsIHJldHVyblN0ZXBzLCByZXR1cm5TdGVwcykgOlxuICAgICAgICAgICAgcmV0dXJuU3RlcHMoKTtcbiAgICB9XG4gICAgX25leHRTdGVwcygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHRoaXMuX3JlYWRlcjtcbiAgICAgICAgaWYgKHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFkZXJMb2NrRXhjZXB0aW9uKCdpdGVyYXRlJykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNvbHZlUHJvbWlzZTtcbiAgICAgICAgbGV0IHJlamVjdFByb21pc2U7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgIHJlamVjdFByb21pc2UgPSByZWplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZWFkUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9jaHVua1N0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb25nb2luZ1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBiZSBkZWxheWVkIGJ5IG9uZSBtaWNyb3Rhc2ssIG90aGVyd2lzZSB3ZSBzdG9wIHB1bGxpbmcgdG9vIGVhcmx5IHdoaWNoIGJyZWFrcyBhIHRlc3QuXG4gICAgICAgICAgICAgICAgLy8gRklYTUUgSXMgdGhpcyBhIGJ1ZyBpbiB0aGUgc3BlY2lmaWNhdGlvbiwgb3IgaW4gdGhlIHRlc3Q/XG4gICAgICAgICAgICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfY2xvc2VTdGVwczogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX29uZ29pbmdQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzRmluaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlUHJvbWlzZSh7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgX2Vycm9yU3RlcHM6IHJlYXNvbiA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb25nb2luZ1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNGaW5pc2hlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgICAgIHJlamVjdFByb21pc2UocmVhc29uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZChyZWFkZXIsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuICAgIF9yZXR1cm5TdGVwcyh2YWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5faXNGaW5pc2hlZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHZhbHVlLCBkb25lOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2lzRmluaXNoZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCByZWFkZXIgPSB0aGlzLl9yZWFkZXI7XG4gICAgICAgIGlmIChyZWFkZXIuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbignZmluaXNoIGl0ZXJhdGluZycpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX3ByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbChyZWFkZXIsIHZhbHVlKTtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1Qcm9taXNlV2l0aChyZXN1bHQsICgpID0+ICh7IHZhbHVlLCBkb25lOiB0cnVlIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHJlYWRlcik7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHsgdmFsdWUsIGRvbmU6IHRydWUgfSk7XG4gICAgfVxufVxuY29uc3QgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlID0ge1xuICAgIG5leHQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbUFzeW5jSXRlcmF0b3JCcmFuZENoZWNrRXhjZXB0aW9uKCduZXh0JykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hc3luY0l0ZXJhdG9ySW1wbC5uZXh0KCk7XG4gICAgfSxcbiAgICByZXR1cm4odmFsdWUpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQXN5bmNJdGVyYXRvckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JldHVybicpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYXN5bmNJdGVyYXRvckltcGwucmV0dXJuKHZhbHVlKTtcbiAgICB9XG59O1xuaWYgKEFzeW5jSXRlcmF0b3JQcm90b3R5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JQcm90b3R5cGUsIEFzeW5jSXRlcmF0b3JQcm90b3R5cGUpO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gQWNxdWlyZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcihzdHJlYW0sIHByZXZlbnRDYW5jZWwpIHtcbiAgICBjb25zdCByZWFkZXIgPSBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHN0cmVhbSk7XG4gICAgY29uc3QgaW1wbCA9IG5ldyBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JJbXBsKHJlYWRlciwgcHJldmVudENhbmNlbCk7XG4gICAgY29uc3QgaXRlcmF0b3IgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvclByb3RvdHlwZSk7XG4gICAgaXRlcmF0b3IuX2FzeW5jSXRlcmF0b3JJbXBsID0gaW1wbDtcbiAgICByZXR1cm4gaXRlcmF0b3I7XG59XG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2FzeW5jSXRlcmF0b3JJbXBsJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyBub2luc3BlY3Rpb24gU3VzcGljaW91c1R5cGVPZkd1YXJkXG4gICAgICAgIHJldHVybiB4Ll9hc3luY0l0ZXJhdG9ySW1wbCBpbnN0YW5jZW9mXG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JJbXBsO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbS5cbmZ1bmN0aW9uIHN0cmVhbUFzeW5jSXRlcmF0b3JCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RlYW1Bc3luY0l0ZXJhdG9yYCk7XG59XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5jb3JlXCIgLz5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL051bWJlci9pc05hTiNQb2x5ZmlsbFxuY29uc3QgTnVtYmVySXNOYU4gPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gKHgpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgcmV0dXJuIHggIT09IHg7XG59O1xuXG5mdW5jdGlvbiBDcmVhdGVBcnJheUZyb21MaXN0KGVsZW1lbnRzKSB7XG4gICAgLy8gV2UgdXNlIGFycmF5cyB0byByZXByZXNlbnQgbGlzdHMsIHNvIHRoaXMgaXMgYmFzaWNhbGx5IGEgbm8tb3AuXG4gICAgLy8gRG8gYSBzbGljZSB0aG91Z2gganVzdCBpbiBjYXNlIHdlIGhhcHBlbiB0byBkZXBlbmQgb24gdGhlIHVuaXF1ZS1uZXNzLlxuICAgIHJldHVybiBlbGVtZW50cy5zbGljZSgpO1xufVxuZnVuY3Rpb24gQ29weURhdGFCbG9ja0J5dGVzKGRlc3QsIGRlc3RPZmZzZXQsIHNyYywgc3JjT2Zmc2V0LCBuKSB7XG4gICAgbmV3IFVpbnQ4QXJyYXkoZGVzdCkuc2V0KG5ldyBVaW50OEFycmF5KHNyYywgc3JjT2Zmc2V0LCBuKSwgZGVzdE9mZnNldCk7XG59XG4vLyBOb3QgaW1wbGVtZW50ZWQgY29ycmVjdGx5XG5mdW5jdGlvbiBUcmFuc2ZlckFycmF5QnVmZmVyKE8pIHtcbiAgICByZXR1cm4gTztcbn1cbi8vIE5vdCBpbXBsZW1lbnRlZCBjb3JyZWN0bHlcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbmZ1bmN0aW9uIElzRGV0YWNoZWRCdWZmZXIoTykge1xuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIEFycmF5QnVmZmVyU2xpY2UoYnVmZmVyLCBiZWdpbiwgZW5kKSB7XG4gICAgLy8gQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBhdmFpbGFibGUgb24gSUUxMFxuICAgIC8vIGh0dHBzOi8vd3d3LmNhbml1c2UuY29tL21kbi1qYXZhc2NyaXB0X2J1aWx0aW5zX2FycmF5YnVmZmVyX3NsaWNlXG4gICAgaWYgKGJ1ZmZlci5zbGljZSkge1xuICAgICAgICByZXR1cm4gYnVmZmVyLnNsaWNlKGJlZ2luLCBlbmQpO1xuICAgIH1cbiAgICBjb25zdCBsZW5ndGggPSBlbmQgLSBiZWdpbjtcbiAgICBjb25zdCBzbGljZSA9IG5ldyBBcnJheUJ1ZmZlcihsZW5ndGgpO1xuICAgIENvcHlEYXRhQmxvY2tCeXRlcyhzbGljZSwgMCwgYnVmZmVyLCBiZWdpbiwgbGVuZ3RoKTtcbiAgICByZXR1cm4gc2xpY2U7XG59XG5cbmZ1bmN0aW9uIElzTm9uTmVnYXRpdmVOdW1iZXIodikge1xuICAgIGlmICh0eXBlb2YgdiAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoTnVtYmVySXNOYU4odikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodiA8IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIENsb25lQXNVaW50OEFycmF5KE8pIHtcbiAgICBjb25zdCBidWZmZXIgPSBBcnJheUJ1ZmZlclNsaWNlKE8uYnVmZmVyLCBPLmJ5dGVPZmZzZXQsIE8uYnl0ZU9mZnNldCArIE8uYnl0ZUxlbmd0aCk7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG59XG5cbmZ1bmN0aW9uIERlcXVldWVWYWx1ZShjb250YWluZXIpIHtcbiAgICBjb25zdCBwYWlyID0gY29udGFpbmVyLl9xdWV1ZS5zaGlmdCgpO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgLT0gcGFpci5zaXplO1xuICAgIGlmIChjb250YWluZXIuX3F1ZXVlVG90YWxTaXplIDwgMCkge1xuICAgICAgICBjb250YWluZXIuX3F1ZXVlVG90YWxTaXplID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHBhaXIudmFsdWU7XG59XG5mdW5jdGlvbiBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250YWluZXIsIHZhbHVlLCBzaXplKSB7XG4gICAgaWYgKCFJc05vbk5lZ2F0aXZlTnVtYmVyKHNpemUpIHx8IHNpemUgPT09IEluZmluaXR5KSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdTaXplIG11c3QgYmUgYSBmaW5pdGUsIG5vbi1OYU4sIG5vbi1uZWdhdGl2ZSBudW1iZXIuJyk7XG4gICAgfVxuICAgIGNvbnRhaW5lci5fcXVldWUucHVzaCh7IHZhbHVlLCBzaXplIH0pO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgKz0gc2l6ZTtcbn1cbmZ1bmN0aW9uIFBlZWtRdWV1ZVZhbHVlKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IHBhaXIgPSBjb250YWluZXIuX3F1ZXVlLnBlZWsoKTtcbiAgICByZXR1cm4gcGFpci52YWx1ZTtcbn1cbmZ1bmN0aW9uIFJlc2V0UXVldWUoY29udGFpbmVyKSB7XG4gICAgY29udGFpbmVyLl9xdWV1ZSA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgPSAwO1xufVxuXG4vKipcbiAqIEEgcHVsbC1pbnRvIHJlcXVlc3QgaW4gYSB7QGxpbmsgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcn0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2aWV3IGZvciB3cml0aW5nIGluIHRvLCBvciBgbnVsbGAgaWYgdGhlIEJZT0IgcmVxdWVzdCBoYXMgYWxyZWFkeSBiZWVuIHJlc3BvbmRlZCB0by5cbiAgICAgKi9cbiAgICBnZXQgdmlldygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbigndmlldycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl92aWV3O1xuICAgIH1cbiAgICByZXNwb25kKGJ5dGVzV3JpdHRlbikge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uKCdyZXNwb25kJyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChieXRlc1dyaXR0ZW4sIDEsICdyZXNwb25kJyk7XG4gICAgICAgIGJ5dGVzV3JpdHRlbiA9IGNvbnZlcnRVbnNpZ25lZExvbmdMb25nV2l0aEVuZm9yY2VSYW5nZShieXRlc1dyaXR0ZW4sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoaXMgQllPQiByZXF1ZXN0IGhhcyBiZWVuIGludmFsaWRhdGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIodGhpcy5fdmlldy5idWZmZXIpKSA7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLCBieXRlc1dyaXR0ZW4pO1xuICAgIH1cbiAgICByZXNwb25kV2l0aE5ld1ZpZXcodmlldykge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uKCdyZXNwb25kV2l0aE5ld1ZpZXcnKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHZpZXcsIDEsICdyZXNwb25kV2l0aE5ld1ZpZXcnKTtcbiAgICAgICAgaWYgKCFBcnJheUJ1ZmZlci5pc1ZpZXcodmlldykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1lvdSBjYW4gb25seSByZXNwb25kIHdpdGggYXJyYXkgYnVmZmVyIHZpZXdzJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoaXMgQllPQiByZXF1ZXN0IGhhcyBiZWVuIGludmFsaWRhdGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIodmlldy5idWZmZXIpKSA7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcodGhpcy5fYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIsIHZpZXcpO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlLCB7XG4gICAgcmVzcG9uZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcmVzcG9uZFdpdGhOZXdWaWV3OiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB2aWV3OiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vKipcbiAqIEFsbG93cyBjb250cm9sIG9mIGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtIHwgcmVhZGFibGUgYnl0ZSBzdHJlYW19J3Mgc3RhdGUgYW5kIGludGVybmFsIHF1ZXVlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgY29uc3RydWN0b3InKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCBCWU9CIHB1bGwgcmVxdWVzdCwgb3IgYG51bGxgIGlmIHRoZXJlIGlzbid0IG9uZS5cbiAgICAgKi9cbiAgICBnZXQgYnlvYlJlcXVlc3QoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlU3RyZWFtQ29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2J5b2JSZXF1ZXN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIGNvbnRyb2xsZWQgc3RyZWFtJ3MgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzXG4gICAgICogb3Zlci1mdWxsLiBBbiB1bmRlcmx5aW5nIGJ5dGUgc291cmNlIG91Z2h0IHRvIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSB3aGVuIGFuZCBob3cgdG8gYXBwbHkgYmFja3ByZXNzdXJlLlxuICAgICAqL1xuICAgIGdldCBkZXNpcmVkU2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVTdHJlYW1Db250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbignZGVzaXJlZFNpemUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldERlc2lyZWRTaXplKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIGNvbnRyb2xsZWQgcmVhZGFibGUgc3RyZWFtLiBDb25zdW1lcnMgd2lsbCBzdGlsbCBiZSBhYmxlIHRvIHJlYWQgYW55IHByZXZpb3VzbHktZW5xdWV1ZWQgY2h1bmtzIGZyb21cbiAgICAgKiB0aGUgc3RyZWFtLCBidXQgb25jZSB0aG9zZSBhcmUgcmVhZCwgdGhlIHN0cmVhbSB3aWxsIGJlY29tZSBjbG9zZWQuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlU3RyZWFtQ29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2Nsb3NlUmVxdWVzdGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkOyBkbyBub3QgY2xvc2UgaXQgYWdhaW4hJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICAgICAgaWYgKHN0YXRlICE9PSAncmVhZGFibGUnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgc3RyZWFtIChpbiAke3N0YXRlfSBzdGF0ZSkgaXMgbm90IGluIHRoZSByZWFkYWJsZSBzdGF0ZSBhbmQgY2Fubm90IGJlIGNsb3NlZGApO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuaykge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlbnF1ZXVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChjaHVuaywgMSwgJ2VucXVldWUnKTtcbiAgICAgICAgaWYgKCFBcnJheUJ1ZmZlci5pc1ZpZXcoY2h1bmspKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjaHVuayBtdXN0IGJlIGFuIGFycmF5IGJ1ZmZlciB2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NodW5rIG11c3QgaGF2ZSBub24temVybyBieXRlTGVuZ3RoJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNodW5rLmJ1ZmZlci5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBjaHVuaydzIGJ1ZmZlciBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aGApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9jbG9zZVJlcXVlc3RlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc3RyZWFtIGlzIGNsb3NlZCBvciBkcmFpbmluZycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbS5fc3RhdGU7XG4gICAgICAgIGlmIChzdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHN0cmVhbSAoaW4gJHtzdGF0ZX0gc3RhdGUpIGlzIG5vdCBpbiB0aGUgcmVhZGFibGUgc3RhdGUgYW5kIGNhbm5vdCBiZSBlbnF1ZXVlZCB0b2ApO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlKHRoaXMsIGNodW5rKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXJyb3JzIHRoZSBjb250cm9sbGVkIHJlYWRhYmxlIHN0cmVhbSwgbWFraW5nIGFsbCBmdXR1cmUgaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuXG4gICAgICovXG4gICAgZXJyb3IoZSA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcih0aGlzLCBlKTtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtDYW5jZWxTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhclBlbmRpbmdQdWxsSW50b3ModGhpcyk7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NhbmNlbEFsZ29yaXRobShyZWFzb24pO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKHRoaXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKiogQGludGVybmFsICovXG4gICAgW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpIHtcbiAgICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICAgICAgaWYgKHRoaXMuX3F1ZXVlVG90YWxTaXplID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZW50cnkgPSB0aGlzLl9xdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgdGhpcy5fcXVldWVUb3RhbFNpemUgLT0gZW50cnkuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJIYW5kbGVRdWV1ZURyYWluKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KGVudHJ5LmJ1ZmZlciwgZW50cnkuYnl0ZU9mZnNldCwgZW50cnkuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICByZWFkUmVxdWVzdC5fY2h1bmtTdGVwcyh2aWV3KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdXRvQWxsb2NhdGVDaHVua1NpemUgPSB0aGlzLl9hdXRvQWxsb2NhdGVDaHVua1NpemU7XG4gICAgICAgIGlmIChhdXRvQWxsb2NhdGVDaHVua1NpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbGV0IGJ1ZmZlcjtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoYnVmZmVyRSkge1xuICAgICAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9lcnJvclN0ZXBzKGJ1ZmZlckUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHB1bGxJbnRvRGVzY3JpcHRvciA9IHtcbiAgICAgICAgICAgICAgICBidWZmZXIsXG4gICAgICAgICAgICAgICAgYnVmZmVyQnl0ZUxlbmd0aDogYXV0b0FsbG9jYXRlQ2h1bmtTaXplLFxuICAgICAgICAgICAgICAgIGJ5dGVPZmZzZXQ6IDAsXG4gICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogYXV0b0FsbG9jYXRlQ2h1bmtTaXplLFxuICAgICAgICAgICAgICAgIGJ5dGVzRmlsbGVkOiAwLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRTaXplOiAxLFxuICAgICAgICAgICAgICAgIHZpZXdDb25zdHJ1Y3RvcjogVWludDhBcnJheSxcbiAgICAgICAgICAgICAgICByZWFkZXJUeXBlOiAnZGVmYXVsdCdcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9wZW5kaW5nUHVsbEludG9zLnB1c2gocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbUFkZFJlYWRSZXF1ZXN0KHN0cmVhbSwgcmVhZFJlcXVlc3QpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSwge1xuICAgIGNsb3NlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlbnF1ZXVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgYnlvYlJlcXVlc3Q6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGRlc2lyZWRTaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5cbmZ1bmN0aW9uIElzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4geCBpbnN0YW5jZW9mIFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3Q7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc2hvdWxkUHVsbCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKTtcbiAgICBpZiAoIXNob3VsZFB1bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcHVsbGluZykge1xuICAgICAgICBjb250cm9sbGVyLl9wdWxsQWdhaW4gPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSB0cnVlO1xuICAgIC8vIFRPRE86IFRlc3QgY29udHJvbGxlciBhcmd1bWVudFxuICAgIGNvbnN0IHB1bGxQcm9taXNlID0gY29udHJvbGxlci5fcHVsbEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHB1bGxQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIuX3B1bGxBZ2Fpbikge1xuICAgICAgICAgICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gZmFsc2U7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICAgICAgfVxuICAgIH0sIGUgPT4ge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSk7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJQZW5kaW5nUHVsbEludG9zKGNvbnRyb2xsZXIpIHtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySW52YWxpZGF0ZUJZT0JSZXF1ZXN0KGNvbnRyb2xsZXIpO1xuICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MgPSBuZXcgU2ltcGxlUXVldWUoKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb21taXRQdWxsSW50b0Rlc2NyaXB0b3Ioc3RyZWFtLCBwdWxsSW50b0Rlc2NyaXB0b3IpIHtcbiAgICBsZXQgZG9uZSA9IGZhbHNlO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZmlsbGVkVmlldyA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb252ZXJ0UHVsbEludG9EZXNjcmlwdG9yKHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgaWYgKHB1bGxJbnRvRGVzY3JpcHRvci5yZWFkZXJUeXBlID09PSAnZGVmYXVsdCcpIHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3Qoc3RyZWFtLCBmaWxsZWRWaWV3LCBkb25lKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIGZpbGxlZFZpZXcsIGRvbmUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb252ZXJ0UHVsbEludG9EZXNjcmlwdG9yKHB1bGxJbnRvRGVzY3JpcHRvcikge1xuICAgIGNvbnN0IGJ5dGVzRmlsbGVkID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkO1xuICAgIGNvbnN0IGVsZW1lbnRTaXplID0gcHVsbEludG9EZXNjcmlwdG9yLmVsZW1lbnRTaXplO1xuICAgIHJldHVybiBuZXcgcHVsbEludG9EZXNjcmlwdG9yLnZpZXdDb25zdHJ1Y3RvcihwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZU9mZnNldCwgYnl0ZXNGaWxsZWQgLyBlbGVtZW50U2l6ZSk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCBidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpIHtcbiAgICBjb250cm9sbGVyLl9xdWV1ZS5wdXNoKHsgYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoIH0pO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplICs9IGJ5dGVMZW5ndGg7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpIHtcbiAgICBjb25zdCBlbGVtZW50U2l6ZSA9IHB1bGxJbnRvRGVzY3JpcHRvci5lbGVtZW50U2l6ZTtcbiAgICBjb25zdCBjdXJyZW50QWxpZ25lZEJ5dGVzID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkIC0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICUgZWxlbWVudFNpemU7XG4gICAgY29uc3QgbWF4Qnl0ZXNUb0NvcHkgPSBNYXRoLm1pbihjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSwgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVMZW5ndGggLSBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQpO1xuICAgIGNvbnN0IG1heEJ5dGVzRmlsbGVkID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICsgbWF4Qnl0ZXNUb0NvcHk7XG4gICAgY29uc3QgbWF4QWxpZ25lZEJ5dGVzID0gbWF4Qnl0ZXNGaWxsZWQgLSBtYXhCeXRlc0ZpbGxlZCAlIGVsZW1lbnRTaXplO1xuICAgIGxldCB0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nID0gbWF4Qnl0ZXNUb0NvcHk7XG4gICAgbGV0IHJlYWR5ID0gZmFsc2U7XG4gICAgaWYgKG1heEFsaWduZWRCeXRlcyA+IGN1cnJlbnRBbGlnbmVkQnl0ZXMpIHtcbiAgICAgICAgdG90YWxCeXRlc1RvQ29weVJlbWFpbmluZyA9IG1heEFsaWduZWRCeXRlcyAtIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZDtcbiAgICAgICAgcmVhZHkgPSB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBxdWV1ZSA9IGNvbnRyb2xsZXIuX3F1ZXVlO1xuICAgIHdoaWxlICh0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nID4gMCkge1xuICAgICAgICBjb25zdCBoZWFkT2ZRdWV1ZSA9IHF1ZXVlLnBlZWsoKTtcbiAgICAgICAgY29uc3QgYnl0ZXNUb0NvcHkgPSBNYXRoLm1pbih0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nLCBoZWFkT2ZRdWV1ZS5ieXRlTGVuZ3RoKTtcbiAgICAgICAgY29uc3QgZGVzdFN0YXJ0ID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVPZmZzZXQgKyBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQ7XG4gICAgICAgIENvcHlEYXRhQmxvY2tCeXRlcyhwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBkZXN0U3RhcnQsIGhlYWRPZlF1ZXVlLmJ1ZmZlciwgaGVhZE9mUXVldWUuYnl0ZU9mZnNldCwgYnl0ZXNUb0NvcHkpO1xuICAgICAgICBpZiAoaGVhZE9mUXVldWUuYnl0ZUxlbmd0aCA9PT0gYnl0ZXNUb0NvcHkpIHtcbiAgICAgICAgICAgIHF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBoZWFkT2ZRdWV1ZS5ieXRlT2Zmc2V0ICs9IGJ5dGVzVG9Db3B5O1xuICAgICAgICAgICAgaGVhZE9mUXVldWUuYnl0ZUxlbmd0aCAtPSBieXRlc1RvQ29weTtcbiAgICAgICAgfVxuICAgICAgICBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSAtPSBieXRlc1RvQ29weTtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxIZWFkUHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIsIGJ5dGVzVG9Db3B5LCBwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgICAgICB0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nIC09IGJ5dGVzVG9Db3B5O1xuICAgIH1cbiAgICByZXR1cm4gcmVhZHk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbEhlYWRQdWxsSW50b0Rlc2NyaXB0b3IoY29udHJvbGxlciwgc2l6ZSwgcHVsbEludG9EZXNjcmlwdG9yKSB7XG4gICAgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICs9IHNpemU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbihjb250cm9sbGVyKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID09PSAwICYmIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQ2xvc2UoY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySW52YWxpZGF0ZUJZT0JSZXF1ZXN0KGNvbnRyb2xsZXIpIHtcbiAgICBpZiAoY29udHJvbGxlci5fYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb250cm9sbGVyLl9ieW9iUmVxdWVzdC5fYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIgPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYnlvYlJlcXVlc3QuX3ZpZXcgPSBudWxsO1xuICAgIGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID0gbnVsbDtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJQcm9jZXNzUHVsbEludG9EZXNjcmlwdG9yc1VzaW5nUXVldWUoY29udHJvbGxlcikge1xuICAgIHdoaWxlIChjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHVsbEludG9EZXNjcmlwdG9yID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgICAgIGlmIChSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpKSB7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8oY29udHJvbGxlcik7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ29tbWl0UHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8oY29udHJvbGxlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBsZXQgZWxlbWVudFNpemUgPSAxO1xuICAgIGlmICh2aWV3LmNvbnN0cnVjdG9yICE9PSBEYXRhVmlldykge1xuICAgICAgICBlbGVtZW50U2l6ZSA9IHZpZXcuY29uc3RydWN0b3IuQllURVNfUEVSX0VMRU1FTlQ7XG4gICAgfVxuICAgIGNvbnN0IGN0b3IgPSB2aWV3LmNvbnN0cnVjdG9yO1xuICAgIC8vIHRyeSB7XG4gICAgY29uc3QgYnVmZmVyID0gVHJhbnNmZXJBcnJheUJ1ZmZlcih2aWV3LmJ1ZmZlcik7XG4gICAgLy8gfSBjYXRjaCAoZSkge1xuICAgIC8vICAgcmVhZEludG9SZXF1ZXN0Ll9lcnJvclN0ZXBzKGUpO1xuICAgIC8vICAgcmV0dXJuO1xuICAgIC8vIH1cbiAgICBjb25zdCBwdWxsSW50b0Rlc2NyaXB0b3IgPSB7XG4gICAgICAgIGJ1ZmZlcixcbiAgICAgICAgYnVmZmVyQnl0ZUxlbmd0aDogYnVmZmVyLmJ5dGVMZW5ndGgsXG4gICAgICAgIGJ5dGVPZmZzZXQ6IHZpZXcuYnl0ZU9mZnNldCxcbiAgICAgICAgYnl0ZUxlbmd0aDogdmlldy5ieXRlTGVuZ3RoLFxuICAgICAgICBieXRlc0ZpbGxlZDogMCxcbiAgICAgICAgZWxlbWVudFNpemUsXG4gICAgICAgIHZpZXdDb25zdHJ1Y3RvcjogY3RvcixcbiAgICAgICAgcmVhZGVyVHlwZTogJ2J5b2InXG4gICAgfTtcbiAgICBpZiAoY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucHVzaChwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgICAgICAvLyBObyBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCgpIGNhbGwgc2luY2U6XG4gICAgICAgIC8vIC0gTm8gY2hhbmdlIGhhcHBlbnMgb24gZGVzaXJlZFNpemVcbiAgICAgICAgLy8gLSBUaGUgc291cmNlIGhhcyBhbHJlYWR5IGJlZW4gbm90aWZpZWQgb2YgdGhhdCB0aGVyZSdzIGF0IGxlYXN0IDEgcGVuZGluZyByZWFkKHZpZXcpXG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQWRkUmVhZEludG9SZXF1ZXN0KHN0cmVhbSwgcmVhZEludG9SZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgY29uc3QgZW1wdHlWaWV3ID0gbmV3IGN0b3IocHVsbEludG9EZXNjcmlwdG9yLmJ1ZmZlciwgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVPZmZzZXQsIDApO1xuICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Nsb3NlU3RlcHMoZW1wdHlWaWV3KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWVUb3RhbFNpemUgPiAwKSB7XG4gICAgICAgIGlmIChSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxsZWRWaWV3ID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbnZlcnRQdWxsSW50b0Rlc2NyaXB0b3IocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJIYW5kbGVRdWV1ZURyYWluKGNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgcmVhZEludG9SZXF1ZXN0Ll9jaHVua1N0ZXBzKGZpbGxlZFZpZXcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCkge1xuICAgICAgICAgICAgY29uc3QgZSA9IG5ldyBUeXBlRXJyb3IoJ0luc3VmZmljaWVudCBieXRlcyB0byBmaWxsIGVsZW1lbnRzIGluIHRoZSBnaXZlbiBidWZmZXInKTtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKTtcbiAgICAgICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fZXJyb3JTdGVwcyhlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnB1c2gocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICBSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluQ2xvc2VkU3RhdGUoY29udHJvbGxlciwgZmlyc3REZXNjcmlwdG9yKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoUmVhZGFibGVTdHJlYW1IYXNCWU9CUmVhZGVyKHN0cmVhbSkpIHtcbiAgICAgICAgd2hpbGUgKFJlYWRhYmxlU3RyZWFtR2V0TnVtUmVhZEludG9SZXF1ZXN0cyhzdHJlYW0pID4gMCkge1xuICAgICAgICAgICAgY29uc3QgcHVsbEludG9EZXNjcmlwdG9yID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclNoaWZ0UGVuZGluZ1B1bGxJbnRvKGNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbW1pdFB1bGxJbnRvRGVzY3JpcHRvcihzdHJlYW0sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluUmVhZGFibGVTdGF0ZShjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4sIHB1bGxJbnRvRGVzY3JpcHRvcikge1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsSGVhZFB1bGxJbnRvRGVzY3JpcHRvcihjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgaWYgKHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZCA8IHB1bGxJbnRvRGVzY3JpcHRvci5lbGVtZW50U2l6ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaGlmdFBlbmRpbmdQdWxsSW50byhjb250cm9sbGVyKTtcbiAgICBjb25zdCByZW1haW5kZXJTaXplID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICUgcHVsbEludG9EZXNjcmlwdG9yLmVsZW1lbnRTaXplO1xuICAgIGlmIChyZW1haW5kZXJTaXplID4gMCkge1xuICAgICAgICBjb25zdCBlbmQgPSBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZU9mZnNldCArIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZDtcbiAgICAgICAgY29uc3QgcmVtYWluZGVyID0gQXJyYXlCdWZmZXJTbGljZShwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBlbmQgLSByZW1haW5kZXJTaXplLCBlbmQpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCByZW1haW5kZXIsIDAsIHJlbWFpbmRlci5ieXRlTGVuZ3RoKTtcbiAgICB9XG4gICAgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkIC09IHJlbWFpbmRlclNpemU7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbW1pdFB1bGxJbnRvRGVzY3JpcHRvcihjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLCBwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJQcm9jZXNzUHVsbEludG9EZXNjcmlwdG9yc1VzaW5nUXVldWUoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEludGVybmFsKGNvbnRyb2xsZXIsIGJ5dGVzV3JpdHRlbikge1xuICAgIGNvbnN0IGZpcnN0RGVzY3JpcHRvciA9IGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucGVlaygpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJJbnZhbGlkYXRlQllPQlJlcXVlc3QoY29udHJvbGxlcik7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5DbG9zZWRTdGF0ZShjb250cm9sbGVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5SZWFkYWJsZVN0YXRlKGNvbnRyb2xsZXIsIGJ5dGVzV3JpdHRlbiwgZmlyc3REZXNjcmlwdG9yKTtcbiAgICB9XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8oY29udHJvbGxlcikge1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnNoaWZ0KCk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hvdWxkQ2FsbFB1bGwoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fY2xvc2VSZXF1ZXN0ZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWNvbnRyb2xsZXIuX3N0YXJ0ZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoUmVhZGFibGVTdHJlYW1IYXNEZWZhdWx0UmVhZGVyKHN0cmVhbSkgJiYgUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChSZWFkYWJsZVN0cmVhbUhhc0JZT0JSZWFkZXIoc3RyZWFtKSAmJiBSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRJbnRvUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGRlc2lyZWRTaXplID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldERlc2lyZWRTaXplKGNvbnRyb2xsZXIpO1xuICAgIGlmIChkZXNpcmVkU2l6ZSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcikge1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fY2FuY2VsQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuLy8gQSBjbGllbnQgb2YgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciBtYXkgdXNlIHRoZXNlIGZ1bmN0aW9ucyBkaXJlY3RseSB0byBieXBhc3Mgc3RhdGUgY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2UoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgaWYgKGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkIHx8IHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWVUb3RhbFNpemUgPiAwKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0UGVuZGluZ1B1bGxJbnRvID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgICAgIGlmIChmaXJzdFBlbmRpbmdQdWxsSW50by5ieXRlc0ZpbGxlZCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGUgPSBuZXcgVHlwZUVycm9yKCdJbnN1ZmZpY2llbnQgYnl0ZXMgdG8gZmlsbCBlbGVtZW50cyBpbiB0aGUgZ2l2ZW4gYnVmZmVyJyk7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSk7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWUoY29udHJvbGxlciwgY2h1bmspIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtO1xuICAgIGlmIChjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCB8fCBzdHJlYW0uX3N0YXRlICE9PSAncmVhZGFibGUnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYnVmZmVyID0gY2h1bmsuYnVmZmVyO1xuICAgIGNvbnN0IGJ5dGVPZmZzZXQgPSBjaHVuay5ieXRlT2Zmc2V0O1xuICAgIGNvbnN0IGJ5dGVMZW5ndGggPSBjaHVuay5ieXRlTGVuZ3RoO1xuICAgIGNvbnN0IHRyYW5zZmVycmVkQnVmZmVyID0gVHJhbnNmZXJBcnJheUJ1ZmZlcihidWZmZXIpO1xuICAgIGlmIChjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZmlyc3RQZW5kaW5nUHVsbEludG8gPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIoZmlyc3RQZW5kaW5nUHVsbEludG8uYnVmZmVyKSkgO1xuICAgICAgICBmaXJzdFBlbmRpbmdQdWxsSW50by5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKGZpcnN0UGVuZGluZ1B1bGxJbnRvLmJ1ZmZlcik7XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJJbnZhbGlkYXRlQllPQlJlcXVlc3QoY29udHJvbGxlcik7XG4gICAgaWYgKFJlYWRhYmxlU3RyZWFtSGFzRGVmYXVsdFJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIGlmIChSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pID09PSAwKSB7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCB0cmFuc2ZlcnJlZEJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2ZlcnJlZFZpZXcgPSBuZXcgVWludDhBcnJheSh0cmFuc2ZlcnJlZEJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUZ1bGZpbGxSZWFkUmVxdWVzdChzdHJlYW0sIHRyYW5zZmVycmVkVmlldywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKFJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIC8vIFRPRE86IElkZWFsbHkgaW4gdGhpcyBicmFuY2ggZGV0YWNoaW5nIHNob3VsZCBoYXBwZW4gb25seSBpZiB0aGUgYnVmZmVyIGlzIG5vdCBjb25zdW1lZCBmdWxseS5cbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgdHJhbnNmZXJyZWRCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHJvY2Vzc1B1bGxJbnRvRGVzY3JpcHRvcnNVc2luZ1F1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgdHJhbnNmZXJyZWRCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgIH1cbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhclBlbmRpbmdQdWxsSW50b3MoY29udHJvbGxlcik7XG4gICAgUmVzZXRRdWV1ZShjb250cm9sbGVyKTtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgIFJlYWRhYmxlU3RyZWFtRXJyb3Ioc3RyZWFtLCBlKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChjb250cm9sbGVyKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID09PSBudWxsICYmIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBmaXJzdERlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICAgICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KGZpcnN0RGVzY3JpcHRvci5idWZmZXIsIGZpcnN0RGVzY3JpcHRvci5ieXRlT2Zmc2V0ICsgZmlyc3REZXNjcmlwdG9yLmJ5dGVzRmlsbGVkLCBmaXJzdERlc2NyaXB0b3IuYnl0ZUxlbmd0aCAtIGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCk7XG4gICAgICAgIGNvbnN0IGJ5b2JSZXF1ZXN0ID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LnByb3RvdHlwZSk7XG4gICAgICAgIFNldFVwUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdChieW9iUmVxdWVzdCwgY29udHJvbGxlciwgdmlldyk7XG4gICAgICAgIGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID0gYnlvYlJlcXVlc3Q7XG4gICAgfVxuICAgIHJldHVybiBjb250cm9sbGVyLl9ieW9iUmVxdWVzdDtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNIC0gY29udHJvbGxlci5fcXVldWVUb3RhbFNpemU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZChjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4pIHtcbiAgICBjb25zdCBmaXJzdERlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgaWYgKGJ5dGVzV3JpdHRlbiAhPT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYnl0ZXNXcml0dGVuIG11c3QgYmUgMCB3aGVuIGNhbGxpbmcgcmVzcG9uZCgpIG9uIGEgY2xvc2VkIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZiAoYnl0ZXNXcml0dGVuID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdieXRlc1dyaXR0ZW4gbXVzdCBiZSBncmVhdGVyIHRoYW4gMCB3aGVuIGNhbGxpbmcgcmVzcG9uZCgpIG9uIGEgcmVhZGFibGUgc3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCArIGJ5dGVzV3JpdHRlbiA+IGZpcnN0RGVzY3JpcHRvci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYnl0ZXNXcml0dGVuIG91dCBvZiByYW5nZScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZpcnN0RGVzY3JpcHRvci5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKGZpcnN0RGVzY3JpcHRvci5idWZmZXIpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW50ZXJuYWwoY29udHJvbGxlciwgYnl0ZXNXcml0dGVuKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcoY29udHJvbGxlciwgdmlldykge1xuICAgIGNvbnN0IGZpcnN0RGVzY3JpcHRvciA9IGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucGVlaygpO1xuICAgIGNvbnN0IHN0YXRlID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICBpZiAodmlldy5ieXRlTGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgdmlld1xcJ3MgbGVuZ3RoIG11c3QgYmUgMCB3aGVuIGNhbGxpbmcgcmVzcG9uZFdpdGhOZXdWaWV3KCkgb24gYSBjbG9zZWQgc3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmICh2aWV3LmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSB2aWV3XFwncyBsZW5ndGggbXVzdCBiZSBncmVhdGVyIHRoYW4gMCB3aGVuIGNhbGxpbmcgcmVzcG9uZFdpdGhOZXdWaWV3KCkgb24gYSByZWFkYWJsZSBzdHJlYW0nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoZmlyc3REZXNjcmlwdG9yLmJ5dGVPZmZzZXQgKyBmaXJzdERlc2NyaXB0b3IuYnl0ZXNGaWxsZWQgIT09IHZpZXcuYnl0ZU9mZnNldCkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHJlZ2lvbiBzcGVjaWZpZWQgYnkgdmlldyBkb2VzIG5vdCBtYXRjaCBieW9iUmVxdWVzdCcpO1xuICAgIH1cbiAgICBpZiAoZmlyc3REZXNjcmlwdG9yLmJ1ZmZlckJ5dGVMZW5ndGggIT09IHZpZXcuYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBidWZmZXIgb2YgdmlldyBoYXMgZGlmZmVyZW50IGNhcGFjaXR5IHRoYW4gYnlvYlJlcXVlc3QnKTtcbiAgICB9XG4gICAgaWYgKGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCArIHZpZXcuYnl0ZUxlbmd0aCA+IGZpcnN0RGVzY3JpcHRvci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgcmVnaW9uIHNwZWNpZmllZCBieSB2aWV3IGlzIGxhcmdlciB0aGFuIGJ5b2JSZXF1ZXN0Jyk7XG4gICAgfVxuICAgIGZpcnN0RGVzY3JpcHRvci5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKHZpZXcuYnVmZmVyKTtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEludGVybmFsKGNvbnRyb2xsZXIsIHZpZXcuYnl0ZUxlbmd0aCk7XG59XG5mdW5jdGlvbiBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBhdXRvQWxsb2NhdGVDaHVua1NpemUpIHtcbiAgICBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtID0gc3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBZ2FpbiA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSBmYWxzZTtcbiAgICBjb250cm9sbGVyLl9ieW9iUmVxdWVzdCA9IG51bGw7XG4gICAgLy8gTmVlZCB0byBzZXQgdGhlIHNsb3RzIHNvIHRoYXQgdGhlIGFzc2VydCBkb2Vzbid0IGZpcmUuIEluIHRoZSBzcGVjIHRoZSBzbG90cyBhbHJlYWR5IGV4aXN0IGltcGxpY2l0bHkuXG4gICAgY29udHJvbGxlci5fcXVldWUgPSBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSA9IHVuZGVmaW5lZDtcbiAgICBSZXNldFF1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNID0gaGlnaFdhdGVyTWFyaztcbiAgICBjb250cm9sbGVyLl9wdWxsQWxnb3JpdGhtID0gcHVsbEFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9jYW5jZWxBbGdvcml0aG0gPSBjYW5jZWxBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fYXV0b0FsbG9jYXRlQ2h1bmtTaXplID0gYXV0b0FsbG9jYXRlQ2h1bmtTaXplO1xuICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICBzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgY29uc3Qgc3RhcnRSZXN1bHQgPSBzdGFydEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2VSZXNvbHZlZFdpdGgoc3RhcnRSZXN1bHQpLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIHIpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2Uoc3RyZWFtLCB1bmRlcmx5aW5nQnl0ZVNvdXJjZSwgaGlnaFdhdGVyTWFyaykge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBsZXQgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlZmluZWQ7XG4gICAgbGV0IHB1bGxBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgbGV0IGNhbmNlbEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2Uuc3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdCeXRlU291cmNlLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2UucHVsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHB1bGxBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nQnl0ZVNvdXJjZS5wdWxsKGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2UuY2FuY2VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2FuY2VsQWxnb3JpdGhtID0gcmVhc29uID0+IHVuZGVybHlpbmdCeXRlU291cmNlLmNhbmNlbChyZWFzb24pO1xuICAgIH1cbiAgICBjb25zdCBhdXRvQWxsb2NhdGVDaHVua1NpemUgPSB1bmRlcmx5aW5nQnl0ZVNvdXJjZS5hdXRvQWxsb2NhdGVDaHVua1NpemU7XG4gICAgaWYgKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhdXRvQWxsb2NhdGVDaHVua1NpemUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgIH1cbiAgICBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBhdXRvQWxsb2NhdGVDaHVua1NpemUpO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0KHJlcXVlc3QsIGNvbnRyb2xsZXIsIHZpZXcpIHtcbiAgICByZXF1ZXN0Ll9hc3NvY2lhdGVkUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgcmVxdWVzdC5fdmlldyA9IHZpZXc7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdC5cbmZ1bmN0aW9uIGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3RgKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLlxuZnVuY3Rpb24gYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcmApO1xufVxuXG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW0uXG5mdW5jdGlvbiBBY3F1aXJlUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHN0cmVhbSkge1xuICAgIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHN0cmVhbSk7XG59XG4vLyBSZWFkYWJsZVN0cmVhbSBBUEkgZXhwb3NlZCBmb3IgY29udHJvbGxlcnMuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIHJlYWRJbnRvUmVxdWVzdCkge1xuICAgIHN0cmVhbS5fcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLnB1c2gocmVhZEludG9SZXF1ZXN0KTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIGNodW5rLCBkb25lKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgY29uc3QgcmVhZEludG9SZXF1ZXN0ID0gcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLnNoaWZ0KCk7XG4gICAgaWYgKGRvbmUpIHtcbiAgICAgICAgcmVhZEludG9SZXF1ZXN0Ll9jbG9zZVN0ZXBzKGNodW5rKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fY2h1bmtTdGVwcyhjaHVuayk7XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkSW50b1JlcXVlc3RzKHN0cmVhbSkge1xuICAgIHJldHVybiBzdHJlYW0uX3JlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5sZW5ndGg7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUhhc0JZT0JSZWFkZXIoc3RyZWFtKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIEEgQllPQiByZWFkZXIgdmVuZGVkIGJ5IGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlciB7XG4gICAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQoc3RyZWFtLCAxLCAnUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyJyk7XG4gICAgICAgIGFzc2VydFJlYWRhYmxlU3RyZWFtKHN0cmVhbSwgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZChzdHJlYW0pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGlzIHN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGxvY2tlZCBmb3IgZXhjbHVzaXZlIHJlYWRpbmcgYnkgYW5vdGhlciByZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcihzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjb25zdHJ1Y3QgYSBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIgZm9yIGEgc3RyZWFtIG5vdCBjb25zdHJ1Y3RlZCB3aXRoIGEgYnl0ZSAnICtcbiAgICAgICAgICAgICAgICAnc291cmNlJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZSh0aGlzLCBzdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWFkSW50b1JlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBmdWxmaWxsZWQgd2hlbiB0aGUgc3RyZWFtIGJlY29tZXMgY2xvc2VkLCBvciByZWplY3RlZCBpZiB0aGUgc3RyZWFtIGV2ZXIgZXJyb3JzIG9yXG4gICAgICogdGhlIHJlYWRlcidzIGxvY2sgaXMgcmVsZWFzZWQgYmVmb3JlIHRoZSBzdHJlYW0gZmluaXNoZXMgY2xvc2luZy5cbiAgICAgKi9cbiAgICBnZXQgY2xvc2VkKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChieW9iUmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbignY2xvc2VkJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9zZWRQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcmVhZGVyIGlzIGFjdGl2ZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QGxpbmsgUmVhZGFibGVTdHJlYW0uY2FuY2VsIHwgc3RyZWFtLmNhbmNlbChyZWFzb24pfS5cbiAgICAgKi9cbiAgICBjYW5jZWwocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdjYW5jZWwnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbignY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNDYW5jZWwodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gcmVhZHMgYnl0ZXMgaW50byB2aWV3LCBhbmQgcmV0dXJucyBhIHByb21pc2UgcmVzb2x2ZWQgd2l0aCB0aGUgcmVzdWx0LlxuICAgICAqXG4gICAgICogSWYgcmVhZGluZyBhIGNodW5rIGNhdXNlcyB0aGUgcXVldWUgdG8gYmVjb21lIGVtcHR5LCBtb3JlIGRhdGEgd2lsbCBiZSBwdWxsZWQgZnJvbSB0aGUgdW5kZXJseWluZyBzb3VyY2UuXG4gICAgICovXG4gICAgcmVhZCh2aWV3KSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KHZpZXcpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCd2aWV3IG11c3QgYmUgYW4gYXJyYXkgYnVmZmVyIHZpZXcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpZXcuYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcigndmlldyBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmlldy5idWZmZXIuYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcihgdmlldydzIGJ1ZmZlciBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aGApKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoSXNEZXRhY2hlZEJ1ZmZlcih2aWV3LmJ1ZmZlcikpIDtcbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbigncmVhZCBmcm9tJykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNvbHZlUHJvbWlzZTtcbiAgICAgICAgbGV0IHJlamVjdFByb21pc2U7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgIHJlamVjdFByb21pc2UgPSByZWplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZWFkSW50b1JlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pLFxuICAgICAgICAgICAgX2Nsb3NlU3RlcHM6IGNodW5rID0+IHJlc29sdmVQcm9taXNlKHsgdmFsdWU6IGNodW5rLCBkb25lOiB0cnVlIH0pLFxuICAgICAgICAgICAgX2Vycm9yU3RlcHM6IGUgPT4gcmVqZWN0UHJvbWlzZShlKVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkKHRoaXMsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlcyB0aGUgcmVhZGVyJ3MgbG9jayBvbiB0aGUgY29ycmVzcG9uZGluZyBzdHJlYW0uIEFmdGVyIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmVhZGVyIGlzIG5vIGxvbmdlciBhY3RpdmUuXG4gICAgICogSWYgdGhlIGFzc29jaWF0ZWQgc3RyZWFtIGlzIGVycm9yZWQgd2hlbiB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJlYWRlciB3aWxsIGFwcGVhciBlcnJvcmVkIGluIHRoZSBzYW1lIHdheVxuICAgICAqIGZyb20gbm93IG9uOyBvdGhlcndpc2UsIHRoZSByZWFkZXIgd2lsbCBhcHBlYXIgY2xvc2VkLlxuICAgICAqXG4gICAgICogQSByZWFkZXIncyBsb2NrIGNhbm5vdCBiZSByZWxlYXNlZCB3aGlsZSBpdCBzdGlsbCBoYXMgYSBwZW5kaW5nIHJlYWQgcmVxdWVzdCwgaS5lLiwgaWYgYSBwcm9taXNlIHJldHVybmVkIGJ5XG4gICAgICogdGhlIHJlYWRlcidzIHtAbGluayBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucmVhZCB8IHJlYWQoKX0gbWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gc2V0dGxlZC4gQXR0ZW1wdGluZyB0b1xuICAgICAqIGRvIHNvIHdpbGwgdGhyb3cgYSBgVHlwZUVycm9yYCBhbmQgbGVhdmUgdGhlIHJlYWRlciBsb2NrZWQgdG8gdGhlIHN0cmVhbS5cbiAgICAgKi9cbiAgICByZWxlYXNlTG9jaygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlbGVhc2VMb2NrJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yZWFkSW50b1JlcXVlc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RyaWVkIHRvIHJlbGVhc2UgYSByZWFkZXIgbG9jayB3aGVuIHRoYXQgcmVhZGVyIGhhcyBwZW5kaW5nIHJlYWQoKSBjYWxscyB1bi1zZXR0bGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZSh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucHJvdG90eXBlLCB7XG4gICAgY2FuY2VsOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWFkOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWxlYXNlTG9jazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2VkOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIHJlYWRlcnMuXG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX3JlYWRJbnRvUmVxdWVzdHMnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyUmVhZChyZWFkZXIsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCkge1xuICAgIGNvbnN0IHN0cmVhbSA9IHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbTtcbiAgICBzdHJlYW0uX2Rpc3R1cmJlZCA9IHRydWU7XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Vycm9yU3RlcHMoc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8oc3RyZWFtLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgfVxufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlci5cbmZ1bmN0aW9uIGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyLnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJgKTtcbn1cblxuZnVuY3Rpb24gRXh0cmFjdEhpZ2hXYXRlck1hcmsoc3RyYXRlZ3ksIGRlZmF1bHRIV00pIHtcbiAgICBjb25zdCB7IGhpZ2hXYXRlck1hcmsgfSA9IHN0cmF0ZWd5O1xuICAgIGlmIChoaWdoV2F0ZXJNYXJrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRIV007XG4gICAgfVxuICAgIGlmIChOdW1iZXJJc05hTihoaWdoV2F0ZXJNYXJrKSB8fCBoaWdoV2F0ZXJNYXJrIDwgMCkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCBoaWdoV2F0ZXJNYXJrJyk7XG4gICAgfVxuICAgIHJldHVybiBoaWdoV2F0ZXJNYXJrO1xufVxuZnVuY3Rpb24gRXh0cmFjdFNpemVBbGdvcml0aG0oc3RyYXRlZ3kpIHtcbiAgICBjb25zdCB7IHNpemUgfSA9IHN0cmF0ZWd5O1xuICAgIGlmICghc2l6ZSkge1xuICAgICAgICByZXR1cm4gKCkgPT4gMTtcbiAgICB9XG4gICAgcmV0dXJuIHNpemU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRRdWV1aW5nU3RyYXRlZ3koaW5pdCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkoaW5pdCwgY29udGV4dCk7XG4gICAgY29uc3QgaGlnaFdhdGVyTWFyayA9IGluaXQgPT09IG51bGwgfHwgaW5pdCA9PT0gdm9pZCAwID8gdm9pZCAwIDogaW5pdC5oaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnN0IHNpemUgPSBpbml0ID09PSBudWxsIHx8IGluaXQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGluaXQuc2l6ZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBoaWdoV2F0ZXJNYXJrOiBoaWdoV2F0ZXJNYXJrID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0VW5yZXN0cmljdGVkRG91YmxlKGhpZ2hXYXRlck1hcmspLFxuICAgICAgICBzaXplOiBzaXplID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5U2l6ZShzaXplLCBgJHtjb250ZXh0fSBoYXMgbWVtYmVyICdzaXplJyB0aGF0YClcbiAgICB9O1xufVxuZnVuY3Rpb24gY29udmVydFF1ZXVpbmdTdHJhdGVneVNpemUoZm4sIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIGNodW5rID0+IGNvbnZlcnRVbnJlc3RyaWN0ZWREb3VibGUoZm4oY2h1bmspKTtcbn1cblxuZnVuY3Rpb24gY29udmVydFVuZGVybHlpbmdTaW5rKG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShvcmlnaW5hbCwgY29udGV4dCk7XG4gICAgY29uc3QgYWJvcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuYWJvcnQ7XG4gICAgY29uc3QgY2xvc2UgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuY2xvc2U7XG4gICAgY29uc3Qgc3RhcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuc3RhcnQ7XG4gICAgY29uc3QgdHlwZSA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC50eXBlO1xuICAgIGNvbnN0IHdyaXRlID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLndyaXRlO1xuICAgIHJldHVybiB7XG4gICAgICAgIGFib3J0OiBhYm9ydCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VW5kZXJseWluZ1NpbmtBYm9ydENhbGxiYWNrKGFib3J0LCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnYWJvcnQnIHRoYXRgKSxcbiAgICAgICAgY2xvc2U6IGNsb3NlID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU2lua0Nsb3NlQ2FsbGJhY2soY2xvc2UsIG9yaWdpbmFsLCBgJHtjb250ZXh0fSBoYXMgbWVtYmVyICdjbG9zZScgdGhhdGApLFxuICAgICAgICBzdGFydDogc3RhcnQgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuZGVybHlpbmdTaW5rU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHdyaXRlOiB3cml0ZSA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VW5kZXJseWluZ1NpbmtXcml0ZUNhbGxiYWNrKHdyaXRlLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnd3JpdGUnIHRoYXRgKSxcbiAgICAgICAgdHlwZVxuICAgIH07XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtBYm9ydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKHJlYXNvbikgPT4gcHJvbWlzZUNhbGwoZm4sIG9yaWdpbmFsLCBbcmVhc29uXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtDbG9zZUNhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKCkgPT4gcHJvbWlzZUNhbGwoZm4sIG9yaWdpbmFsLCBbXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtTdGFydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHJlZmxlY3RDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU2lua1dyaXRlQ2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAoY2h1bmssIGNvbnRyb2xsZXIpID0+IHByb21pc2VDYWxsKGZuLCBvcmlnaW5hbCwgW2NodW5rLCBjb250cm9sbGVyXSk7XG59XG5cbmZ1bmN0aW9uIGFzc2VydFdyaXRhYmxlU3RyZWFtKHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW0oeCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYSBXcml0YWJsZVN0cmVhbS5gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzQWJvcnRTaWduYWwodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyB8fCB2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUuYWJvcnRlZCA9PT0gJ2Jvb2xlYW4nO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgLy8gQWJvcnRTaWduYWwucHJvdG90eXBlLmFib3J0ZWQgdGhyb3dzIGlmIGl0cyBicmFuZCBjaGVjayBmYWlsc1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuY29uc3Qgc3VwcG9ydHNBYm9ydENvbnRyb2xsZXIgPSB0eXBlb2YgQWJvcnRDb250cm9sbGVyID09PSAnZnVuY3Rpb24nO1xuLyoqXG4gKiBDb25zdHJ1Y3QgYSBuZXcgQWJvcnRDb250cm9sbGVyLCBpZiBzdXBwb3J0ZWQgYnkgdGhlIHBsYXRmb3JtLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5mdW5jdGlvbiBjcmVhdGVBYm9ydENvbnRyb2xsZXIoKSB7XG4gICAgaWYgKHN1cHBvcnRzQWJvcnRDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQSB3cml0YWJsZSBzdHJlYW0gcmVwcmVzZW50cyBhIGRlc3RpbmF0aW9uIGZvciBkYXRhLCBpbnRvIHdoaWNoIHlvdSBjYW4gd3JpdGUuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBXcml0YWJsZVN0cmVhbSB7XG4gICAgY29uc3RydWN0b3IocmF3VW5kZXJseWluZ1NpbmsgPSB7fSwgcmF3U3RyYXRlZ3kgPSB7fSkge1xuICAgICAgICBpZiAocmF3VW5kZXJseWluZ1NpbmsgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmF3VW5kZXJseWluZ1NpbmsgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYXNzZXJ0T2JqZWN0KHJhd1VuZGVybHlpbmdTaW5rLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyYXRlZ3kgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5KHJhd1N0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCB1bmRlcmx5aW5nU2luayA9IGNvbnZlcnRVbmRlcmx5aW5nU2luayhyYXdVbmRlcmx5aW5nU2luaywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBJbml0aWFsaXplV3JpdGFibGVTdHJlYW0odGhpcyk7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB1bmRlcmx5aW5nU2luay50eXBlO1xuICAgICAgICBpZiAodHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlIGlzIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShzdHJhdGVneSk7XG4gICAgICAgIGNvbnN0IGhpZ2hXYXRlck1hcmsgPSBFeHRyYWN0SGlnaFdhdGVyTWFyayhzdHJhdGVneSwgMSk7XG4gICAgICAgIFNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayh0aGlzLCB1bmRlcmx5aW5nU2luaywgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHdyaXRhYmxlIHN0cmVhbSBpcyBsb2NrZWQgdG8gYSB3cml0ZXIuXG4gICAgICovXG4gICAgZ2V0IGxvY2tlZCgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2xvY2tlZCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBYm9ydHMgdGhlIHN0cmVhbSwgc2lnbmFsaW5nIHRoYXQgdGhlIHByb2R1Y2VyIGNhbiBubyBsb25nZXIgc3VjY2Vzc2Z1bGx5IHdyaXRlIHRvIHRoZSBzdHJlYW0gYW5kIGl0IGlzIHRvIGJlXG4gICAgICogaW1tZWRpYXRlbHkgbW92ZWQgdG8gYW4gZXJyb3JlZCBzdGF0ZSwgd2l0aCBhbnkgcXVldWVkLXVwIHdyaXRlcyBkaXNjYXJkZWQuIFRoaXMgd2lsbCBhbHNvIGV4ZWN1dGUgYW55IGFib3J0XG4gICAgICogbWVjaGFuaXNtIG9mIHRoZSB1bmRlcmx5aW5nIHNpbmsuXG4gICAgICpcbiAgICAgKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGZ1bGZpbGwgaWYgdGhlIHN0cmVhbSBzaHV0cyBkb3duIHN1Y2Nlc3NmdWxseSwgb3IgcmVqZWN0IGlmIHRoZSB1bmRlcmx5aW5nIHNpbmsgc2lnbmFsZWRcbiAgICAgKiB0aGF0IHRoZXJlIHdhcyBhbiBlcnJvciBkb2luZyBzby4gQWRkaXRpb25hbGx5LCBpdCB3aWxsIHJlamVjdCB3aXRoIGEgYFR5cGVFcnJvcmAgKHdpdGhvdXQgYXR0ZW1wdGluZyB0byBjYW5jZWxcbiAgICAgKiB0aGUgc3RyZWFtKSBpZiB0aGUgc3RyZWFtIGlzIGN1cnJlbnRseSBsb2NrZWQuXG4gICAgICovXG4gICAgYWJvcnQocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdhYm9ydCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoSXNXcml0YWJsZVN0cmVhbUxvY2tlZCh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcignQ2Fubm90IGFib3J0IGEgc3RyZWFtIHRoYXQgYWxyZWFkeSBoYXMgYSB3cml0ZXInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtQWJvcnQodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBzdHJlYW0uIFRoZSB1bmRlcmx5aW5nIHNpbmsgd2lsbCBmaW5pc2ggcHJvY2Vzc2luZyBhbnkgcHJldmlvdXNseS13cml0dGVuIGNodW5rcywgYmVmb3JlIGludm9raW5nIGl0c1xuICAgICAqIGNsb3NlIGJlaGF2aW9yLiBEdXJpbmcgdGhpcyB0aW1lIGFueSBmdXJ0aGVyIGF0dGVtcHRzIHRvIHdyaXRlIHdpbGwgZmFpbCAod2l0aG91dCBlcnJvcmluZyB0aGUgc3RyZWFtKS5cbiAgICAgKlxuICAgICAqIFRoZSBtZXRob2QgcmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGZ1bGZpbGwgaWYgYWxsIHJlbWFpbmluZyBjaHVua3MgYXJlIHN1Y2Nlc3NmdWxseSB3cml0dGVuIGFuZCB0aGUgc3RyZWFtXG4gICAgICogc3VjY2Vzc2Z1bGx5IGNsb3Nlcywgb3IgcmVqZWN0cyBpZiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZCBkdXJpbmcgdGhpcyBwcm9jZXNzLiBBZGRpdGlvbmFsbHksIGl0IHdpbGwgcmVqZWN0IHdpdGhcbiAgICAgKiBhIGBUeXBlRXJyb3JgICh3aXRob3V0IGF0dGVtcHRpbmcgdG8gY2FuY2VsIHRoZSBzdHJlYW0pIGlmIHRoZSBzdHJlYW0gaXMgY3VycmVudGx5IGxvY2tlZC5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2xvc2UgYSBzdHJlYW0gdGhhdCBhbHJlYWR5IGhhcyBhIHdyaXRlcicpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjbG9zZSBhbiBhbHJlYWR5LWNsb3Npbmcgc3RyZWFtJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUNsb3NlKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEge0BsaW5rIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciB8IHdyaXRlcn0gYW5kIGxvY2tzIHRoZSBzdHJlYW0gdG8gdGhlIG5ldyB3cml0ZXIuIFdoaWxlIHRoZSBzdHJlYW1cbiAgICAgKiBpcyBsb2NrZWQsIG5vIG90aGVyIHdyaXRlciBjYW4gYmUgYWNxdWlyZWQgdW50aWwgdGhpcyBvbmUgaXMgcmVsZWFzZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIGZ1bmN0aW9uYWxpdHkgaXMgZXNwZWNpYWxseSB1c2VmdWwgZm9yIGNyZWF0aW5nIGFic3RyYWN0aW9ucyB0aGF0IGRlc2lyZSB0aGUgYWJpbGl0eSB0byB3cml0ZSB0byBhIHN0cmVhbVxuICAgICAqIHdpdGhvdXQgaW50ZXJydXB0aW9uIG9yIGludGVybGVhdmluZy4gQnkgZ2V0dGluZyBhIHdyaXRlciBmb3IgdGhlIHN0cmVhbSwgeW91IGNhbiBlbnN1cmUgbm9ib2R5IGVsc2UgY2FuIHdyaXRlIGF0XG4gICAgICogdGhlIHNhbWUgdGltZSwgd2hpY2ggd291bGQgY2F1c2UgdGhlIHJlc3VsdGluZyB3cml0dGVuIGRhdGEgdG8gYmUgdW5wcmVkaWN0YWJsZSBhbmQgcHJvYmFibHkgdXNlbGVzcy5cbiAgICAgKi9cbiAgICBnZXRXcml0ZXIoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdnZXRXcml0ZXInKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQWNxdWlyZVdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBhYm9ydDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2U6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGdldFdyaXRlcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgbG9ja2VkOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnV3JpdGFibGVTdHJlYW0nLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbi8vIEFic3RyYWN0IG9wZXJhdGlvbnMgZm9yIHRoZSBXcml0YWJsZVN0cmVhbS5cbmZ1bmN0aW9uIEFjcXVpcmVXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoc3RyZWFtKSB7XG4gICAgcmV0dXJuIG5ldyBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoc3RyZWFtKTtcbn1cbi8vIFRocm93cyBpZiBhbmQgb25seSBpZiBzdGFydEFsZ29yaXRobSB0aHJvd3MuXG5mdW5jdGlvbiBDcmVhdGVXcml0YWJsZVN0cmVhbShzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyayA9IDEsIHNpemVBbGdvcml0aG0gPSAoKSA9PiAxKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gT2JqZWN0LmNyZWF0ZShXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUpO1xuICAgIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbShzdHJlYW0pO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbmZ1bmN0aW9uIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ3dyaXRhYmxlJztcbiAgICAvLyBUaGUgZXJyb3IgdGhhdCB3aWxsIGJlIHJlcG9ydGVkIGJ5IG5ldyBtZXRob2QgY2FsbHMgb25jZSB0aGUgc3RhdGUgYmVjb21lcyBlcnJvcmVkLiBPbmx5IHNldCB3aGVuIFtbc3RhdGVdXSBpc1xuICAgIC8vICdlcnJvcmluZycgb3IgJ2Vycm9yZWQnLiBNYXkgYmUgc2V0IHRvIGFuIHVuZGVmaW5lZCB2YWx1ZS5cbiAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fd3JpdGVyID0gdW5kZWZpbmVkO1xuICAgIC8vIEluaXRpYWxpemUgdG8gdW5kZWZpbmVkIGZpcnN0IGJlY2F1c2UgdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBjb250cm9sbGVyIGNoZWNrcyB0aGlzXG4gICAgLy8gdmFyaWFibGUgdG8gdmFsaWRhdGUgdGhlIGNhbGxlci5cbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlciA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGlzIHF1ZXVlIGlzIHBsYWNlZCBoZXJlIGluc3RlYWQgb2YgdGhlIHdyaXRlciBjbGFzcyBpbiBvcmRlciB0byBhbGxvdyBmb3IgcGFzc2luZyBhIHdyaXRlciB0byB0aGUgbmV4dCBkYXRhXG4gICAgLy8gcHJvZHVjZXIgd2l0aG91dCB3YWl0aW5nIGZvciB0aGUgcXVldWVkIHdyaXRlcyB0byBmaW5pc2guXG4gICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgLy8gV3JpdGUgcmVxdWVzdHMgYXJlIHJlbW92ZWQgZnJvbSBfd3JpdGVSZXF1ZXN0cyB3aGVuIHdyaXRlKCkgaXMgY2FsbGVkIG9uIHRoZSB1bmRlcmx5aW5nIHNpbmsuIFRoaXMgcHJldmVudHNcbiAgICAvLyB0aGVtIGZyb20gYmVpbmcgZXJyb25lb3VzbHkgcmVqZWN0ZWQgb24gZXJyb3IuIElmIGEgd3JpdGUoKSBjYWxsIGlzIGluLWZsaWdodCwgdGhlIHJlcXVlc3QgaXMgc3RvcmVkIGhlcmUuXG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGUgcHJvbWlzZSB0aGF0IHdhcyByZXR1cm5lZCBmcm9tIHdyaXRlci5jbG9zZSgpLiBTdG9yZWQgaGVyZSBiZWNhdXNlIGl0IG1heSBiZSBmdWxmaWxsZWQgYWZ0ZXIgdGhlIHdyaXRlclxuICAgIC8vIGhhcyBiZWVuIGRldGFjaGVkLlxuICAgIHN0cmVhbS5fY2xvc2VSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIC8vIENsb3NlIHJlcXVlc3QgaXMgcmVtb3ZlZCBmcm9tIF9jbG9zZVJlcXVlc3Qgd2hlbiBjbG9zZSgpIGlzIGNhbGxlZCBvbiB0aGUgdW5kZXJseWluZyBzaW5rLiBUaGlzIHByZXZlbnRzIGl0XG4gICAgLy8gZnJvbSBiZWluZyBlcnJvbmVvdXNseSByZWplY3RlZCBvbiBlcnJvci4gSWYgYSBjbG9zZSgpIGNhbGwgaXMgaW4tZmxpZ2h0LCB0aGUgcmVxdWVzdCBpcyBzdG9yZWQgaGVyZS5cbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIC8vIFRoZSBwcm9taXNlIHRoYXQgd2FzIHJldHVybmVkIGZyb20gd3JpdGVyLmFib3J0KCkuIFRoaXMgbWF5IGFsc28gYmUgZnVsZmlsbGVkIGFmdGVyIHRoZSB3cml0ZXIgaGFzIGRldGFjaGVkLlxuICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGUgYmFja3ByZXNzdXJlIHNpZ25hbCBzZXQgYnkgdGhlIGNvbnRyb2xsZXIuXG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW0oeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ193cml0YWJsZVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgV3JpdGFibGVTdHJlYW07XG59XG5mdW5jdGlvbiBJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX3dyaXRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUFib3J0KHN0cmVhbSwgcmVhc29uKSB7XG4gICAgdmFyIF9hO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJyB8fCBzdHJlYW0uX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIuX2Fib3J0UmVhc29uID0gcmVhc29uO1xuICAgIChfYSA9IHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyLl9hYm9ydENvbnRyb2xsZXIpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5hYm9ydCgpO1xuICAgIC8vIFR5cGVTY3JpcHQgbmFycm93cyB0aGUgdHlwZSBvZiBgc3RyZWFtLl9zdGF0ZWAgZG93biB0byAnd3JpdGFibGUnIHwgJ2Vycm9yaW5nJyxcbiAgICAvLyBidXQgaXQgZG9lc24ndCBrbm93IHRoYXQgc2lnbmFsaW5nIGFib3J0IHJ1bnMgYXV0aG9yIGNvZGUgdGhhdCBtaWdodCBoYXZlIGNoYW5nZWQgdGhlIHN0YXRlLlxuICAgIC8vIFdpZGVuIHRoZSB0eXBlIGFnYWluIGJ5IGNhc3RpbmcgdG8gV3JpdGFibGVTdHJlYW1TdGF0ZS5cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJyB8fCBzdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIGlmIChzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0Ll9wcm9taXNlO1xuICAgIH1cbiAgICBsZXQgd2FzQWxyZWFkeUVycm9yaW5nID0gZmFsc2U7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHdhc0FscmVhZHlFcnJvcmluZyA9IHRydWU7XG4gICAgICAgIC8vIHJlYXNvbiB3aWxsIG5vdCBiZSB1c2VkLCBzbyBkb24ndCBrZWVwIGEgcmVmZXJlbmNlIHRvIGl0LlxuICAgICAgICByZWFzb24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX3Byb21pc2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIF9yZXNvbHZlOiByZXNvbHZlLFxuICAgICAgICAgICAgX3JlamVjdDogcmVqZWN0LFxuICAgICAgICAgICAgX3JlYXNvbjogcmVhc29uLFxuICAgICAgICAgICAgX3dhc0FscmVhZHlFcnJvcmluZzogd2FzQWxyZWFkeUVycm9yaW5nXG4gICAgICAgIH07XG4gICAgfSk7XG4gICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0Ll9wcm9taXNlID0gcHJvbWlzZTtcbiAgICBpZiAoIXdhc0FscmVhZHlFcnJvcmluZykge1xuICAgICAgICBXcml0YWJsZVN0cmVhbVN0YXJ0RXJyb3Jpbmcoc3RyZWFtLCByZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcgfHwgc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKGBUaGUgc3RyZWFtIChpbiAke3N0YXRlfSBzdGF0ZSkgaXMgbm90IGluIHRoZSB3cml0YWJsZSBzdGF0ZSBhbmQgY2Fubm90IGJlIGNsb3NlZGApKTtcbiAgICB9XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCBjbG9zZVJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfcmVzb2x2ZTogcmVzb2x2ZSxcbiAgICAgICAgICAgIF9yZWplY3Q6IHJlamVjdFxuICAgICAgICB9O1xuICAgICAgICBzdHJlYW0uX2Nsb3NlUmVxdWVzdCA9IGNsb3NlUmVxdWVzdDtcbiAgICB9KTtcbiAgICBjb25zdCB3cml0ZXIgPSBzdHJlYW0uX3dyaXRlcjtcbiAgICBpZiAod3JpdGVyICE9PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9iYWNrcHJlc3N1cmUgJiYgc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc29sdmUod3JpdGVyKTtcbiAgICB9XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbi8vIFdyaXRhYmxlU3RyZWFtIEFQSSBleHBvc2VkIGZvciBjb250cm9sbGVycy5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtQWRkV3JpdGVSZXF1ZXN0KHN0cmVhbSkge1xuICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3Qgd3JpdGVSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX3Jlc29sdmU6IHJlc29sdmUsXG4gICAgICAgICAgICBfcmVqZWN0OiByZWplY3RcbiAgICAgICAgfTtcbiAgICAgICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzLnB1c2god3JpdGVSZXF1ZXN0KTtcbiAgICB9KTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCBlcnJvcikge1xuICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1TdGFydEVycm9yaW5nKHN0cmVhbSwgZXJyb3IpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtU3RhcnRFcnJvcmluZyhzdHJlYW0sIHJlYXNvbikge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcjtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ2Vycm9yaW5nJztcbiAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gcmVhc29uO1xuICAgIGNvbnN0IHdyaXRlciA9IHN0cmVhbS5fd3JpdGVyO1xuICAgIGlmICh3cml0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVSZWFkeVByb21pc2VSZWplY3RlZCh3cml0ZXIsIHJlYXNvbik7XG4gICAgfVxuICAgIGlmICghV3JpdGFibGVTdHJlYW1IYXNPcGVyYXRpb25NYXJrZWRJbkZsaWdodChzdHJlYW0pICYmIGNvbnRyb2xsZXIuX3N0YXJ0ZWQpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1GaW5pc2hFcnJvcmluZyhzdHJlYW0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKSB7XG4gICAgc3RyZWFtLl9zdGF0ZSA9ICdlcnJvcmVkJztcbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcltFcnJvclN0ZXBzXSgpO1xuICAgIGNvbnN0IHN0b3JlZEVycm9yID0gc3RyZWFtLl9zdG9yZWRFcnJvcjtcbiAgICBzdHJlYW0uX3dyaXRlUmVxdWVzdHMuZm9yRWFjaCh3cml0ZVJlcXVlc3QgPT4ge1xuICAgICAgICB3cml0ZVJlcXVlc3QuX3JlamVjdChzdG9yZWRFcnJvcik7XG4gICAgfSk7XG4gICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgaWYgKHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhYm9ydFJlcXVlc3QgPSBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3Q7XG4gICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIGlmIChhYm9ydFJlcXVlc3QuX3dhc0FscmVhZHlFcnJvcmluZykge1xuICAgICAgICBhYm9ydFJlcXVlc3QuX3JlamVjdChzdG9yZWRFcnJvcik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwcm9taXNlID0gc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXJbQWJvcnRTdGVwc10oYWJvcnRSZXF1ZXN0Ll9yZWFzb24pO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2UsICgpID0+IHtcbiAgICAgICAgYWJvcnRSZXF1ZXN0Ll9yZXNvbHZlKCk7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICB9LCAocmVhc29uKSA9PiB7XG4gICAgICAgIGFib3J0UmVxdWVzdC5fcmVqZWN0KHJlYXNvbik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0Ll9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZVdpdGhFcnJvcihzdHJlYW0sIGVycm9yKSB7XG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdC5fcmVqZWN0KGVycm9yKTtcbiAgICBzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCBlcnJvcik7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0Q2xvc2Uoc3RyZWFtKSB7XG4gICAgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdC5fcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIHN0cmVhbS5faW5GbGlnaHRDbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yaW5nJykge1xuICAgICAgICAvLyBUaGUgZXJyb3Igd2FzIHRvbyBsYXRlIHRvIGRvIGFueXRoaW5nLCBzbyBpdCBpcyBpZ25vcmVkLlxuICAgICAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdC5fcmVzb2x2ZSgpO1xuICAgICAgICAgICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0cmVhbS5fc3RhdGUgPSAnY2xvc2VkJztcbiAgICBjb25zdCB3cml0ZXIgPSBzdHJlYW0uX3dyaXRlcjtcbiAgICBpZiAod3JpdGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlKHdyaXRlcik7XG4gICAgfVxufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlV2l0aEVycm9yKHN0cmVhbSwgZXJyb3IpIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0Ll9yZWplY3QoZXJyb3IpO1xuICAgIHN0cmVhbS5faW5GbGlnaHRDbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgLy8gTmV2ZXIgZXhlY3V0ZSBzaW5rIGFib3J0KCkgYWZ0ZXIgc2luayBjbG9zZSgpLlxuICAgIGlmIChzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QuX3JlamVjdChlcnJvcik7XG4gICAgICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgV3JpdGFibGVTdHJlYW1EZWFsV2l0aFJlamVjdGlvbihzdHJlYW0sIGVycm9yKTtcbn1cbi8vIFRPRE8ocmljZWEpOiBGaXggYWxwaGFiZXRpY2FsIG9yZGVyLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQoc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5fY2xvc2VSZXF1ZXN0ID09PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUhhc09wZXJhdGlvbk1hcmtlZEluRmxpZ2h0KHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ID09PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbU1hcmtDbG9zZVJlcXVlc3RJbkZsaWdodChzdHJlYW0pIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID0gc3RyZWFtLl9jbG9zZVJlcXVlc3Q7XG4gICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbU1hcmtGaXJzdFdyaXRlUmVxdWVzdEluRmxpZ2h0KHN0cmVhbSkge1xuICAgIHN0cmVhbS5faW5GbGlnaHRXcml0ZVJlcXVlc3QgPSBzdHJlYW0uX3dyaXRlUmVxdWVzdHMuc2hpZnQoKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5fY2xvc2VSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QuX3JlamVjdChzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICAgICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IHdyaXRlciA9IHN0cmVhbS5fd3JpdGVyO1xuICAgIGlmICh3cml0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCh3cml0ZXIsIHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtVXBkYXRlQmFja3ByZXNzdXJlKHN0cmVhbSwgYmFja3ByZXNzdXJlKSB7XG4gICAgY29uc3Qgd3JpdGVyID0gc3RyZWFtLl93cml0ZXI7XG4gICAgaWYgKHdyaXRlciAhPT0gdW5kZWZpbmVkICYmIGJhY2twcmVzc3VyZSAhPT0gc3RyZWFtLl9iYWNrcHJlc3N1cmUpIHtcbiAgICAgICAgaWYgKGJhY2twcmVzc3VyZSkge1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0KHdyaXRlcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSh3cml0ZXIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlID0gYmFja3ByZXNzdXJlO1xufVxuLyoqXG4gKiBBIGRlZmF1bHQgd3JpdGVyIHZlbmRlZCBieSBhIHtAbGluayBXcml0YWJsZVN0cmVhbX0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIge1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHN0cmVhbSwgMSwgJ1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcicpO1xuICAgICAgICBhc3NlcnRXcml0YWJsZVN0cmVhbShzdHJlYW0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhpcyBzdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBsb2NrZWQgZm9yIGV4Y2x1c2l2ZSB3cml0aW5nIGJ5IGFub3RoZXIgd3JpdGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgc3RyZWFtLl93cml0ZXIgPSB0aGlzO1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICAgICAgaWYgKCFXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pICYmIHN0cmVhbS5fYmFja3ByZXNzdXJlKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemUodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh0aGlzLCBzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZCh0aGlzKTtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzdG9yZWRFcnJvciA9IHN0cmVhbS5fc3RvcmVkRXJyb3I7XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQodGhpcywgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh0aGlzLCBzdG9yZWRFcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBzdHJlYW0gYmVjb21lcyBjbG9zZWQsIG9yIHJlamVjdGVkIGlmIHRoZSBzdHJlYW0gZXZlciBlcnJvcnMgb3JcbiAgICAgKiB0aGUgd3JpdGVy4oCZcyBsb2NrIGlzIHJlbGVhc2VkIGJlZm9yZSB0aGUgc3RyZWFtIGZpbmlzaGVzIGNsb3NpbmcuXG4gICAgICovXG4gICAgZ2V0IGNsb3NlZCgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlZCcpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2VkUHJvbWlzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIHN0cmVhbeKAmXMgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzIG92ZXItZnVsbC5cbiAgICAgKiBBIHByb2R1Y2VyIGNhbiB1c2UgdGhpcyBpbmZvcm1hdGlvbiB0byBkZXRlcm1pbmUgdGhlIHJpZ2h0IGFtb3VudCBvZiBkYXRhIHRvIHdyaXRlLlxuICAgICAqXG4gICAgICogSXQgd2lsbCBiZSBgbnVsbGAgaWYgdGhlIHN0cmVhbSBjYW5ub3QgYmUgc3VjY2Vzc2Z1bGx5IHdyaXR0ZW4gdG8gKGR1ZSB0byBlaXRoZXIgYmVpbmcgZXJyb3JlZCwgb3IgaGF2aW5nIGFuIGFib3J0XG4gICAgICogcXVldWVkIHVwKS4gSXQgd2lsbCByZXR1cm4gemVybyBpZiB0aGUgc3RyZWFtIGlzIGNsb3NlZC4gQW5kIHRoZSBnZXR0ZXIgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgaW52b2tlZCB3aGVuXG4gICAgICogdGhlIHdyaXRlcuKAmXMgbG9jayBpcyByZWxlYXNlZC5cbiAgICAgKi9cbiAgICBnZXQgZGVzaXJlZFNpemUoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lcldyaXRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJMb2NrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJHZXREZXNpcmVkU2l6ZSh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgc3RyZWFt4oCZcyBpbnRlcm5hbCBxdWV1ZSB0cmFuc2l0aW9uc1xuICAgICAqIGZyb20gbm9uLXBvc2l0aXZlIHRvIHBvc2l0aXZlLCBzaWduYWxpbmcgdGhhdCBpdCBpcyBubyBsb25nZXIgYXBwbHlpbmcgYmFja3ByZXNzdXJlLiBPbmNlIHRoZSBkZXNpcmVkIHNpemUgZGlwc1xuICAgICAqIGJhY2sgdG8gemVybyBvciBiZWxvdywgdGhlIGdldHRlciB3aWxsIHJldHVybiBhIG5ldyBwcm9taXNlIHRoYXQgc3RheXMgcGVuZGluZyB1bnRpbCB0aGUgbmV4dCB0cmFuc2l0aW9uLlxuICAgICAqXG4gICAgICogSWYgdGhlIHN0cmVhbSBiZWNvbWVzIGVycm9yZWQgb3IgYWJvcnRlZCwgb3IgdGhlIHdyaXRlcuKAmXMgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJldHVybmVkIHByb21pc2Ugd2lsbCBiZWNvbWVcbiAgICAgKiByZWplY3RlZC5cbiAgICAgKi9cbiAgICBnZXQgcmVhZHkoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkeScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcmVhZHlQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcmVhZGVyIGlzIGFjdGl2ZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QGxpbmsgV3JpdGFibGVTdHJlYW0uYWJvcnQgfCBzdHJlYW0uYWJvcnQocmVhc29uKX0uXG4gICAgICovXG4gICAgYWJvcnQocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdhYm9ydCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbignYWJvcnQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckFib3J0KHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSByZWFkZXIgaXMgYWN0aXZlLCBiZWhhdmVzIHRoZSBzYW1lIGFzIHtAbGluayBXcml0YWJsZVN0cmVhbS5jbG9zZSB8IHN0cmVhbS5jbG9zZSgpfS5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgICAgIGlmIChzdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckxvY2tFeGNlcHRpb24oJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2xvc2UgYW4gYWxyZWFkeS1jbG9zaW5nIHN0cmVhbScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2UodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbGVhc2VzIHRoZSB3cml0ZXLigJlzIGxvY2sgb24gdGhlIGNvcnJlc3BvbmRpbmcgc3RyZWFtLiBBZnRlciB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHdyaXRlciBpcyBubyBsb25nZXIgYWN0aXZlLlxuICAgICAqIElmIHRoZSBhc3NvY2lhdGVkIHN0cmVhbSBpcyBlcnJvcmVkIHdoZW4gdGhlIGxvY2sgaXMgcmVsZWFzZWQsIHRoZSB3cml0ZXIgd2lsbCBhcHBlYXIgZXJyb3JlZCBpbiB0aGUgc2FtZSB3YXkgZnJvbVxuICAgICAqIG5vdyBvbjsgb3RoZXJ3aXNlLCB0aGUgd3JpdGVyIHdpbGwgYXBwZWFyIGNsb3NlZC5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCB0aGUgbG9jayBjYW4gc3RpbGwgYmUgcmVsZWFzZWQgZXZlbiBpZiBzb21lIG9uZ29pbmcgd3JpdGVzIGhhdmUgbm90IHlldCBmaW5pc2hlZCAoaS5lLiBldmVuIGlmIHRoZVxuICAgICAqIHByb21pc2VzIHJldHVybmVkIGZyb20gcHJldmlvdXMgY2FsbHMgdG8ge0BsaW5rIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci53cml0ZSB8IHdyaXRlKCl9IGhhdmUgbm90IHlldCBzZXR0bGVkKS5cbiAgICAgKiBJdOKAmXMgbm90IG5lY2Vzc2FyeSB0byBob2xkIHRoZSBsb2NrIG9uIHRoZSB3cml0ZXIgZm9yIHRoZSBkdXJhdGlvbiBvZiB0aGUgd3JpdGU7IHRoZSBsb2NrIGluc3RlYWQgc2ltcGx5IHByZXZlbnRzXG4gICAgICogb3RoZXIgcHJvZHVjZXJzIGZyb20gd3JpdGluZyBpbiBhbiBpbnRlcmxlYXZlZCBtYW5uZXIuXG4gICAgICovXG4gICAgcmVsZWFzZUxvY2soKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWxlYXNlTG9jaycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgICAgIGlmIChzdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlclJlbGVhc2UodGhpcyk7XG4gICAgfVxuICAgIHdyaXRlKGNodW5rID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCd3cml0ZScpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbignd3JpdGUgdG8nKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcldyaXRlKHRoaXMsIGNodW5rKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIucHJvdG90eXBlLCB7XG4gICAgYWJvcnQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGNsb3NlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWxlYXNlTG9jazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgd3JpdGU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGNsb3NlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgZGVzaXJlZFNpemU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlYWR5OiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfb3duZXJXcml0YWJsZVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXI7XG59XG4vLyBBIGNsaWVudCBvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIgbWF5IHVzZSB0aGVzZSBmdW5jdGlvbnMgZGlyZWN0bHkgdG8gYnlwYXNzIHN0YXRlIGNoZWNrLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQWJvcnQod3JpdGVyLCByZWFzb24pIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtQWJvcnQoc3RyZWFtLCByZWFzb24pO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2Uod3JpdGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJDbG9zZVdpdGhFcnJvclByb3BhZ2F0aW9uKHdyaXRlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IHdyaXRlci5fb3duZXJXcml0YWJsZVN0cmVhbTtcbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKFdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkgfHwgc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbiAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2Uod3JpdGVyKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZUNsb3NlZFByb21pc2VSZWplY3RlZCh3cml0ZXIsIGVycm9yKSB7XG4gICAgaWYgKHdyaXRlci5fY2xvc2VkUHJvbWlzZVN0YXRlID09PSAncGVuZGluZycpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZWplY3Qod3JpdGVyLCBlcnJvcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVSZWFkeVByb21pc2VSZWplY3RlZCh3cml0ZXIsIGVycm9yKSB7XG4gICAgaWYgKHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPT09ICdwZW5kaW5nJykge1xuICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVqZWN0KHdyaXRlciwgZXJyb3IpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJHZXREZXNpcmVkU2l6ZSh3cml0ZXIpIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yZWQnIHx8IHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplKHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlclJlbGVhc2Uod3JpdGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIGNvbnN0IHJlbGVhc2VkRXJyb3IgPSBuZXcgVHlwZUVycm9yKGBXcml0ZXIgd2FzIHJlbGVhc2VkIGFuZCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgdG8gbW9uaXRvciB0aGUgc3RyZWFtJ3MgY2xvc2VkbmVzc2ApO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZVJlYWR5UHJvbWlzZVJlamVjdGVkKHdyaXRlciwgcmVsZWFzZWRFcnJvcik7XG4gICAgLy8gVGhlIHN0YXRlIHRyYW5zaXRpb25zIHRvIFwiZXJyb3JlZFwiIGJlZm9yZSB0aGUgc2luayBhYm9ydCgpIG1ldGhvZCBydW5zLCBidXQgdGhlIHdyaXRlci5jbG9zZWQgcHJvbWlzZSBpcyBub3RcbiAgICAvLyByZWplY3RlZCB1bnRpbCBhZnRlcndhcmRzLiBUaGlzIG1lYW5zIHRoYXQgc2ltcGx5IHRlc3Rpbmcgc3RhdGUgd2lsbCBub3Qgd29yay5cbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVDbG9zZWRQcm9taXNlUmVqZWN0ZWQod3JpdGVyLCByZWxlYXNlZEVycm9yKTtcbiAgICBzdHJlYW0uX3dyaXRlciA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW0gPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJXcml0ZSh3cml0ZXIsIGNodW5rKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcjtcbiAgICBjb25zdCBjaHVua1NpemUgPSBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0Q2h1bmtTaXplKGNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICBpZiAoc3RyZWFtICE9PSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW0pIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckxvY2tFeGNlcHRpb24oJ3dyaXRlIHRvJykpO1xuICAgIH1cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICAgIGlmIChXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pIHx8IHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGlzIGNsb3Npbmcgb3IgY2xvc2VkIGFuZCBjYW5ub3QgYmUgd3JpdHRlbiB0bycpKTtcbiAgICB9XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbiAgICBjb25zdCBwcm9taXNlID0gV3JpdGFibGVTdHJlYW1BZGRXcml0ZVJlcXVlc3Qoc3RyZWFtKTtcbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyV3JpdGUoY29udHJvbGxlciwgY2h1bmssIGNodW5rU2l6ZSk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5jb25zdCBjbG9zZVNlbnRpbmVsID0ge307XG4vKipcbiAqIEFsbG93cyBjb250cm9sIG9mIGEge0BsaW5rIFdyaXRhYmxlU3RyZWFtIHwgd3JpdGFibGUgc3RyZWFtfSdzIHN0YXRlIGFuZCBpbnRlcm5hbCBxdWV1ZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIGNvbnN0cnVjdG9yJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWFzb24gd2hpY2ggd2FzIHBhc3NlZCB0byBgV3JpdGFibGVTdHJlYW0uYWJvcnQocmVhc29uKWAgd2hlbiB0aGUgc3RyZWFtIHdhcyBhYm9ydGVkLlxuICAgICAqL1xuICAgIGdldCBhYm9ydFJlYXNvbigpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdhYm9ydFJlYXNvbicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hYm9ydFJlYXNvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQW4gYEFib3J0U2lnbmFsYCB0aGF0IGNhbiBiZSB1c2VkIHRvIGFib3J0IHRoZSBwZW5kaW5nIHdyaXRlIG9yIGNsb3NlIG9wZXJhdGlvbiB3aGVuIHRoZSBzdHJlYW0gaXMgYWJvcnRlZC5cbiAgICAgKi9cbiAgICBnZXQgc2lnbmFsKCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIoJ3NpZ25hbCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9hYm9ydENvbnRyb2xsZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gT2xkZXIgYnJvd3NlcnMgb3Igb2xkZXIgTm9kZSB2ZXJzaW9ucyBtYXkgbm90IHN1cHBvcnQgYEFib3J0Q29udHJvbGxlcmAgb3IgYEFib3J0U2lnbmFsYC5cbiAgICAgICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gYnVuZGxlIGFuZCBzaGlwIGFuIGBBYm9ydENvbnRyb2xsZXJgIHBvbHlmaWxsIHRvZ2V0aGVyIHdpdGggb3VyIHBvbHlmaWxsLFxuICAgICAgICAgICAgLy8gc28gaW5zdGVhZCB3ZSBvbmx5IGltcGxlbWVudCBzdXBwb3J0IGZvciBgc2lnbmFsYCBpZiB3ZSBmaW5kIGEgZ2xvYmFsIGBBYm9ydENvbnRyb2xsZXJgIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUuc2lnbmFsIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYWJvcnRDb250cm9sbGVyLnNpZ25hbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBjb250cm9sbGVkIHdyaXRhYmxlIHN0cmVhbSwgbWFraW5nIGFsbCBmdXR1cmUgaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyByYXJlbHkgdXNlZCwgc2luY2UgdXN1YWxseSBpdCBzdWZmaWNlcyB0byByZXR1cm4gYSByZWplY3RlZCBwcm9taXNlIGZyb20gb25lIG9mIHRoZSB1bmRlcmx5aW5nXG4gICAgICogc2luaydzIG1ldGhvZHMuIEhvd2V2ZXIsIGl0IGNhbiBiZSB1c2VmdWwgZm9yIHN1ZGRlbmx5IHNodXR0aW5nIGRvd24gYSBzdHJlYW0gaW4gcmVzcG9uc2UgdG8gYW4gZXZlbnQgb3V0c2lkZSB0aGVcbiAgICAgKiBub3JtYWwgbGlmZWN5Y2xlIG9mIGludGVyYWN0aW9ucyB3aXRoIHRoZSB1bmRlcmx5aW5nIHNpbmsuXG4gICAgICovXG4gICAgZXJyb3IoZSA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2Vycm9yJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW0uX3N0YXRlO1xuICAgICAgICBpZiAoc3RhdGUgIT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgICAgIC8vIFRoZSBzdHJlYW0gaXMgY2xvc2VkLCBlcnJvcmVkIG9yIHdpbGwgYmUgc29vbi4gVGhlIHNpbmsgY2FuJ3QgZG8gYW55dGhpbmcgdXNlZnVsIGlmIGl0IGdldHMgYW4gZXJyb3IgaGVyZSwgc29cbiAgICAgICAgICAgIC8vIGp1c3QgdHJlYXQgaXQgYXMgYSBuby1vcC5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IodGhpcywgZSk7XG4gICAgfVxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBbQWJvcnRTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2Fib3J0QWxnb3JpdGhtKHJlYXNvbik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXModGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBbRXJyb3JTdGVwc10oKSB7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBpbXBsZW1lbnRpbmcgaW50ZXJmYWNlIHJlcXVpcmVkIGJ5IHRoZSBXcml0YWJsZVN0cmVhbS5cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyO1xufVxuZnVuY3Rpb24gU2V0VXBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHdyaXRlQWxnb3JpdGhtLCBjbG9zZUFsZ29yaXRobSwgYWJvcnRBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmssIHNpemVBbGdvcml0aG0pIHtcbiAgICBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW0gPSBzdHJlYW07XG4gICAgc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuICAgIC8vIE5lZWQgdG8gc2V0IHRoZSBzbG90cyBzbyB0aGF0IHRoZSBhc3NlcnQgZG9lc24ndCBmaXJlLiBJbiB0aGUgc3BlYyB0aGUgc2xvdHMgYWxyZWFkeSBleGlzdCBpbXBsaWNpdGx5LlxuICAgIGNvbnRyb2xsZXIuX3F1ZXVlID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID0gdW5kZWZpbmVkO1xuICAgIFJlc2V0UXVldWUoY29udHJvbGxlcik7XG4gICAgY29udHJvbGxlci5fYWJvcnRSZWFzb24gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYWJvcnRDb250cm9sbGVyID0gY3JlYXRlQWJvcnRDb250cm9sbGVyKCk7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSA9IHNpemVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lIV00gPSBoaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnRyb2xsZXIuX3dyaXRlQWxnb3JpdGhtID0gd3JpdGVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fY2xvc2VBbGdvcml0aG0gPSBjbG9zZUFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9hYm9ydEFsZ29yaXRobSA9IGFib3J0QWxnb3JpdGhtO1xuICAgIGNvbnN0IGJhY2twcmVzc3VyZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRCYWNrcHJlc3N1cmUoY29udHJvbGxlcik7XG4gICAgV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpO1xuICAgIGNvbnN0IHN0YXJ0UmVzdWx0ID0gc3RhcnRBbGdvcml0aG0oKTtcbiAgICBjb25zdCBzdGFydFByb21pc2UgPSBwcm9taXNlUmVzb2x2ZWRXaXRoKHN0YXJ0UmVzdWx0KTtcbiAgICB1cG9uUHJvbWlzZShzdGFydFByb21pc2UsICgpID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJBZHZhbmNlUXVldWVJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCByKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayhzdHJlYW0sIHVuZGVybHlpbmdTaW5rLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUpO1xuICAgIGxldCBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBsZXQgd3JpdGVBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgbGV0IGNsb3NlQWxnb3JpdGhtID0gKCkgPT4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIGxldCBhYm9ydEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodW5kZXJseWluZ1Npbmsuc3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdTaW5rLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1Npbmsud3JpdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB3cml0ZUFsZ29yaXRobSA9IGNodW5rID0+IHVuZGVybHlpbmdTaW5rLndyaXRlKGNodW5rLCBjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTaW5rLmNsb3NlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2xvc2VBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nU2luay5jbG9zZSgpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1NpbmsuYWJvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhYm9ydEFsZ29yaXRobSA9IHJlYXNvbiA9PiB1bmRlcmx5aW5nU2luay5hYm9ydChyZWFzb24pO1xuICAgIH1cbiAgICBTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG59XG4vLyBDbGVhckFsZ29yaXRobXMgbWF5IGJlIGNhbGxlZCB0d2ljZS4gRXJyb3JpbmcgdGhlIHNhbWUgc3RyZWFtIGluIG11bHRpcGxlIHdheXMgd2lsbCBvZnRlbiByZXN1bHQgaW4gcmVkdW5kYW50IGNhbGxzLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKSB7XG4gICAgY29udHJvbGxlci5fd3JpdGVBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fY2xvc2VBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYWJvcnRBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lTaXplQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKGNvbnRyb2xsZXIpIHtcbiAgICBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250cm9sbGVyLCBjbG9zZVNlbnRpbmVsLCAwKTtcbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0Q2h1bmtTaXplKGNvbnRyb2xsZXIsIGNodW5rKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobShjaHVuayk7XG4gICAgfVxuICAgIGNhdGNoIChjaHVua1NpemVFKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGNodW5rU2l6ZUUpO1xuICAgICAgICByZXR1cm4gMTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUoY29udHJvbGxlcikge1xuICAgIHJldHVybiBjb250cm9sbGVyLl9zdHJhdGVneUhXTSAtIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcldyaXRlKGNvbnRyb2xsZXIsIGNodW5rLCBjaHVua1NpemUpIHtcbiAgICB0cnkge1xuICAgICAgICBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250cm9sbGVyLCBjaHVuaywgY2h1bmtTaXplKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVucXVldWVFKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGVucXVldWVFKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW07XG4gICAgaWYgKCFXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pICYmIHN0cmVhbS5fc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgY29uc3QgYmFja3ByZXNzdXJlID0gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldEJhY2twcmVzc3VyZShjb250cm9sbGVyKTtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpO1xuICAgIH1cbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJBZHZhbmNlUXVldWVJZk5lZWRlZChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIGlmICghY29udHJvbGxlci5fc3RhcnRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdmFsdWUgPSBQZWVrUXVldWVWYWx1ZShjb250cm9sbGVyKTtcbiAgICBpZiAodmFsdWUgPT09IGNsb3NlU2VudGluZWwpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NDbG9zZShjb250cm9sbGVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQcm9jZXNzV3JpdGUoY29udHJvbGxlciwgdmFsdWUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGVycm9yKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbS5fc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc0Nsb3NlKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW07XG4gICAgV3JpdGFibGVTdHJlYW1NYXJrQ2xvc2VSZXF1ZXN0SW5GbGlnaHQoc3RyZWFtKTtcbiAgICBEZXF1ZXVlVmFsdWUoY29udHJvbGxlcik7XG4gICAgY29uc3Qgc2lua0Nsb3NlUHJvbWlzZSA9IGNvbnRyb2xsZXIuX2Nsb3NlQWxnb3JpdGhtKCk7XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKTtcbiAgICB1cG9uUHJvbWlzZShzaW5rQ2xvc2VQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZShzdHJlYW0pO1xuICAgIH0sIHJlYXNvbiA9PiB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZVdpdGhFcnJvcihzdHJlYW0sIHJlYXNvbik7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc1dyaXRlKGNvbnRyb2xsZXIsIGNodW5rKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIFdyaXRhYmxlU3RyZWFtTWFya0ZpcnN0V3JpdGVSZXF1ZXN0SW5GbGlnaHQoc3RyZWFtKTtcbiAgICBjb25zdCBzaW5rV3JpdGVQcm9taXNlID0gY29udHJvbGxlci5fd3JpdGVBbGdvcml0aG0oY2h1bmspO1xuICAgIHVwb25Qcm9taXNlKHNpbmtXcml0ZVByb21pc2UsICgpID0+IHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodFdyaXRlKHN0cmVhbSk7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICAgICAgRGVxdWV1ZVZhbHVlKGNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoIVdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkgJiYgc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgICAgIGNvbnN0IGJhY2twcmVzc3VyZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRCYWNrcHJlc3N1cmUoY29udHJvbGxlcik7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbVVwZGF0ZUJhY2twcmVzc3VyZShzdHJlYW0sIGJhY2twcmVzc3VyZSk7XG4gICAgICAgIH1cbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckFkdmFuY2VRdWV1ZUlmTmVlZGVkKGNvbnRyb2xsZXIpO1xuICAgIH0sIHJlYXNvbiA9PiB7XG4gICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnd3JpdGFibGUnKSB7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgICAgICB9XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZVdpdGhFcnJvcihzdHJlYW0sIHJlYXNvbik7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0QmFja3ByZXNzdXJlKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBkZXNpcmVkU2l6ZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZShjb250cm9sbGVyKTtcbiAgICByZXR1cm4gZGVzaXJlZFNpemUgPD0gMDtcbn1cbi8vIEEgY2xpZW50IG9mIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIgbWF5IHVzZSB0aGVzZSBmdW5jdGlvbnMgZGlyZWN0bHkgdG8gYnlwYXNzIHN0YXRlIGNoZWNrLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVycm9yKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgV3JpdGFibGVTdHJlYW1TdGFydEVycm9yaW5nKHN0cmVhbSwgZXJyb3IpO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW0ucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFdyaXRhYmxlU3RyZWFtYCk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5cbmZ1bmN0aW9uIGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQyKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcmApO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyLnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJgKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJMb2NrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcignQ2Fubm90ICcgKyBuYW1lICsgJyBhIHN0cmVhbSB1c2luZyBhIHJlbGVhc2VkIHdyaXRlcicpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplKHdyaXRlcikge1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QgPSByZWplY3Q7XG4gICAgICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZVN0YXRlID0gJ3BlbmRpbmcnO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xuICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVqZWN0KHdyaXRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQod3JpdGVyKSB7XG4gICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplKHdyaXRlcik7XG4gICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlKHdyaXRlcik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGlmICh3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlKHdyaXRlci5fY2xvc2VkUHJvbWlzZSk7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdChyZWFzb24pO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlU3RhdGUgPSAncmVqZWN0ZWQnO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHdyaXRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVzb2x2ZSh3cml0ZXIpIHtcbiAgICBpZiAod3JpdGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VTdGF0ZSA9ICdyZXNvbHZlZCc7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpIHtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID0gcmVqZWN0O1xuICAgIH0pO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPSAncGVuZGluZyc7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZWplY3Qod3JpdGVyLCByZWFzb24pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHdyaXRlcikge1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplKHdyaXRlcik7XG4gICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc29sdmUod3JpdGVyKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZWplY3Qod3JpdGVyLCByZWFzb24pIHtcbiAgICBpZiAod3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlKHdyaXRlci5fcmVhZHlQcm9taXNlKTtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZWplY3QocmVhc29uKTtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZVN0YXRlID0gJ3JlamVjdGVkJztcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNldCh3cml0ZXIpIHtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh3cml0ZXIsIHJlYXNvbik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSh3cml0ZXIpIHtcbiAgICBpZiAod3JpdGVyLl9yZWFkeVByb21pc2VfcmVzb2x2ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPSAnZnVsZmlsbGVkJztcbn1cblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZG9tXCIgLz5cbmNvbnN0IE5hdGl2ZURPTUV4Y2VwdGlvbiA9IHR5cGVvZiBET01FeGNlcHRpb24gIT09ICd1bmRlZmluZWQnID8gRE9NRXhjZXB0aW9uIDogdW5kZWZpbmVkO1xuXG4vLy8gPHJlZmVyZW5jZSB0eXBlcz1cIm5vZGVcIiAvPlxuZnVuY3Rpb24gaXNET01FeGNlcHRpb25Db25zdHJ1Y3RvcihjdG9yKSB7XG4gICAgaWYgKCEodHlwZW9mIGN0b3IgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGN0b3IgPT09ICdvYmplY3QnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIG5ldyBjdG9yKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZURPTUV4Y2VwdGlvblBvbHlmaWxsKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdCBjdG9yID0gZnVuY3Rpb24gRE9NRXhjZXB0aW9uKG1lc3NhZ2UsIG5hbWUpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZSB8fCAnJztcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZSB8fCAnRXJyb3InO1xuICAgICAgICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICAgICAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3Rvci5wcm90b3R5cGUsICdjb25zdHJ1Y3RvcicsIHsgdmFsdWU6IGN0b3IsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSk7XG4gICAgcmV0dXJuIGN0b3I7XG59XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVkZWNsYXJlXG5jb25zdCBET01FeGNlcHRpb24kMSA9IGlzRE9NRXhjZXB0aW9uQ29uc3RydWN0b3IoTmF0aXZlRE9NRXhjZXB0aW9uKSA/IE5hdGl2ZURPTUV4Y2VwdGlvbiA6IGNyZWF0ZURPTUV4Y2VwdGlvblBvbHlmaWxsKCk7XG5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtUGlwZVRvKHNvdXJjZSwgZGVzdCwgcHJldmVudENsb3NlLCBwcmV2ZW50QWJvcnQsIHByZXZlbnRDYW5jZWwsIHNpZ25hbCkge1xuICAgIGNvbnN0IHJlYWRlciA9IEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc291cmNlKTtcbiAgICBjb25zdCB3cml0ZXIgPSBBY3F1aXJlV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyKGRlc3QpO1xuICAgIHNvdXJjZS5fZGlzdHVyYmVkID0gdHJ1ZTtcbiAgICBsZXQgc2h1dHRpbmdEb3duID0gZmFsc2U7XG4gICAgLy8gVGhpcyBpcyB1c2VkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIHNwZWMncyByZXF1aXJlbWVudCB0aGF0IHdlIHdhaXQgZm9yIG9uZ29pbmcgd3JpdGVzIGR1cmluZyBzaHV0ZG93bi5cbiAgICBsZXQgY3VycmVudFdyaXRlID0gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIHJldHVybiBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgbGV0IGFib3J0QWxnb3JpdGhtO1xuICAgICAgICBpZiAoc2lnbmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGFib3J0QWxnb3JpdGhtID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IERPTUV4Y2VwdGlvbiQxKCdBYm9ydGVkJywgJ0Fib3J0RXJyb3InKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3Rpb25zID0gW107XG4gICAgICAgICAgICAgICAgaWYgKCFwcmV2ZW50QWJvcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXN0Ll9zdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUFib3J0KGRlc3QsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuX3N0YXRlID09PSAncmVhZGFibGUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHNvdXJjZSwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNodXRkb3duV2l0aEFjdGlvbigoKSA9PiBQcm9taXNlLmFsbChhY3Rpb25zLm1hcChhY3Rpb24gPT4gYWN0aW9uKCkpKSwgdHJ1ZSwgZXJyb3IpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgICAgICAgIGFib3J0QWxnb3JpdGhtKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnRBbGdvcml0aG0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFVzaW5nIHJlYWRlciBhbmQgd3JpdGVyLCByZWFkIGFsbCBjaHVua3MgZnJvbSB0aGlzIGFuZCB3cml0ZSB0aGVtIHRvIGRlc3RcbiAgICAgICAgLy8gLSBCYWNrcHJlc3N1cmUgbXVzdCBiZSBlbmZvcmNlZFxuICAgICAgICAvLyAtIFNodXRkb3duIG11c3Qgc3RvcCBhbGwgYWN0aXZpdHlcbiAgICAgICAgZnVuY3Rpb24gcGlwZUxvb3AoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3UHJvbWlzZSgocmVzb2x2ZUxvb3AsIHJlamVjdExvb3ApID0+IHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBuZXh0KGRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVMb29wKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgYFBlcmZvcm1Qcm9taXNlVGhlbmAgaW5zdGVhZCBvZiBgdXBvblByb21pc2VgIHRvIGF2b2lkXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGRpbmcgdW5uZWNlc3NhcnkgYC5jYXRjaChyZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24pYCBoYW5kbGVyc1xuICAgICAgICAgICAgICAgICAgICAgICAgUGVyZm9ybVByb21pc2VUaGVuKHBpcGVTdGVwKCksIG5leHQsIHJlamVjdExvb3ApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5leHQoZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcGlwZVN0ZXAoKSB7XG4gICAgICAgICAgICBpZiAoc2h1dHRpbmdEb3duKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gUGVyZm9ybVByb21pc2VUaGVuKHdyaXRlci5fcmVhZHlQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ld1Byb21pc2UoKHJlc29sdmVSZWFkLCByZWplY3RSZWFkKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQocmVhZGVyLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRXcml0ZSA9IFBlcmZvcm1Qcm9taXNlVGhlbihXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJXcml0ZSh3cml0ZXIsIGNodW5rKSwgdW5kZWZpbmVkLCBub29wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlUmVhZChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgX2Nsb3NlU3RlcHM6ICgpID0+IHJlc29sdmVSZWFkKHRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yU3RlcHM6IHJlamVjdFJlYWRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBFcnJvcnMgbXVzdCBiZSBwcm9wYWdhdGVkIGZvcndhcmRcbiAgICAgICAgaXNPckJlY29tZXNFcnJvcmVkKHNvdXJjZSwgcmVhZGVyLl9jbG9zZWRQcm9taXNlLCBzdG9yZWRFcnJvciA9PiB7XG4gICAgICAgICAgICBpZiAoIXByZXZlbnRBYm9ydCkge1xuICAgICAgICAgICAgICAgIHNodXRkb3duV2l0aEFjdGlvbigoKSA9PiBXcml0YWJsZVN0cmVhbUFib3J0KGRlc3QsIHN0b3JlZEVycm9yKSwgdHJ1ZSwgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd24odHJ1ZSwgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gRXJyb3JzIG11c3QgYmUgcHJvcGFnYXRlZCBiYWNrd2FyZFxuICAgICAgICBpc09yQmVjb21lc0Vycm9yZWQoZGVzdCwgd3JpdGVyLl9jbG9zZWRQcm9taXNlLCBzdG9yZWRFcnJvciA9PiB7XG4gICAgICAgICAgICBpZiAoIXByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgICAgICBzaHV0ZG93bldpdGhBY3Rpb24oKCkgPT4gUmVhZGFibGVTdHJlYW1DYW5jZWwoc291cmNlLCBzdG9yZWRFcnJvciksIHRydWUsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNodXRkb3duKHRydWUsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIENsb3NpbmcgbXVzdCBiZSBwcm9wYWdhdGVkIGZvcndhcmRcbiAgICAgICAgaXNPckJlY29tZXNDbG9zZWQoc291cmNlLCByZWFkZXIuX2Nsb3NlZFByb21pc2UsICgpID0+IHtcbiAgICAgICAgICAgIGlmICghcHJldmVudENsb3NlKSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd25XaXRoQWN0aW9uKCgpID0+IFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckNsb3NlV2l0aEVycm9yUHJvcGFnYXRpb24od3JpdGVyKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaHV0ZG93bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQ2xvc2luZyBtdXN0IGJlIHByb3BhZ2F0ZWQgYmFja3dhcmRcbiAgICAgICAgaWYgKFdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KGRlc3QpIHx8IGRlc3QuX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgY29uc3QgZGVzdENsb3NlZCA9IG5ldyBUeXBlRXJyb3IoJ3RoZSBkZXN0aW5hdGlvbiB3cml0YWJsZSBzdHJlYW0gY2xvc2VkIGJlZm9yZSBhbGwgZGF0YSBjb3VsZCBiZSBwaXBlZCB0byBpdCcpO1xuICAgICAgICAgICAgaWYgKCFwcmV2ZW50Q2FuY2VsKSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd25XaXRoQWN0aW9uKCgpID0+IFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHNvdXJjZSwgZGVzdENsb3NlZCksIHRydWUsIGRlc3RDbG9zZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd24odHJ1ZSwgZGVzdENsb3NlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShwaXBlTG9vcCgpKTtcbiAgICAgICAgZnVuY3Rpb24gd2FpdEZvcldyaXRlc1RvRmluaXNoKCkge1xuICAgICAgICAgICAgLy8gQW5vdGhlciB3cml0ZSBtYXkgaGF2ZSBzdGFydGVkIHdoaWxlIHdlIHdlcmUgd2FpdGluZyBvbiB0aGlzIGN1cnJlbnRXcml0ZSwgc28gd2UgaGF2ZSB0byBiZSBzdXJlIHRvIHdhaXRcbiAgICAgICAgICAgIC8vIGZvciB0aGF0IHRvby5cbiAgICAgICAgICAgIGNvbnN0IG9sZEN1cnJlbnRXcml0ZSA9IGN1cnJlbnRXcml0ZTtcbiAgICAgICAgICAgIHJldHVybiBQZXJmb3JtUHJvbWlzZVRoZW4oY3VycmVudFdyaXRlLCAoKSA9PiBvbGRDdXJyZW50V3JpdGUgIT09IGN1cnJlbnRXcml0ZSA/IHdhaXRGb3JXcml0ZXNUb0ZpbmlzaCgpIDogdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBpc09yQmVjb21lc0Vycm9yZWQoc3RyZWFtLCBwcm9taXNlLCBhY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb24oc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB1cG9uUmVqZWN0aW9uKHByb21pc2UsIGFjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNPckJlY29tZXNDbG9zZWQoc3RyZWFtLCBwcm9taXNlLCBhY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIGFjdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBvbkZ1bGZpbGxtZW50KHByb21pc2UsIGFjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gc2h1dGRvd25XaXRoQWN0aW9uKGFjdGlvbiwgb3JpZ2luYWxJc0Vycm9yLCBvcmlnaW5hbEVycm9yKSB7XG4gICAgICAgICAgICBpZiAoc2h1dHRpbmdEb3duKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2h1dHRpbmdEb3duID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChkZXN0Ll9zdGF0ZSA9PT0gJ3dyaXRhYmxlJyAmJiAhV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQoZGVzdCkpIHtcbiAgICAgICAgICAgICAgICB1cG9uRnVsZmlsbG1lbnQod2FpdEZvcldyaXRlc1RvRmluaXNoKCksIGRvVGhlUmVzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb1RoZVJlc3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIGRvVGhlUmVzdCgpIHtcbiAgICAgICAgICAgICAgICB1cG9uUHJvbWlzZShhY3Rpb24oKSwgKCkgPT4gZmluYWxpemUob3JpZ2luYWxJc0Vycm9yLCBvcmlnaW5hbEVycm9yKSwgbmV3RXJyb3IgPT4gZmluYWxpemUodHJ1ZSwgbmV3RXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzaHV0ZG93bihpc0Vycm9yLCBlcnJvcikge1xuICAgICAgICAgICAgaWYgKHNodXR0aW5nRG93bikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNodXR0aW5nRG93biA9IHRydWU7XG4gICAgICAgICAgICBpZiAoZGVzdC5fc3RhdGUgPT09ICd3cml0YWJsZScgJiYgIVdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KGRlc3QpKSB7XG4gICAgICAgICAgICAgICAgdXBvbkZ1bGZpbGxtZW50KHdhaXRGb3JXcml0ZXNUb0ZpbmlzaCgpLCAoKSA9PiBmaW5hbGl6ZShpc0Vycm9yLCBlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZmluYWxpemUoaXNFcnJvciwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGZpbmFsaXplKGlzRXJyb3IsIGVycm9yKSB7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJSZWxlYXNlKHdyaXRlcik7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHJlYWRlcik7XG4gICAgICAgICAgICBpZiAoc2lnbmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFsZ29yaXRobSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNFcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBbGxvd3MgY29udHJvbCBvZiBhIHtAbGluayBSZWFkYWJsZVN0cmVhbSB8IHJlYWRhYmxlIHN0cmVhbX0ncyBzdGF0ZSBhbmQgaW50ZXJuYWwgcXVldWUuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgY29udHJvbGxlZCBzdHJlYW0ncyBpbnRlcm5hbCBxdWV1ZS4gSXQgY2FuIGJlIG5lZ2F0aXZlLCBpZiB0aGUgcXVldWUgaXNcbiAgICAgKiBvdmVyLWZ1bGwuIEFuIHVuZGVybHlpbmcgc291cmNlIG91Z2h0IHRvIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSB3aGVuIGFuZCBob3cgdG8gYXBwbHkgYmFja3ByZXNzdXJlLlxuICAgICAqL1xuICAgIGdldCBkZXNpcmVkU2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgY29udHJvbGxlZCByZWFkYWJsZSBzdHJlYW0uIENvbnN1bWVycyB3aWxsIHN0aWxsIGJlIGFibGUgdG8gcmVhZCBhbnkgcHJldmlvdXNseS1lbnF1ZXVlZCBjaHVua3MgZnJvbVxuICAgICAqIHRoZSBzdHJlYW0sIGJ1dCBvbmNlIHRob3NlIGFyZSByZWFkLCB0aGUgc3RyZWFtIHdpbGwgYmVjb21lIGNsb3NlZC5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdjbG9zZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGlzIG5vdCBpbiBhIHN0YXRlIHRoYXQgcGVybWl0cyBjbG9zZScpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuayA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDEoJ2VucXVldWUnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIVJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYW5DbG9zZU9yRW5xdWV1ZSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIHN0cmVhbSBpcyBub3QgaW4gYSBzdGF0ZSB0aGF0IHBlcm1pdHMgZW5xdWV1ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSh0aGlzLCBjaHVuayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVycm9ycyB0aGUgY29udHJvbGxlZCByZWFkYWJsZSBzdHJlYW0sIG1ha2luZyBhbGwgZnV0dXJlIGludGVyYWN0aW9ucyB3aXRoIGl0IGZhaWwgd2l0aCB0aGUgZ2l2ZW4gZXJyb3IgYGVgLlxuICAgICAqL1xuICAgIGVycm9yKGUgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcih0aGlzLCBlKTtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtDYW5jZWxTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NhbmNlbEFsZ29yaXRobShyZWFzb24pO1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKHRoaXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKiogQGludGVybmFsICovXG4gICAgW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpIHtcbiAgICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgICAgICBpZiAodGhpcy5fcXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgY2h1bmsgPSBEZXF1ZXVlVmFsdWUodGhpcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5fY2xvc2VSZXF1ZXN0ZWQgJiYgdGhpcy5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyh0aGlzKTtcbiAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9jaHVua1N0ZXBzKGNodW5rKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtQWRkUmVhZFJlcXVlc3Qoc3RyZWFtLCByZWFkUmVxdWVzdCk7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLCB7XG4gICAgY2xvc2U6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGVucXVldWU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGVycm9yOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBkZXNpcmVkU2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIuXG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19jb250cm9sbGVkUmVhZGFibGVTdHJlYW0nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzaG91bGRQdWxsID0gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsKGNvbnRyb2xsZXIpO1xuICAgIGlmICghc2hvdWxkUHVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjb250cm9sbGVyLl9wdWxsaW5nKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3B1bGxBZ2FpbiA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29udHJvbGxlci5fcHVsbGluZyA9IHRydWU7XG4gICAgY29uc3QgcHVsbFByb21pc2UgPSBjb250cm9sbGVyLl9wdWxsQWxnb3JpdGhtKCk7XG4gICAgdXBvblByb21pc2UocHVsbFByb21pc2UsICgpID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fcHVsbGluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoY29udHJvbGxlci5fcHVsbEFnYWluKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLl9wdWxsQWdhaW4gPSBmYWxzZTtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpO1xuICAgICAgICB9XG4gICAgfSwgZSA9PiB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFjb250cm9sbGVyLl9zdGFydGVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKElzUmVhZGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSAmJiBSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZGVzaXJlZFNpemUgPSBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUoY29udHJvbGxlcik7XG4gICAgaWYgKGRlc2lyZWRTaXplID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKSB7XG4gICAgY29udHJvbGxlci5fcHVsbEFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9jYW5jZWxBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lTaXplQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuLy8gQSBjbGllbnQgb2YgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciBtYXkgdXNlIHRoZXNlIGZ1bmN0aW9ucyBkaXJlY3RseSB0byBieXBhc3Mgc3RhdGUgY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UoY29udHJvbGxlcikge1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gdHJ1ZTtcbiAgICBpZiAoY29udHJvbGxlci5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkgJiYgUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3Qoc3RyZWFtLCBjaHVuaywgZmFsc2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbGV0IGNodW5rU2l6ZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNodW5rU2l6ZSA9IGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobShjaHVuayk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGNodW5rU2l6ZUUpIHtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBjaHVua1NpemVFKTtcbiAgICAgICAgICAgIHRocm93IGNodW5rU2l6ZUU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIEVucXVldWVWYWx1ZVdpdGhTaXplKGNvbnRyb2xsZXIsIGNodW5rLCBjaHVua1NpemUpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlbnF1ZXVlRSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVucXVldWVFKTtcbiAgICAgICAgICAgIHRocm93IGVucXVldWVFO1xuICAgICAgICB9XG4gICAgfVxuICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGUpIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVTdHJlYW07XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBSZXNldFF1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgUmVhZGFibGVTdHJlYW1FcnJvcihzdHJlYW0sIGUpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiBjb250cm9sbGVyLl9zdHJhdGVneUhXTSAtIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplO1xufVxuLy8gVGhpcyBpcyB1c2VkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBUcmFuc2Zvcm1TdHJlYW0uXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVySGFzQmFja3ByZXNzdXJlKGNvbnRyb2xsZXIpIHtcbiAgICBpZiAoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FuQ2xvc2VPckVucXVldWUoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0YXRlID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoIWNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkICYmIHN0YXRlID09PSAncmVhZGFibGUnKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBTZXRVcFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtID0gc3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID0gdW5kZWZpbmVkO1xuICAgIFJlc2V0UXVldWUoY29udHJvbGxlcik7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fcHVsbGluZyA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSA9IHNpemVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lIV00gPSBoaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0gPSBwdWxsQWxnb3JpdGhtO1xuICAgIGNvbnRyb2xsZXIuX2NhbmNlbEFsZ29yaXRobSA9IGNhbmNlbEFsZ29yaXRobTtcbiAgICBzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgY29uc3Qgc3RhcnRSZXN1bHQgPSBzdGFydEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2VSZXNvbHZlZFdpdGgoc3RhcnRSZXN1bHQpLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIHIpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2Uoc3RyZWFtLCB1bmRlcmx5aW5nU291cmNlLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUpO1xuICAgIGxldCBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBsZXQgcHVsbEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBsZXQgY2FuY2VsQWxnb3JpdGhtID0gKCkgPT4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIGlmICh1bmRlcmx5aW5nU291cmNlLnN0YXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nU291cmNlLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1NvdXJjZS5wdWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcHVsbEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdTb3VyY2UucHVsbChjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTb3VyY2UuY2FuY2VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2FuY2VsQWxnb3JpdGhtID0gcmVhc29uID0+IHVuZGVybHlpbmdTb3VyY2UuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuICAgIFNldFVwUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcihzdHJlYW0sIGNvbnRyb2xsZXIsIHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmssIHNpemVBbGdvcml0aG0pO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIuXG5mdW5jdGlvbiBkZWZhdWx0Q29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24kMShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJgKTtcbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1UZWUoc3RyZWFtLCBjbG9uZUZvckJyYW5jaDIpIHtcbiAgICBpZiAoSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKSkge1xuICAgICAgICByZXR1cm4gUmVhZGFibGVCeXRlU3RyZWFtVGVlKHN0cmVhbSk7XG4gICAgfVxuICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRUZWUoc3RyZWFtKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFRlZShzdHJlYW0sIGNsb25lRm9yQnJhbmNoMikge1xuICAgIGNvbnN0IHJlYWRlciA9IEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKTtcbiAgICBsZXQgcmVhZGluZyA9IGZhbHNlO1xuICAgIGxldCBjYW5jZWxlZDEgPSBmYWxzZTtcbiAgICBsZXQgY2FuY2VsZWQyID0gZmFsc2U7XG4gICAgbGV0IHJlYXNvbjE7XG4gICAgbGV0IHJlYXNvbjI7XG4gICAgbGV0IGJyYW5jaDE7XG4gICAgbGV0IGJyYW5jaDI7XG4gICAgbGV0IHJlc29sdmVDYW5jZWxQcm9taXNlO1xuICAgIGNvbnN0IGNhbmNlbFByb21pc2UgPSBuZXdQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gICAgZnVuY3Rpb24gcHVsbEFsZ29yaXRobSgpIHtcbiAgICAgICAgaWYgKHJlYWRpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVhZGluZyA9IHRydWU7XG4gICAgICAgIGNvbnN0IHJlYWRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX2NodW5rU3RlcHM6IGNodW5rID0+IHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGJlIGRlbGF5ZWQgYSBtaWNyb3Rhc2sgYmVjYXVzZSBpdCB0YWtlcyBhdCBsZWFzdCBhIG1pY3JvdGFzayB0byBkZXRlY3QgZXJyb3JzICh1c2luZ1xuICAgICAgICAgICAgICAgIC8vIHJlYWRlci5fY2xvc2VkUHJvbWlzZSBiZWxvdyksIGFuZCB3ZSB3YW50IGVycm9ycyBpbiBzdHJlYW0gdG8gZXJyb3IgYm90aCBicmFuY2hlcyBpbW1lZGlhdGVseS4gV2UgY2Fubm90IGxldFxuICAgICAgICAgICAgICAgIC8vIHN1Y2Nlc3NmdWwgc3luY2hyb25vdXNseS1hdmFpbGFibGUgcmVhZHMgZ2V0IGFoZWFkIG9mIGFzeW5jaHJvbm91c2x5LWF2YWlsYWJsZSBlcnJvcnMuXG4gICAgICAgICAgICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWFkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNodW5rMSA9IGNodW5rO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaHVuazIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gd2F5IHRvIGFjY2VzcyB0aGUgY2xvbmluZyBjb2RlIHJpZ2h0IG5vdyBpbiB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBhZGQgb25lIHRoZW4gd2UnbGwgbmVlZCBhbiBpbXBsZW1lbnRhdGlvbiBmb3Igc2VyaWFsaXphYmxlIG9iamVjdHMuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmICghY2FuY2VsZWQyICYmIGNsb25lRm9yQnJhbmNoMikge1xuICAgICAgICAgICAgICAgICAgICAvLyAgIGNodW5rMiA9IFN0cnVjdHVyZWREZXNlcmlhbGl6ZShTdHJ1Y3R1cmVkU2VyaWFsaXplKGNodW5rMikpO1xuICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmsyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDEgfHwgIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfZXJyb3JTdGVwczogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZChyZWFkZXIsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2FuY2VsMUFsZ29yaXRobShyZWFzb24pIHtcbiAgICAgICAgY2FuY2VsZWQxID0gdHJ1ZTtcbiAgICAgICAgcmVhc29uMSA9IHJlYXNvbjtcbiAgICAgICAgaWYgKGNhbmNlbGVkMikge1xuICAgICAgICAgICAgY29uc3QgY29tcG9zaXRlUmVhc29uID0gQ3JlYXRlQXJyYXlGcm9tTGlzdChbcmVhc29uMSwgcmVhc29uMl0pO1xuICAgICAgICAgICAgY29uc3QgY2FuY2VsUmVzdWx0ID0gUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjb21wb3NpdGVSZWFzb24pO1xuICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoY2FuY2VsUmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FuY2VsUHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2FuY2VsMkFsZ29yaXRobShyZWFzb24pIHtcbiAgICAgICAgY2FuY2VsZWQyID0gdHJ1ZTtcbiAgICAgICAgcmVhc29uMiA9IHJlYXNvbjtcbiAgICAgICAgaWYgKGNhbmNlbGVkMSkge1xuICAgICAgICAgICAgY29uc3QgY29tcG9zaXRlUmVhc29uID0gQ3JlYXRlQXJyYXlGcm9tTGlzdChbcmVhc29uMSwgcmVhc29uMl0pO1xuICAgICAgICAgICAgY29uc3QgY2FuY2VsUmVzdWx0ID0gUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjb21wb3NpdGVSZWFzb24pO1xuICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoY2FuY2VsUmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FuY2VsUHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gc3RhcnRBbGdvcml0aG0oKSB7XG4gICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICB9XG4gICAgYnJhbmNoMSA9IENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWwxQWxnb3JpdGhtKTtcbiAgICBicmFuY2gyID0gQ3JlYXRlUmVhZGFibGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbDJBbGdvcml0aG0pO1xuICAgIHVwb25SZWplY3Rpb24ocmVhZGVyLl9jbG9zZWRQcm9taXNlLCAocikgPT4ge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IoYnJhbmNoMS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCByKTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgcik7XG4gICAgICAgIGlmICghY2FuY2VsZWQxIHx8ICFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gW2JyYW5jaDEsIGJyYW5jaDJdO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtVGVlKHN0cmVhbSkge1xuICAgIGxldCByZWFkZXIgPSBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHN0cmVhbSk7XG4gICAgbGV0IHJlYWRpbmcgPSBmYWxzZTtcbiAgICBsZXQgY2FuY2VsZWQxID0gZmFsc2U7XG4gICAgbGV0IGNhbmNlbGVkMiA9IGZhbHNlO1xuICAgIGxldCByZWFzb24xO1xuICAgIGxldCByZWFzb24yO1xuICAgIGxldCBicmFuY2gxO1xuICAgIGxldCBicmFuY2gyO1xuICAgIGxldCByZXNvbHZlQ2FuY2VsUHJvbWlzZTtcbiAgICBjb25zdCBjYW5jZWxQcm9taXNlID0gbmV3UHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UgPSByZXNvbHZlO1xuICAgIH0pO1xuICAgIGZ1bmN0aW9uIGZvcndhcmRSZWFkZXJFcnJvcih0aGlzUmVhZGVyKSB7XG4gICAgICAgIHVwb25SZWplY3Rpb24odGhpc1JlYWRlci5fY2xvc2VkUHJvbWlzZSwgciA9PiB7XG4gICAgICAgICAgICBpZiAodGhpc1JlYWRlciAhPT0gcmVhZGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgcik7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCByKTtcbiAgICAgICAgICAgIGlmICghY2FuY2VsZWQxIHx8ICFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbFdpdGhEZWZhdWx0UmVhZGVyKCkge1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgcmVhZGVyID0gQWNxdWlyZVJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcihzdHJlYW0pO1xuICAgICAgICAgICAgZm9yd2FyZFJlYWRlckVycm9yKHJlYWRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVhZFJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4ge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgbmVlZHMgdG8gYmUgZGVsYXllZCBhIG1pY3JvdGFzayBiZWNhdXNlIGl0IHRha2VzIGF0IGxlYXN0IGEgbWljcm90YXNrIHRvIGRldGVjdCBlcnJvcnMgKHVzaW5nXG4gICAgICAgICAgICAgICAgLy8gcmVhZGVyLl9jbG9zZWRQcm9taXNlIGJlbG93KSwgYW5kIHdlIHdhbnQgZXJyb3JzIGluIHN0cmVhbSB0byBlcnJvciBib3RoIGJyYW5jaGVzIGltbWVkaWF0ZWx5LiBXZSBjYW5ub3QgbGV0XG4gICAgICAgICAgICAgICAgLy8gc3VjY2Vzc2Z1bCBzeW5jaHJvbm91c2x5LWF2YWlsYWJsZSByZWFkcyBnZXQgYWhlYWQgb2YgYXN5bmNocm9ub3VzbHktYXZhaWxhYmxlIGVycm9ycy5cbiAgICAgICAgICAgICAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2h1bmsxID0gY2h1bms7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjaHVuazIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDEgJiYgIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHVuazIgPSBDbG9uZUFzVWludDhBcnJheShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoY2xvbmVFKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2xvbmVFKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjbG9uZUUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgY2xvbmVFKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmsyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2UoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMSB8fCAhY2FuY2VsZWQyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJSZWFkKHJlYWRlciwgcmVhZFJlcXVlc3QpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBwdWxsV2l0aEJZT0JSZWFkZXIodmlldywgZm9yQnJhbmNoMikge1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgcmVhZGVyID0gQWNxdWlyZVJlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihzdHJlYW0pO1xuICAgICAgICAgICAgZm9yd2FyZFJlYWRlckVycm9yKHJlYWRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYnlvYkJyYW5jaCA9IGZvckJyYW5jaDIgPyBicmFuY2gyIDogYnJhbmNoMTtcbiAgICAgICAgY29uc3Qgb3RoZXJCcmFuY2ggPSBmb3JCcmFuY2gyID8gYnJhbmNoMSA6IGJyYW5jaDI7XG4gICAgICAgIGNvbnN0IHJlYWRJbnRvUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9jaHVua1N0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBiZSBkZWxheWVkIGEgbWljcm90YXNrIGJlY2F1c2UgaXQgdGFrZXMgYXQgbGVhc3QgYSBtaWNyb3Rhc2sgdG8gZGV0ZWN0IGVycm9ycyAodXNpbmdcbiAgICAgICAgICAgICAgICAvLyByZWFkZXIuX2Nsb3NlZFByb21pc2UgYmVsb3cpLCBhbmQgd2Ugd2FudCBlcnJvcnMgaW4gc3RyZWFtIHRvIGVycm9yIGJvdGggYnJhbmNoZXMgaW1tZWRpYXRlbHkuIFdlIGNhbm5vdCBsZXRcbiAgICAgICAgICAgICAgICAvLyBzdWNjZXNzZnVsIHN5bmNocm9ub3VzbHktYXZhaWxhYmxlIHJlYWRzIGdldCBhaGVhZCBvZiBhc3luY2hyb25vdXNseS1hdmFpbGFibGUgZXJyb3JzLlxuICAgICAgICAgICAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBieW9iQ2FuY2VsZWQgPSBmb3JCcmFuY2gyID8gY2FuY2VsZWQyIDogY2FuY2VsZWQxO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdGhlckNhbmNlbGVkID0gZm9yQnJhbmNoMiA/IGNhbmNlbGVkMSA6IGNhbmNlbGVkMjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvdGhlckNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2xvbmVkQ2h1bms7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lZENodW5rID0gQ2xvbmVBc1VpbnQ4QXJyYXkoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGNsb25lRSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihieW9iQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNsb25lRSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKG90aGVyQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNsb25lRSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjbG9uZUUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWJ5b2JDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcoYnlvYkJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZShvdGhlckJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjbG9uZWRDaHVuayk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWJ5b2JDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRXaXRoTmV3VmlldyhieW9iQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ5b2JDYW5jZWxlZCA9IGZvckJyYW5jaDIgPyBjYW5jZWxlZDIgOiBjYW5jZWxlZDE7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3RoZXJDYW5jZWxlZCA9IGZvckJyYW5jaDIgPyBjYW5jZWxlZDEgOiBjYW5jZWxlZDI7XG4gICAgICAgICAgICAgICAgaWYgKCFieW9iQ2FuY2VsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsb3NlKGJ5b2JCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghb3RoZXJDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2Uob3RoZXJCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjaHVuayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghYnlvYkNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZFdpdGhOZXdWaWV3KGJ5b2JCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghb3RoZXJDYW5jZWxlZCAmJiBvdGhlckJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKG90aGVyQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIDApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYnlvYkNhbmNlbGVkIHx8ICFvdGhlckNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkKHJlYWRlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbDFBbGdvcml0aG0oKSB7XG4gICAgICAgIGlmIChyZWFkaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJlYWRpbmcgPSB0cnVlO1xuICAgICAgICBjb25zdCBieW9iUmVxdWVzdCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHB1bGxXaXRoRGVmYXVsdFJlYWRlcigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHVsbFdpdGhCWU9CUmVhZGVyKGJ5b2JSZXF1ZXN0Ll92aWV3LCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbDJBbGdvcml0aG0oKSB7XG4gICAgICAgIGlmIChyZWFkaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJlYWRpbmcgPSB0cnVlO1xuICAgICAgICBjb25zdCBieW9iUmVxdWVzdCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHB1bGxXaXRoRGVmYXVsdFJlYWRlcigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHVsbFdpdGhCWU9CUmVhZGVyKGJ5b2JSZXF1ZXN0Ll92aWV3LCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWwxQWxnb3JpdGhtKHJlYXNvbikge1xuICAgICAgICBjYW5jZWxlZDEgPSB0cnVlO1xuICAgICAgICByZWFzb24xID0gcmVhc29uO1xuICAgICAgICBpZiAoY2FuY2VsZWQyKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wb3NpdGVSZWFzb24gPSBDcmVhdGVBcnJheUZyb21MaXN0KFtyZWFzb24xLCByZWFzb24yXSk7XG4gICAgICAgICAgICBjb25zdCBjYW5jZWxSZXN1bHQgPSBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIGNvbXBvc2l0ZVJlYXNvbik7XG4gICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZShjYW5jZWxSZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYW5jZWxQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWwyQWxnb3JpdGhtKHJlYXNvbikge1xuICAgICAgICBjYW5jZWxlZDIgPSB0cnVlO1xuICAgICAgICByZWFzb24yID0gcmVhc29uO1xuICAgICAgICBpZiAoY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wb3NpdGVSZWFzb24gPSBDcmVhdGVBcnJheUZyb21MaXN0KFtyZWFzb24xLCByZWFzb24yXSk7XG4gICAgICAgICAgICBjb25zdCBjYW5jZWxSZXN1bHQgPSBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIGNvbXBvc2l0ZVJlYXNvbik7XG4gICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZShjYW5jZWxSZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYW5jZWxQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzdGFydEFsZ29yaXRobSgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBicmFuY2gxID0gQ3JlYXRlUmVhZGFibGVCeXRlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsMUFsZ29yaXRobSwgY2FuY2VsMUFsZ29yaXRobSk7XG4gICAgYnJhbmNoMiA9IENyZWF0ZVJlYWRhYmxlQnl0ZVN0cmVhbShzdGFydEFsZ29yaXRobSwgcHVsbDJBbGdvcml0aG0sIGNhbmNlbDJBbGdvcml0aG0pO1xuICAgIGZvcndhcmRSZWFkZXJFcnJvcihyZWFkZXIpO1xuICAgIHJldHVybiBbYnJhbmNoMSwgYnJhbmNoMl07XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nRGVmYXVsdE9yQnl0ZVNvdXJjZShzb3VyY2UsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KHNvdXJjZSwgY29udGV4dCk7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSBzb3VyY2U7XG4gICAgY29uc3QgYXV0b0FsbG9jYXRlQ2h1bmtTaXplID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLmF1dG9BbGxvY2F0ZUNodW5rU2l6ZTtcbiAgICBjb25zdCBjYW5jZWwgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuY2FuY2VsO1xuICAgIGNvbnN0IHB1bGwgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwucHVsbDtcbiAgICBjb25zdCBzdGFydCA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5zdGFydDtcbiAgICBjb25zdCB0eXBlID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnR5cGU7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYXV0b0FsbG9jYXRlQ2h1bmtTaXplOiBhdXRvQWxsb2NhdGVDaHVua1NpemUgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuc2lnbmVkTG9uZ0xvbmdXaXRoRW5mb3JjZVJhbmdlKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnYXV0b0FsbG9jYXRlQ2h1bmtTaXplJyB0aGF0YCksXG4gICAgICAgIGNhbmNlbDogY2FuY2VsID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlQ2FuY2VsQ2FsbGJhY2soY2FuY2VsLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnY2FuY2VsJyB0aGF0YCksXG4gICAgICAgIHB1bGw6IHB1bGwgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuZGVybHlpbmdTb3VyY2VQdWxsQ2FsbGJhY2socHVsbCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3B1bGwnIHRoYXRgKSxcbiAgICAgICAgc3RhcnQ6IHN0YXJ0ID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHR5cGU6IHR5cGUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGNvbnZlcnRSZWFkYWJsZVN0cmVhbVR5cGUodHlwZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAndHlwZScgdGhhdGApXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlQ2FuY2VsQ2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAocmVhc29uKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtyZWFzb25dKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlUHVsbENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHByb21pc2VDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlU3RhcnRDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjb250cm9sbGVyKSA9PiByZWZsZWN0Q2FsbChmbiwgb3JpZ2luYWwsIFtjb250cm9sbGVyXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0UmVhZGFibGVTdHJlYW1UeXBlKHR5cGUsIGNvbnRleHQpIHtcbiAgICB0eXBlID0gYCR7dHlwZX1gO1xuICAgIGlmICh0eXBlICE9PSAnYnl0ZXMnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gJyR7dHlwZX0nIGlzIG5vdCBhIHZhbGlkIGVudW1lcmF0aW9uIHZhbHVlIGZvciBSZWFkYWJsZVN0cmVhbVR5cGVgKTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWFkZXJPcHRpb25zKG9wdGlvbnMsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KG9wdGlvbnMsIGNvbnRleHQpO1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubW9kZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtb2RlOiBtb2RlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0UmVhZGFibGVTdHJlYW1SZWFkZXJNb2RlKG1vZGUsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ21vZGUnIHRoYXRgKVxuICAgIH07XG59XG5mdW5jdGlvbiBjb252ZXJ0UmVhZGFibGVTdHJlYW1SZWFkZXJNb2RlKG1vZGUsIGNvbnRleHQpIHtcbiAgICBtb2RlID0gYCR7bW9kZX1gO1xuICAgIGlmIChtb2RlICE9PSAnYnlvYicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSAnJHttb2RlfScgaXMgbm90IGEgdmFsaWQgZW51bWVyYXRpb24gdmFsdWUgZm9yIFJlYWRhYmxlU3RyZWFtUmVhZGVyTW9kZWApO1xuICAgIH1cbiAgICByZXR1cm4gbW9kZTtcbn1cblxuZnVuY3Rpb24gY29udmVydEl0ZXJhdG9yT3B0aW9ucyhvcHRpb25zLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShvcHRpb25zLCBjb250ZXh0KTtcbiAgICBjb25zdCBwcmV2ZW50Q2FuY2VsID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDYW5jZWw7XG4gICAgcmV0dXJuIHsgcHJldmVudENhbmNlbDogQm9vbGVhbihwcmV2ZW50Q2FuY2VsKSB9O1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UGlwZU9wdGlvbnMob3B0aW9ucywgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkob3B0aW9ucywgY29udGV4dCk7XG4gICAgY29uc3QgcHJldmVudEFib3J0ID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRBYm9ydDtcbiAgICBjb25zdCBwcmV2ZW50Q2FuY2VsID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDYW5jZWw7XG4gICAgY29uc3QgcHJldmVudENsb3NlID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDbG9zZTtcbiAgICBjb25zdCBzaWduYWwgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMuc2lnbmFsO1xuICAgIGlmIChzaWduYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhc3NlcnRBYm9ydFNpZ25hbChzaWduYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3NpZ25hbCcgdGhhdGApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBwcmV2ZW50QWJvcnQ6IEJvb2xlYW4ocHJldmVudEFib3J0KSxcbiAgICAgICAgcHJldmVudENhbmNlbDogQm9vbGVhbihwcmV2ZW50Q2FuY2VsKSxcbiAgICAgICAgcHJldmVudENsb3NlOiBCb29sZWFuKHByZXZlbnRDbG9zZSksXG4gICAgICAgIHNpZ25hbFxuICAgIH07XG59XG5mdW5jdGlvbiBhc3NlcnRBYm9ydFNpZ25hbChzaWduYWwsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzQWJvcnRTaWduYWwoc2lnbmFsKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NvbnRleHR9IGlzIG5vdCBhbiBBYm9ydFNpZ25hbC5gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpcihwYWlyLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShwYWlyLCBjb250ZXh0KTtcbiAgICBjb25zdCByZWFkYWJsZSA9IHBhaXIgPT09IG51bGwgfHwgcGFpciA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFpci5yZWFkYWJsZTtcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKHJlYWRhYmxlLCAncmVhZGFibGUnLCAnUmVhZGFibGVXcml0YWJsZVBhaXInKTtcbiAgICBhc3NlcnRSZWFkYWJsZVN0cmVhbShyZWFkYWJsZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAncmVhZGFibGUnIHRoYXRgKTtcbiAgICBjb25zdCB3cml0YWJsZSA9IHBhaXIgPT09IG51bGwgfHwgcGFpciA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFpci53cml0YWJsZTtcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKHdyaXRhYmxlLCAnd3JpdGFibGUnLCAnUmVhZGFibGVXcml0YWJsZVBhaXInKTtcbiAgICBhc3NlcnRXcml0YWJsZVN0cmVhbSh3cml0YWJsZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnd3JpdGFibGUnIHRoYXRgKTtcbiAgICByZXR1cm4geyByZWFkYWJsZSwgd3JpdGFibGUgfTtcbn1cblxuLyoqXG4gKiBBIHJlYWRhYmxlIHN0cmVhbSByZXByZXNlbnRzIGEgc291cmNlIG9mIGRhdGEsIGZyb20gd2hpY2ggeW91IGNhbiByZWFkLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVTdHJlYW0ge1xuICAgIGNvbnN0cnVjdG9yKHJhd1VuZGVybHlpbmdTb3VyY2UgPSB7fSwgcmF3U3RyYXRlZ3kgPSB7fSkge1xuICAgICAgICBpZiAocmF3VW5kZXJseWluZ1NvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByYXdVbmRlcmx5aW5nU291cmNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFzc2VydE9iamVjdChyYXdVbmRlcmx5aW5nU291cmNlLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyYXRlZ3kgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5KHJhd1N0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCB1bmRlcmx5aW5nU291cmNlID0gY29udmVydFVuZGVybHlpbmdEZWZhdWx0T3JCeXRlU291cmNlKHJhd1VuZGVybHlpbmdTb3VyY2UsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgSW5pdGlhbGl6ZVJlYWRhYmxlU3RyZWFtKHRoaXMpO1xuICAgICAgICBpZiAodW5kZXJseWluZ1NvdXJjZS50eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgICAgICBpZiAoc3RyYXRlZ3kuc2l6ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBzdHJhdGVneSBmb3IgYSBieXRlIHN0cmVhbSBjYW5ub3QgaGF2ZSBhIHNpemUgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGhpZ2hXYXRlck1hcmsgPSBFeHRyYWN0SGlnaFdhdGVyTWFyayhzdHJhdGVneSwgMCk7XG4gICAgICAgICAgICBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGcm9tVW5kZXJseWluZ1NvdXJjZSh0aGlzLCB1bmRlcmx5aW5nU291cmNlLCBoaWdoV2F0ZXJNYXJrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShzdHJhdGVneSk7XG4gICAgICAgICAgICBjb25zdCBoaWdoV2F0ZXJNYXJrID0gRXh0cmFjdEhpZ2hXYXRlck1hcmsoc3RyYXRlZ3ksIDEpO1xuICAgICAgICAgICAgU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2UodGhpcywgdW5kZXJseWluZ1NvdXJjZSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hldGhlciBvciBub3QgdGhlIHJlYWRhYmxlIHN0cmVhbSBpcyBsb2NrZWQgdG8gYSB7QGxpbmsgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyIHwgcmVhZGVyfS5cbiAgICAgKi9cbiAgICBnZXQgbG9ja2VkKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnbG9ja2VkJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIElzUmVhZGFibGVTdHJlYW1Mb2NrZWQodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgdGhlIHN0cmVhbSwgc2lnbmFsaW5nIGEgbG9zcyBvZiBpbnRlcmVzdCBpbiB0aGUgc3RyZWFtIGJ5IGEgY29uc3VtZXIuXG4gICAgICpcbiAgICAgKiBUaGUgc3VwcGxpZWQgYHJlYXNvbmAgYXJndW1lbnQgd2lsbCBiZSBnaXZlbiB0byB0aGUgdW5kZXJseWluZyBzb3VyY2UncyB7QGxpbmsgVW5kZXJseWluZ1NvdXJjZS5jYW5jZWwgfCBjYW5jZWwoKX1cbiAgICAgKiBtZXRob2QsIHdoaWNoIG1pZ2h0IG9yIG1pZ2h0IG5vdCB1c2UgaXQuXG4gICAgICovXG4gICAgY2FuY2VsKHJlYXNvbiA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FuY2VsIGEgc3RyZWFtIHRoYXQgYWxyZWFkeSBoYXMgYSByZWFkZXInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIGdldFJlYWRlcihyYXdPcHRpb25zID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdnZXRSZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0gY29udmVydFJlYWRlck9wdGlvbnMocmF3T3B0aW9ucywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAob3B0aW9ucy5tb2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBBY3F1aXJlUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpO1xuICAgIH1cbiAgICBwaXBlVGhyb3VnaChyYXdUcmFuc2Zvcm0sIHJhd09wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgncGlwZVRocm91Z2gnKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHJhd1RyYW5zZm9ybSwgMSwgJ3BpcGVUaHJvdWdoJyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpcihyYXdUcmFuc2Zvcm0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbnZlcnRQaXBlT3B0aW9ucyhyYXdPcHRpb25zLCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUaHJvdWdoIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFJlYWRhYmxlU3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQodHJhbnNmb3JtLndyaXRhYmxlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUaHJvdWdoIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFdyaXRhYmxlU3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IFJlYWRhYmxlU3RyZWFtUGlwZVRvKHRoaXMsIHRyYW5zZm9ybS53cml0YWJsZSwgb3B0aW9ucy5wcmV2ZW50Q2xvc2UsIG9wdGlvbnMucHJldmVudEFib3J0LCBvcHRpb25zLnByZXZlbnRDYW5jZWwsIG9wdGlvbnMuc2lnbmFsKTtcbiAgICAgICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShwcm9taXNlKTtcbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybS5yZWFkYWJsZTtcbiAgICB9XG4gICAgcGlwZVRvKGRlc3RpbmF0aW9uLCByYXdPcHRpb25zID0ge30pIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3BpcGVUbycpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVzdGluYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoYFBhcmFtZXRlciAxIGlzIHJlcXVpcmVkIGluICdwaXBlVG8nLmApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZS5waXBlVG8ncyBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgV3JpdGFibGVTdHJlYW1gKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBvcHRpb25zID0gY29udmVydFBpcGVPcHRpb25zKHJhd09wdGlvbnMsICdTZWNvbmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUucGlwZVRvIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFJlYWRhYmxlU3RyZWFtJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUbyBjYW5ub3QgYmUgdXNlZCBvbiBhIGxvY2tlZCBXcml0YWJsZVN0cmVhbScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVTdHJlYW1QaXBlVG8odGhpcywgZGVzdGluYXRpb24sIG9wdGlvbnMucHJldmVudENsb3NlLCBvcHRpb25zLnByZXZlbnRBYm9ydCwgb3B0aW9ucy5wcmV2ZW50Q2FuY2VsLCBvcHRpb25zLnNpZ25hbCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRlZXMgdGhpcyByZWFkYWJsZSBzdHJlYW0sIHJldHVybmluZyBhIHR3by1lbGVtZW50IGFycmF5IGNvbnRhaW5pbmcgdGhlIHR3byByZXN1bHRpbmcgYnJhbmNoZXMgYXNcbiAgICAgKiBuZXcge0BsaW5rIFJlYWRhYmxlU3RyZWFtfSBpbnN0YW5jZXMuXG4gICAgICpcbiAgICAgKiBUZWVpbmcgYSBzdHJlYW0gd2lsbCBsb2NrIGl0LCBwcmV2ZW50aW5nIGFueSBvdGhlciBjb25zdW1lciBmcm9tIGFjcXVpcmluZyBhIHJlYWRlci5cbiAgICAgKiBUbyBjYW5jZWwgdGhlIHN0cmVhbSwgY2FuY2VsIGJvdGggb2YgdGhlIHJlc3VsdGluZyBicmFuY2hlczsgYSBjb21wb3NpdGUgY2FuY2VsbGF0aW9uIHJlYXNvbiB3aWxsIHRoZW4gYmVcbiAgICAgKiBwcm9wYWdhdGVkIHRvIHRoZSBzdHJlYW0ncyB1bmRlcmx5aW5nIHNvdXJjZS5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCB0aGUgY2h1bmtzIHNlZW4gaW4gZWFjaCBicmFuY2ggd2lsbCBiZSB0aGUgc2FtZSBvYmplY3QuIElmIHRoZSBjaHVua3MgYXJlIG5vdCBpbW11dGFibGUsXG4gICAgICogdGhpcyBjb3VsZCBhbGxvdyBpbnRlcmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGJyYW5jaGVzLlxuICAgICAqL1xuICAgIHRlZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3RlZScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJyYW5jaGVzID0gUmVhZGFibGVTdHJlYW1UZWUodGhpcyk7XG4gICAgICAgIHJldHVybiBDcmVhdGVBcnJheUZyb21MaXN0KGJyYW5jaGVzKTtcbiAgICB9XG4gICAgdmFsdWVzKHJhd09wdGlvbnMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3ZhbHVlcycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb252ZXJ0SXRlcmF0b3JPcHRpb25zKHJhd09wdGlvbnMsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgcmV0dXJuIEFjcXVpcmVSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IodGhpcywgb3B0aW9ucy5wcmV2ZW50Q2FuY2VsKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBjYW5jZWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGdldFJlYWRlcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcGlwZVRocm91Z2g6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHBpcGVUbzogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgdGVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB2YWx1ZXM6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGxvY2tlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1JlYWRhYmxlU3RyZWFtJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLmFzeW5jSXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwuYXN5bmNJdGVyYXRvciwge1xuICAgICAgICB2YWx1ZTogUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnZhbHVlcyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuLy8gVGhyb3dzIGlmIGFuZCBvbmx5IGlmIHN0YXJ0QWxnb3JpdGhtIHRocm93cy5cbmZ1bmN0aW9uIENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmsgPSAxLCBzaXplQWxnb3JpdGhtID0gKCkgPT4gMSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlKTtcbiAgICBJbml0aWFsaXplUmVhZGFibGVTdHJlYW0oc3RyZWFtKTtcbiAgICBjb25zdCBjb250cm9sbGVyID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLnByb3RvdHlwZSk7XG4gICAgU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbi8vIFRocm93cyBpZiBhbmQgb25seSBpZiBzdGFydEFsZ29yaXRobSB0aHJvd3MuXG5mdW5jdGlvbiBDcmVhdGVSZWFkYWJsZUJ5dGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlKTtcbiAgICBJbml0aWFsaXplUmVhZGFibGVTdHJlYW0oc3RyZWFtKTtcbiAgICBjb25zdCBjb250cm9sbGVyID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSk7XG4gICAgU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgMCwgdW5kZWZpbmVkKTtcbiAgICByZXR1cm4gc3RyZWFtO1xufVxuZnVuY3Rpb24gSW5pdGlhbGl6ZVJlYWRhYmxlU3RyZWFtKHN0cmVhbSkge1xuICAgIHN0cmVhbS5fc3RhdGUgPSAncmVhZGFibGUnO1xuICAgIHN0cmVhbS5fcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fc3RvcmVkRXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgc3RyZWFtLl9kaXN0dXJiZWQgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW0oeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW07XG59XG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX3JlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vLyBSZWFkYWJsZVN0cmVhbSBBUEkgZXhwb3NlZCBmb3IgY29udHJvbGxlcnMuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIHJlYXNvbikge1xuICAgIHN0cmVhbS5fZGlzdHVyYmVkID0gdHJ1ZTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gICAgUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pO1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5fcmVhZGVyO1xuICAgIGlmIChyZWFkZXIgIT09IHVuZGVmaW5lZCAmJiBJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5mb3JFYWNoKHJlYWRJbnRvUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Nsb3NlU3RlcHModW5kZWZpbmVkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cyA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2VDYW5jZWxQcm9taXNlID0gc3RyZWFtLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXJbQ2FuY2VsU3RlcHNdKHJlYXNvbik7XG4gICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKHNvdXJjZUNhbmNlbFByb21pc2UsIG5vb3ApO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ2Nsb3NlZCc7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNvbHZlKHJlYWRlcik7XG4gICAgaWYgKElzUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHJlYWRlcikpIHtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMuZm9yRWFjaChyZWFkUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkUmVxdWVzdC5fY2xvc2VTdGVwcygpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUVycm9yKHN0cmVhbSwgZSkge1xuICAgIHN0cmVhbS5fc3RhdGUgPSAnZXJyb3JlZCc7XG4gICAgc3RyZWFtLl9zdG9yZWRFcnJvciA9IGU7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCBlKTtcbiAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICByZWFkZXIuX3JlYWRSZXF1ZXN0cy5mb3JFYWNoKHJlYWRSZXF1ZXN0ID0+IHtcbiAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9lcnJvclN0ZXBzKGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5mb3JFYWNoKHJlYWRJbnRvUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Vycm9yU3RlcHMoZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZWFkZXIuX3JlYWRJbnRvUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW0uXG5mdW5jdGlvbiBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEobmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVTdHJlYW1gKTtcbn1cblxuZnVuY3Rpb24gY29udmVydFF1ZXVpbmdTdHJhdGVneUluaXQoaW5pdCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkoaW5pdCwgY29udGV4dCk7XG4gICAgY29uc3QgaGlnaFdhdGVyTWFyayA9IGluaXQgPT09IG51bGwgfHwgaW5pdCA9PT0gdm9pZCAwID8gdm9pZCAwIDogaW5pdC5oaWdoV2F0ZXJNYXJrO1xuICAgIGFzc2VydFJlcXVpcmVkRmllbGQoaGlnaFdhdGVyTWFyaywgJ2hpZ2hXYXRlck1hcmsnLCAnUXVldWluZ1N0cmF0ZWd5SW5pdCcpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGhpZ2hXYXRlck1hcms6IGNvbnZlcnRVbnJlc3RyaWN0ZWREb3VibGUoaGlnaFdhdGVyTWFyaylcbiAgICB9O1xufVxuXG4vLyBUaGUgc2l6ZSBmdW5jdGlvbiBtdXN0IG5vdCBoYXZlIGEgcHJvdG90eXBlIHByb3BlcnR5IG5vciBiZSBhIGNvbnN0cnVjdG9yXG5jb25zdCBieXRlTGVuZ3RoU2l6ZUZ1bmN0aW9uID0gKGNodW5rKSA9PiB7XG4gICAgcmV0dXJuIGNodW5rLmJ5dGVMZW5ndGg7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGJ5dGVMZW5ndGhTaXplRnVuY3Rpb24sICduYW1lJywge1xuICAgIHZhbHVlOiAnc2l6ZScsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG59KTtcbi8qKlxuICogQSBxdWV1aW5nIHN0cmF0ZWd5IHRoYXQgY291bnRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gZWFjaCBjaHVuay5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChvcHRpb25zLCAxLCAnQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneScpO1xuICAgICAgICBvcHRpb25zID0gY29udmVydFF1ZXVpbmdTdHJhdGVneUluaXQob3B0aW9ucywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICB0aGlzLl9ieXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGlnaCB3YXRlciBtYXJrIHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBnZXQgaGlnaFdhdGVyTWFyaygpIHtcbiAgICAgICAgaWYgKCFJc0J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKCdoaWdoV2F0ZXJNYXJrJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNZWFzdXJlcyB0aGUgc2l6ZSBvZiBgY2h1bmtgIGJ5IHJldHVybmluZyB0aGUgdmFsdWUgb2YgaXRzIGBieXRlTGVuZ3RoYCBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc0J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKCdzaXplJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJ5dGVMZW5ndGhTaXplRnVuY3Rpb247XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUsIHtcbiAgICBoaWdoV2F0ZXJNYXJrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBzaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5LnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneWApO1xufVxuZnVuY3Rpb24gSXNCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5KHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfYnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneTtcbn1cblxuLy8gVGhlIHNpemUgZnVuY3Rpb24gbXVzdCBub3QgaGF2ZSBhIHByb3RvdHlwZSBwcm9wZXJ0eSBub3IgYmUgYSBjb25zdHJ1Y3RvclxuY29uc3QgY291bnRTaXplRnVuY3Rpb24gPSAoKSA9PiB7XG4gICAgcmV0dXJuIDE7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvdW50U2l6ZUZ1bmN0aW9uLCAnbmFtZScsIHtcbiAgICB2YWx1ZTogJ3NpemUnLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxufSk7XG4vKipcbiAqIEEgcXVldWluZyBzdHJhdGVneSB0aGF0IGNvdW50cyB0aGUgbnVtYmVyIG9mIGNodW5rcy5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIENvdW50UXVldWluZ1N0cmF0ZWd5IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQob3B0aW9ucywgMSwgJ0NvdW50UXVldWluZ1N0cmF0ZWd5Jyk7XG4gICAgICAgIG9wdGlvbnMgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5SW5pdChvcHRpb25zLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIHRoaXMuX2NvdW50UXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGlnaCB3YXRlciBtYXJrIHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBnZXQgaGlnaFdhdGVyTWFyaygpIHtcbiAgICAgICAgaWYgKCFJc0NvdW50UXVldWluZ1N0cmF0ZWd5KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24oJ2hpZ2hXYXRlck1hcmsnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fY291bnRRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNZWFzdXJlcyB0aGUgc2l6ZSBvZiBgY2h1bmtgIGJ5IGFsd2F5cyByZXR1cm5pbmcgMS5cbiAgICAgKiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgdG90YWwgcXVldWUgc2l6ZSBpcyBhIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgY2h1bmtzIGluIHRoZSBxdWV1ZS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc0NvdW50UXVldWluZ1N0cmF0ZWd5KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24oJ3NpemUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY291bnRTaXplRnVuY3Rpb247XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQ291bnRRdWV1aW5nU3RyYXRlZ3kucHJvdG90eXBlLCB7XG4gICAgaGlnaFdhdGVyTWFyazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgc2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ291bnRRdWV1aW5nU3RyYXRlZ3kucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ0NvdW50UXVldWluZ1N0cmF0ZWd5JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgQ291bnRRdWV1aW5nU3RyYXRlZ3kuXG5mdW5jdGlvbiBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24obmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBDb3VudFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgQ291bnRRdWV1aW5nU3RyYXRlZ3lgKTtcbn1cbmZ1bmN0aW9uIElzQ291bnRRdWV1aW5nU3RyYXRlZ3koeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19jb3VudFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgQ291bnRRdWV1aW5nU3RyYXRlZ3k7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2Zvcm1lcihvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkob3JpZ2luYWwsIGNvbnRleHQpO1xuICAgIGNvbnN0IGZsdXNoID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLmZsdXNoO1xuICAgIGNvbnN0IHJlYWRhYmxlVHlwZSA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5yZWFkYWJsZVR5cGU7XG4gICAgY29uc3Qgc3RhcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuc3RhcnQ7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnRyYW5zZm9ybTtcbiAgICBjb25zdCB3cml0YWJsZVR5cGUgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwud3JpdGFibGVUeXBlO1xuICAgIHJldHVybiB7XG4gICAgICAgIGZsdXNoOiBmbHVzaCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VHJhbnNmb3JtZXJGbHVzaENhbGxiYWNrKGZsdXNoLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnZmx1c2gnIHRoYXRgKSxcbiAgICAgICAgcmVhZGFibGVUeXBlLFxuICAgICAgICBzdGFydDogc3RhcnQgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFRyYW5zZm9ybWVyU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNmb3JtID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrKHRyYW5zZm9ybSwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3RyYW5zZm9ybScgdGhhdGApLFxuICAgICAgICB3cml0YWJsZVR5cGVcbiAgICB9O1xufVxuZnVuY3Rpb24gY29udmVydFRyYW5zZm9ybWVyRmx1c2hDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjb250cm9sbGVyKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtjb250cm9sbGVyXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VHJhbnNmb3JtZXJTdGFydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHJlZmxlY3RDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNodW5rLCBjb250cm9sbGVyKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtjaHVuaywgY29udHJvbGxlcl0pO1xufVxuXG4vLyBDbGFzcyBUcmFuc2Zvcm1TdHJlYW1cbi8qKlxuICogQSB0cmFuc2Zvcm0gc3RyZWFtIGNvbnNpc3RzIG9mIGEgcGFpciBvZiBzdHJlYW1zOiBhIHtAbGluayBXcml0YWJsZVN0cmVhbSB8IHdyaXRhYmxlIHN0cmVhbX0sXG4gKiBrbm93biBhcyBpdHMgd3JpdGFibGUgc2lkZSwgYW5kIGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtIHwgcmVhZGFibGUgc3RyZWFtfSwga25vd24gYXMgaXRzIHJlYWRhYmxlIHNpZGUuXG4gKiBJbiBhIG1hbm5lciBzcGVjaWZpYyB0byB0aGUgdHJhbnNmb3JtIHN0cmVhbSBpbiBxdWVzdGlvbiwgd3JpdGVzIHRvIHRoZSB3cml0YWJsZSBzaWRlIHJlc3VsdCBpbiBuZXcgZGF0YSBiZWluZ1xuICogbWFkZSBhdmFpbGFibGUgZm9yIHJlYWRpbmcgZnJvbSB0aGUgcmVhZGFibGUgc2lkZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFRyYW5zZm9ybVN0cmVhbSB7XG4gICAgY29uc3RydWN0b3IocmF3VHJhbnNmb3JtZXIgPSB7fSwgcmF3V3JpdGFibGVTdHJhdGVneSA9IHt9LCByYXdSZWFkYWJsZVN0cmF0ZWd5ID0ge30pIHtcbiAgICAgICAgaWYgKHJhd1RyYW5zZm9ybWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJhd1RyYW5zZm9ybWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3cml0YWJsZVN0cmF0ZWd5ID0gY29udmVydFF1ZXVpbmdTdHJhdGVneShyYXdXcml0YWJsZVN0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCByZWFkYWJsZVN0cmF0ZWd5ID0gY29udmVydFF1ZXVpbmdTdHJhdGVneShyYXdSZWFkYWJsZVN0cmF0ZWd5LCAnVGhpcmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gY29udmVydFRyYW5zZm9ybWVyKHJhd1RyYW5zZm9ybWVyLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci5yZWFkYWJsZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgcmVhZGFibGVUeXBlIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci53cml0YWJsZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgd3JpdGFibGVUeXBlIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlSGlnaFdhdGVyTWFyayA9IEV4dHJhY3RIaWdoV2F0ZXJNYXJrKHJlYWRhYmxlU3RyYXRlZ3ksIDApO1xuICAgICAgICBjb25zdCByZWFkYWJsZVNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShyZWFkYWJsZVN0cmF0ZWd5KTtcbiAgICAgICAgY29uc3Qgd3JpdGFibGVIaWdoV2F0ZXJNYXJrID0gRXh0cmFjdEhpZ2hXYXRlck1hcmsod3JpdGFibGVTdHJhdGVneSwgMSk7XG4gICAgICAgIGNvbnN0IHdyaXRhYmxlU2l6ZUFsZ29yaXRobSA9IEV4dHJhY3RTaXplQWxnb3JpdGhtKHdyaXRhYmxlU3RyYXRlZ3kpO1xuICAgICAgICBsZXQgc3RhcnRQcm9taXNlX3Jlc29sdmU7XG4gICAgICAgIGNvbnN0IHN0YXJ0UHJvbWlzZSA9IG5ld1Byb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBJbml0aWFsaXplVHJhbnNmb3JtU3RyZWFtKHRoaXMsIHN0YXJ0UHJvbWlzZSwgd3JpdGFibGVIaWdoV2F0ZXJNYXJrLCB3cml0YWJsZVNpemVBbGdvcml0aG0sIHJlYWRhYmxlSGlnaFdhdGVyTWFyaywgcmVhZGFibGVTaXplQWxnb3JpdGhtKTtcbiAgICAgICAgU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21UcmFuc2Zvcm1lcih0aGlzLCB0cmFuc2Zvcm1lcik7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci5zdGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSh0cmFuc2Zvcm1lci5zdGFydCh0aGlzLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWFkYWJsZSBzaWRlIG9mIHRoZSB0cmFuc2Zvcm0gc3RyZWFtLlxuICAgICAqL1xuICAgIGdldCByZWFkYWJsZSgpIHtcbiAgICAgICAgaWYgKCFJc1RyYW5zZm9ybVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbigncmVhZGFibGUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcmVhZGFibGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB3cml0YWJsZSBzaWRlIG9mIHRoZSB0cmFuc2Zvcm0gc3RyZWFtLlxuICAgICAqL1xuICAgIGdldCB3cml0YWJsZSgpIHtcbiAgICAgICAgaWYgKCFJc1RyYW5zZm9ybVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbignd3JpdGFibGUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fd3JpdGFibGU7XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoVHJhbnNmb3JtU3RyZWFtLnByb3RvdHlwZSwge1xuICAgIHJlYWRhYmxlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB3cml0YWJsZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVHJhbnNmb3JtU3RyZWFtLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdUcmFuc2Zvcm1TdHJlYW0nLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIEluaXRpYWxpemVUcmFuc2Zvcm1TdHJlYW0oc3RyZWFtLCBzdGFydFByb21pc2UsIHdyaXRhYmxlSGlnaFdhdGVyTWFyaywgd3JpdGFibGVTaXplQWxnb3JpdGhtLCByZWFkYWJsZUhpZ2hXYXRlck1hcmssIHJlYWRhYmxlU2l6ZUFsZ29yaXRobSkge1xuICAgIGZ1bmN0aW9uIHN0YXJ0QWxnb3JpdGhtKCkge1xuICAgICAgICByZXR1cm4gc3RhcnRQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiB3cml0ZUFsZ29yaXRobShjaHVuaykge1xuICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtXcml0ZUFsZ29yaXRobShzdHJlYW0sIGNodW5rKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYWJvcnRBbGdvcml0aG0ocmVhc29uKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua0Fib3J0QWxnb3JpdGhtKHN0cmVhbSwgcmVhc29uKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2xvc2VBbGdvcml0aG0oKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua0Nsb3NlQWxnb3JpdGhtKHN0cmVhbSk7XG4gICAgfVxuICAgIHN0cmVhbS5fd3JpdGFibGUgPSBDcmVhdGVXcml0YWJsZVN0cmVhbShzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgd3JpdGFibGVIaWdoV2F0ZXJNYXJrLCB3cml0YWJsZVNpemVBbGdvcml0aG0pO1xuICAgIGZ1bmN0aW9uIHB1bGxBbGdvcml0aG0oKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U291cmNlUHVsbEFsZ29yaXRobShzdHJlYW0pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWxBbGdvcml0aG0ocmVhc29uKSB7XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUoc3RyZWFtLCByZWFzb24pO1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIH1cbiAgICBzdHJlYW0uX3JlYWRhYmxlID0gQ3JlYXRlUmVhZGFibGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgcmVhZGFibGVIaWdoV2F0ZXJNYXJrLCByZWFkYWJsZVNpemVBbGdvcml0aG0pO1xuICAgIC8vIFRoZSBbW2JhY2twcmVzc3VyZV1dIHNsb3QgaXMgc2V0IHRvIHVuZGVmaW5lZCBzbyB0aGF0IGl0IGNhbiBiZSBpbml0aWFsaXNlZCBieSBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUuXG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSB1bmRlZmluZWQ7XG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIHRydWUpO1xuICAgIHN0cmVhbS5fdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlciA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIElzVHJhbnNmb3JtU3RyZWFtKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlcicpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBUcmFuc2Zvcm1TdHJlYW07XG59XG4vLyBUaGlzIGlzIGEgbm8tb3AgaWYgYm90aCBzaWRlcyBhcmUgYWxyZWFkeSBlcnJvcmVkLlxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRXJyb3Ioc3RyZWFtLCBlKSB7XG4gICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKHN0cmVhbS5fcmVhZGFibGUuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgZSk7XG4gICAgVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZShzdHJlYW0sIGUpO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZShzdHJlYW0sIGUpIHtcbiAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKHN0cmVhbS5fd3JpdGFibGUuX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlciwgZSk7XG4gICAgaWYgKHN0cmVhbS5fYmFja3ByZXNzdXJlKSB7XG4gICAgICAgIC8vIFByZXRlbmQgdGhhdCBwdWxsKCkgd2FzIGNhbGxlZCB0byBwZXJtaXQgYW55IHBlbmRpbmcgd3JpdGUoKSBjYWxscyB0byBjb21wbGV0ZS4gVHJhbnNmb3JtU3RyZWFtU2V0QmFja3ByZXNzdXJlKClcbiAgICAgICAgLy8gY2Fubm90IGJlIGNhbGxlZCBmcm9tIGVucXVldWUoKSBvciBwdWxsKCkgb25jZSB0aGUgUmVhZGFibGVTdHJlYW0gaXMgZXJyb3JlZCwgc28gdGhpcyB3aWxsIHdpbGwgYmUgdGhlIGZpbmFsIHRpbWVcbiAgICAgICAgLy8gX2JhY2twcmVzc3VyZSBpcyBzZXQuXG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIGZhbHNlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpIHtcbiAgICAvLyBQYXNzZXMgYWxzbyB3aGVuIGNhbGxlZCBkdXJpbmcgY29uc3RydWN0aW9uLlxuICAgIGlmIChzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSgpO1xuICAgIH1cbiAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2UgPSBuZXdQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSBiYWNrcHJlc3N1cmU7XG59XG4vLyBDbGFzcyBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclxuLyoqXG4gKiBBbGxvd3MgY29udHJvbCBvZiB0aGUge0BsaW5rIFJlYWRhYmxlU3RyZWFtfSBhbmQge0BsaW5rIFdyaXRhYmxlU3RyZWFtfSBvZiB0aGUgYXNzb2NpYXRlZCB7QGxpbmsgVHJhbnNmb3JtU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgcmVhZGFibGUgc2lkZeKAmXMgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzIG92ZXItZnVsbC5cbiAgICAgKi9cbiAgICBnZXQgZGVzaXJlZFNpemUoKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlQ29udHJvbGxlciA9IHRoaXMuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW0uX3JlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUocmVhZGFibGVDb250cm9sbGVyKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuayA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbignZW5xdWV1ZScpO1xuICAgICAgICB9XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSh0aGlzLCBjaHVuayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVycm9ycyBib3RoIHRoZSByZWFkYWJsZSBzaWRlIGFuZCB0aGUgd3JpdGFibGUgc2lkZSBvZiB0aGUgY29udHJvbGxlZCB0cmFuc2Zvcm0gc3RyZWFtLCBtYWtpbmcgYWxsIGZ1dHVyZVxuICAgICAqIGludGVyYWN0aW9ucyB3aXRoIGl0IGZhaWwgd2l0aCB0aGUgZ2l2ZW4gZXJyb3IgYGVgLiBBbnkgY2h1bmtzIHF1ZXVlZCBmb3IgdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBkaXNjYXJkZWQuXG4gICAgICovXG4gICAgZXJyb3IocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSByZWFkYWJsZSBzaWRlIGFuZCBlcnJvcnMgdGhlIHdyaXRhYmxlIHNpZGUgb2YgdGhlIGNvbnRyb2xsZWQgdHJhbnNmb3JtIHN0cmVhbS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB0aGVcbiAgICAgKiB0cmFuc2Zvcm1lciBvbmx5IG5lZWRzIHRvIGNvbnN1bWUgYSBwb3J0aW9uIG9mIHRoZSBjaHVua3Mgd3JpdHRlbiB0byB0aGUgd3JpdGFibGUgc2lkZS5cbiAgICAgKi9cbiAgICB0ZXJtaW5hdGUoKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCd0ZXJtaW5hdGUnKTtcbiAgICAgICAgfVxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclRlcm1pbmF0ZSh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBlbnF1ZXVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgdGVybWluYXRlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBkZXNpcmVkU2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBUcmFuc2Zvcm0gU3RyZWFtIERlZmF1bHQgQ29udHJvbGxlciBBYnN0cmFjdCBPcGVyYXRpb25zXG5mdW5jdGlvbiBJc1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIFNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCB0cmFuc2Zvcm1BbGdvcml0aG0sIGZsdXNoQWxnb3JpdGhtKSB7XG4gICAgY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSA9IHN0cmVhbTtcbiAgICBzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuICAgIGNvbnRyb2xsZXIuX3RyYW5zZm9ybUFsZ29yaXRobSA9IHRyYW5zZm9ybUFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9mbHVzaEFsZ29yaXRobSA9IGZsdXNoQWxnb3JpdGhtO1xufVxuZnVuY3Rpb24gU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21UcmFuc2Zvcm1lcihzdHJlYW0sIHRyYW5zZm9ybWVyKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBsZXQgdHJhbnNmb3JtQWxnb3JpdGhtID0gKGNodW5rKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUoY29udHJvbGxlciwgY2h1bmspO1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAodHJhbnNmb3JtUmVzdWx0RSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgodHJhbnNmb3JtUmVzdWx0RSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGxldCBmbHVzaEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodHJhbnNmb3JtZXIudHJhbnNmb3JtICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHJhbnNmb3JtQWxnb3JpdGhtID0gY2h1bmsgPT4gdHJhbnNmb3JtZXIudHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHRyYW5zZm9ybWVyLmZsdXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZmx1c2hBbGdvcml0aG0gPSAoKSA9PiB0cmFuc2Zvcm1lci5mbHVzaChjb250cm9sbGVyKTtcbiAgICB9XG4gICAgU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcihzdHJlYW0sIGNvbnRyb2xsZXIsIHRyYW5zZm9ybUFsZ29yaXRobSwgZmx1c2hBbGdvcml0aG0pO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcikge1xuICAgIGNvbnRyb2xsZXIuX3RyYW5zZm9ybUFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9mbHVzaEFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW07XG4gICAgY29uc3QgcmVhZGFibGVDb250cm9sbGVyID0gc3RyZWFtLl9yZWFkYWJsZS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyO1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKHJlYWRhYmxlQ29udHJvbGxlcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGUgc2lkZSBpcyBub3QgaW4gYSBzdGF0ZSB0aGF0IHBlcm1pdHMgZW5xdWV1ZScpO1xuICAgIH1cbiAgICAvLyBXZSB0aHJvdHRsZSB0cmFuc2Zvcm0gaW52b2NhdGlvbnMgYmFzZWQgb24gdGhlIGJhY2twcmVzc3VyZSBvZiB0aGUgUmVhZGFibGVTdHJlYW0sIGJ1dCB3ZSBzdGlsbFxuICAgIC8vIGFjY2VwdCBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUoKSBjYWxscy5cbiAgICB0cnkge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShyZWFkYWJsZUNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICB9XG4gICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gVGhpcyBoYXBwZW5zIHdoZW4gcmVhZGFibGVTdHJhdGVneS5zaXplKCkgdGhyb3dzLlxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1FcnJvcldyaXRhYmxlQW5kVW5ibG9ja1dyaXRlKHN0cmVhbSwgZSk7XG4gICAgICAgIHRocm93IHN0cmVhbS5fcmVhZGFibGUuX3N0b3JlZEVycm9yO1xuICAgIH1cbiAgICBjb25zdCBiYWNrcHJlc3N1cmUgPSBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVySGFzQmFja3ByZXNzdXJlKHJlYWRhYmxlQ29udHJvbGxlcik7XG4gICAgaWYgKGJhY2twcmVzc3VyZSAhPT0gc3RyZWFtLl9iYWNrcHJlc3N1cmUpIHtcbiAgICAgICAgVHJhbnNmb3JtU3RyZWFtU2V0QmFja3ByZXNzdXJlKHN0cmVhbSwgdHJ1ZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKSB7XG4gICAgVHJhbnNmb3JtU3RyZWFtRXJyb3IoY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSwgZSk7XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclBlcmZvcm1UcmFuc2Zvcm0oY29udHJvbGxlciwgY2h1bmspIHtcbiAgICBjb25zdCB0cmFuc2Zvcm1Qcm9taXNlID0gY29udHJvbGxlci5fdHJhbnNmb3JtQWxnb3JpdGhtKGNodW5rKTtcbiAgICByZXR1cm4gdHJhbnNmb3JtUHJvbWlzZVdpdGgodHJhbnNmb3JtUHJvbWlzZSwgdW5kZWZpbmVkLCByID0+IHtcbiAgICAgICAgVHJhbnNmb3JtU3RyZWFtRXJyb3IoY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSwgcik7XG4gICAgICAgIHRocm93IHI7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclRlcm1pbmF0ZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbTtcbiAgICBjb25zdCByZWFkYWJsZUNvbnRyb2xsZXIgPSBzdHJlYW0uX3JlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKHJlYWRhYmxlQ29udHJvbGxlcik7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgVHlwZUVycm9yKCdUcmFuc2Zvcm1TdHJlYW0gdGVybWluYXRlZCcpO1xuICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUoc3RyZWFtLCBlcnJvcik7XG59XG4vLyBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2luayBBbGdvcml0aG1zXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua1dyaXRlQWxnb3JpdGhtKHN0cmVhbSwgY2h1bmspIHtcbiAgICBjb25zdCBjb250cm9sbGVyID0gc3RyZWFtLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyO1xuICAgIGlmIChzdHJlYW0uX2JhY2twcmVzc3VyZSkge1xuICAgICAgICBjb25zdCBiYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlID0gc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlO1xuICAgICAgICByZXR1cm4gdHJhbnNmb3JtUHJvbWlzZVdpdGgoYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgd3JpdGFibGUgPSBzdHJlYW0uX3dyaXRhYmxlO1xuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSB3cml0YWJsZS5fc3RhdGU7XG4gICAgICAgICAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyB3cml0YWJsZS5fc3RvcmVkRXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQZXJmb3JtVHJhbnNmb3JtKGNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclBlcmZvcm1UcmFuc2Zvcm0oY29udHJvbGxlciwgY2h1bmspO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtBYm9ydEFsZ29yaXRobShzdHJlYW0sIHJlYXNvbikge1xuICAgIC8vIGFib3J0KCkgaXMgbm90IGNhbGxlZCBzeW5jaHJvbm91c2x5LCBzbyBpdCBpcyBwb3NzaWJsZSBmb3IgYWJvcnQoKSB0byBiZSBjYWxsZWQgd2hlbiB0aGUgc3RyZWFtIGlzIGFscmVhZHlcbiAgICAvLyBlcnJvcmVkLlxuICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yKHN0cmVhbSwgcmVhc29uKTtcbiAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtDbG9zZUFsZ29yaXRobShzdHJlYW0pIHtcbiAgICAvLyBzdHJlYW0uX3JlYWRhYmxlIGNhbm5vdCBjaGFuZ2UgYWZ0ZXIgY29uc3RydWN0aW9uLCBzbyBjYWNoaW5nIGl0IGFjcm9zcyBhIGNhbGwgdG8gdXNlciBjb2RlIGlzIHNhZmUuXG4gICAgY29uc3QgcmVhZGFibGUgPSBzdHJlYW0uX3JlYWRhYmxlO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgY29uc3QgZmx1c2hQcm9taXNlID0gY29udHJvbGxlci5fZmx1c2hBbGdvcml0aG0oKTtcbiAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKTtcbiAgICAvLyBSZXR1cm4gYSBwcm9taXNlIHRoYXQgaXMgZnVsZmlsbGVkIHdpdGggdW5kZWZpbmVkIG9uIHN1Y2Nlc3MuXG4gICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKGZsdXNoUHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICBpZiAocmVhZGFibGUuX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgICAgIHRocm93IHJlYWRhYmxlLl9zdG9yZWRFcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UocmVhZGFibGUuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgfSwgciA9PiB7XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yKHN0cmVhbSwgcik7XG4gICAgICAgIHRocm93IHJlYWRhYmxlLl9zdG9yZWRFcnJvcjtcbiAgICB9KTtcbn1cbi8vIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRTb3VyY2UgQWxnb3JpdGhtc1xuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNvdXJjZVB1bGxBbGdvcml0aG0oc3RyZWFtKSB7XG4gICAgLy8gSW52YXJpYW50LiBFbmZvcmNlZCBieSB0aGUgcHJvbWlzZXMgcmV0dXJuZWQgYnkgc3RhcnQoKSBhbmQgcHVsbCgpLlxuICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIGZhbHNlKTtcbiAgICAvLyBQcmV2ZW50IHRoZSBuZXh0IHB1bGwoKSBjYWxsIHVudGlsIHRoZXJlIGlzIGJhY2twcmVzc3VyZS5cbiAgICByZXR1cm4gc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyLlxuZnVuY3Rpb24gZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyYCk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgVHJhbnNmb3JtU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFRyYW5zZm9ybVN0cmVhbS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgVHJhbnNmb3JtU3RyZWFtYCk7XG59XG5cbmV4cG9ydCB7IEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3ksIENvdW50UXVldWluZ1N0cmF0ZWd5LCBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLCBSZWFkYWJsZVN0cmVhbSwgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyLCBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LCBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLCBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIsIFRyYW5zZm9ybVN0cmVhbSwgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIsIFdyaXRhYmxlU3RyZWFtLCBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLCBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvbnlmaWxsLmVzMjAxOC5tanMubWFwXG4iLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdGlkOiBtb2R1bGVJZCxcblx0XHRsb2FkZWQ6IGZhbHNlLFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcblx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5ubWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZS5wYXRocyA9IFtdO1xuXHRpZiAoIW1vZHVsZS5jaGlsZHJlbikgbW9kdWxlLmNoaWxkcmVuID0gW107XG5cdHJldHVybiBtb2R1bGU7XG59OyIsIi8vIHN0YXJ0dXBcbi8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLy8gVGhpcyBlbnRyeSBtb2R1bGUgaXMgcmVmZXJlbmNlZCBieSBvdGhlciBtb2R1bGVzIHNvIGl0IGNhbid0IGJlIGlubGluZWRcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0OCk7XG4iXSwibmFtZXMiOlsicm9vdCIsImZhY3RvcnkiLCJleHBvcnRzIiwibW9kdWxlIiwiZGVmaW5lIiwiYW1kIiwidGhpcyIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwidmFsdWUiLCJldmVudFRhcmdldFNoaW0iLCJBYm9ydFNpZ25hbCIsIkV2ZW50VGFyZ2V0IiwiY29uc3RydWN0b3IiLCJzdXBlciIsIlR5cGVFcnJvciIsImFib3J0ZWQiLCJhYm9ydGVkRmxhZ3MiLCJnZXQiLCJkZWZpbmVFdmVudEF0dHJpYnV0ZSIsInByb3RvdHlwZSIsIldlYWtNYXAiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZW51bWVyYWJsZSIsIlN5bWJvbCIsInRvU3RyaW5nVGFnIiwiY29uZmlndXJhYmxlIiwiQWJvcnRDb250cm9sbGVyIiwic2lnbmFscyIsInNldCIsInNpZ25hbCIsImNyZWF0ZSIsImNhbGwiLCJjcmVhdGVBYm9ydFNpZ25hbCIsImdldFNpZ25hbCIsImFib3J0IiwiZGlzcGF0Y2hFdmVudCIsInR5cGUiLCJjb250cm9sbGVyIiwiRm9ybURhdGEiLCJmb3JtRGF0YSIsImNsaWVudCIsIm9wdGlvbnMiLCJNYWlsZ3VuIiwiY29uZmlnIiwidXJsIiwidXNlcm5hbWUiLCJFcnJvciIsImtleSIsInJlcXVlc3QiLCJtYWlsTGlzdHNNZW1iZXJzIiwiZG9tYWlucyIsIndlYmhvb2tzIiwiZXZlbnRzIiwic3RhdHMiLCJzdXBwcmVzc2lvbnMiLCJtZXNzYWdlcyIsInJvdXRlcyIsImlwcyIsImlwX3Bvb2xzIiwibGlzdHMiLCJwdWJsaWNfa2V5IiwicHVibGljX3JlcXVlc3QiLCJ2YWxpZGF0ZSIsInBhcnNlIiwiZGF0YSIsInJlY2VpdmluZyIsInNlbmRpbmciLCJuYW1lIiwicmVxdWlyZV90bHMiLCJza2lwX3ZlcmlmaWNhdGlvbiIsInN0YXRlIiwid2lsZGNhcmQiLCJzcGFtX2FjdGlvbiIsImNyZWF0ZWRfYXQiLCJzbXRwX3Bhc3N3b3JkIiwic210cF9sb2dpbiIsInJlY2VpdmluZ19kbnNfcmVjb3JkcyIsInNlbmRpbmdfZG5zX3JlY29yZHMiLCJfcGFyc2VNZXNzYWdlIiwicmVzcG9uc2UiLCJib2R5IiwiX3BhcnNlRG9tYWluTGlzdCIsIml0ZW1zIiwibWFwIiwiaXRlbSIsIkRvbWFpbiIsIl9wYXJzZURvbWFpbiIsImRvbWFpbiIsIl9wYXJzZVRyYWNraW5nU2V0dGluZ3MiLCJ0cmFja2luZyIsIl9wYXJzZVRyYWNraW5nVXBkYXRlIiwibGlzdCIsInF1ZXJ5IiwidGhlbiIsInJlcyIsInBvc3RXaXRoRkQiLCJkZXN0cm95IiwiZGVsZXRlIiwiZ2V0VHJhY2tpbmciLCJ1cGRhdGVUcmFja2luZyIsImFjdGl2ZSIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJtZXNzYWdlIiwicHV0V2l0aEZEIiwiZ2V0SXBzIiwiYXNzaWduSXAiLCJpcCIsImRlbGV0ZUlwIiwibGlua0lwUG9vbCIsInBvb2xfaWQiLCJ1bmxpbmtJcFBvbGwiLCJib2R5TWVzc2FnZSIsImVycm9yIiwic3RhY2siLCJkZXRhaWxzIiwiX3BhcnNlUGFnZU51bWJlciIsInNwbGl0IiwicG9wIiwiX3BhcnNlUGFnZSIsImlkIiwibnVtYmVyIiwiX3BhcnNlUGFnZUxpbmtzIiwiZW50cmllcyIsInBhZ2luZyIsInJlZHVjZSIsImFjYyIsImVudHJpZSIsIl9wYXJzZUV2ZW50TGlzdCIsInBhZ2VzIiwicXVlcnlDb3B5IiwicGFnZSIsInBhcnNlSXBQb29sc1Jlc3BvbnNlIiwicG9zdCIsInVwZGF0ZSIsInBvb2xJZCIsInBhdGNoIiwicGFyc2VJcHNSZXNwb25zZSIsIm1lbWJlcnMiLCJiYXNlUm91dGUiLCJtYWlsTGlzdEFkZHJlc3MiLCJjaGVja0FuZFVwZGF0ZURhdGEiLCJuZXdEYXRhIiwidmFycyIsIkpTT04iLCJzdHJpbmdpZnkiLCJzdWJzY3JpYmVkIiwibGlzdE1lbWJlcnMiLCJnZXRNZW1iZXIiLCJtYWlsTGlzdE1lbWJlckFkZHJlc3MiLCJjcmVhdGVNZW1iZXIiLCJyZXFEYXRhIiwiY3JlYXRlTWVtYmVycyIsIkFycmF5IiwiaXNBcnJheSIsInVwc2VydCIsInVwZGF0ZU1lbWJlciIsImRlc3Ryb3lNZW1iZXIiLCJfcGFyc2VSZXNwb25zZSIsImFkZHJlc3NlcyIsImVuYWJsZURuc0VzcENoZWNrcyIsImpvaW4iLCJzeW50YXhfb25seSIsImlzU3RyZWFtIiwiYXR0YWNobWVudCIsInBpcGUiLCJ0aW1lb3V0IiwiaGVhZGVycyIsIm1ldGhvZCIsImlucHV0T3B0aW9ucyIsImJhc2ljIiwiZW5jb2RlIiwiQXV0aG9yaXphdGlvbiIsInBhcmFtcyIsImdldE93blByb3BlcnR5TmFtZXMiLCJsZW5ndGgiLCJzZWFyY2hQYXJhbXMiLCJ0b0xvY2FsZVVwcGVyQ2FzZSIsInRocm93SHR0cEVycm9ycyIsIm9rIiwic3RyZWFtIiwiY2h1bmtzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJvbiIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsInRvU3RyaW5nIiwianNvbiIsImNvbW1hbmQiLCJoZWFkIiwiY3JlYXRlRm9ybURhdGEiLCJhcHBlbmRGaWxlVG9GRCIsIm9iaiIsImZvcm1EYXRhSW5zdGFuY2UiLCJvYmpEYXRhIiwiZmlsZW5hbWUiLCJjb250ZW50VHlwZSIsImtub3duTGVuZ3RoIiwiZ2V0QXR0YWNobWVudE9wdGlvbnMiLCJ1bmRlZmluZWQiLCJnZXRIZWFkZXJzIiwiaXNOb2RlRm9ybURhdGEiLCJhcHBlbmQiLCJrZXlzIiwiZmlsdGVyIiwiZm9ybURhdGFBY2MiLCJmb3JFYWNoIiwicHV0IiwiUmVxdWVzdCIsInN0YXJ0IiwiRGF0ZSIsImVuZCIsInJlc29sdXRpb24iLCJzdGF0IiwidGltZSIsIl9wYXJzZVN0YXRzIiwiU3RhdHMiLCJnZXREb21haW4iLCJnZXRBY2NvdW50IiwiY3JlYXRlT3B0aW9ucyIsImFkZHJlc3MiLCJjb2RlIiwidGFncyIsIm1vZGVscyIsImJvdW5jZXMiLCJCb3VuY2UiLCJjb21wbGFpbnRzIiwiQ29tcGxhaW50IiwidW5zdWJzY3JpYmVzIiwiVW5zdWJzY3JpYmUiLCJwYWdlVXJsIiwiX3BhcnNlTGlzdCIsIk1vZGVsIiwiZCIsIl9wYXJzZUl0ZW0iLCJtb2RlbCIsImVuY29kZVVSSUNvbXBvbmVudCIsInBvc3REYXRhIiwiU3VwcHJlc3Npb25DbGllbnQiLCJfcGFyc2VXZWJob29rTGlzdCIsIl9wYXJzZVdlYmhvb2tXaXRoSUQiLCJ3ZWJob29rUmVzcG9uc2UiLCJ3ZWJob29rIiwidXJscyIsIldlYmhvb2siLCJfcGFyc2VXZWJob29rVGVzdCIsInRlc3QiLCJmcmVlRXhwb3J0cyIsImZyZWVHbG9iYWwiLCJnbG9iYWwiLCJ3aW5kb3ciLCJJbnZhbGlkQ2hhcmFjdGVyRXJyb3IiLCJUQUJMRSIsIlJFR0VYX1NQQUNFX0NIQVJBQ1RFUlMiLCJiYXNlNjQiLCJpbnB1dCIsIlN0cmluZyIsImEiLCJiIiwiYyIsImJ1ZmZlciIsInBhZGRpbmciLCJvdXRwdXQiLCJwb3NpdGlvbiIsImNoYXJDb2RlQXQiLCJjaGFyQXQiLCJyZXBsYWNlIiwiYml0U3RvcmFnZSIsImJpdENvdW50ZXIiLCJpbmRleE9mIiwiZnJvbUNoYXJDb2RlIiwidXJpIiwiZmlyc3RDb21tYSIsIm1ldGEiLCJzdWJzdHJpbmciLCJjaGFyc2V0IiwidHlwZUZ1bGwiLCJpIiwiZW5jb2RpbmciLCJ1bmVzY2FwZSIsImZyb20iLCJwcml2YXRlRGF0YSIsIndyYXBwZXJzIiwicGQiLCJldmVudCIsInJldHYiLCJjb25zb2xlIiwiYXNzZXJ0Iiwic2V0Q2FuY2VsRmxhZyIsInBhc3NpdmVMaXN0ZW5lciIsImNhbmNlbGFibGUiLCJjYW5jZWxlZCIsInByZXZlbnREZWZhdWx0IiwiRXZlbnQiLCJldmVudFRhcmdldCIsImV2ZW50UGhhc2UiLCJjdXJyZW50VGFyZ2V0Iiwic3RvcHBlZCIsImltbWVkaWF0ZVN0b3BwZWQiLCJ0aW1lU3RhbXAiLCJub3ciLCJkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3IiLCJkZWZpbmVDYWxsRGVzY3JpcHRvciIsImFwcGx5IiwiYXJndW1lbnRzIiwiZ2V0V3JhcHBlciIsInByb3RvIiwid3JhcHBlciIsIkJhc2VFdmVudCIsIkN1c3RvbUV2ZW50Iiwid3JpdGFibGUiLCJpc0Z1bmMiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJkZWZpbmVXcmFwcGVyIiwiZ2V0UHJvdG90eXBlT2YiLCJpc1N0b3BwZWQiLCJzZXRQYXNzaXZlTGlzdGVuZXIiLCJ0YXJnZXQiLCJjb21wb3NlZFBhdGgiLCJOT05FIiwiQ0FQVFVSSU5HX1BIQVNFIiwiQVRfVEFSR0VUIiwiQlVCQkxJTkdfUEhBU0UiLCJzdG9wUHJvcGFnYXRpb24iLCJzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24iLCJidWJibGVzIiwiQm9vbGVhbiIsImRlZmF1bHRQcmV2ZW50ZWQiLCJjb21wb3NlZCIsInNyY0VsZW1lbnQiLCJjYW5jZWxCdWJibGUiLCJyZXR1cm5WYWx1ZSIsImluaXRFdmVudCIsInNldFByb3RvdHlwZU9mIiwibGlzdGVuZXJzTWFwIiwiaXNPYmplY3QiLCJ4IiwiZ2V0TGlzdGVuZXJzIiwibGlzdGVuZXJzIiwiZXZlbnRUYXJnZXRQcm90b3R5cGUiLCJldmVudE5hbWUiLCJub2RlIiwibGlzdGVuZXJUeXBlIiwibGlzdGVuZXIiLCJuZXh0IiwicHJldiIsIm5ld05vZGUiLCJwYXNzaXZlIiwib25jZSIsImRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvciIsImRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0IiwiZXZlbnROYW1lcyIsIkN1c3RvbUV2ZW50VGFyZ2V0IiwidHlwZXMiLCJNYXAiLCJhZGRFdmVudExpc3RlbmVyIiwib3B0aW9uc0lzT2JqIiwiY2FwdHVyZSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJ3cmFwcGVkRXZlbnQiLCJ3cmFwRXZlbnQiLCJlcnIiLCJoYW5kbGVFdmVudCIsInNldEV2ZW50UGhhc2UiLCJzZXRDdXJyZW50VGFyZ2V0IiwiUmVhZGFibGUiLCJ3bSIsIkJsb2IiLCJibG9iUGFydHMiLCJzaXplIiwicGFydHMiLCJlbGVtZW50IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJieXRlT2Zmc2V0IiwiYnl0ZUxlbmd0aCIsInRvTG93ZXJDYXNlIiwiYXN5bmMiLCJhcnJheUJ1ZmZlciIsIlVpbnQ4QXJyYXkiLCJvZmZzZXQiLCJwYXJ0IiwicmVhZCIsInNsaWNlIiwicmVsYXRpdmVTdGFydCIsIk1hdGgiLCJtYXgiLCJtaW4iLCJyZWxhdGl2ZUVuZCIsInNwYW4iLCJ2YWx1ZXMiLCJhZGRlZCIsImJsb2IiLCJhc3NpZ24iLCJzdGF0aWMiLCJoYXNJbnN0YW5jZSIsIm9iamVjdCIsImZldGNoIiwiaGlnaFdhdGVyTWFyayIsIkhlYWRlcnMiLCJSZXNwb25zZSIsIlJlYWRhYmxlU3RyZWFtIiwiXyIsImdsb2JhbHMiLCJnZXRHbG9iYWwiLCJwcm9wZXJ0eSIsInNlbGYiLCJnbG9iYWxUaGlzIiwiZ2xvYmFsUHJvcGVydGllcyIsImdsb2JhbE9iamVjdCIsImJpbmQiLCJzdXBwb3J0c0Fib3J0Q29udHJvbGxlciIsInN1cHBvcnRzU3RyZWFtcyIsInN1cHBvcnRzRm9ybURhdGEiLCJtZXJnZUhlYWRlcnMiLCJzb3VyY2UxIiwic291cmNlMiIsInJlc3VsdCIsImlzSGVhZGVyc0luc3RhbmNlIiwic291cmNlIiwiZGVlcE1lcmdlIiwic291cmNlcyIsInJlcXVlc3RNZXRob2RzIiwicmVzcG9uc2VUeXBlcyIsInRleHQiLCJyZXRyeUFmdGVyU3RhdHVzQ29kZXMiLCJzdG9wIiwiSFRUUEVycm9yIiwiVGltZW91dEVycm9yIiwiZGVsYXkiLCJtcyIsInNldFRpbWVvdXQiLCJub3JtYWxpemVSZXF1ZXN0TWV0aG9kIiwiaW5jbHVkZXMiLCJ0b1VwcGVyQ2FzZSIsImRlZmF1bHRSZXRyeU9wdGlvbnMiLCJsaW1pdCIsIm1ldGhvZHMiLCJzdGF0dXNDb2RlcyIsImFmdGVyU3RhdHVzQ29kZXMiLCJub3JtYWxpemVSZXRyeU9wdGlvbnMiLCJyZXRyeSIsIm1heFNhZmVUaW1lb3V0IiwiS3kiLCJfcmV0cnlDb3VudCIsIl9pbnB1dCIsIl9vcHRpb25zIiwiY3JlZGVudGlhbHMiLCJob29rcyIsImJlZm9yZVJlcXVlc3QiLCJiZWZvcmVSZXRyeSIsImFmdGVyUmVzcG9uc2UiLCJwcmVmaXhVcmwiLCJVUkwiLCJzdGFydHNXaXRoIiwiZW5kc1dpdGgiLCJhYm9ydENvbnRyb2xsZXIiLCJVUkxTZWFyY2hQYXJhbXMiLCJmbiIsIlJhbmdlRXJyb3IiLCJfZmV0Y2giLCJob29rIiwibW9kaWZpZWRSZXNwb25zZSIsIl9kZWNvcmF0ZVJlc3BvbnNlIiwiY2xvbmUiLCJvbkRvd25sb2FkUHJvZ3Jlc3MiLCJfc3RyZWFtIiwiX3JldHJ5IiwibWltZVR5cGUiLCJwYXJzZUpzb24iLCJfY2FsY3VsYXRlUmV0cnlEZWxheSIsInJldHJ5QWZ0ZXIiLCJhZnRlciIsIk51bWJlciIsImlzTmFOIiwibWF4UmV0cnlBZnRlciIsInJldHJ5Q291bnQiLCJ0aW1lb3V0SUQiLCJjYXRjaCIsImNsZWFyVGltZW91dCIsInRvdGFsQnl0ZXMiLCJ0cmFuc2ZlcnJlZEJ5dGVzIiwicmVhZGVyIiwiZ2V0UmVhZGVyIiwicGVyY2VudCIsImRvbmUiLCJjbG9zZSIsImVucXVldWUiLCJ2YWxpZGF0ZUFuZE1lcmdlIiwiY3JlYXRlSW5zdGFuY2UiLCJkZWZhdWx0cyIsImt5IiwibmV3RGVmYXVsdHMiLCJleHRlbmQiLCJub3JtYWxpemUiLCJzdHIiLCJqb2luZWQiLCJyZXF1aXJlIiwiaHR0cCIsImh0dHBzIiwiemxpYiIsIlN0cmVhbSIsImRhdGFVcmlUb0J1ZmZlciIsInV0aWwiLCJjcnlwdG8iLCJGZXRjaEJhc2VFcnJvciIsImNhcHR1cmVTdGFja1RyYWNlIiwiRmV0Y2hFcnJvciIsInN5c3RlbUVycm9yIiwiZXJybm8iLCJlcnJvcmVkU3lzQ2FsbCIsInN5c2NhbGwiLCJOQU1FIiwiaXNVUkxTZWFyY2hQYXJhbWV0ZXJzIiwiZ2V0QWxsIiwiaGFzIiwic29ydCIsImlzQmxvYiIsImlzRm9ybURhdGEiLCJjYXJyaWFnZSIsImRhc2hlcyIsInJlcGVhdCIsImNhcnJpYWdlTGVuZ3RoIiwiZ2V0Rm9vdGVyIiwiYm91bmRhcnkiLCJnZXRIZWFkZXIiLCJmaWVsZCIsImhlYWRlciIsIklOVEVSTkFMUyIsIkJvZHkiLCJpc0J1ZmZlciIsImlzQW55QXJyYXlCdWZmZXIiLCJyYW5kb21CeXRlcyIsImZvcm0iLCJmb3JtRGF0YUl0ZXJhdG9yIiwiZGlzdHVyYmVkIiwiYm9keVVzZWQiLCJjb25zdW1lQm9keSIsImN0IiwiYnVmIiwiYWxsb2MiLCJhY2N1bSIsImFjY3VtQnl0ZXMiLCJyZWFkYWJsZUVuZGVkIiwiX3JlYWRhYmxlU3RhdGUiLCJlbmRlZCIsImV2ZXJ5IiwiaW5zdGFuY2UiLCJwMSIsInAyIiwiZ2V0Qm91bmRhcnkiLCJQYXNzVGhyb3VnaCIsImV4dHJhY3RDb250ZW50VHlwZSIsImdldFRvdGFsQnl0ZXMiLCJnZXRMZW5ndGhTeW5jIiwiaGFzS25vd25MZW5ndGgiLCJnZXRGb3JtRGF0YUxlbmd0aCIsInZhbGlkYXRlSGVhZGVyTmFtZSIsInZhbGlkYXRlSGVhZGVyVmFsdWUiLCJpbml0IiwicmF3IiwiaXNCb3hlZFByaW1pdGl2ZSIsIml0ZXJhdG9yIiwicGFpciIsIlByb3h5IiwicCIsInJlY2VpdmVyIiwiU2V0IiwiUmVmbGVjdCIsImNhbGxiYWNrIiwiZm9yIiwicmVkaXJlY3RTdGF0dXMiLCJpc1JlZGlyZWN0IiwiSU5URVJOQUxTJDEiLCJjb3VudGVyIiwicmVkaXJlY3RlZCIsImxvY2F0aW9uIiwiSU5URVJOQUxTJDIiLCJpc1JlcXVlc3QiLCJwYXJzZWRVUkwiLCJpbnB1dEJvZHkiLCJyZWRpcmVjdCIsImZvbGxvdyIsImNvbXByZXNzIiwiYWdlbnQiLCJpbnNlY3VyZUhUVFBQYXJzZXIiLCJmb3JtYXQiLCJBYm9ydEVycm9yIiwic3VwcG9ydGVkU2NoZW1hcyIsIm9wdGlvbnNfIiwiY29udGVudExlbmd0aFZhbHVlIiwic2VhcmNoIiwibGFzdE9mZnNldCIsImhyZWYiLCJoYXNoIiwiZ2V0U2VhcmNoIiwicGF0aCIsInBhdGhuYW1lIiwiaG9zdG5hbWUiLCJwcm90b2NvbCIsInBvcnQiLCJnZXROb2RlUmVxdWVzdE9wdGlvbnMiLCJzZW5kIiwiZW1pdCIsImFib3J0QW5kRmluYWxpemUiLCJmaW5hbGl6ZSIsInJlcXVlc3RfIiwicmVzcG9uc2VfIiwiaW5kZXgiLCJhcnJheSIsImZyb21SYXdIZWFkZXJzIiwicmF3SGVhZGVycyIsInN0YXR1c0NvZGUiLCJsb2NhdGlvblVSTCIsInJlcXVlc3RPcHRpb25zIiwicGlwZWxpbmUiLCJwcm9jZXNzIiwidmVyc2lvbiIsInJlc3BvbnNlT3B0aW9ucyIsInN0YXR1c01lc3NhZ2UiLCJjb2RpbmdzIiwiemxpYk9wdGlvbnMiLCJmbHVzaCIsIlpfU1lOQ19GTFVTSCIsImZpbmlzaEZsdXNoIiwiY3JlYXRlR3VuemlwIiwiY3JlYXRlQnJvdGxpRGVjb21wcmVzcyIsImNyZWF0ZUluZmxhdGUiLCJjcmVhdGVJbmZsYXRlUmF3IiwiZGVzdCIsIndyaXRlIiwid3JpdGVUb1N0cmVhbSIsIlN5bWJvbFBvbHlmaWxsIiwiZGVzY3JpcHRpb24iLCJub29wIiwidHlwZUlzT2JqZWN0IiwicmV0aHJvd0Fzc2VydGlvbkVycm9yUmVqZWN0aW9uIiwib3JpZ2luYWxQcm9taXNlIiwib3JpZ2luYWxQcm9taXNlVGhlbiIsIm9yaWdpbmFsUHJvbWlzZVJlc29sdmUiLCJvcmlnaW5hbFByb21pc2VSZWplY3QiLCJuZXdQcm9taXNlIiwiZXhlY3V0b3IiLCJwcm9taXNlUmVzb2x2ZWRXaXRoIiwicHJvbWlzZVJlamVjdGVkV2l0aCIsInJlYXNvbiIsIlBlcmZvcm1Qcm9taXNlVGhlbiIsInByb21pc2UiLCJvbkZ1bGZpbGxlZCIsIm9uUmVqZWN0ZWQiLCJ1cG9uUHJvbWlzZSIsInVwb25GdWxmaWxsbWVudCIsInVwb25SZWplY3Rpb24iLCJ0cmFuc2Zvcm1Qcm9taXNlV2l0aCIsImZ1bGZpbGxtZW50SGFuZGxlciIsInJlamVjdGlvbkhhbmRsZXIiLCJzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlIiwicXVldWVNaWNyb3Rhc2siLCJnbG9iYWxRdWV1ZU1pY3JvdGFzayIsInJlc29sdmVkUHJvbWlzZSIsInJlZmxlY3RDYWxsIiwiRiIsIlYiLCJhcmdzIiwiRnVuY3Rpb24iLCJwcm9taXNlQ2FsbCIsIlNpbXBsZVF1ZXVlIiwiX2N1cnNvciIsIl9zaXplIiwiX2Zyb250IiwiX2VsZW1lbnRzIiwiX25leHQiLCJfYmFjayIsIm9sZEJhY2siLCJuZXdCYWNrIiwiUVVFVUVfTUFYX0FSUkFZX1NJWkUiLCJzaGlmdCIsIm9sZEZyb250IiwibmV3RnJvbnQiLCJvbGRDdXJzb3IiLCJuZXdDdXJzb3IiLCJlbGVtZW50cyIsInBlZWsiLCJmcm9udCIsImN1cnNvciIsIlJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0luaXRpYWxpemUiLCJfb3duZXJSZWFkYWJsZVN0cmVhbSIsIl9yZWFkZXIiLCJfc3RhdGUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlc29sdmUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkIiwiZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCIsIl9zdG9yZWRFcnJvciIsIlJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbCIsIlJlYWRhYmxlU3RyZWFtQ2FuY2VsIiwiUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZSIsImRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVqZWN0IiwiZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQiLCJyZWFkZXJMb2NrRXhjZXB0aW9uIiwiX2Nsb3NlZFByb21pc2UiLCJfY2xvc2VkUHJvbWlzZV9yZXNvbHZlIiwiX2Nsb3NlZFByb21pc2VfcmVqZWN0IiwiQWJvcnRTdGVwcyIsIkVycm9yU3RlcHMiLCJDYW5jZWxTdGVwcyIsIlB1bGxTdGVwcyIsIk51bWJlcklzRmluaXRlIiwiaXNGaW5pdGUiLCJNYXRoVHJ1bmMiLCJ0cnVuYyIsInYiLCJjZWlsIiwiZmxvb3IiLCJhc3NlcnREaWN0aW9uYXJ5IiwiY29udGV4dCIsImFzc2VydEZ1bmN0aW9uIiwiYXNzZXJ0T2JqZWN0IiwiYXNzZXJ0UmVxdWlyZWRBcmd1bWVudCIsImFzc2VydFJlcXVpcmVkRmllbGQiLCJjb252ZXJ0VW5yZXN0cmljdGVkRG91YmxlIiwiY2Vuc29yTmVnYXRpdmVaZXJvIiwiY29udmVydFVuc2lnbmVkTG9uZ0xvbmdXaXRoRW5mb3JjZVJhbmdlIiwidXBwZXJCb3VuZCIsIk1BWF9TQUZFX0lOVEVHRVIiLCJpbnRlZ2VyUGFydCIsImFzc2VydFJlYWRhYmxlU3RyZWFtIiwiSXNSZWFkYWJsZVN0cmVhbSIsIkFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUFkZFJlYWRSZXF1ZXN0IiwicmVhZFJlcXVlc3QiLCJfcmVhZFJlcXVlc3RzIiwiUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3QiLCJfY2xvc2VTdGVwcyIsIl9jaHVua1N0ZXBzIiwiUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMiLCJSZWFkYWJsZVN0cmVhbUhhc0RlZmF1bHRSZWFkZXIiLCJJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciIsIklzUmVhZGFibGVTdHJlYW1Mb2NrZWQiLCJjbG9zZWQiLCJkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsImNhbmNlbCIsInJlc29sdmVQcm9taXNlIiwicmVqZWN0UHJvbWlzZSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQiLCJfZXJyb3JTdGVwcyIsImUiLCJyZWxlYXNlTG9jayIsImhhc093blByb3BlcnR5IiwiX2Rpc3R1cmJlZCIsIl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIiLCJBc3luY0l0ZXJhdG9yUHJvdG90eXBlIiwiUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9ySW1wbCIsInByZXZlbnRDYW5jZWwiLCJfb25nb2luZ1Byb21pc2UiLCJfaXNGaW5pc2hlZCIsIl9wcmV2ZW50Q2FuY2VsIiwibmV4dFN0ZXBzIiwiX25leHRTdGVwcyIsInJldHVybiIsInJldHVyblN0ZXBzIiwiX3JldHVyblN0ZXBzIiwiUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlIiwiSXNSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IiLCJfYXN5bmNJdGVyYXRvckltcGwiLCJzdHJlYW1Bc3luY0l0ZXJhdG9yQnJhbmRDaGVja0V4Y2VwdGlvbiIsIl9hIiwiTnVtYmVySXNOYU4iLCJDcmVhdGVBcnJheUZyb21MaXN0IiwiQ29weURhdGFCbG9ja0J5dGVzIiwiZGVzdE9mZnNldCIsInNyYyIsInNyY09mZnNldCIsIm4iLCJBcnJheUJ1ZmZlclNsaWNlIiwiYmVnaW4iLCJDbG9uZUFzVWludDhBcnJheSIsIk8iLCJEZXF1ZXVlVmFsdWUiLCJjb250YWluZXIiLCJfcXVldWUiLCJfcXVldWVUb3RhbFNpemUiLCJFbnF1ZXVlVmFsdWVXaXRoU2l6ZSIsIkluZmluaXR5IiwiUmVzZXRRdWV1ZSIsIlJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QiLCJ2aWV3IiwiSXNSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IiwiYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uIiwiX3ZpZXciLCJyZXNwb25kIiwiYnl0ZXNXcml0dGVuIiwiX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmQiLCJyZXNwb25kV2l0aE5ld1ZpZXciLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZFdpdGhOZXdWaWV3IiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciIsImJ5b2JSZXF1ZXN0IiwiSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwiYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldEJZT0JSZXF1ZXN0IiwiZGVzaXJlZFNpemUiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyR2V0RGVzaXJlZFNpemUiLCJfY2xvc2VSZXF1ZXN0ZWQiLCJfY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbSIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZSIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyUGVuZGluZ1B1bGxJbnRvcyIsIl9jYW5jZWxBbGdvcml0aG0iLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiZW50cnkiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbiIsImF1dG9BbGxvY2F0ZUNodW5rU2l6ZSIsIl9hdXRvQWxsb2NhdGVDaHVua1NpemUiLCJidWZmZXJFIiwicHVsbEludG9EZXNjcmlwdG9yIiwiYnVmZmVyQnl0ZUxlbmd0aCIsImJ5dGVzRmlsbGVkIiwiZWxlbWVudFNpemUiLCJ2aWV3Q29uc3RydWN0b3IiLCJyZWFkZXJUeXBlIiwiX3BlbmRpbmdQdWxsSW50b3MiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCIsInNob3VsZFB1bGwiLCJfc3RhcnRlZCIsIlJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlciIsIlJlYWRhYmxlU3RyZWFtR2V0TnVtUmVhZEludG9SZXF1ZXN0cyIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaG91bGRDYWxsUHVsbCIsIl9wdWxsaW5nIiwiX3B1bGxBZ2FpbiIsIl9wdWxsQWxnb3JpdGhtIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckludmFsaWRhdGVCWU9CUmVxdWVzdCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb21taXRQdWxsSW50b0Rlc2NyaXB0b3IiLCJmaWxsZWRWaWV3IiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbnZlcnRQdWxsSW50b0Rlc2NyaXB0b3IiLCJyZWFkSW50b1JlcXVlc3QiLCJfcmVhZEludG9SZXF1ZXN0cyIsIlJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlQ2h1bmtUb1F1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxQdWxsSW50b0Rlc2NyaXB0b3JGcm9tUXVldWUiLCJjdXJyZW50QWxpZ25lZEJ5dGVzIiwibWF4Qnl0ZXNUb0NvcHkiLCJtYXhCeXRlc0ZpbGxlZCIsIm1heEFsaWduZWRCeXRlcyIsInRvdGFsQnl0ZXNUb0NvcHlSZW1haW5pbmciLCJyZWFkeSIsInF1ZXVlIiwiaGVhZE9mUXVldWUiLCJieXRlc1RvQ29weSIsImRlc3RTdGFydCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsSGVhZFB1bGxJbnRvRGVzY3JpcHRvciIsIlJlYWRhYmxlU3RyZWFtQ2xvc2UiLCJfYnlvYlJlcXVlc3QiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHJvY2Vzc1B1bGxJbnRvRGVzY3JpcHRvcnNVc2luZ1F1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclNoaWZ0UGVuZGluZ1B1bGxJbnRvIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRJbnRlcm5hbCIsImZpcnN0RGVzY3JpcHRvciIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5DbG9zZWRTdGF0ZSIsInJlbWFpbmRlclNpemUiLCJyZW1haW5kZXIiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluUmVhZGFibGVTdGF0ZSIsInRyYW5zZmVycmVkQnVmZmVyIiwiZmlyc3RQZW5kaW5nUHVsbEludG8iLCJSZWFkYWJsZVN0cmVhbUVycm9yIiwiU2V0VXBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IiwiX3N0cmF0ZWd5SFdNIiwiU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwic3RhcnRBbGdvcml0aG0iLCJwdWxsQWxnb3JpdGhtIiwiY2FuY2VsQWxnb3JpdGhtIiwiciIsIkFjcXVpcmVSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdCIsIklzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyIiwiYnlvYlJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24iLCJSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkIiwiRGF0YVZpZXciLCJCWVRFU19QRVJfRUxFTUVOVCIsImN0b3IiLCJlbXB0eVZpZXciLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8iLCJFeHRyYWN0SGlnaFdhdGVyTWFyayIsInN0cmF0ZWd5IiwiZGVmYXVsdEhXTSIsIkV4dHJhY3RTaXplQWxnb3JpdGhtIiwiY29udmVydFF1ZXVpbmdTdHJhdGVneSIsImNvbnZlcnRRdWV1aW5nU3RyYXRlZ3lTaXplIiwiY29udmVydFVuZGVybHlpbmdTaW5rQWJvcnRDYWxsYmFjayIsIm9yaWdpbmFsIiwiY29udmVydFVuZGVybHlpbmdTaW5rQ2xvc2VDYWxsYmFjayIsImNvbnZlcnRVbmRlcmx5aW5nU2lua1N0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0VW5kZXJseWluZ1NpbmtXcml0ZUNhbGxiYWNrIiwiYXNzZXJ0V3JpdGFibGVTdHJlYW0iLCJJc1dyaXRhYmxlU3RyZWFtIiwiV3JpdGFibGVTdHJlYW0iLCJyYXdVbmRlcmx5aW5nU2luayIsInJhd1N0cmF0ZWd5IiwidW5kZXJseWluZ1NpbmsiLCJjb252ZXJ0VW5kZXJseWluZ1NpbmsiLCJJbml0aWFsaXplV3JpdGFibGVTdHJlYW0iLCJzaXplQWxnb3JpdGhtIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIndyaXRlQWxnb3JpdGhtIiwiY2xvc2VBbGdvcml0aG0iLCJhYm9ydEFsZ29yaXRobSIsIlNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIlNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayIsImxvY2tlZCIsInN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMiIsIklzV3JpdGFibGVTdHJlYW1Mb2NrZWQiLCJXcml0YWJsZVN0cmVhbUFib3J0IiwiV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQiLCJXcml0YWJsZVN0cmVhbUNsb3NlIiwiZ2V0V3JpdGVyIiwiQWNxdWlyZVdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciIsIl93cml0ZXIiLCJfd3JpdGFibGVTdHJlYW1Db250cm9sbGVyIiwiX3dyaXRlUmVxdWVzdHMiLCJfaW5GbGlnaHRXcml0ZVJlcXVlc3QiLCJfY2xvc2VSZXF1ZXN0IiwiX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0IiwiX3BlbmRpbmdBYm9ydFJlcXVlc3QiLCJfYmFja3ByZXNzdXJlIiwiX2Fib3J0UmVhc29uIiwiX2Fib3J0Q29udHJvbGxlciIsIl9wcm9taXNlIiwid2FzQWxyZWFkeUVycm9yaW5nIiwiX3Jlc29sdmUiLCJfcmVqZWN0IiwiX3JlYXNvbiIsIl93YXNBbHJlYWR5RXJyb3JpbmciLCJXcml0YWJsZVN0cmVhbVN0YXJ0RXJyb3JpbmciLCJjbG9zZVJlcXVlc3QiLCJ3cml0ZXIiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSIsImNsb3NlU2VudGluZWwiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQiLCJXcml0YWJsZVN0cmVhbURlYWxXaXRoUmVqZWN0aW9uIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hFcnJvcmluZyIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZVJlYWR5UHJvbWlzZVJlamVjdGVkIiwiV3JpdGFibGVTdHJlYW1IYXNPcGVyYXRpb25NYXJrZWRJbkZsaWdodCIsInN0b3JlZEVycm9yIiwid3JpdGVSZXF1ZXN0IiwiV3JpdGFibGVTdHJlYW1SZWplY3RDbG9zZUFuZENsb3NlZFByb21pc2VJZk5lZWRlZCIsImFib3J0UmVxdWVzdCIsImRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVqZWN0IiwiV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUiLCJiYWNrcHJlc3N1cmUiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSIsImRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNldCIsIl9vd25lcldyaXRhYmxlU3RyZWFtIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCIsIklzV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyIiwiZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24iLCJkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbiIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckdldERlc2lyZWRTaXplIiwiX3JlYWR5UHJvbWlzZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckFib3J0IiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2UiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJSZWxlYXNlIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyV3JpdGUiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVDbG9zZWRQcm9taXNlUmVqZWN0ZWQiLCJfY2xvc2VkUHJvbWlzZVN0YXRlIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQiLCJfcmVhZHlQcm9taXNlU3RhdGUiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVqZWN0IiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCIsInJlbGVhc2VkRXJyb3IiLCJjaHVua1NpemUiLCJfc3RyYXRlZ3lTaXplQWxnb3JpdGhtIiwiY2h1bmtTaXplRSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldENodW5rU2l6ZSIsIldyaXRhYmxlU3RyZWFtQWRkV3JpdGVSZXF1ZXN0IiwiZW5xdWV1ZUUiLCJfY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldEJhY2twcmVzc3VyZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJXcml0ZSIsImFib3J0UmVhc29uIiwiSXNXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIiwiZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IiLCJfYWJvcnRBbGdvcml0aG0iLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiY3JlYXRlQWJvcnRDb250cm9sbGVyIiwiX3dyaXRlQWxnb3JpdGhtIiwiX2Nsb3NlQWxnb3JpdGhtIiwiV3JpdGFibGVTdHJlYW1NYXJrQ2xvc2VSZXF1ZXN0SW5GbGlnaHQiLCJzaW5rQ2xvc2VQcm9taXNlIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlV2l0aEVycm9yIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NDbG9zZSIsIldyaXRhYmxlU3RyZWFtTWFya0ZpcnN0V3JpdGVSZXF1ZXN0SW5GbGlnaHQiLCJXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0V3JpdGUiLCJXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0V3JpdGVXaXRoRXJyb3IiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc1dyaXRlIiwiX3JlYWR5UHJvbWlzZV9yZXNvbHZlIiwiX3JlYWR5UHJvbWlzZV9yZWplY3QiLCJOYXRpdmVET01FeGNlcHRpb24iLCJET01FeGNlcHRpb24iLCJET01FeGNlcHRpb24kMSIsImlzRE9NRXhjZXB0aW9uQ29uc3RydWN0b3IiLCJjcmVhdGVET01FeGNlcHRpb25Qb2x5ZmlsbCIsIlJlYWRhYmxlU3RyZWFtUGlwZVRvIiwicHJldmVudENsb3NlIiwicHJldmVudEFib3J0Iiwic2h1dHRpbmdEb3duIiwiY3VycmVudFdyaXRlIiwiYWN0aW9ucyIsInNodXRkb3duV2l0aEFjdGlvbiIsImFsbCIsImFjdGlvbiIsImlzT3JCZWNvbWVzRXJyb3JlZCIsInNodXRkb3duIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2VXaXRoRXJyb3JQcm9wYWdhdGlvbiIsImRlc3RDbG9zZWQiLCJ3YWl0Rm9yV3JpdGVzVG9GaW5pc2giLCJvbGRDdXJyZW50V3JpdGUiLCJvcmlnaW5hbElzRXJyb3IiLCJvcmlnaW5hbEVycm9yIiwiZG9UaGVSZXN0IiwibmV3RXJyb3IiLCJpc0Vycm9yIiwicmVzb2x2ZUxvb3AiLCJyZWplY3RMb29wIiwicmVzb2x2ZVJlYWQiLCJyZWplY3RSZWFkIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIklzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsImRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsIiwiU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIiwiUmVhZGFibGVTdHJlYW1UZWUiLCJjbG9uZUZvckJyYW5jaDIiLCJyZWFzb24xIiwicmVhc29uMiIsImJyYW5jaDEiLCJicmFuY2gyIiwicmVzb2x2ZUNhbmNlbFByb21pc2UiLCJyZWFkaW5nIiwiY2FuY2VsZWQxIiwiY2FuY2VsZWQyIiwiY2FuY2VsUHJvbWlzZSIsImZvcndhcmRSZWFkZXJFcnJvciIsInRoaXNSZWFkZXIiLCJwdWxsV2l0aERlZmF1bHRSZWFkZXIiLCJjaHVuazEiLCJjaHVuazIiLCJjbG9uZUUiLCJwdWxsV2l0aEJZT0JSZWFkZXIiLCJmb3JCcmFuY2gyIiwiYnlvYkJyYW5jaCIsIm90aGVyQnJhbmNoIiwiYnlvYkNhbmNlbGVkIiwiY2xvbmVkQ2h1bmsiLCJvdGhlckNhbmNlbGVkIiwicHVsbDFBbGdvcml0aG0iLCJwdWxsMkFsZ29yaXRobSIsImNhbmNlbDFBbGdvcml0aG0iLCJjb21wb3NpdGVSZWFzb24iLCJjYW5jZWxSZXN1bHQiLCJjYW5jZWwyQWxnb3JpdGhtIiwiQ3JlYXRlUmVhZGFibGVCeXRlU3RyZWFtIiwiUmVhZGFibGVCeXRlU3RyZWFtVGVlIiwiQ3JlYXRlUmVhZGFibGVTdHJlYW0iLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRUZWUiLCJjb252ZXJ0VW5kZXJseWluZ1NvdXJjZUNhbmNlbENhbGxiYWNrIiwiY29udmVydFVuZGVybHlpbmdTb3VyY2VQdWxsQ2FsbGJhY2siLCJjb252ZXJ0VW5kZXJseWluZ1NvdXJjZVN0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0UmVhZGFibGVTdHJlYW1UeXBlIiwiY29udmVydFJlYWRhYmxlU3RyZWFtUmVhZGVyTW9kZSIsIm1vZGUiLCJjb252ZXJ0UGlwZU9wdGlvbnMiLCJpc0Fib3J0U2lnbmFsIiwiYXNzZXJ0QWJvcnRTaWduYWwiLCJyYXdVbmRlcmx5aW5nU291cmNlIiwidW5kZXJseWluZ1NvdXJjZSIsInB1bGwiLCJjb252ZXJ0VW5kZXJseWluZ0RlZmF1bHRPckJ5dGVTb3VyY2UiLCJJbml0aWFsaXplUmVhZGFibGVTdHJlYW0iLCJ1bmRlcmx5aW5nQnl0ZVNvdXJjZSIsIlNldFVwUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZyb21VbmRlcmx5aW5nU291cmNlIiwiU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2UiLCJzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEiLCJyYXdPcHRpb25zIiwiY29udmVydFJlYWRlck9wdGlvbnMiLCJwaXBlVGhyb3VnaCIsInJhd1RyYW5zZm9ybSIsInRyYW5zZm9ybSIsInJlYWRhYmxlIiwiY29udmVydFJlYWRhYmxlV3JpdGFibGVQYWlyIiwicGlwZVRvIiwiZGVzdGluYXRpb24iLCJ0ZWUiLCJpbXBsIiwiQWNxdWlyZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciIsImNvbnZlcnRJdGVyYXRvck9wdGlvbnMiLCJjb252ZXJ0UXVldWluZ1N0cmF0ZWd5SW5pdCIsImFzeW5jSXRlcmF0b3IiLCJieXRlTGVuZ3RoU2l6ZUZ1bmN0aW9uIiwiQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneSIsIl9ieXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayIsIklzQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneSIsImJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uIiwiY291bnRTaXplRnVuY3Rpb24iLCJDb3VudFF1ZXVpbmdTdHJhdGVneSIsIl9jb3VudFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsiLCJJc0NvdW50UXVldWluZ1N0cmF0ZWd5IiwiY291bnRCcmFuZENoZWNrRXhjZXB0aW9uIiwiY29udmVydFRyYW5zZm9ybWVyRmx1c2hDYWxsYmFjayIsImNvbnZlcnRUcmFuc2Zvcm1lclN0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0VHJhbnNmb3JtZXJUcmFuc2Zvcm1DYWxsYmFjayIsIlRyYW5zZm9ybVN0cmVhbSIsInJhd1RyYW5zZm9ybWVyIiwicmF3V3JpdGFibGVTdHJhdGVneSIsInJhd1JlYWRhYmxlU3RyYXRlZ3kiLCJ3cml0YWJsZVN0cmF0ZWd5IiwicmVhZGFibGVTdHJhdGVneSIsInRyYW5zZm9ybWVyIiwicmVhZGFibGVUeXBlIiwid3JpdGFibGVUeXBlIiwiY29udmVydFRyYW5zZm9ybWVyIiwicmVhZGFibGVIaWdoV2F0ZXJNYXJrIiwicmVhZGFibGVTaXplQWxnb3JpdGhtIiwid3JpdGFibGVIaWdoV2F0ZXJNYXJrIiwid3JpdGFibGVTaXplQWxnb3JpdGhtIiwic3RhcnRQcm9taXNlX3Jlc29sdmUiLCJzdGFydFByb21pc2UiLCJfdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlciIsIl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlIiwiX3dyaXRhYmxlIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQZXJmb3JtVHJhbnNmb3JtIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtXcml0ZUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbUVycm9yIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtBYm9ydEFsZ29yaXRobSIsIl9yZWFkYWJsZSIsImZsdXNoUHJvbWlzZSIsIl9mbHVzaEFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtDbG9zZUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRTb3VyY2VQdWxsQWxnb3JpdGhtIiwiVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZSIsIkNyZWF0ZVdyaXRhYmxlU3RyZWFtIiwiX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSIsIkluaXRpYWxpemVUcmFuc2Zvcm1TdHJlYW0iLCJUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsInRyYW5zZm9ybUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSIsInRyYW5zZm9ybVJlc3VsdEUiLCJmbHVzaEFsZ29yaXRobSIsIl9jb250cm9sbGVkVHJhbnNmb3JtU3RyZWFtIiwiX3RyYW5zZm9ybUFsZ29yaXRobSIsIlNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIiLCJTZXRVcFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVRyYW5zZm9ybWVyIiwiSXNUcmFuc2Zvcm1TdHJlYW0iLCJzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uIiwiSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsImRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsInRlcm1pbmF0ZSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyVGVybWluYXRlIiwicmVhZGFibGVDb250cm9sbGVyIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckhhc0JhY2twcmVzc3VyZSIsIl9fd2VicGFja19tb2R1bGVfY2FjaGVfXyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsImNhY2hlZE1vZHVsZSIsImxvYWRlZCIsIl9fd2VicGFja19tb2R1bGVzX18iLCJkZWZpbml0aW9uIiwibyIsInByb3AiLCJubWQiLCJwYXRocyIsImNoaWxkcmVuIl0sInNvdXJjZVJvb3QiOiIifQ== + +/***/ }), + +/***/ 4294: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +module.exports = __nccwpck_require__(4219); + + +/***/ }), + +/***/ 4219: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +var net = __nccwpck_require__(1808); +var tls = __nccwpck_require__(4404); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var events = __nccwpck_require__(2361); +var assert = __nccwpck_require__(9491); +var util = __nccwpck_require__(3837); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port + } + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; + } + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test + + +/***/ }), + +/***/ 1773: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Client = __nccwpck_require__(3598) +const Dispatcher = __nccwpck_require__(412) +const errors = __nccwpck_require__(8045) +const Pool = __nccwpck_require__(4634) +const BalancedPool = __nccwpck_require__(7931) +const Agent = __nccwpck_require__(7890) +const util = __nccwpck_require__(3983) +const { InvalidArgumentError } = errors +const api = __nccwpck_require__(4059) +const buildConnector = __nccwpck_require__(2067) +const MockClient = __nccwpck_require__(8687) +const MockAgent = __nccwpck_require__(6771) +const MockPool = __nccwpck_require__(6193) +const mockErrors = __nccwpck_require__(888) +const ProxyAgent = __nccwpck_require__(7858) +const RetryHandler = __nccwpck_require__(2286) +const { getGlobalDispatcher, setGlobalDispatcher } = __nccwpck_require__(1892) +const DecoratorHandler = __nccwpck_require__(6930) +const RedirectHandler = __nccwpck_require__(2860) +const createRedirectInterceptor = __nccwpck_require__(8861) + +let hasCrypto +try { + __nccwpck_require__(6113) + hasCrypto = true +} catch { + hasCrypto = false +} + +Object.assign(Dispatcher.prototype, api) + +module.exports.Dispatcher = Dispatcher +module.exports.Client = Client +module.exports.Pool = Pool +module.exports.BalancedPool = BalancedPool +module.exports.Agent = Agent +module.exports.ProxyAgent = ProxyAgent +module.exports.RetryHandler = RetryHandler + +module.exports.DecoratorHandler = DecoratorHandler +module.exports.RedirectHandler = RedirectHandler +module.exports.createRedirectInterceptor = createRedirectInterceptor + +module.exports.buildConnector = buildConnector +module.exports.errors = errors + +function makeDispatcher (fn) { + return (url, opts, handler) => { + if (typeof opts === 'function') { + handler = opts + opts = null + } + + if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { + throw new InvalidArgumentError('invalid url') + } + + if (opts != null && typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (opts && opts.path != null) { + if (typeof opts.path !== 'string') { + throw new InvalidArgumentError('invalid opts.path') + } + + let path = opts.path + if (!opts.path.startsWith('/')) { + path = `/${path}` + } + + url = new URL(util.parseOrigin(url).origin + path) + } else { + if (!opts) { + opts = typeof url === 'object' ? url : {} + } + + url = util.parseURL(url) + } + + const { agent, dispatcher = getGlobalDispatcher() } = opts + + if (agent) { + throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') + } + + return fn.call(dispatcher, { + ...opts, + origin: url.origin, + path: url.search ? `${url.pathname}${url.search}` : url.pathname, + method: opts.method || (opts.body ? 'PUT' : 'GET') + }, handler) + } +} + +module.exports.setGlobalDispatcher = setGlobalDispatcher +module.exports.getGlobalDispatcher = getGlobalDispatcher + +if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) { + let fetchImpl = null + module.exports.fetch = async function fetch (resource) { + if (!fetchImpl) { + fetchImpl = (__nccwpck_require__(4881).fetch) + } + + try { + return await fetchImpl(...arguments) + } catch (err) { + if (typeof err === 'object') { + Error.captureStackTrace(err, this) + } + + throw err + } + } + module.exports.Headers = __nccwpck_require__(554).Headers + module.exports.Response = __nccwpck_require__(7823).Response + module.exports.Request = __nccwpck_require__(8359).Request + module.exports.FormData = __nccwpck_require__(2015).FormData + module.exports.File = __nccwpck_require__(8511).File + module.exports.FileReader = __nccwpck_require__(1446).FileReader + + const { setGlobalOrigin, getGlobalOrigin } = __nccwpck_require__(1246) + + module.exports.setGlobalOrigin = setGlobalOrigin + module.exports.getGlobalOrigin = getGlobalOrigin + + const { CacheStorage } = __nccwpck_require__(7907) + const { kConstruct } = __nccwpck_require__(9174) + + // Cache & CacheStorage are tightly coupled with fetch. Even if it may run + // in an older version of Node, it doesn't have any use without fetch. + module.exports.caches = new CacheStorage(kConstruct) +} + +if (util.nodeMajor >= 16) { + const { deleteCookie, getCookies, getSetCookies, setCookie } = __nccwpck_require__(1724) + + module.exports.deleteCookie = deleteCookie + module.exports.getCookies = getCookies + module.exports.getSetCookies = getSetCookies + module.exports.setCookie = setCookie + + const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) + + module.exports.parseMIMEType = parseMIMEType + module.exports.serializeAMimeType = serializeAMimeType +} + +if (util.nodeMajor >= 18 && hasCrypto) { + const { WebSocket } = __nccwpck_require__(4284) + + module.exports.WebSocket = WebSocket +} + +module.exports.request = makeDispatcher(api.request) +module.exports.stream = makeDispatcher(api.stream) +module.exports.pipeline = makeDispatcher(api.pipeline) +module.exports.connect = makeDispatcher(api.connect) +module.exports.upgrade = makeDispatcher(api.upgrade) + +module.exports.MockClient = MockClient +module.exports.MockPool = MockPool +module.exports.MockAgent = MockAgent +module.exports.mockErrors = mockErrors + + +/***/ }), + +/***/ 7890: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = __nccwpck_require__(2785) +const DispatcherBase = __nccwpck_require__(4839) +const Pool = __nccwpck_require__(4634) +const Client = __nccwpck_require__(3598) +const util = __nccwpck_require__(3983) +const createRedirectInterceptor = __nccwpck_require__(8861) +const { WeakRef, FinalizationRegistry } = __nccwpck_require__(6436)() + +const kOnConnect = Symbol('onConnect') +const kOnDisconnect = Symbol('onDisconnect') +const kOnConnectionError = Symbol('onConnectionError') +const kMaxRedirections = Symbol('maxRedirections') +const kOnDrain = Symbol('onDrain') +const kFactory = Symbol('factory') +const kFinalizer = Symbol('finalizer') +const kOptions = Symbol('options') + +function defaultFactory (origin, opts) { + return opts && opts.connections === 1 + ? new Client(origin, opts) + : new Pool(origin, opts) +} + +class Agent extends DispatcherBase { + constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + super() + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } + + if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } + + if (connect && typeof connect !== 'function') { + connect = { ...connect } + } + + this[kInterceptors] = options.interceptors && options.interceptors.Agent && Array.isArray(options.interceptors.Agent) + ? options.interceptors.Agent + : [createRedirectInterceptor({ maxRedirections })] + + this[kOptions] = { ...util.deepClone(options), connect } + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined + this[kMaxRedirections] = maxRedirections + this[kFactory] = factory + this[kClients] = new Map() + this[kFinalizer] = new FinalizationRegistry(/* istanbul ignore next: gc is undeterministic */ key => { + const ref = this[kClients].get(key) + if (ref !== undefined && ref.deref() === undefined) { + this[kClients].delete(key) + } + }) + + const agent = this + + this[kOnDrain] = (origin, targets) => { + agent.emit('drain', origin, [agent, ...targets]) + } + + this[kOnConnect] = (origin, targets) => { + agent.emit('connect', origin, [agent, ...targets]) + } + + this[kOnDisconnect] = (origin, targets, err) => { + agent.emit('disconnect', origin, [agent, ...targets], err) + } + + this[kOnConnectionError] = (origin, targets, err) => { + agent.emit('connectionError', origin, [agent, ...targets], err) + } + } + + get [kRunning] () { + let ret = 0 + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore next: gc is undeterministic */ + if (client) { + ret += client[kRunning] + } + } + return ret + } + + [kDispatch] (opts, handler) { + let key + if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { + key = String(opts.origin) + } else { + throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') + } + + const ref = this[kClients].get(key) + + let dispatcher = ref ? ref.deref() : null + if (!dispatcher) { + dispatcher = this[kFactory](opts.origin, this[kOptions]) + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) + + this[kClients].set(key, new WeakRef(dispatcher)) + this[kFinalizer].register(dispatcher, key) + } + + return dispatcher.dispatch(opts, handler) + } + + async [kClose] () { + const closePromises = [] + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore else: gc is undeterministic */ + if (client) { + closePromises.push(client.close()) + } + } + + await Promise.all(closePromises) + } + + async [kDestroy] (err) { + const destroyPromises = [] + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore else: gc is undeterministic */ + if (client) { + destroyPromises.push(client.destroy(err)) + } + } + + await Promise.all(destroyPromises) + } +} + +module.exports = Agent + + +/***/ }), + +/***/ 7032: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +const { addAbortListener } = __nccwpck_require__(3983) +const { RequestAbortedError } = __nccwpck_require__(8045) + +const kListener = Symbol('kListener') +const kSignal = Symbol('kSignal') + +function abort (self) { + if (self.abort) { + self.abort() + } else { + self.onError(new RequestAbortedError()) + } +} + +function addSignal (self, signal) { + self[kSignal] = null + self[kListener] = null + + if (!signal) { + return + } + + if (signal.aborted) { + abort(self) + return + } + + self[kSignal] = signal + self[kListener] = () => { + abort(self) + } + + addAbortListener(self[kSignal], self[kListener]) +} + +function removeSignal (self) { + if (!self[kSignal]) { + return + } + + if ('removeEventListener' in self[kSignal]) { + self[kSignal].removeEventListener('abort', self[kListener]) + } else { + self[kSignal].removeListener('abort', self[kListener]) + } + + self[kSignal] = null + self[kListener] = null +} + +module.exports = { + addSignal, + removeSignal +} + + +/***/ }), + +/***/ 9744: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { AsyncResource } = __nccwpck_require__(852) +const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { addSignal, removeSignal } = __nccwpck_require__(7032) + +class ConnectHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + const { signal, opaque, responseHeaders } = opts + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + super('UNDICI_CONNECT') + + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.callback = callback + this.abort = null + + addSignal(this, signal) + } + + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } + + this.abort = abort + this.context = context + } + + onHeaders () { + throw new SocketError('bad connect', null) + } + + onUpgrade (statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this + + removeSignal(this) + + this.callback = null + + let headers = rawHeaders + // Indicates is an HTTP2Session + if (headers != null) { + headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + } + + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + socket, + opaque, + context + }) + } + + onError (err) { + const { callback, opaque } = this + + removeSignal(this) + + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } +} + +function connect (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + connect.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const connectHandler = new ConnectHandler(opts, callback) + this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} + +module.exports = connect + + +/***/ }), + +/***/ 8752: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + Readable, + Duplex, + PassThrough +} = __nccwpck_require__(2781) +const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) +const assert = __nccwpck_require__(9491) + +const kResume = Symbol('resume') + +class PipelineRequest extends Readable { + constructor () { + super({ autoDestroy: true }) + + this[kResume] = null + } + + _read () { + const { [kResume]: resume } = this + + if (resume) { + this[kResume] = null + resume() + } + } + + _destroy (err, callback) { + this._read() + + callback(err) + } +} + +class PipelineResponse extends Readable { + constructor (resume) { + super({ autoDestroy: true }) + this[kResume] = resume + } + + _read () { + this[kResume]() + } + + _destroy (err, callback) { + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() + } + + callback(err) + } +} + +class PipelineHandler extends AsyncResource { + constructor (opts, handler) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof handler !== 'function') { + throw new InvalidArgumentError('invalid handler') + } + + const { signal, method, opaque, onInfo, responseHeaders } = opts + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_PIPELINE') + + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.handler = handler + this.abort = null + this.context = null + this.onInfo = onInfo || null + + this.req = new PipelineRequest().on('error', util.nop) + + this.ret = new Duplex({ + readableObjectMode: opts.objectMode, + autoDestroy: true, + read: () => { + const { body } = this + + if (body && body.resume) { + body.resume() + } + }, + write: (chunk, encoding, callback) => { + const { req } = this + + if (req.push(chunk, encoding) || req._readableState.destroyed) { + callback() + } else { + req[kResume] = callback + } + }, + destroy: (err, callback) => { + const { body, req, res, ret, abort } = this + + if (!err && !ret._readableState.endEmitted) { + err = new RequestAbortedError() + } + + if (abort && err) { + abort() + } + + util.destroy(body, err) + util.destroy(req, err) + util.destroy(res, err) + + removeSignal(this) + + callback(err) + } + }).on('prefinish', () => { + const { req } = this + + // Node < 15 does not call _final in same tick. + req.push(null) + }) + + this.res = null + + addSignal(this, signal) + } + + onConnect (abort, context) { + const { ret, res } = this + + assert(!res, 'pipeline cannot be retried') + + if (ret.destroyed) { + throw new RequestAbortedError() + } + + this.abort = abort + this.context = context + } + + onHeaders (statusCode, rawHeaders, resume) { + const { opaque, handler, context } = this + + if (statusCode < 200) { + if (this.onInfo) { + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + this.onInfo({ statusCode, headers }) + } + return + } + + this.res = new PipelineResponse(resume) + + let body + try { + this.handler = null + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + body = this.runInAsyncScope(handler, null, { + statusCode, + headers, + opaque, + body: this.res, + context + }) + } catch (err) { + this.res.on('error', util.nop) + throw err + } + + if (!body || typeof body.on !== 'function') { + throw new InvalidReturnValueError('expected Readable') + } + + body + .on('data', (chunk) => { + const { ret, body } = this + + if (!ret.push(chunk) && body.pause) { + body.pause() + } + }) + .on('error', (err) => { + const { ret } = this + + util.destroy(ret, err) + }) + .on('end', () => { + const { ret } = this + + ret.push(null) + }) + .on('close', () => { + const { ret } = this + + if (!ret._readableState.ended) { + util.destroy(ret, new RequestAbortedError()) + } + }) + + this.body = body + } + + onData (chunk) { + const { res } = this + return res.push(chunk) + } + + onComplete (trailers) { + const { res } = this + res.push(null) + } + + onError (err) { + const { ret } = this + this.handler = null + util.destroy(ret, err) + } +} + +function pipeline (opts, handler) { + try { + const pipelineHandler = new PipelineHandler(opts, handler) + this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler) + return pipelineHandler.ret + } catch (err) { + return new PassThrough().destroy(err) + } +} + +module.exports = pipeline + + +/***/ }), + +/***/ 5448: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Readable = __nccwpck_require__(3858) +const { + InvalidArgumentError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) + +class RequestHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts + + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) { + throw new InvalidArgumentError('invalid highWaterMark') + } + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_REQUEST') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err) + } + throw err + } + + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.res = null + this.abort = null + this.body = body + this.trailers = {} + this.context = null + this.onInfo = onInfo || null + this.throwOnError = throwOnError + this.highWaterMark = highWaterMark + + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err) + }) + } + + addSignal(this, signal) + } + + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } + + this.abort = abort + this.context = context + } + + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this + + const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }) + } + return + } + + const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers + const contentType = parsedHeaders['content-type'] + const body = new Readable({ resume, abort, contentType, highWaterMark }) + + this.callback = null + this.res = body + if (callback !== null) { + if (this.throwOnError && statusCode >= 400) { + this.runInAsyncScope(getResolveErrorBodyCallback, null, + { callback, body, contentType, statusCode, statusMessage, headers } + ) + } else { + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + trailers: this.trailers, + opaque, + body, + context + }) + } + } + } + + onData (chunk) { + const { res } = this + return res.push(chunk) + } + + onComplete (trailers) { + const { res } = this + + removeSignal(this) + + util.parseHeaders(trailers, this.trailers) + + res.push(null) + } + + onError (err) { + const { res, callback, body, opaque } = this + + removeSignal(this) + + if (callback) { + // TODO: Does this need queueMicrotask? + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + + if (res) { + this.res = null + // Ensure all queued handlers are invoked before destroying res. + queueMicrotask(() => { + util.destroy(res, err) + }) + } + + if (body) { + this.body = null + util.destroy(body, err) + } + } +} + +function request (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + request.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + this.dispatch(opts, new RequestHandler(opts, callback)) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} + +module.exports = request +module.exports.RequestHandler = RequestHandler + + +/***/ }), + +/***/ 5395: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { finished, PassThrough } = __nccwpck_require__(2781) +const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) + +class StreamHandler extends AsyncResource { + constructor (opts, factory, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts + + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('invalid factory') + } + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_STREAM') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err) + } + throw err + } + + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.factory = factory + this.callback = callback + this.res = null + this.abort = null + this.context = null + this.trailers = null + this.body = body + this.onInfo = onInfo || null + this.throwOnError = throwOnError || false + + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err) + }) + } + + addSignal(this, signal) + } + + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } + + this.abort = abort + this.context = context + } + + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const { factory, opaque, context, callback, responseHeaders } = this + + const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }) + } + return + } + + this.factory = null + + let res + + if (this.throwOnError && statusCode >= 400) { + const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers + const contentType = parsedHeaders['content-type'] + res = new PassThrough() + + this.callback = null + this.runInAsyncScope(getResolveErrorBodyCallback, null, + { callback, body: res, contentType, statusCode, statusMessage, headers } + ) + } else { + if (factory === null) { + return + } + + res = this.runInAsyncScope(factory, null, { + statusCode, + headers, + opaque, + context + }) + + if ( + !res || + typeof res.write !== 'function' || + typeof res.end !== 'function' || + typeof res.on !== 'function' + ) { + throw new InvalidReturnValueError('expected Writable') + } + + // TODO: Avoid finished. It registers an unnecessary amount of listeners. + finished(res, { readable: false }, (err) => { + const { callback, res, opaque, trailers, abort } = this + + this.res = null + if (err || !res.readable) { + util.destroy(res, err) + } + + this.callback = null + this.runInAsyncScope(callback, null, err || null, { opaque, trailers }) + + if (err) { + abort() + } + }) + } + + res.on('drain', resume) + + this.res = res + + const needDrain = res.writableNeedDrain !== undefined + ? res.writableNeedDrain + : res._writableState && res._writableState.needDrain + + return needDrain !== true + } + + onData (chunk) { + const { res } = this + + return res ? res.write(chunk) : true + } + + onComplete (trailers) { + const { res } = this + + removeSignal(this) + + if (!res) { + return + } + + this.trailers = util.parseHeaders(trailers) + + res.end() + } + + onError (err) { + const { res, callback, opaque, body } = this + + removeSignal(this) + + this.factory = null + + if (res) { + this.res = null + util.destroy(res, err) + } else if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + + if (body) { + this.body = null + util.destroy(body, err) + } + } +} + +function stream (opts, factory, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + stream.call(this, opts, factory, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + this.dispatch(opts, new StreamHandler(opts, factory, callback)) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} + +module.exports = stream + + +/***/ }), + +/***/ 6923: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) +const { AsyncResource } = __nccwpck_require__(852) +const util = __nccwpck_require__(3983) +const { addSignal, removeSignal } = __nccwpck_require__(7032) +const assert = __nccwpck_require__(9491) + +class UpgradeHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + const { signal, opaque, responseHeaders } = opts + + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + + super('UNDICI_UPGRADE') + + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.abort = null + this.context = null + + addSignal(this, signal) + } + + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } + + this.abort = abort + this.context = null + } + + onHeaders () { + throw new SocketError('bad upgrade', null) + } + + onUpgrade (statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this + + assert.strictEqual(statusCode, 101) + + removeSignal(this) + + this.callback = null + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + this.runInAsyncScope(callback, null, null, { + headers, + socket, + opaque, + context + }) + } + + onError (err) { + const { callback, opaque } = this + + removeSignal(this) + + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } +} + +function upgrade (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + upgrade.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const upgradeHandler = new UpgradeHandler(opts, callback) + this.dispatch({ + ...opts, + method: opts.method || 'GET', + upgrade: opts.protocol || 'Websocket' + }, upgradeHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} + +module.exports = upgrade + + +/***/ }), + +/***/ 4059: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +module.exports.request = __nccwpck_require__(5448) +module.exports.stream = __nccwpck_require__(5395) +module.exports.pipeline = __nccwpck_require__(8752) +module.exports.upgrade = __nccwpck_require__(6923) +module.exports.connect = __nccwpck_require__(9744) + + +/***/ }), + +/***/ 3858: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// Ported from https://github.com/nodejs/undici/pull/907 + + + +const assert = __nccwpck_require__(9491) +const { Readable } = __nccwpck_require__(2781) +const { RequestAbortedError, NotSupportedError, InvalidArgumentError } = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { ReadableStreamFrom, toUSVString } = __nccwpck_require__(3983) + +let Blob + +const kConsume = Symbol('kConsume') +const kReading = Symbol('kReading') +const kBody = Symbol('kBody') +const kAbort = Symbol('abort') +const kContentType = Symbol('kContentType') + +const noop = () => {} + +module.exports = class BodyReadable extends Readable { + constructor ({ + resume, + abort, + contentType = '', + highWaterMark = 64 * 1024 // Same as nodejs fs streams. + }) { + super({ + autoDestroy: true, + read: resume, + highWaterMark + }) + + this._readableState.dataEmitted = false + + this[kAbort] = abort + this[kConsume] = null + this[kBody] = null + this[kContentType] = contentType + + // Is stream being consumed through Readable API? + // This is an optimization so that we avoid checking + // for 'data' and 'readable' listeners in the hot path + // inside push(). + this[kReading] = false + } + + destroy (err) { + if (this.destroyed) { + // Node < 16 + return this + } + + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() + } + + if (err) { + this[kAbort]() + } + + return super.destroy(err) + } + + emit (ev, ...args) { + if (ev === 'data') { + // Node < 16.7 + this._readableState.dataEmitted = true + } else if (ev === 'error') { + // Node < 16 + this._readableState.errorEmitted = true + } + return super.emit(ev, ...args) + } + + on (ev, ...args) { + if (ev === 'data' || ev === 'readable') { + this[kReading] = true + } + return super.on(ev, ...args) + } + + addListener (ev, ...args) { + return this.on(ev, ...args) + } + + off (ev, ...args) { + const ret = super.off(ev, ...args) + if (ev === 'data' || ev === 'readable') { + this[kReading] = ( + this.listenerCount('data') > 0 || + this.listenerCount('readable') > 0 + ) + } + return ret + } + + removeListener (ev, ...args) { + return this.off(ev, ...args) + } + + push (chunk) { + if (this[kConsume] && chunk !== null && this.readableLength === 0) { + consumePush(this[kConsume], chunk) + return this[kReading] ? super.push(chunk) : true + } + return super.push(chunk) + } + + // https://fetch.spec.whatwg.org/#dom-body-text + async text () { + return consume(this, 'text') + } + + // https://fetch.spec.whatwg.org/#dom-body-json + async json () { + return consume(this, 'json') + } + + // https://fetch.spec.whatwg.org/#dom-body-blob + async blob () { + return consume(this, 'blob') + } + + // https://fetch.spec.whatwg.org/#dom-body-arraybuffer + async arrayBuffer () { + return consume(this, 'arrayBuffer') + } + + // https://fetch.spec.whatwg.org/#dom-body-formdata + async formData () { + // TODO: Implement. + throw new NotSupportedError() + } + + // https://fetch.spec.whatwg.org/#dom-body-bodyused + get bodyUsed () { + return util.isDisturbed(this) + } + + // https://fetch.spec.whatwg.org/#dom-body-body + get body () { + if (!this[kBody]) { + this[kBody] = ReadableStreamFrom(this) + if (this[kConsume]) { + // TODO: Is this the best way to force a lock? + this[kBody].getReader() // Ensure stream is locked. + assert(this[kBody].locked) + } + } + return this[kBody] + } + + dump (opts) { + let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 + const signal = opts && opts.signal + + if (signal) { + try { + if (typeof signal !== 'object' || !('aborted' in signal)) { + throw new InvalidArgumentError('signal must be an AbortSignal') + } + util.throwIfAborted(signal) + } catch (err) { + return Promise.reject(err) + } + } + + if (this.closed) { + return Promise.resolve(null) + } + + return new Promise((resolve, reject) => { + const signalListenerCleanup = signal + ? util.addAbortListener(signal, () => { + this.destroy() + }) + : noop + + this + .on('close', function () { + signalListenerCleanup() + if (signal && signal.aborted) { + reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) + } else { + resolve(null) + } + }) + .on('error', noop) + .on('data', function (chunk) { + limit -= chunk.length + if (limit <= 0) { + this.destroy() + } + }) + .resume() + }) + } +} + +// https://streams.spec.whatwg.org/#readablestream-locked +function isLocked (self) { + // Consume is an implicit lock. + return (self[kBody] && self[kBody].locked === true) || self[kConsume] +} + +// https://fetch.spec.whatwg.org/#body-unusable +function isUnusable (self) { + return util.isDisturbed(self) || isLocked(self) +} + +async function consume (stream, type) { + if (isUnusable(stream)) { + throw new TypeError('unusable') + } + + assert(!stream[kConsume]) + + return new Promise((resolve, reject) => { + stream[kConsume] = { + type, + stream, + resolve, + reject, + length: 0, + body: [] + } + + stream + .on('error', function (err) { + consumeFinish(this[kConsume], err) + }) + .on('close', function () { + if (this[kConsume].body !== null) { + consumeFinish(this[kConsume], new RequestAbortedError()) + } + }) + + process.nextTick(consumeStart, stream[kConsume]) + }) +} + +function consumeStart (consume) { + if (consume.body === null) { + return + } + + const { _readableState: state } = consume.stream + + for (const chunk of state.buffer) { + consumePush(consume, chunk) + } + + if (state.endEmitted) { + consumeEnd(this[kConsume]) + } else { + consume.stream.on('end', function () { + consumeEnd(this[kConsume]) + }) + } + + consume.stream.resume() + + while (consume.stream.read() != null) { + // Loop + } +} + +function consumeEnd (consume) { + const { type, body, resolve, stream, length } = consume + + try { + if (type === 'text') { + resolve(toUSVString(Buffer.concat(body))) + } else if (type === 'json') { + resolve(JSON.parse(Buffer.concat(body))) + } else if (type === 'arrayBuffer') { + const dst = new Uint8Array(length) + + let pos = 0 + for (const buf of body) { + dst.set(buf, pos) + pos += buf.byteLength + } + + resolve(dst.buffer) + } else if (type === 'blob') { + if (!Blob) { + Blob = (__nccwpck_require__(4300).Blob) + } + resolve(new Blob(body, { type: stream[kContentType] })) + } + + consumeFinish(consume) + } catch (err) { + stream.destroy(err) + } +} + +function consumePush (consume, chunk) { + consume.length += chunk.length + consume.body.push(chunk) +} + +function consumeFinish (consume, err) { + if (consume.body === null) { + return + } + + if (err) { + consume.reject(err) + } else { + consume.resolve() + } + + consume.type = null + consume.stream = null + consume.resolve = null + consume.reject = null + consume.length = 0 + consume.body = null +} + + +/***/ }), + +/***/ 7474: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +const assert = __nccwpck_require__(9491) +const { + ResponseStatusCodeError +} = __nccwpck_require__(8045) +const { toUSVString } = __nccwpck_require__(3983) + +async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) { + assert(body) + + let chunks = [] + let limit = 0 + + for await (const chunk of body) { + chunks.push(chunk) + limit += chunk.length + if (limit > 128 * 1024) { + chunks = null + break + } + } + + if (statusCode === 204 || !contentType || !chunks) { + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) + return + } + + try { + if (contentType.startsWith('application/json')) { + const payload = JSON.parse(toUSVString(Buffer.concat(chunks))) + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) + return + } + + if (contentType.startsWith('text/')) { + const payload = toUSVString(Buffer.concat(chunks)) + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) + return + } + } catch (err) { + // Process in a fallback if error + } + + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) +} + +module.exports = { getResolveErrorBodyCallback } + + +/***/ }), + +/***/ 7931: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + BalancedPoolMissingUpstreamError, + InvalidArgumentError +} = __nccwpck_require__(8045) +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher +} = __nccwpck_require__(3198) +const Pool = __nccwpck_require__(4634) +const { kUrl, kInterceptors } = __nccwpck_require__(2785) +const { parseOrigin } = __nccwpck_require__(3983) +const kFactory = Symbol('factory') + +const kOptions = Symbol('options') +const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor') +const kCurrentWeight = Symbol('kCurrentWeight') +const kIndex = Symbol('kIndex') +const kWeight = Symbol('kWeight') +const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') +const kErrorPenalty = Symbol('kErrorPenalty') + +function getGreatestCommonDivisor (a, b) { + if (b === 0) return a + return getGreatestCommonDivisor(b, a % b) +} + +function defaultFactory (origin, opts) { + return new Pool(origin, opts) +} + +class BalancedPool extends PoolBase { + constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) { + super() + + this[kOptions] = opts + this[kIndex] = -1 + this[kCurrentWeight] = 0 + + this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100 + this[kErrorPenalty] = this[kOptions].errorPenalty || 15 + + if (!Array.isArray(upstreams)) { + upstreams = [upstreams] + } + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + this[kInterceptors] = opts.interceptors && opts.interceptors.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) + ? opts.interceptors.BalancedPool + : [] + this[kFactory] = factory + + for (const upstream of upstreams) { + this.addUpstream(upstream) + } + this._updateBalancedPoolStats() + } + + addUpstream (upstream) { + const upstreamOrigin = parseOrigin(upstream).origin + + if (this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + ))) { + return this + } + const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])) + + this[kAddClient](pool) + pool.on('connect', () => { + pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]) + }) + + pool.on('connectionError', () => { + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() + }) + + pool.on('disconnect', (...args) => { + const err = args[2] + if (err && err.code === 'UND_ERR_SOCKET') { + // decrease the weight of the pool. + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() + } + }) + + for (const client of this[kClients]) { + client[kWeight] = this[kMaxWeightPerServer] + } + + this._updateBalancedPoolStats() + + return this + } + + _updateBalancedPoolStats () { + this[kGreatestCommonDivisor] = this[kClients].map(p => p[kWeight]).reduce(getGreatestCommonDivisor, 0) + } + + removeUpstream (upstream) { + const upstreamOrigin = parseOrigin(upstream).origin + + const pool = this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + )) + + if (pool) { + this[kRemoveClient](pool) + } + + return this + } + + get upstreams () { + return this[kClients] + .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) + .map((p) => p[kUrl].origin) + } + + [kGetDispatcher] () { + // We validate that pools is greater than 0, + // otherwise we would have to wait until an upstream + // is added, which might never happen. + if (this[kClients].length === 0) { + throw new BalancedPoolMissingUpstreamError() + } + + const dispatcher = this[kClients].find(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )) + + if (!dispatcher) { + return + } + + const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true) + + if (allClientsBusy) { + return + } + + let counter = 0 + + let maxWeightIndex = this[kClients].findIndex(pool => !pool[kNeedDrain]) + + while (counter++ < this[kClients].length) { + this[kIndex] = (this[kIndex] + 1) % this[kClients].length + const pool = this[kClients][this[kIndex]] + + // find pool index with the largest weight + if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { + maxWeightIndex = this[kIndex] + } + + // decrease the current weight every `this[kClients].length`. + if (this[kIndex] === 0) { + // Set the current weight to the next lower weight. + this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor] + + if (this[kCurrentWeight] <= 0) { + this[kCurrentWeight] = this[kMaxWeightPerServer] + } + } + if (pool[kWeight] >= this[kCurrentWeight] && (!pool[kNeedDrain])) { + return pool + } + } + + this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight] + this[kIndex] = maxWeightIndex + return this[kClients][maxWeightIndex] + } +} + +module.exports = BalancedPool + + +/***/ }), + +/***/ 6101: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { kConstruct } = __nccwpck_require__(9174) +const { urlEquals, fieldValues: getFieldValues } = __nccwpck_require__(2396) +const { kEnumerableProperty, isDisturbed } = __nccwpck_require__(3983) +const { kHeadersList } = __nccwpck_require__(2785) +const { webidl } = __nccwpck_require__(1744) +const { Response, cloneResponse } = __nccwpck_require__(7823) +const { Request } = __nccwpck_require__(8359) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const { fetching } = __nccwpck_require__(4881) +const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = __nccwpck_require__(2538) +const assert = __nccwpck_require__(9491) +const { getGlobalDispatcher } = __nccwpck_require__(1892) + +/** + * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation + * @typedef {Object} CacheBatchOperation + * @property {'delete' | 'put'} type + * @property {any} request + * @property {any} response + * @property {import('../../types/cache').CacheQueryOptions} options + */ + +/** + * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list + * @typedef {[any, any][]} requestResponseList + */ + +class Cache { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list + * @type {requestResponseList} + */ + #relevantRequestResponseList + + constructor () { + if (arguments[0] !== kConstruct) { + webidl.illegalConstructor() + } + + this.#relevantRequestResponseList = arguments[1] + } + + async match (request, options = {}) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.match' }) + + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) + + const p = await this.matchAll(request, options) + + if (p.length === 0) { + return + } + + return p[0] + } + + async matchAll (request = undefined, options = {}) { + webidl.brandCheck(this, Cache) + + if (request !== undefined) request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) + + // 1. + let r = null + + // 2. + if (request !== undefined) { + if (request instanceof Request) { + // 2.1.1 + r = request[kState] + + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { + // 2.2.1 + r = new Request(request)[kState] + } + } + + // 5. + // 5.1 + const responses = [] + + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + responses.push(requestResponse[1]) + } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) + + // 5.3.2 + for (const requestResponse of requestResponses) { + responses.push(requestResponse[1]) + } + } + + // 5.4 + // We don't implement CORs so we don't need to loop over the responses, yay! + + // 5.5.1 + const responseList = [] + + // 5.5.2 + for (const response of responses) { + // 5.5.2.1 + const responseObject = new Response(response.body?.source ?? null) + const body = responseObject[kState].body + responseObject[kState] = response + responseObject[kState].body = body + responseObject[kHeaders][kHeadersList] = response.headersList + responseObject[kHeaders][kGuard] = 'immutable' + + responseList.push(responseObject) + } + + // 6. + return Object.freeze(responseList) + } + + async add (request) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.add' }) + + request = webidl.converters.RequestInfo(request) + + // 1. + const requests = [request] + + // 2. + const responseArrayPromise = this.addAll(requests) + + // 3. + return await responseArrayPromise + } + + async addAll (requests) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.addAll' }) + + requests = webidl.converters['sequence'](requests) + + // 1. + const responsePromises = [] + + // 2. + const requestList = [] + + // 3. + for (const request of requests) { + if (typeof request === 'string') { + continue + } + + // 3.1 + const r = request[kState] + + // 3.2 + if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Expected http/s scheme when method is not GET.' + }) + } + } + + // 4. + /** @type {ReturnType[]} */ + const fetchControllers = [] + + // 5. + for (const request of requests) { + // 5.1 + const r = new Request(request)[kState] + + // 5.2 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Expected http/s scheme.' + }) + } + + // 5.4 + r.initiator = 'fetch' + r.destination = 'subresource' + + // 5.5 + requestList.push(r) + + // 5.6 + const responsePromise = createDeferredPromise() + + // 5.7 + fetchControllers.push(fetching({ + request: r, + dispatcher: getGlobalDispatcher(), + processResponse (response) { + // 1. + if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Received an invalid status code or the request failed.' + })) + } else if (response.headersList.contains('vary')) { // 2. + // 2.1 + const fieldValues = getFieldValues(response.headersList.get('vary')) + + // 2.2 + for (const fieldValue of fieldValues) { + // 2.2.1 + if (fieldValue === '*') { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'invalid vary field value' + })) + + for (const controller of fetchControllers) { + controller.abort() + } + + return + } + } + } + }, + processResponseEndOfBody (response) { + // 1. + if (response.aborted) { + responsePromise.reject(new DOMException('aborted', 'AbortError')) + return + } + + // 2. + responsePromise.resolve(response) + } + })) + + // 5.8 + responsePromises.push(responsePromise.promise) + } + + // 6. + const p = Promise.all(responsePromises) + + // 7. + const responses = await p + + // 7.1 + const operations = [] + + // 7.2 + let index = 0 + + // 7.3 + for (const response of responses) { + // 7.3.1 + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 7.3.2 + request: requestList[index], // 7.3.3 + response // 7.3.4 + } + + operations.push(operation) // 7.3.5 + + index++ // 7.3.6 + } + + // 7.5 + const cacheJobPromise = createDeferredPromise() + + // 7.6.1 + let errorData = null + + // 7.6.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e + } + + // 7.6.3 + queueMicrotask(() => { + // 7.6.3.1 + if (errorData === null) { + cacheJobPromise.resolve(undefined) + } else { + // 7.6.3.2 + cacheJobPromise.reject(errorData) + } + }) + + // 7.7 + return cacheJobPromise.promise + } + + async put (request, response) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 2, { header: 'Cache.put' }) + + request = webidl.converters.RequestInfo(request) + response = webidl.converters.Response(response) + + // 1. + let innerRequest = null + + // 2. + if (request instanceof Request) { + innerRequest = request[kState] + } else { // 3. + innerRequest = new Request(request)[kState] + } + + // 4. + if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Expected an http/s scheme when method is not GET' + }) + } + + // 5. + const innerResponse = response[kState] + + // 6. + if (innerResponse.status === 206) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Got 206 status' + }) + } + + // 7. + if (innerResponse.headersList.contains('vary')) { + // 7.1. + const fieldValues = getFieldValues(innerResponse.headersList.get('vary')) + + // 7.2. + for (const fieldValue of fieldValues) { + // 7.2.1 + if (fieldValue === '*') { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Got * vary field value' + }) + } + } + } + + // 8. + if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Response body is locked or disturbed' + }) + } + + // 9. + const clonedResponse = cloneResponse(innerResponse) + + // 10. + const bodyReadPromise = createDeferredPromise() + + // 11. + if (innerResponse.body != null) { + // 11.1 + const stream = innerResponse.body.stream + + // 11.2 + const reader = stream.getReader() + + // 11.3 + readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject) + } else { + bodyReadPromise.resolve(undefined) + } + + // 12. + /** @type {CacheBatchOperation[]} */ + const operations = [] + + // 13. + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 14. + request: innerRequest, // 15. + response: clonedResponse // 16. + } + + // 17. + operations.push(operation) + + // 19. + const bytes = await bodyReadPromise.promise + + if (clonedResponse.body != null) { + clonedResponse.body.source = bytes + } + + // 19.1 + const cacheJobPromise = createDeferredPromise() + + // 19.2.1 + let errorData = null + + // 19.2.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e + } + + // 19.2.3 + queueMicrotask(() => { + // 19.2.3.1 + if (errorData === null) { + cacheJobPromise.resolve() + } else { // 19.2.3.2 + cacheJobPromise.reject(errorData) + } + }) + + return cacheJobPromise.promise + } + + async delete (request, options = {}) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.delete' }) + + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) + + /** + * @type {Request} + */ + let r = null + + if (request instanceof Request) { + r = request[kState] + + if (r.method !== 'GET' && !options.ignoreMethod) { + return false + } + } else { + assert(typeof request === 'string') + + r = new Request(request)[kState] + } + + /** @type {CacheBatchOperation[]} */ + const operations = [] + + /** @type {CacheBatchOperation} */ + const operation = { + type: 'delete', + request: r, + options + } + + operations.push(operation) + + const cacheJobPromise = createDeferredPromise() + + let errorData = null + let requestResponses + + try { + requestResponses = this.#batchCacheOperations(operations) + } catch (e) { + errorData = e + } + + queueMicrotask(() => { + if (errorData === null) { + cacheJobPromise.resolve(!!requestResponses?.length) + } else { + cacheJobPromise.reject(errorData) + } + }) + + return cacheJobPromise.promise + } + + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys + * @param {any} request + * @param {import('../../types/cache').CacheQueryOptions} options + * @returns {readonly Request[]} + */ + async keys (request = undefined, options = {}) { + webidl.brandCheck(this, Cache) + + if (request !== undefined) request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) + + // 1. + let r = null + + // 2. + if (request !== undefined) { + // 2.1 + if (request instanceof Request) { + // 2.1.1 + r = request[kState] + + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { // 2.2 + r = new Request(request)[kState] + } + } + + // 4. + const promise = createDeferredPromise() + + // 5. + // 5.1 + const requests = [] + + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + // 5.2.1.1 + requests.push(requestResponse[0]) + } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) + + // 5.3.2 + for (const requestResponse of requestResponses) { + // 5.3.2.1 + requests.push(requestResponse[0]) + } + } + + // 5.4 + queueMicrotask(() => { + // 5.4.1 + const requestList = [] + + // 5.4.2 + for (const request of requests) { + const requestObject = new Request('https://a') + requestObject[kState] = request + requestObject[kHeaders][kHeadersList] = request.headersList + requestObject[kHeaders][kGuard] = 'immutable' + requestObject[kRealm] = request.client + + // 5.4.2.1 + requestList.push(requestObject) + } + + // 5.4.3 + promise.resolve(Object.freeze(requestList)) + }) + + return promise.promise + } + + /** + * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm + * @param {CacheBatchOperation[]} operations + * @returns {requestResponseList} + */ + #batchCacheOperations (operations) { + // 1. + const cache = this.#relevantRequestResponseList + + // 2. + const backupCache = [...cache] + + // 3. + const addedItems = [] + + // 4.1 + const resultList = [] + + try { + // 4.2 + for (const operation of operations) { + // 4.2.1 + if (operation.type !== 'delete' && operation.type !== 'put') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'operation type does not match "delete" or "put"' + }) + } + + // 4.2.2 + if (operation.type === 'delete' && operation.response != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'delete operation should not have an associated response' + }) + } + + // 4.2.3 + if (this.#queryCache(operation.request, operation.options, addedItems).length) { + throw new DOMException('???', 'InvalidStateError') + } + + // 4.2.4 + let requestResponses + + // 4.2.5 + if (operation.type === 'delete') { + // 4.2.5.1 + requestResponses = this.#queryCache(operation.request, operation.options) + + // TODO: the spec is wrong, this is needed to pass WPTs + if (requestResponses.length === 0) { + return [] + } + + // 4.2.5.2 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) + + // 4.2.5.2.1 + cache.splice(idx, 1) + } + } else if (operation.type === 'put') { // 4.2.6 + // 4.2.6.1 + if (operation.response == null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'put operation should have an associated response' + }) + } + + // 4.2.6.2 + const r = operation.request + + // 4.2.6.3 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'expected http or https scheme' + }) + } + + // 4.2.6.4 + if (r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'not get method' + }) + } + + // 4.2.6.5 + if (operation.options != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'options must not be defined' + }) + } + + // 4.2.6.6 + requestResponses = this.#queryCache(operation.request) + + // 4.2.6.7 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) + + // 4.2.6.7.1 + cache.splice(idx, 1) + } + + // 4.2.6.8 + cache.push([operation.request, operation.response]) + + // 4.2.6.10 + addedItems.push([operation.request, operation.response]) + } + + // 4.2.7 + resultList.push([operation.request, operation.response]) + } + + // 4.3 + return resultList + } catch (e) { // 5. + // 5.1 + this.#relevantRequestResponseList.length = 0 + + // 5.2 + this.#relevantRequestResponseList = backupCache + + // 5.3 + throw e + } + } + + /** + * @see https://w3c.github.io/ServiceWorker/#query-cache + * @param {any} requestQuery + * @param {import('../../types/cache').CacheQueryOptions} options + * @param {requestResponseList} targetStorage + * @returns {requestResponseList} + */ + #queryCache (requestQuery, options, targetStorage) { + /** @type {requestResponseList} */ + const resultList = [] + + const storage = targetStorage ?? this.#relevantRequestResponseList + + for (const requestResponse of storage) { + const [cachedRequest, cachedResponse] = requestResponse + if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { + resultList.push(requestResponse) + } + } + + return resultList + } + + /** + * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm + * @param {any} requestQuery + * @param {any} request + * @param {any | null} response + * @param {import('../../types/cache').CacheQueryOptions | undefined} options + * @returns {boolean} + */ + #requestMatchesCachedItem (requestQuery, request, response = null, options) { + // if (options?.ignoreMethod === false && request.method === 'GET') { + // return false + // } + + const queryURL = new URL(requestQuery.url) + + const cachedURL = new URL(request.url) + + if (options?.ignoreSearch) { + cachedURL.search = '' + + queryURL.search = '' + } + + if (!urlEquals(queryURL, cachedURL, true)) { + return false + } + + if ( + response == null || + options?.ignoreVary || + !response.headersList.contains('vary') + ) { + return true + } + + const fieldValues = getFieldValues(response.headersList.get('vary')) + + for (const fieldValue of fieldValues) { + if (fieldValue === '*') { + return false + } + + const requestValue = request.headersList.get(fieldValue) + const queryValue = requestQuery.headersList.get(fieldValue) + + // If one has the header and the other doesn't, or one has + // a different value than the other, return false + if (requestValue !== queryValue) { + return false + } + } + + return true + } +} + +Object.defineProperties(Cache.prototype, { + [Symbol.toStringTag]: { + value: 'Cache', + configurable: true + }, + match: kEnumerableProperty, + matchAll: kEnumerableProperty, + add: kEnumerableProperty, + addAll: kEnumerableProperty, + put: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty +}) + +const cacheQueryOptionConverters = [ + { + key: 'ignoreSearch', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'ignoreMethod', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'ignoreVary', + converter: webidl.converters.boolean, + defaultValue: false + } +] + +webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters) + +webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ + ...cacheQueryOptionConverters, + { + key: 'cacheName', + converter: webidl.converters.DOMString + } +]) + +webidl.converters.Response = webidl.interfaceConverter(Response) + +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.RequestInfo +) + +module.exports = { + Cache +} + + +/***/ }), + +/***/ 7907: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { kConstruct } = __nccwpck_require__(9174) +const { Cache } = __nccwpck_require__(6101) +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) + +class CacheStorage { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map + * @type {Map} + */ + async has (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.has' }) + + cacheName = webidl.converters.DOMString(cacheName) + + // 2.1.1 + // 2.2 + return this.#caches.has(cacheName) + } + + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open + * @param {string} cacheName + * @returns {Promise} + */ + async open (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.open' }) + + cacheName = webidl.converters.DOMString(cacheName) + + // 2.1 + if (this.#caches.has(cacheName)) { + // await caches.open('v1') !== await caches.open('v1') + + // 2.1.1 + const cache = this.#caches.get(cacheName) + + // 2.1.1.1 + return new Cache(kConstruct, cache) + } + + // 2.2 + const cache = [] + + // 2.3 + this.#caches.set(cacheName, cache) + + // 2.4 + return new Cache(kConstruct, cache) + } + + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete + * @param {string} cacheName + * @returns {Promise} + */ + async delete (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.delete' }) + + cacheName = webidl.converters.DOMString(cacheName) + + return this.#caches.delete(cacheName) + } + + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys + * @returns {string[]} + */ + async keys () { + webidl.brandCheck(this, CacheStorage) + + // 2.1 + const keys = this.#caches.keys() + + // 2.2 + return [...keys] + } +} + +Object.defineProperties(CacheStorage.prototype, { + [Symbol.toStringTag]: { + value: 'CacheStorage', + configurable: true + }, + match: kEnumerableProperty, + has: kEnumerableProperty, + open: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty +}) + +module.exports = { + CacheStorage +} + + +/***/ }), + +/***/ 9174: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +module.exports = { + kConstruct: (__nccwpck_require__(2785).kConstruct) +} + + +/***/ }), + +/***/ 2396: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(9491) +const { URLSerializer } = __nccwpck_require__(685) +const { isValidHeaderName } = __nccwpck_require__(2538) + +/** + * @see https://url.spec.whatwg.org/#concept-url-equals + * @param {URL} A + * @param {URL} B + * @param {boolean | undefined} excludeFragment + * @returns {boolean} + */ +function urlEquals (A, B, excludeFragment = false) { + const serializedA = URLSerializer(A, excludeFragment) + + const serializedB = URLSerializer(B, excludeFragment) + + return serializedA === serializedB +} + +/** + * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 + * @param {string} header + */ +function fieldValues (header) { + assert(header !== null) + + const values = [] + + for (let value of header.split(',')) { + value = value.trim() + + if (!value.length) { + continue + } else if (!isValidHeaderName(value)) { + continue + } + + values.push(value) + } + + return values +} + +module.exports = { + urlEquals, + fieldValues +} + + +/***/ }), + +/***/ 3598: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// @ts-check + + + +/* global WebAssembly */ + +const assert = __nccwpck_require__(9491) +const net = __nccwpck_require__(1808) +const http = __nccwpck_require__(3685) +const { pipeline } = __nccwpck_require__(2781) +const util = __nccwpck_require__(3983) +const timers = __nccwpck_require__(9459) +const Request = __nccwpck_require__(2905) +const DispatcherBase = __nccwpck_require__(4839) +const { + RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, + InvalidArgumentError, + RequestAbortedError, + HeadersTimeoutError, + HeadersOverflowError, + SocketError, + InformationalError, + BodyTimeoutError, + HTTPParserError, + ResponseExceededMaxSizeError, + ClientDestroyedError +} = __nccwpck_require__(8045) +const buildConnector = __nccwpck_require__(2067) +const { + kUrl, + kReset, + kServerName, + kClient, + kBusy, + kParser, + kConnect, + kBlocking, + kResuming, + kRunning, + kPending, + kSize, + kWriting, + kQueue, + kConnected, + kConnecting, + kNeedDrain, + kNoRef, + kKeepAliveDefaultTimeout, + kHostHeader, + kPendingIdx, + kRunningIdx, + kError, + kPipelining, + kSocket, + kKeepAliveTimeoutValue, + kMaxHeadersSize, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kHeadersTimeout, + kBodyTimeout, + kStrictContentLength, + kConnector, + kMaxRedirections, + kMaxRequests, + kCounter, + kClose, + kDestroy, + kDispatch, + kInterceptors, + kLocalAddress, + kMaxResponseSize, + kHTTPConnVersion, + // HTTP2 + kHost, + kHTTP2Session, + kHTTP2SessionState, + kHTTP2BuildRequest, + kHTTP2CopyHeaders, + kHTTP1BuildRequest +} = __nccwpck_require__(2785) + +/** @type {import('http2')} */ +let http2 +try { + http2 = __nccwpck_require__(5158) +} catch { + // @ts-ignore + http2 = { constants: {} } +} + +const { + constants: { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_SCHEME, + HTTP2_HEADER_CONTENT_LENGTH, + HTTP2_HEADER_EXPECT, + HTTP2_HEADER_STATUS + } +} = http2 + +// Experimental +let h2ExperimentalWarned = false + +const FastBuffer = Buffer[Symbol.species] + +const kClosedResolve = Symbol('kClosedResolve') + +const channels = {} + +try { + const diagnosticsChannel = __nccwpck_require__(7643) + channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders') + channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect') + channels.connectError = diagnosticsChannel.channel('undici:client:connectError') + channels.connected = diagnosticsChannel.channel('undici:client:connected') +} catch { + channels.sendHeaders = { hasSubscribers: false } + channels.beforeConnect = { hasSubscribers: false } + channels.connectError = { hasSubscribers: false } + channels.connected = { hasSubscribers: false } +} + +/** + * @type {import('../types/client').default} + */ +class Client extends DispatcherBase { + /** + * + * @param {string|URL} url + * @param {import('../types/client').Client.Options} options + */ + constructor (url, { + interceptors, + maxHeaderSize, + headersTimeout, + socketTimeout, + requestTimeout, + connectTimeout, + bodyTimeout, + idleTimeout, + keepAlive, + keepAliveTimeout, + maxKeepAliveTimeout, + keepAliveMaxTimeout, + keepAliveTimeoutThreshold, + socketPath, + pipelining, + tls, + strictContentLength, + maxCachedSessions, + maxRedirections, + connect, + maxRequestsPerClient, + localAddress, + maxResponseSize, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + // h2 + allowH2, + maxConcurrentStreams + } = {}) { + super() + + if (keepAlive !== undefined) { + throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') + } + + if (socketTimeout !== undefined) { + throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') + } + + if (requestTimeout !== undefined) { + throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') + } + + if (idleTimeout !== undefined) { + throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') + } + + if (maxKeepAliveTimeout !== undefined) { + throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') + } + + if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { + throw new InvalidArgumentError('invalid maxHeaderSize') + } + + if (socketPath != null && typeof socketPath !== 'string') { + throw new InvalidArgumentError('invalid socketPath') + } + + if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { + throw new InvalidArgumentError('invalid connectTimeout') + } + + if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveTimeout') + } + + if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveMaxTimeout') + } + + if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { + throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') + } + + if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') + } + + if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') + } + + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } + + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } + + if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { + throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') + } + + if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { + throw new InvalidArgumentError('localAddress must be valid string IP address') + } + + if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { + throw new InvalidArgumentError('maxResponseSize must be a positive number') + } + + if ( + autoSelectFamilyAttemptTimeout != null && + (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) + ) { + throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') + } + + // h2 + if (allowH2 != null && typeof allowH2 !== 'boolean') { + throw new InvalidArgumentError('allowH2 must be a valid boolean value') + } + + if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { + throw new InvalidArgumentError('maxConcurrentStreams must be a possitive integer, greater than 0') + } + + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) + } + + this[kInterceptors] = interceptors && interceptors.Client && Array.isArray(interceptors.Client) + ? interceptors.Client + : [createRedirectInterceptor({ maxRedirections })] + this[kUrl] = util.parseOrigin(url) + this[kConnector] = connect + this[kSocket] = null + this[kPipelining] = pipelining != null ? pipelining : 1 + this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize + this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout + this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout + this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold + this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout] + this[kServerName] = null + this[kLocalAddress] = localAddress != null ? localAddress : null + this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n` + this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3 + this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3 + this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength + this[kMaxRedirections] = maxRedirections + this[kMaxRequests] = maxRequestsPerClient + this[kClosedResolve] = null + this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 + this[kHTTPConnVersion] = 'h1' + + // HTTP/2 + this[kHTTP2Session] = null + this[kHTTP2SessionState] = !allowH2 + ? null + : { + // streams: null, // Fixed queue of streams - For future support of `push` + openStreams: 0, // Keep track of them to decide wether or not unref the session + maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server + } + this[kHost] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}` + + // kQueue is built up of 3 sections separated by + // the kRunningIdx and kPendingIdx indices. + // | complete | running | pending | + // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length + // kRunningIdx points to the first running element. + // kPendingIdx points to the first pending element. + // This implements a fast queue with an amortized + // time of O(1). + + this[kQueue] = [] + this[kRunningIdx] = 0 + this[kPendingIdx] = 0 + } + + get pipelining () { + return this[kPipelining] + } + + set pipelining (value) { + this[kPipelining] = value + resume(this, true) + } + + get [kPending] () { + return this[kQueue].length - this[kPendingIdx] + } + + get [kRunning] () { + return this[kPendingIdx] - this[kRunningIdx] + } + + get [kSize] () { + return this[kQueue].length - this[kRunningIdx] + } + + get [kConnected] () { + return !!this[kSocket] && !this[kConnecting] && !this[kSocket].destroyed + } + + get [kBusy] () { + const socket = this[kSocket] + return ( + (socket && (socket[kReset] || socket[kWriting] || socket[kBlocking])) || + (this[kSize] >= (this[kPipelining] || 1)) || + this[kPending] > 0 + ) + } + + /* istanbul ignore: only used for test */ + [kConnect] (cb) { + connect(this) + this.once('connect', cb) + } + + [kDispatch] (opts, handler) { + const origin = opts.origin || this[kUrl].origin + + const request = this[kHTTPConnVersion] === 'h2' + ? Request[kHTTP2BuildRequest](origin, opts, handler) + : Request[kHTTP1BuildRequest](origin, opts, handler) + + this[kQueue].push(request) + if (this[kResuming]) { + // Do nothing. + } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { + // Wait a tick in case stream/iterator is ended in the same tick. + this[kResuming] = 1 + process.nextTick(resume, this) + } else { + resume(this, true) + } + + if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { + this[kNeedDrain] = 2 + } + + return this[kNeedDrain] < 2 + } + + async [kClose] () { + // TODO: for H2 we need to gracefully flush the remaining enqueued + // request and close each stream. + return new Promise((resolve) => { + if (!this[kSize]) { + resolve(null) + } else { + this[kClosedResolve] = resolve + } + }) + } + + async [kDestroy] (err) { + return new Promise((resolve) => { + const requests = this[kQueue].splice(this[kPendingIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) + } + + const callback = () => { + if (this[kClosedResolve]) { + // TODO (fix): Should we error here with ClientDestroyedError? + this[kClosedResolve]() + this[kClosedResolve] = null + } + resolve() + } + + if (this[kHTTP2Session] != null) { + util.destroy(this[kHTTP2Session], err) + this[kHTTP2Session] = null + this[kHTTP2SessionState] = null + } + + if (!this[kSocket]) { + queueMicrotask(callback) + } else { + util.destroy(this[kSocket].on('close', callback), err) + } + + resume(this) + }) + } +} + +function onHttp2SessionError (err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + + this[kSocket][kError] = err + + onError(this[kClient], err) +} + +function onHttp2FrameError (type, code, id) { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) + + if (id === 0) { + this[kSocket][kError] = err + onError(this[kClient], err) + } +} + +function onHttp2SessionEnd () { + util.destroy(this, new SocketError('other side closed')) + util.destroy(this[kSocket], new SocketError('other side closed')) +} + +function onHTTP2GoAway (code) { + const client = this[kClient] + const err = new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${code}`) + client[kSocket] = null + client[kHTTP2Session] = null + + if (client.destroyed) { + assert(this[kPending] === 0) + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) + } + } else if (client[kRunning] > 0) { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null + + errorRequest(client, request, err) + } + + client[kPendingIdx] = client[kRunningIdx] + + assert(client[kRunning] === 0) + + client.emit('disconnect', + client[kUrl], + [client], + err + ) + + resume(client) +} + +const constants = __nccwpck_require__(953) +const createRedirectInterceptor = __nccwpck_require__(8861) +const EMPTY_BUF = Buffer.alloc(0) + +async function lazyllhttp () { + const llhttpWasmData = process.env.JEST_WORKER_ID ? __nccwpck_require__(1145) : undefined + + let mod + try { + mod = await WebAssembly.compile(Buffer.from(__nccwpck_require__(5627), 'base64')) + } catch (e) { + /* istanbul ignore next */ + + // We could check if the error was caused by the simd option not + // being enabled, but the occurring of this other error + // * https://github.com/emscripten-core/emscripten/issues/11495 + // got me to remove that check to avoid breaking Node 12. + mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || __nccwpck_require__(1145), 'base64')) + } + + return await WebAssembly.instantiate(mod, { + env: { + /* eslint-disable camelcase */ + + wasm_on_url: (p, at, len) => { + /* istanbul ignore next */ + return 0 + }, + wasm_on_status: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_message_begin: (p) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onMessageBegin() || 0 + }, + wasm_on_header_field: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_header_value: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0 + }, + wasm_on_body: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_message_complete: (p) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onMessageComplete() || 0 + } + + /* eslint-enable camelcase */ + } + }) +} + +let llhttpInstance = null +let llhttpPromise = lazyllhttp() +llhttpPromise.catch() + +let currentParser = null +let currentBufferRef = null +let currentBufferSize = 0 +let currentBufferPtr = null + +const TIMEOUT_HEADERS = 1 +const TIMEOUT_BODY = 2 +const TIMEOUT_IDLE = 3 + +class Parser { + constructor (client, socket, { exports }) { + assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0) + + this.llhttp = exports + this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE) + this.client = client + this.socket = socket + this.timeout = null + this.timeoutValue = null + this.timeoutType = null + this.statusCode = null + this.statusText = '' + this.upgrade = false + this.headers = [] + this.headersSize = 0 + this.headersMaxSize = client[kMaxHeadersSize] + this.shouldKeepAlive = false + this.paused = false + this.resume = this.resume.bind(this) + + this.bytesRead = 0 + + this.keepAlive = '' + this.contentLength = '' + this.connection = '' + this.maxResponseSize = client[kMaxResponseSize] + } + + setTimeout (value, type) { + this.timeoutType = type + if (value !== this.timeoutValue) { + timers.clearTimeout(this.timeout) + if (value) { + this.timeout = timers.setTimeout(onParserTimeout, value, this) + // istanbul ignore else: only for jest + if (this.timeout.unref) { + this.timeout.unref() + } + } else { + this.timeout = null + } + this.timeoutValue = value + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + } + + resume () { + if (this.socket.destroyed || !this.paused) { + return + } + + assert(this.ptr != null) + assert(currentParser == null) + + this.llhttp.llhttp_resume(this.ptr) + + assert(this.timeoutType === TIMEOUT_BODY) + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + + this.paused = false + this.execute(this.socket.read() || EMPTY_BUF) // Flush parser. + this.readMore() + } + + readMore () { + while (!this.paused && this.ptr) { + const chunk = this.socket.read() + if (chunk === null) { + break + } + this.execute(chunk) + } + } + + execute (data) { + assert(this.ptr != null) + assert(currentParser == null) + assert(!this.paused) + + const { socket, llhttp } = this + + if (data.length > currentBufferSize) { + if (currentBufferPtr) { + llhttp.free(currentBufferPtr) + } + currentBufferSize = Math.ceil(data.length / 4096) * 4096 + currentBufferPtr = llhttp.malloc(currentBufferSize) + } + + new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data) + + // Call `execute` on the wasm parser. + // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, + // and finally the length of bytes to parse. + // The return value is an error code or `constants.ERROR.OK`. + try { + let ret + + try { + currentBufferRef = data + currentParser = this + ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length) + /* eslint-disable-next-line no-useless-catch */ + } catch (err) { + /* istanbul ignore next: difficult to make a test case for */ + throw err + } finally { + currentParser = null + currentBufferRef = null + } + + const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr + + if (ret === constants.ERROR.PAUSED_UPGRADE) { + this.onUpgrade(data.slice(offset)) + } else if (ret === constants.ERROR.PAUSED) { + this.paused = true + socket.unshift(data.slice(offset)) + } else if (ret !== constants.ERROR.OK) { + const ptr = llhttp.llhttp_get_error_reason(this.ptr) + let message = '' + /* istanbul ignore else: difficult to make a test case for */ + if (ptr) { + const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0) + message = + 'Response does not match the HTTP/1.1 protocol (' + + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + + ')' + } + throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset)) + } + } catch (err) { + util.destroy(socket, err) + } + } + + destroy () { + assert(this.ptr != null) + assert(currentParser == null) + + this.llhttp.llhttp_free(this.ptr) + this.ptr = null + + timers.clearTimeout(this.timeout) + this.timeout = null + this.timeoutValue = null + this.timeoutType = null + + this.paused = false + } + + onStatus (buf) { + this.statusText = buf.toString() + } + + onMessageBegin () { + const { socket, client } = this + + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 + } + + const request = client[kQueue][client[kRunningIdx]] + if (!request) { + return -1 + } + } + + onHeaderField (buf) { + const len = this.headers.length + + if ((len & 1) === 0) { + this.headers.push(buf) + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + } + + this.trackHeader(buf.length) + } + + onHeaderValue (buf) { + let len = this.headers.length + + if ((len & 1) === 1) { + this.headers.push(buf) + len += 1 + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + } + + const key = this.headers[len - 2] + if (key.length === 10 && key.toString().toLowerCase() === 'keep-alive') { + this.keepAlive += buf.toString() + } else if (key.length === 10 && key.toString().toLowerCase() === 'connection') { + this.connection += buf.toString() + } else if (key.length === 14 && key.toString().toLowerCase() === 'content-length') { + this.contentLength += buf.toString() + } + + this.trackHeader(buf.length) + } + + trackHeader (len) { + this.headersSize += len + if (this.headersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) + } + } + + onUpgrade (head) { + const { upgrade, client, socket, headers, statusCode } = this + + assert(upgrade) + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + + assert(!socket.destroyed) + assert(socket === client[kSocket]) + assert(!this.paused) + assert(request.upgrade || request.method === 'CONNECT') + + this.statusCode = null + this.statusText = '' + this.shouldKeepAlive = null + + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 + + socket.unshift(head) + + socket[kParser].destroy() + socket[kParser] = null + + socket[kClient] = null + socket[kError] = null + socket + .removeListener('error', onSocketError) + .removeListener('readable', onSocketReadable) + .removeListener('end', onSocketEnd) + .removeListener('close', onSocketClose) + + client[kSocket] = null + client[kQueue][client[kRunningIdx]++] = null + client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) + + try { + request.onUpgrade(statusCode, headers, socket) + } catch (err) { + util.destroy(socket, err) + } + + resume(client) + } + + onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { + const { client, socket, headers, statusText } = this + + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 + } + + const request = client[kQueue][client[kRunningIdx]] + + /* istanbul ignore next: difficult to make a test case for */ + if (!request) { + return -1 + } + + assert(!this.upgrade) + assert(this.statusCode < 200) + + if (statusCode === 100) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) + return -1 + } + + /* this can only happen if server is misbehaving */ + if (upgrade && !request.upgrade) { + util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))) + return -1 + } + + assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS) + + this.statusCode = statusCode + this.shouldKeepAlive = ( + shouldKeepAlive || + // Override llhttp value which does not allow keepAlive for HEAD. + (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive') + ) + + if (this.statusCode >= 200) { + const bodyTimeout = request.bodyTimeout != null + ? request.bodyTimeout + : client[kBodyTimeout] + this.setTimeout(bodyTimeout, TIMEOUT_BODY) + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + + if (request.method === 'CONNECT') { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } + + if (upgrade) { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } + + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 + + if (this.shouldKeepAlive && client[kPipelining]) { + const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null + + if (keepAliveTimeout != null) { + const timeout = Math.min( + keepAliveTimeout - client[kKeepAliveTimeoutThreshold], + client[kKeepAliveMaxTimeout] + ) + if (timeout <= 0) { + socket[kReset] = true + } else { + client[kKeepAliveTimeoutValue] = timeout + } + } else { + client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] + } + } else { + // Stop more requests from being dispatched. + socket[kReset] = true + } + + const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false + + if (request.aborted) { + return -1 + } + + if (request.method === 'HEAD') { + return 1 + } + + if (statusCode < 200) { + return 1 + } + + if (socket[kBlocking]) { + socket[kBlocking] = false + resume(client) + } + + return pause ? constants.ERROR.PAUSED : 0 + } + + onBody (buf) { + const { client, socket, statusCode, maxResponseSize } = this + + if (socket.destroyed) { + return -1 + } + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + + assert.strictEqual(this.timeoutType, TIMEOUT_BODY) + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + + assert(statusCode >= 200) + + if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { + util.destroy(socket, new ResponseExceededMaxSizeError()) + return -1 + } + + this.bytesRead += buf.length + + if (request.onData(buf) === false) { + return constants.ERROR.PAUSED + } + } + + onMessageComplete () { + const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this + + if (socket.destroyed && (!statusCode || shouldKeepAlive)) { + return -1 + } + + if (upgrade) { + return + } + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + + assert(statusCode >= 100) + + this.statusCode = null + this.statusText = '' + this.bytesRead = 0 + this.contentLength = '' + this.keepAlive = '' + this.connection = '' + + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 + + if (statusCode < 200) { + return + } + + /* istanbul ignore next: should be handled by llhttp? */ + if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) { + util.destroy(socket, new ResponseContentLengthMismatchError()) + return -1 + } + + request.onComplete(headers) + + client[kQueue][client[kRunningIdx]++] = null + + if (socket[kWriting]) { + assert.strictEqual(client[kRunning], 0) + // Response completed before request. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (!shouldKeepAlive) { + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (socket[kReset] && client[kRunning] === 0) { + // Destroy socket once all requests have completed. + // The request at the tail of the pipeline is the one + // that requested reset and no further requests should + // have been queued since then. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (client[kPipelining] === 1) { + // We must wait a full event loop cycle to reuse this socket to make sure + // that non-spec compliant servers are not closing the connection even if they + // said they won't. + setImmediate(resume, client) + } else { + resume(client) + } + } +} + +function onParserTimeout (parser) { + const { socket, timeoutType, client } = parser + + /* istanbul ignore else */ + if (timeoutType === TIMEOUT_HEADERS) { + if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { + assert(!parser.paused, 'cannot be paused while waiting for headers') + util.destroy(socket, new HeadersTimeoutError()) + } + } else if (timeoutType === TIMEOUT_BODY) { + if (!parser.paused) { + util.destroy(socket, new BodyTimeoutError()) + } + } else if (timeoutType === TIMEOUT_IDLE) { + assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) + util.destroy(socket, new InformationalError('socket idle timeout')) + } +} + +function onSocketReadable () { + const { [kParser]: parser } = this + if (parser) { + parser.readMore() + } +} + +function onSocketError (err) { + const { [kClient]: client, [kParser]: parser } = this + + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + + if (client[kHTTPConnVersion] !== 'h2') { + // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded + // to the user. + if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so for as a valid response. + parser.onMessageComplete() + return + } + } + + this[kError] = err + + onError(this[kClient], err) +} + +function onError (client, err) { + if ( + client[kRunning] === 0 && + err.code !== 'UND_ERR_INFO' && + err.code !== 'UND_ERR_SOCKET' + ) { + // Error is not caused by running request and not a recoverable + // socket error. + + assert(client[kPendingIdx] === client[kRunningIdx]) + + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(client, request, err) + } + assert(client[kSize] === 0) + } +} + +function onSocketEnd () { + const { [kParser]: parser, [kClient]: client } = this + + if (client[kHTTPConnVersion] !== 'h2') { + if (parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + return + } + } + + util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) +} + +function onSocketClose () { + const { [kClient]: client, [kParser]: parser } = this + + if (client[kHTTPConnVersion] === 'h1' && parser) { + if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + } + + this[kParser].destroy() + this[kParser] = null + } + + const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) + + client[kSocket] = null + + if (client.destroyed) { + assert(client[kPending] === 0) + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(client, request, err) + } + } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null + + errorRequest(client, request, err) + } + + client[kPendingIdx] = client[kRunningIdx] + + assert(client[kRunning] === 0) + + client.emit('disconnect', client[kUrl], [client], err) + + resume(client) +} + +async function connect (client) { + assert(!client[kConnecting]) + assert(!client[kSocket]) + + let { host, hostname, protocol, port } = client[kUrl] + + // Resolve ipv6 + if (hostname[0] === '[') { + const idx = hostname.indexOf(']') + + assert(idx !== -1) + const ip = hostname.substring(1, idx) + + assert(net.isIP(ip)) + hostname = ip + } + + client[kConnecting] = true + + if (channels.beforeConnect.hasSubscribers) { + channels.beforeConnect.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector] + }) + } + + try { + const socket = await new Promise((resolve, reject) => { + client[kConnector]({ + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, (err, socket) => { + if (err) { + reject(err) + } else { + resolve(socket) + } + }) + }) + + if (client.destroyed) { + util.destroy(socket.on('error', () => {}), new ClientDestroyedError()) + return + } + + client[kConnecting] = false + + assert(socket) + + const isH2 = socket.alpnProtocol === 'h2' + if (isH2) { + if (!h2ExperimentalWarned) { + h2ExperimentalWarned = true + process.emitWarning('H2 support is experimental, expect them to change at any time.', { + code: 'UNDICI-H2' + }) + } + + const session = http2.connect(client[kUrl], { + createConnection: () => socket, + peerMaxConcurrentStreams: client[kHTTP2SessionState].maxConcurrentStreams + }) + + client[kHTTPConnVersion] = 'h2' + session[kClient] = client + session[kSocket] = socket + session.on('error', onHttp2SessionError) + session.on('frameError', onHttp2FrameError) + session.on('end', onHttp2SessionEnd) + session.on('goaway', onHTTP2GoAway) + session.on('close', onSocketClose) + session.unref() + + client[kHTTP2Session] = session + socket[kHTTP2Session] = session + } else { + if (!llhttpInstance) { + llhttpInstance = await llhttpPromise + llhttpPromise = null + } + + socket[kNoRef] = false + socket[kWriting] = false + socket[kReset] = false + socket[kBlocking] = false + socket[kParser] = new Parser(client, socket, llhttpInstance) + } + + socket[kCounter] = 0 + socket[kMaxRequests] = client[kMaxRequests] + socket[kClient] = client + socket[kError] = null + + socket + .on('error', onSocketError) + .on('readable', onSocketReadable) + .on('end', onSocketEnd) + .on('close', onSocketClose) + + client[kSocket] = socket + + if (channels.connected.hasSubscribers) { + channels.connected.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + socket + }) + } + client.emit('connect', client[kUrl], [client]) + } catch (err) { + if (client.destroyed) { + return + } + + client[kConnecting] = false + + if (channels.connectError.hasSubscribers) { + channels.connectError.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + error: err + }) + } + + if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + assert(client[kRunning] === 0) + while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { + const request = client[kQueue][client[kPendingIdx]++] + errorRequest(client, request, err) + } + } else { + onError(client, err) + } + + client.emit('connectionError', client[kUrl], [client], err) + } + + resume(client) +} + +function emitDrain (client) { + client[kNeedDrain] = 0 + client.emit('drain', client[kUrl], [client]) +} + +function resume (client, sync) { + if (client[kResuming] === 2) { + return + } + + client[kResuming] = 2 + + _resume(client, sync) + client[kResuming] = 0 + + if (client[kRunningIdx] > 256) { + client[kQueue].splice(0, client[kRunningIdx]) + client[kPendingIdx] -= client[kRunningIdx] + client[kRunningIdx] = 0 + } +} + +function _resume (client, sync) { + while (true) { + if (client.destroyed) { + assert(client[kPending] === 0) + return + } + + if (client[kClosedResolve] && !client[kSize]) { + client[kClosedResolve]() + client[kClosedResolve] = null + return + } + + const socket = client[kSocket] + + if (socket && !socket.destroyed && socket.alpnProtocol !== 'h2') { + if (client[kSize] === 0) { + if (!socket[kNoRef] && socket.unref) { + socket.unref() + socket[kNoRef] = true + } + } else if (socket[kNoRef] && socket.ref) { + socket.ref() + socket[kNoRef] = false + } + + if (client[kSize] === 0) { + if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { + socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE) + } + } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { + if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { + const request = client[kQueue][client[kRunningIdx]] + const headersTimeout = request.headersTimeout != null + ? request.headersTimeout + : client[kHeadersTimeout] + socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) + } + } + } + + if (client[kBusy]) { + client[kNeedDrain] = 2 + } else if (client[kNeedDrain] === 2) { + if (sync) { + client[kNeedDrain] = 1 + process.nextTick(emitDrain, client) + } else { + emitDrain(client) + } + continue + } + + if (client[kPending] === 0) { + return + } + + if (client[kRunning] >= (client[kPipelining] || 1)) { + return + } + + const request = client[kQueue][client[kPendingIdx]] + + if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { + if (client[kRunning] > 0) { + return + } + + client[kServerName] = request.servername + + if (socket && socket.servername !== request.servername) { + util.destroy(socket, new InformationalError('servername changed')) + return + } + } + + if (client[kConnecting]) { + return + } + + if (!socket && !client[kHTTP2Session]) { + connect(client) + return + } + + if (socket.destroyed || socket[kWriting] || socket[kReset] || socket[kBlocking]) { + return + } + + if (client[kRunning] > 0 && !request.idempotent) { + // Non-idempotent request cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return + } + + if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { + // Don't dispatch an upgrade until all preceding requests have completed. + // A misbehaving server might upgrade the connection before all pipelined + // request has completed. + return + } + + if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && + (util.isStream(request.body) || util.isAsyncIterable(request.body))) { + // Request with stream or iterator body can error while other requests + // are inflight and indirectly error those as well. + // Ensure this doesn't happen by waiting for inflight + // to complete before dispatching. + + // Request with stream or iterator body cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return + } + + if (!request.aborted && write(client, request)) { + client[kPendingIdx]++ + } else { + client[kQueue].splice(client[kPendingIdx], 1) + } + } +} + +// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 +function shouldSendContentLength (method) { + return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' +} + +function write (client, request) { + if (client[kHTTPConnVersion] === 'h2') { + writeH2(client, client[kHTTP2Session], request) + return + } + + const { body, method, path, host, upgrade, headers, blocking, reset } = request + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ) + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } + + const bodyLength = util.bodyLength(body) + + let contentLength = bodyLength + + if (contentLength === null) { + contentLength = request.contentLength + } + + if (contentLength === 0 && !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null + } + + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + errorRequest(client, request, new RequestContentLengthMismatchError()) + return false + } + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + const socket = client[kSocket] + + try { + request.onConnect((err) => { + if (request.aborted || request.completed) { + return + } + + errorRequest(client, request, err || new RequestAbortedError()) + + util.destroy(socket, new InformationalError('aborted')) + }) + } catch (err) { + errorRequest(client, request, err) + } + + if (request.aborted) { + return false + } + + if (method === 'HEAD') { + // https://github.com/mcollina/undici/issues/258 + // Close after a HEAD request to interop with misbehaving servers + // that may send a body in the response. + + socket[kReset] = true + } + + if (upgrade || method === 'CONNECT') { + // On CONNECT or upgrade, block pipeline from dispatching further + // requests on this connection. + + socket[kReset] = true + } + + if (reset != null) { + socket[kReset] = reset + } + + if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { + socket[kReset] = true + } + + if (blocking) { + socket[kBlocking] = true + } + + let header = `${method} ${path} HTTP/1.1\r\n` + + if (typeof host === 'string') { + header += `host: ${host}\r\n` + } else { + header += client[kHostHeader] + } + + if (upgrade) { + header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n` + } else if (client[kPipelining] && !socket[kReset]) { + header += 'connection: keep-alive\r\n' + } else { + header += 'connection: close\r\n' + } + + if (headers) { + header += headers + } + + if (channels.sendHeaders.hasSubscribers) { + channels.sendHeaders.publish({ request, headers: header, socket }) + } + + /* istanbul ignore else: assertion */ + if (!body || bodyLength === 0) { + if (contentLength === 0) { + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + assert(contentLength === null, 'no body must not have content length') + socket.write(`${header}\r\n`, 'latin1') + } + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') + + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(body) + socket.uncork() + request.onBodySent(body) + request.onRequestSent() + if (!expectsPayload) { + socket[kReset] = true + } + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ body: body.stream(), client, request, socket, contentLength, header, expectsPayload }) + } else { + writeBlob({ body, client, request, socket, contentLength, header, expectsPayload }) + } + } else if (util.isStream(body)) { + writeStream({ body, client, request, socket, contentLength, header, expectsPayload }) + } else if (util.isIterable(body)) { + writeIterable({ body, client, request, socket, contentLength, header, expectsPayload }) + } else { + assert(false) + } + + return true +} + +function writeH2 (client, session, request) { + const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request + + let headers + if (typeof reqHeaders === 'string') headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()) + else headers = reqHeaders + + if (upgrade) { + errorRequest(client, request, new Error('Upgrade not supported for H2')) + return false + } + + try { + // TODO(HTTP/2): Should we call onConnect immediately or on stream ready event? + request.onConnect((err) => { + if (request.aborted || request.completed) { + return + } + + errorRequest(client, request, err || new RequestAbortedError()) + }) + } catch (err) { + errorRequest(client, request, err) + } + + if (request.aborted) { + return false + } + + /** @type {import('node:http2').ClientHttp2Stream} */ + let stream + const h2State = client[kHTTP2SessionState] + + headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost] + headers[HTTP2_HEADER_METHOD] = method + + if (method === 'CONNECT') { + session.ref() + // we are already connected, streams are pending, first request + // will create a new stream. We trigger a request to create the stream and wait until + // `ready` event is triggered + // We disabled endStream to allow the user to write to the stream + stream = session.request(headers, { endStream: false, signal }) + + if (stream.id && !stream.pending) { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + } else { + stream.once('ready', () => { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + }) + } + + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) session.unref() + }) + + return true + } + + // https://tools.ietf.org/html/rfc7540#section-8.3 + // :path and :scheme headers must be omited when sending CONNECT + + headers[HTTP2_HEADER_PATH] = path + headers[HTTP2_HEADER_SCHEME] = 'https' + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ) + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } + + let contentLength = util.bodyLength(body) + + if (contentLength == null) { + contentLength = request.contentLength + } + + if (contentLength === 0 || !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null + } + + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + errorRequest(client, request, new RequestContentLengthMismatchError()) + return false + } + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + if (contentLength != null) { + assert(body, 'no body must not have content length') + headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` + } + + session.ref() + + const shouldEndStream = method === 'GET' || method === 'HEAD' + if (expectContinue) { + headers[HTTP2_HEADER_EXPECT] = '100-continue' + stream = session.request(headers, { endStream: shouldEndStream, signal }) + + stream.once('continue', writeBodyH2) + } else { + stream = session.request(headers, { + endStream: shouldEndStream, + signal + }) + writeBodyH2() + } + + // Increment counter as we have new several streams open + ++h2State.openStreams + + stream.once('response', headers => { + const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers + + if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), '') === false) { + stream.pause() + } + }) + + stream.once('end', () => { + request.onComplete([]) + }) + + stream.on('data', (chunk) => { + if (request.onData(chunk) === false) { + stream.pause() + } + }) + + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) { + session.unref() + } + }) + + stream.once('error', function (err) { + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1 + util.destroy(stream, err) + } + }) + + stream.once('frameError', (type, code) => { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) + errorRequest(client, request, err) + + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1 + util.destroy(stream, err) + } + }) + + // stream.on('aborted', () => { + // // TODO(HTTP/2): Support aborted + // }) + + // stream.on('timeout', () => { + // // TODO(HTTP/2): Support timeout + // }) + + // stream.on('push', headers => { + // // TODO(HTTP/2): Suppor push + // }) + + // stream.on('trailers', headers => { + // // TODO(HTTP/2): Support trailers + // }) + + return true + + function writeBodyH2 () { + /* istanbul ignore else: assertion */ + if (!body) { + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') + stream.cork() + stream.write(body) + stream.uncork() + stream.end() + request.onBodySent(body) + request.onRequestSent() + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ + client, + request, + contentLength, + h2stream: stream, + expectsPayload, + body: body.stream(), + socket: client[kSocket], + header: '' + }) + } else { + writeBlob({ + body, + client, + request, + contentLength, + expectsPayload, + h2stream: stream, + header: '', + socket: client[kSocket] + }) + } + } else if (util.isStream(body)) { + writeStream({ + body, + client, + request, + contentLength, + expectsPayload, + socket: client[kSocket], + h2stream: stream, + header: '' + }) + } else if (util.isIterable(body)) { + writeIterable({ + body, + client, + request, + contentLength, + expectsPayload, + header: '', + h2stream: stream, + socket: client[kSocket] + }) + } else { + assert(false) + } + } +} + +function writeStream ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') + + if (client[kHTTPConnVersion] === 'h2') { + // For HTTP/2, is enough to pipe the stream + const pipe = pipeline( + body, + h2stream, + (err) => { + if (err) { + util.destroy(body, err) + util.destroy(h2stream, err) + } else { + request.onRequestSent() + } + } + ) + + pipe.on('data', onPipeData) + pipe.once('end', () => { + pipe.removeListener('data', onPipeData) + util.destroy(pipe) + }) + + function onPipeData (chunk) { + request.onBodySent(chunk) + } + + return + } + + let finished = false + + const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) + + const onData = function (chunk) { + if (finished) { + return + } + + try { + if (!writer.write(chunk) && this.pause) { + this.pause() + } + } catch (err) { + util.destroy(this, err) + } + } + const onDrain = function () { + if (finished) { + return + } + + if (body.resume) { + body.resume() + } + } + const onAbort = function () { + if (finished) { + return + } + const err = new RequestAbortedError() + queueMicrotask(() => onFinished(err)) + } + const onFinished = function (err) { + if (finished) { + return + } + + finished = true + + assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)) + + socket + .off('drain', onDrain) + .off('error', onFinished) + + body + .removeListener('data', onData) + .removeListener('end', onFinished) + .removeListener('error', onFinished) + .removeListener('close', onAbort) + + if (!err) { + try { + writer.end() + } catch (er) { + err = er + } + } + + writer.destroy(err) + + if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { + util.destroy(body, err) + } else { + util.destroy(body) + } + } + + body + .on('data', onData) + .on('end', onFinished) + .on('error', onFinished) + .on('close', onAbort) + + if (body.resume) { + body.resume() + } + + socket + .on('drain', onDrain) + .on('error', onFinished) +} + +async function writeBlob ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength === body.size, 'blob body must have content length') + + const isH2 = client[kHTTPConnVersion] === 'h2' + try { + if (contentLength != null && contentLength !== body.size) { + throw new RequestContentLengthMismatchError() + } + + const buffer = Buffer.from(await body.arrayBuffer()) + + if (isH2) { + h2stream.cork() + h2stream.write(buffer) + h2stream.uncork() + } else { + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(buffer) + socket.uncork() + } + + request.onBodySent(buffer) + request.onRequestSent() + + if (!expectsPayload) { + socket[kReset] = true + } + + resume(client) + } catch (err) { + util.destroy(isH2 ? h2stream : socket, err) + } +} + +async function writeIterable ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') + + let callback = null + function onDrain () { + if (callback) { + const cb = callback + callback = null + cb() + } + } + + const waitForDrain = () => new Promise((resolve, reject) => { + assert(callback === null) + + if (socket[kError]) { + reject(socket[kError]) + } else { + callback = resolve + } + }) + + if (client[kHTTPConnVersion] === 'h2') { + h2stream + .on('close', onDrain) + .on('drain', onDrain) + + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + const res = h2stream.write(chunk) + request.onBodySent(chunk) + if (!res) { + await waitForDrain() + } + } + } catch (err) { + h2stream.destroy(err) + } finally { + request.onRequestSent() + h2stream.end() + h2stream + .off('close', onDrain) + .off('drain', onDrain) + } + + return + } + + socket + .on('close', onDrain) + .on('drain', onDrain) + + const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + if (!writer.write(chunk)) { + await waitForDrain() + } + } + + writer.end() + } catch (err) { + writer.destroy(err) + } finally { + socket + .off('close', onDrain) + .off('drain', onDrain) + } +} + +class AsyncWriter { + constructor ({ socket, request, contentLength, client, expectsPayload, header }) { + this.socket = socket + this.request = request + this.contentLength = contentLength + this.client = client + this.bytesWritten = 0 + this.expectsPayload = expectsPayload + this.header = header + + socket[kWriting] = true + } + + write (chunk) { + const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this + + if (socket[kError]) { + throw socket[kError] + } + + if (socket.destroyed) { + return false + } + + const len = Buffer.byteLength(chunk) + if (!len) { + return true + } + + // We should defer writing chunks. + if (contentLength !== null && bytesWritten + len > contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + socket.cork() + + if (bytesWritten === 0) { + if (!expectsPayload) { + socket[kReset] = true + } + + if (contentLength === null) { + socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1') + } else { + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + } + } + + if (contentLength === null) { + socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1') + } + + this.bytesWritten += len + + const ret = socket.write(chunk) + + socket.uncork() + + request.onBodySent(chunk) + + if (!ret) { + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } + } + } + + return ret + } + + end () { + const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this + request.onRequestSent() + + socket[kWriting] = false + + if (socket[kError]) { + throw socket[kError] + } + + if (socket.destroyed) { + return + } + + if (bytesWritten === 0) { + if (expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD send a Content-Length in a request message when + // no Transfer-Encoding is sent and the request method defines a meaning + // for an enclosed payload body. + + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + socket.write(`${header}\r\n`, 'latin1') + } + } else if (contentLength === null) { + socket.write('\r\n0\r\n\r\n', 'latin1') + } + + if (contentLength !== null && bytesWritten !== contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } else { + process.emitWarning(new RequestContentLengthMismatchError()) + } + } + + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } + } + + resume(client) + } + + destroy (err) { + const { socket, client } = this + + socket[kWriting] = false + + if (err) { + assert(client[kRunning] <= 1, 'pipeline should only contain this request') + util.destroy(socket, err) + } + } +} + +function errorRequest (client, request, err) { + try { + request.onError(err) + assert(request.aborted) + } catch (err) { + client.emit('error', err) + } +} + +module.exports = Client + + +/***/ }), + +/***/ 6436: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +/* istanbul ignore file: only for Node 12 */ + +const { kConnected, kSize } = __nccwpck_require__(2785) + +class CompatWeakRef { + constructor (value) { + this.value = value + } + + deref () { + return this.value[kConnected] === 0 && this.value[kSize] === 0 + ? undefined + : this.value + } +} + +class CompatFinalizer { + constructor (finalizer) { + this.finalizer = finalizer + } + + register (dispatcher, key) { + if (dispatcher.on) { + dispatcher.on('disconnect', () => { + if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { + this.finalizer(key) + } + }) + } + } +} + +module.exports = function () { + // FIXME: remove workaround when the Node bug is fixed + // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 + if (process.env.NODE_V8_COVERAGE) { + return { + WeakRef: CompatWeakRef, + FinalizationRegistry: CompatFinalizer + } + } + return { + WeakRef: global.WeakRef || CompatWeakRef, + FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer + } +} + + +/***/ }), + +/***/ 663: +/***/ ((module) => { + +"use strict"; + + +// https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size +const maxAttributeValueSize = 1024 + +// https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size +const maxNameValuePairSize = 4096 + +module.exports = { + maxAttributeValueSize, + maxNameValuePairSize +} + + +/***/ }), + +/***/ 1724: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { parseSetCookie } = __nccwpck_require__(4408) +const { stringify, getHeadersList } = __nccwpck_require__(3121) +const { webidl } = __nccwpck_require__(1744) +const { Headers } = __nccwpck_require__(554) + +/** + * @typedef {Object} Cookie + * @property {string} name + * @property {string} value + * @property {Date|number|undefined} expires + * @property {number|undefined} maxAge + * @property {string|undefined} domain + * @property {string|undefined} path + * @property {boolean|undefined} secure + * @property {boolean|undefined} httpOnly + * @property {'Strict'|'Lax'|'None'} sameSite + * @property {string[]} unparsed + */ + +/** + * @param {Headers} headers + * @returns {Record} + */ +function getCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, { header: 'getCookies' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + const cookie = headers.get('cookie') + const out = {} + + if (!cookie) { + return out + } + + for (const piece of cookie.split(';')) { + const [name, ...value] = piece.split('=') + + out[name.trim()] = value.join('=') + } + + return out +} + +/** + * @param {Headers} headers + * @param {string} name + * @param {{ path?: string, domain?: string }|undefined} attributes + * @returns {void} + */ +function deleteCookie (headers, name, attributes) { + webidl.argumentLengthCheck(arguments, 2, { header: 'deleteCookie' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + name = webidl.converters.DOMString(name) + attributes = webidl.converters.DeleteCookieAttributes(attributes) + + // Matches behavior of + // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 + setCookie(headers, { + name, + value: '', + expires: new Date(0), + ...attributes + }) +} + +/** + * @param {Headers} headers + * @returns {Cookie[]} + */ +function getSetCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, { header: 'getSetCookies' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + const cookies = getHeadersList(headers).cookies + + if (!cookies) { + return [] + } + + // In older versions of undici, cookies is a list of name:value. + return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair)) +} + +/** + * @param {Headers} headers + * @param {Cookie} cookie + * @returns {void} + */ +function setCookie (headers, cookie) { + webidl.argumentLengthCheck(arguments, 2, { header: 'setCookie' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + cookie = webidl.converters.Cookie(cookie) + + const str = stringify(cookie) + + if (str) { + headers.append('Set-Cookie', stringify(cookie)) + } +} + +webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: null + } +]) + +webidl.converters.Cookie = webidl.dictionaryConverter([ + { + converter: webidl.converters.DOMString, + key: 'name' + }, + { + converter: webidl.converters.DOMString, + key: 'value' + }, + { + converter: webidl.nullableConverter((value) => { + if (typeof value === 'number') { + return webidl.converters['unsigned long long'](value) + } + + return new Date(value) + }), + key: 'expires', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters['long long']), + key: 'maxAge', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'secure', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'httpOnly', + defaultValue: null + }, + { + converter: webidl.converters.USVString, + key: 'sameSite', + allowedValues: ['Strict', 'Lax', 'None'] + }, + { + converter: webidl.sequenceConverter(webidl.converters.DOMString), + key: 'unparsed', + defaultValue: [] + } +]) + +module.exports = { + getCookies, + deleteCookie, + getSetCookies, + setCookie +} + + +/***/ }), + +/***/ 4408: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { maxNameValuePairSize, maxAttributeValueSize } = __nccwpck_require__(663) +const { isCTLExcludingHtab } = __nccwpck_require__(3121) +const { collectASequenceOfCodePointsFast } = __nccwpck_require__(685) +const assert = __nccwpck_require__(9491) + +/** + * @description Parses the field-value attributes of a set-cookie header string. + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} header + * @returns if the header is invalid, null will be returned + */ +function parseSetCookie (header) { + // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F + // character (CTL characters excluding HTAB): Abort these steps and + // ignore the set-cookie-string entirely. + if (isCTLExcludingHtab(header)) { + return null + } + + let nameValuePair = '' + let unparsedAttributes = '' + let name = '' + let value = '' + + // 2. If the set-cookie-string contains a %x3B (";") character: + if (header.includes(';')) { + // 1. The name-value-pair string consists of the characters up to, + // but not including, the first %x3B (";"), and the unparsed- + // attributes consist of the remainder of the set-cookie-string + // (including the %x3B (";") in question). + const position = { position: 0 } + + nameValuePair = collectASequenceOfCodePointsFast(';', header, position) + unparsedAttributes = header.slice(position.position) + } else { + // Otherwise: + + // 1. The name-value-pair string consists of all the characters + // contained in the set-cookie-string, and the unparsed- + // attributes is the empty string. + nameValuePair = header + } + + // 3. If the name-value-pair string lacks a %x3D ("=") character, then + // the name string is empty, and the value string is the value of + // name-value-pair. + if (!nameValuePair.includes('=')) { + value = nameValuePair + } else { + // Otherwise, the name string consists of the characters up to, but + // not including, the first %x3D ("=") character, and the (possibly + // empty) value string consists of the characters after the first + // %x3D ("=") character. + const position = { position: 0 } + name = collectASequenceOfCodePointsFast( + '=', + nameValuePair, + position + ) + value = nameValuePair.slice(position.position + 1) + } + + // 4. Remove any leading or trailing WSP characters from the name + // string and the value string. + name = name.trim() + value = value.trim() + + // 5. If the sum of the lengths of the name string and the value string + // is more than 4096 octets, abort these steps and ignore the set- + // cookie-string entirely. + if (name.length + value.length > maxNameValuePairSize) { + return null + } + + // 6. The cookie-name is the name string, and the cookie-value is the + // value string. + return { + name, value, ...parseUnparsedAttributes(unparsedAttributes) + } +} + +/** + * Parses the remaining attributes of a set-cookie header + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} unparsedAttributes + * @param {[Object.]={}} cookieAttributeList + */ +function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) { + // 1. If the unparsed-attributes string is empty, skip the rest of + // these steps. + if (unparsedAttributes.length === 0) { + return cookieAttributeList + } + + // 2. Discard the first character of the unparsed-attributes (which + // will be a %x3B (";") character). + assert(unparsedAttributes[0] === ';') + unparsedAttributes = unparsedAttributes.slice(1) + + let cookieAv = '' + + // 3. If the remaining unparsed-attributes contains a %x3B (";") + // character: + if (unparsedAttributes.includes(';')) { + // 1. Consume the characters of the unparsed-attributes up to, but + // not including, the first %x3B (";") character. + cookieAv = collectASequenceOfCodePointsFast( + ';', + unparsedAttributes, + { position: 0 } + ) + unparsedAttributes = unparsedAttributes.slice(cookieAv.length) + } else { + // Otherwise: + + // 1. Consume the remainder of the unparsed-attributes. + cookieAv = unparsedAttributes + unparsedAttributes = '' + } + + // Let the cookie-av string be the characters consumed in this step. + + let attributeName = '' + let attributeValue = '' + + // 4. If the cookie-av string contains a %x3D ("=") character: + if (cookieAv.includes('=')) { + // 1. The (possibly empty) attribute-name string consists of the + // characters up to, but not including, the first %x3D ("=") + // character, and the (possibly empty) attribute-value string + // consists of the characters after the first %x3D ("=") + // character. + const position = { position: 0 } + + attributeName = collectASequenceOfCodePointsFast( + '=', + cookieAv, + position + ) + attributeValue = cookieAv.slice(position.position + 1) + } else { + // Otherwise: + + // 1. The attribute-name string consists of the entire cookie-av + // string, and the attribute-value string is empty. + attributeName = cookieAv + } + + // 5. Remove any leading or trailing WSP characters from the attribute- + // name string and the attribute-value string. + attributeName = attributeName.trim() + attributeValue = attributeValue.trim() + + // 6. If the attribute-value is longer than 1024 octets, ignore the + // cookie-av string and return to Step 1 of this algorithm. + if (attributeValue.length > maxAttributeValueSize) { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) + } + + // 7. Process the attribute-name and attribute-value according to the + // requirements in the following subsections. (Notice that + // attributes with unrecognized attribute-names are ignored.) + const attributeNameLowercase = attributeName.toLowerCase() + + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 + // If the attribute-name case-insensitively matches the string + // "Expires", the user agent MUST process the cookie-av as follows. + if (attributeNameLowercase === 'expires') { + // 1. Let the expiry-time be the result of parsing the attribute-value + // as cookie-date (see Section 5.1.1). + const expiryTime = new Date(attributeValue) + + // 2. If the attribute-value failed to parse as a cookie date, ignore + // the cookie-av. + + cookieAttributeList.expires = expiryTime + } else if (attributeNameLowercase === 'max-age') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 + // If the attribute-name case-insensitively matches the string "Max- + // Age", the user agent MUST process the cookie-av as follows. + + // 1. If the first character of the attribute-value is not a DIGIT or a + // "-" character, ignore the cookie-av. + const charCode = attributeValue.charCodeAt(0) + + if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) + } + + // 2. If the remainder of attribute-value contains a non-DIGIT + // character, ignore the cookie-av. + if (!/^\d+$/.test(attributeValue)) { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) + } + + // 3. Let delta-seconds be the attribute-value converted to an integer. + const deltaSeconds = Number(attributeValue) + + // 4. Let cookie-age-limit be the maximum age of the cookie (which + // SHOULD be 400 days or less, see Section 4.1.2.2). + + // 5. Set delta-seconds to the smaller of its present value and cookie- + // age-limit. + // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) + + // 6. If delta-seconds is less than or equal to zero (0), let expiry- + // time be the earliest representable date and time. Otherwise, let + // the expiry-time be the current date and time plus delta-seconds + // seconds. + // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds + + // 7. Append an attribute to the cookie-attribute-list with an + // attribute-name of Max-Age and an attribute-value of expiry-time. + cookieAttributeList.maxAge = deltaSeconds + } else if (attributeNameLowercase === 'domain') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 + // If the attribute-name case-insensitively matches the string "Domain", + // the user agent MUST process the cookie-av as follows. + + // 1. Let cookie-domain be the attribute-value. + let cookieDomain = attributeValue + + // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be + // cookie-domain without its leading %x2E ("."). + if (cookieDomain[0] === '.') { + cookieDomain = cookieDomain.slice(1) + } + + // 3. Convert the cookie-domain to lower case. + cookieDomain = cookieDomain.toLowerCase() + + // 4. Append an attribute to the cookie-attribute-list with an + // attribute-name of Domain and an attribute-value of cookie-domain. + cookieAttributeList.domain = cookieDomain + } else if (attributeNameLowercase === 'path') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 + // If the attribute-name case-insensitively matches the string "Path", + // the user agent MUST process the cookie-av as follows. + + // 1. If the attribute-value is empty or if the first character of the + // attribute-value is not %x2F ("/"): + let cookiePath = '' + if (attributeValue.length === 0 || attributeValue[0] !== '/') { + // 1. Let cookie-path be the default-path. + cookiePath = '/' + } else { + // Otherwise: + + // 1. Let cookie-path be the attribute-value. + cookiePath = attributeValue + } + + // 2. Append an attribute to the cookie-attribute-list with an + // attribute-name of Path and an attribute-value of cookie-path. + cookieAttributeList.path = cookiePath + } else if (attributeNameLowercase === 'secure') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 + // If the attribute-name case-insensitively matches the string "Secure", + // the user agent MUST append an attribute to the cookie-attribute-list + // with an attribute-name of Secure and an empty attribute-value. + + cookieAttributeList.secure = true + } else if (attributeNameLowercase === 'httponly') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 + // If the attribute-name case-insensitively matches the string + // "HttpOnly", the user agent MUST append an attribute to the cookie- + // attribute-list with an attribute-name of HttpOnly and an empty + // attribute-value. + + cookieAttributeList.httpOnly = true + } else if (attributeNameLowercase === 'samesite') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 + // If the attribute-name case-insensitively matches the string + // "SameSite", the user agent MUST process the cookie-av as follows: + + // 1. Let enforcement be "Default". + let enforcement = 'Default' + + const attributeValueLowercase = attributeValue.toLowerCase() + // 2. If cookie-av's attribute-value is a case-insensitive match for + // "None", set enforcement to "None". + if (attributeValueLowercase.includes('none')) { + enforcement = 'None' + } + + // 3. If cookie-av's attribute-value is a case-insensitive match for + // "Strict", set enforcement to "Strict". + if (attributeValueLowercase.includes('strict')) { + enforcement = 'Strict' + } + + // 4. If cookie-av's attribute-value is a case-insensitive match for + // "Lax", set enforcement to "Lax". + if (attributeValueLowercase.includes('lax')) { + enforcement = 'Lax' + } + + // 5. Append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of + // enforcement. + cookieAttributeList.sameSite = enforcement + } else { + cookieAttributeList.unparsed ??= [] + + cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`) + } + + // 8. Return to Step 1 of this algorithm. + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) +} + +module.exports = { + parseSetCookie, + parseUnparsedAttributes +} + + +/***/ }), + +/***/ 3121: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(9491) +const { kHeadersList } = __nccwpck_require__(2785) + +function isCTLExcludingHtab (value) { + if (value.length === 0) { + return false + } + + for (const char of value) { + const code = char.charCodeAt(0) + + if ( + (code >= 0x00 || code <= 0x08) || + (code >= 0x0A || code <= 0x1F) || + code === 0x7F + ) { + return false + } + } +} + +/** + CHAR = + token = 1* + separators = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + * @param {string} name + */ +function validateCookieName (name) { + for (const char of name) { + const code = char.charCodeAt(0) + + if ( + (code <= 0x20 || code > 0x7F) || + char === '(' || + char === ')' || + char === '>' || + char === '<' || + char === '@' || + char === ',' || + char === ';' || + char === ':' || + char === '\\' || + char === '"' || + char === '/' || + char === '[' || + char === ']' || + char === '?' || + char === '=' || + char === '{' || + char === '}' + ) { + throw new Error('Invalid cookie name') + } + } +} + +/** + cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) + cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + ; US-ASCII characters excluding CTLs, + ; whitespace DQUOTE, comma, semicolon, + ; and backslash + * @param {string} value + */ +function validateCookieValue (value) { + for (const char of value) { + const code = char.charCodeAt(0) + + if ( + code < 0x21 || // exclude CTLs (0-31) + code === 0x22 || + code === 0x2C || + code === 0x3B || + code === 0x5C || + code > 0x7E // non-ascii + ) { + throw new Error('Invalid header value') + } + } +} + +/** + * path-value = + * @param {string} path + */ +function validateCookiePath (path) { + for (const char of path) { + const code = char.charCodeAt(0) + + if (code < 0x21 || char === ';') { + throw new Error('Invalid cookie path') + } + } +} + +/** + * I have no idea why these values aren't allowed to be honest, + * but Deno tests these. - Khafra + * @param {string} domain + */ +function validateCookieDomain (domain) { + if ( + domain.startsWith('-') || + domain.endsWith('.') || + domain.endsWith('-') + ) { + throw new Error('Invalid cookie domain') + } +} + +/** + * @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.1 + * @param {number|Date} date + IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT + ; fixed length/zone/capitalization subset of the format + ; see Section 3.3 of [RFC5322] + + day-name = %x4D.6F.6E ; "Mon", case-sensitive + / %x54.75.65 ; "Tue", case-sensitive + / %x57.65.64 ; "Wed", case-sensitive + / %x54.68.75 ; "Thu", case-sensitive + / %x46.72.69 ; "Fri", case-sensitive + / %x53.61.74 ; "Sat", case-sensitive + / %x53.75.6E ; "Sun", case-sensitive + date1 = day SP month SP year + ; e.g., 02 Jun 1982 + + day = 2DIGIT + month = %x4A.61.6E ; "Jan", case-sensitive + / %x46.65.62 ; "Feb", case-sensitive + / %x4D.61.72 ; "Mar", case-sensitive + / %x41.70.72 ; "Apr", case-sensitive + / %x4D.61.79 ; "May", case-sensitive + / %x4A.75.6E ; "Jun", case-sensitive + / %x4A.75.6C ; "Jul", case-sensitive + / %x41.75.67 ; "Aug", case-sensitive + / %x53.65.70 ; "Sep", case-sensitive + / %x4F.63.74 ; "Oct", case-sensitive + / %x4E.6F.76 ; "Nov", case-sensitive + / %x44.65.63 ; "Dec", case-sensitive + year = 4DIGIT + + GMT = %x47.4D.54 ; "GMT", case-sensitive + + time-of-day = hour ":" minute ":" second + ; 00:00:00 - 23:59:60 (leap second) + + hour = 2DIGIT + minute = 2DIGIT + second = 2DIGIT + */ +function toIMFDate (date) { + if (typeof date === 'number') { + date = new Date(date) + } + + const days = [ + 'Sun', 'Mon', 'Tue', 'Wed', + 'Thu', 'Fri', 'Sat' + ] + + const months = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ] + + const dayName = days[date.getUTCDay()] + const day = date.getUTCDate().toString().padStart(2, '0') + const month = months[date.getUTCMonth()] + const year = date.getUTCFullYear() + const hour = date.getUTCHours().toString().padStart(2, '0') + const minute = date.getUTCMinutes().toString().padStart(2, '0') + const second = date.getUTCSeconds().toString().padStart(2, '0') + + return `${dayName}, ${day} ${month} ${year} ${hour}:${minute}:${second} GMT` +} + +/** + max-age-av = "Max-Age=" non-zero-digit *DIGIT + ; In practice, both expires-av and max-age-av + ; are limited to dates representable by the + ; user agent. + * @param {number} maxAge + */ +function validateCookieMaxAge (maxAge) { + if (maxAge < 0) { + throw new Error('Invalid cookie max-age') + } +} + +/** + * @see https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1 + * @param {import('./index').Cookie} cookie + */ +function stringify (cookie) { + if (cookie.name.length === 0) { + return null + } + + validateCookieName(cookie.name) + validateCookieValue(cookie.value) + + const out = [`${cookie.name}=${cookie.value}`] + + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1 + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2 + if (cookie.name.startsWith('__Secure-')) { + cookie.secure = true + } + + if (cookie.name.startsWith('__Host-')) { + cookie.secure = true + cookie.domain = null + cookie.path = '/' + } + + if (cookie.secure) { + out.push('Secure') + } + + if (cookie.httpOnly) { + out.push('HttpOnly') + } + + if (typeof cookie.maxAge === 'number') { + validateCookieMaxAge(cookie.maxAge) + out.push(`Max-Age=${cookie.maxAge}`) + } + + if (cookie.domain) { + validateCookieDomain(cookie.domain) + out.push(`Domain=${cookie.domain}`) + } + + if (cookie.path) { + validateCookiePath(cookie.path) + out.push(`Path=${cookie.path}`) + } + + if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') { + out.push(`Expires=${toIMFDate(cookie.expires)}`) + } + + if (cookie.sameSite) { + out.push(`SameSite=${cookie.sameSite}`) + } + + for (const part of cookie.unparsed) { + if (!part.includes('=')) { + throw new Error('Invalid unparsed') + } + + const [key, ...value] = part.split('=') + + out.push(`${key.trim()}=${value.join('=')}`) + } + + return out.join('; ') +} + +let kHeadersListNode + +function getHeadersList (headers) { + if (headers[kHeadersList]) { + return headers[kHeadersList] + } + + if (!kHeadersListNode) { + kHeadersListNode = Object.getOwnPropertySymbols(headers).find( + (symbol) => symbol.description === 'headers list' + ) + + assert(kHeadersListNode, 'Headers cannot be parsed') + } + + const headersList = headers[kHeadersListNode] + assert(headersList) + + return headersList +} + +module.exports = { + isCTLExcludingHtab, + stringify, + getHeadersList +} + + +/***/ }), + +/***/ 2067: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const net = __nccwpck_require__(1808) +const assert = __nccwpck_require__(9491) +const util = __nccwpck_require__(3983) +const { InvalidArgumentError, ConnectTimeoutError } = __nccwpck_require__(8045) + +let tls // include tls conditionally since it is not always available + +// TODO: session re-use does not wait for the first +// connection to resolve the session and might therefore +// resolve the same servername multiple times even when +// re-use is enabled. + +let SessionCache +// FIXME: remove workaround when the Node bug is fixed +// https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 +if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) { + SessionCache = class WeakSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + this._sessionRegistry = new global.FinalizationRegistry((key) => { + if (this._sessionCache.size < this._maxCachedSessions) { + return + } + + const ref = this._sessionCache.get(key) + if (ref !== undefined && ref.deref() === undefined) { + this._sessionCache.delete(key) + } + }) + } + + get (sessionKey) { + const ref = this._sessionCache.get(sessionKey) + return ref ? ref.deref() : null + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return + } + + this._sessionCache.set(sessionKey, new WeakRef(session)) + this._sessionRegistry.register(session, sessionKey) + } + } +} else { + SessionCache = class SimpleSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + } + + get (sessionKey) { + return this._sessionCache.get(sessionKey) + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return + } + + if (this._sessionCache.size >= this._maxCachedSessions) { + // remove the oldest session + const { value: oldestKey } = this._sessionCache.keys().next() + this._sessionCache.delete(oldestKey) + } + + this._sessionCache.set(sessionKey, session) + } + } +} + +function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, ...opts }) { + if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { + throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') + } + + const options = { path: socketPath, ...opts } + const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) + timeout = timeout == null ? 10e3 : timeout + allowH2 = allowH2 != null ? allowH2 : false + return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { + let socket + if (protocol === 'https:') { + if (!tls) { + tls = __nccwpck_require__(4404) + } + servername = servername || options.servername || util.getServerName(host) || null + + const sessionKey = servername || hostname + const session = sessionCache.get(sessionKey) || null + + assert(sessionKey) + + socket = tls.connect({ + highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... + ...options, + servername, + session, + localAddress, + // TODO(HTTP/2): Add support for h2c + ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], + socket: httpSocket, // upgrade socket connection + port: port || 443, + host: hostname + }) + + socket + .on('session', function (session) { + // TODO (fix): Can a session become invalid once established? Don't think so? + sessionCache.set(sessionKey, session) + }) + } else { + assert(!httpSocket, 'httpSocket can only be sent on TLS update') + socket = net.connect({ + highWaterMark: 64 * 1024, // Same as nodejs fs streams. + ...options, + localAddress, + port: port || 80, + host: hostname + }) + } + + // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket + if (options.keepAlive == null || options.keepAlive) { + const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay + socket.setKeepAlive(true, keepAliveInitialDelay) + } + + const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout) + + socket + .setNoDelay(true) + .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { + cancelTimeout() + + if (callback) { + const cb = callback + callback = null + cb(null, this) + } + }) + .on('error', function (err) { + cancelTimeout() + + if (callback) { + const cb = callback + callback = null + cb(err) + } + }) + + return socket + } +} + +function setupTimeout (onConnectTimeout, timeout) { + if (!timeout) { + return () => {} + } + + let s1 = null + let s2 = null + const timeoutId = setTimeout(() => { + // setImmediate is added to make sure that we priotorise socket error events over timeouts + s1 = setImmediate(() => { + if (process.platform === 'win32') { + // Windows needs an extra setImmediate probably due to implementation differences in the socket logic + s2 = setImmediate(() => onConnectTimeout()) + } else { + onConnectTimeout() + } + }) + }, timeout) + return () => { + clearTimeout(timeoutId) + clearImmediate(s1) + clearImmediate(s2) + } +} + +function onConnectTimeout (socket) { + util.destroy(socket, new ConnectTimeoutError()) +} + +module.exports = buildConnector + + +/***/ }), + +/***/ 8045: +/***/ ((module) => { + +"use strict"; + + +class UndiciError extends Error { + constructor (message) { + super(message) + this.name = 'UndiciError' + this.code = 'UND_ERR' + } +} + +class ConnectTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ConnectTimeoutError) + this.name = 'ConnectTimeoutError' + this.message = message || 'Connect Timeout Error' + this.code = 'UND_ERR_CONNECT_TIMEOUT' + } +} + +class HeadersTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, HeadersTimeoutError) + this.name = 'HeadersTimeoutError' + this.message = message || 'Headers Timeout Error' + this.code = 'UND_ERR_HEADERS_TIMEOUT' + } +} + +class HeadersOverflowError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, HeadersOverflowError) + this.name = 'HeadersOverflowError' + this.message = message || 'Headers Overflow Error' + this.code = 'UND_ERR_HEADERS_OVERFLOW' + } +} + +class BodyTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, BodyTimeoutError) + this.name = 'BodyTimeoutError' + this.message = message || 'Body Timeout Error' + this.code = 'UND_ERR_BODY_TIMEOUT' + } +} + +class ResponseStatusCodeError extends UndiciError { + constructor (message, statusCode, headers, body) { + super(message) + Error.captureStackTrace(this, ResponseStatusCodeError) + this.name = 'ResponseStatusCodeError' + this.message = message || 'Response Status Code Error' + this.code = 'UND_ERR_RESPONSE_STATUS_CODE' + this.body = body + this.status = statusCode + this.statusCode = statusCode + this.headers = headers + } +} + +class InvalidArgumentError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InvalidArgumentError) + this.name = 'InvalidArgumentError' + this.message = message || 'Invalid Argument Error' + this.code = 'UND_ERR_INVALID_ARG' + } +} + +class InvalidReturnValueError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InvalidReturnValueError) + this.name = 'InvalidReturnValueError' + this.message = message || 'Invalid Return Value Error' + this.code = 'UND_ERR_INVALID_RETURN_VALUE' + } +} + +class RequestAbortedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, RequestAbortedError) + this.name = 'AbortError' + this.message = message || 'Request aborted' + this.code = 'UND_ERR_ABORTED' + } +} + +class InformationalError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InformationalError) + this.name = 'InformationalError' + this.message = message || 'Request information' + this.code = 'UND_ERR_INFO' + } +} + +class RequestContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, RequestContentLengthMismatchError) + this.name = 'RequestContentLengthMismatchError' + this.message = message || 'Request body length does not match content-length header' + this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' + } +} + +class ResponseContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ResponseContentLengthMismatchError) + this.name = 'ResponseContentLengthMismatchError' + this.message = message || 'Response body length does not match content-length header' + this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' + } +} + +class ClientDestroyedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ClientDestroyedError) + this.name = 'ClientDestroyedError' + this.message = message || 'The client is destroyed' + this.code = 'UND_ERR_DESTROYED' + } +} + +class ClientClosedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ClientClosedError) + this.name = 'ClientClosedError' + this.message = message || 'The client is closed' + this.code = 'UND_ERR_CLOSED' + } +} + +class SocketError extends UndiciError { + constructor (message, socket) { + super(message) + Error.captureStackTrace(this, SocketError) + this.name = 'SocketError' + this.message = message || 'Socket error' + this.code = 'UND_ERR_SOCKET' + this.socket = socket + } +} + +class NotSupportedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, NotSupportedError) + this.name = 'NotSupportedError' + this.message = message || 'Not supported error' + this.code = 'UND_ERR_NOT_SUPPORTED' + } +} + +class BalancedPoolMissingUpstreamError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, NotSupportedError) + this.name = 'MissingUpstreamError' + this.message = message || 'No upstream has been added to the BalancedPool' + this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' + } +} + +class HTTPParserError extends Error { + constructor (message, code, data) { + super(message) + Error.captureStackTrace(this, HTTPParserError) + this.name = 'HTTPParserError' + this.code = code ? `HPE_${code}` : undefined + this.data = data ? data.toString() : undefined + } +} + +class ResponseExceededMaxSizeError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ResponseExceededMaxSizeError) + this.name = 'ResponseExceededMaxSizeError' + this.message = message || 'Response content exceeded max size' + this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' + } +} + +class RequestRetryError extends UndiciError { + constructor (message, code, { headers, data }) { + super(message) + Error.captureStackTrace(this, RequestRetryError) + this.name = 'RequestRetryError' + this.message = message || 'Request retry error' + this.code = 'UND_ERR_REQ_RETRY' + this.statusCode = code + this.data = data + this.headers = headers + } +} + +module.exports = { + HTTPParserError, + UndiciError, + HeadersTimeoutError, + HeadersOverflowError, + BodyTimeoutError, + RequestContentLengthMismatchError, + ConnectTimeoutError, + ResponseStatusCodeError, + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError, + ClientDestroyedError, + ClientClosedError, + InformationalError, + SocketError, + NotSupportedError, + ResponseContentLengthMismatchError, + BalancedPoolMissingUpstreamError, + ResponseExceededMaxSizeError, + RequestRetryError +} + + +/***/ }), + +/***/ 2905: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + InvalidArgumentError, + NotSupportedError +} = __nccwpck_require__(8045) +const assert = __nccwpck_require__(9491) +const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = __nccwpck_require__(2785) +const util = __nccwpck_require__(3983) + +// tokenRegExp and headerCharRegex have been lifted from +// https://github.com/nodejs/node/blob/main/lib/_http_common.js + +/** + * Verifies that the given val is a valid HTTP token + * per the rules defined in RFC 7230 + * See https://tools.ietf.org/html/rfc7230#section-3.2.6 + */ +const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/ + +/** + * Matches if val contains an invalid field-vchar + * field-value = *( field-content / obs-fold ) + * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + * field-vchar = VCHAR / obs-text + */ +const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/ + +// Verifies that a given path is valid does not contain control chars \x00 to \x20 +const invalidPathRegex = /[^\u0021-\u00ff]/ + +const kHandler = Symbol('handler') + +const channels = {} + +let extractBody + +try { + const diagnosticsChannel = __nccwpck_require__(7643) + channels.create = diagnosticsChannel.channel('undici:request:create') + channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent') + channels.headers = diagnosticsChannel.channel('undici:request:headers') + channels.trailers = diagnosticsChannel.channel('undici:request:trailers') + channels.error = diagnosticsChannel.channel('undici:request:error') +} catch { + channels.create = { hasSubscribers: false } + channels.bodySent = { hasSubscribers: false } + channels.headers = { hasSubscribers: false } + channels.trailers = { hasSubscribers: false } + channels.error = { hasSubscribers: false } +} + +class Request { + constructor (origin, { + path, + method, + body, + headers, + query, + idempotent, + blocking, + upgrade, + headersTimeout, + bodyTimeout, + reset, + throwOnError, + expectContinue + }, handler) { + if (typeof path !== 'string') { + throw new InvalidArgumentError('path must be a string') + } else if ( + path[0] !== '/' && + !(path.startsWith('http://') || path.startsWith('https://')) && + method !== 'CONNECT' + ) { + throw new InvalidArgumentError('path must be an absolute URL or start with a slash') + } else if (invalidPathRegex.exec(path) !== null) { + throw new InvalidArgumentError('invalid request path') + } + + if (typeof method !== 'string') { + throw new InvalidArgumentError('method must be a string') + } else if (tokenRegExp.exec(method) === null) { + throw new InvalidArgumentError('invalid request method') + } + + if (upgrade && typeof upgrade !== 'string') { + throw new InvalidArgumentError('upgrade must be a string') + } + + if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('invalid headersTimeout') + } + + if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('invalid bodyTimeout') + } + + if (reset != null && typeof reset !== 'boolean') { + throw new InvalidArgumentError('invalid reset') + } + + if (expectContinue != null && typeof expectContinue !== 'boolean') { + throw new InvalidArgumentError('invalid expectContinue') + } + + this.headersTimeout = headersTimeout + + this.bodyTimeout = bodyTimeout + + this.throwOnError = throwOnError === true + + this.method = method + + this.abort = null + + if (body == null) { + this.body = null + } else if (util.isStream(body)) { + this.body = body + + const rState = this.body._readableState + if (!rState || !rState.autoDestroy) { + this.endHandler = function autoDestroy () { + util.destroy(this) + } + this.body.on('end', this.endHandler) + } + + this.errorHandler = err => { + if (this.abort) { + this.abort(err) + } else { + this.error = err + } + } + this.body.on('error', this.errorHandler) + } else if (util.isBuffer(body)) { + this.body = body.byteLength ? body : null + } else if (ArrayBuffer.isView(body)) { + this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null + } else if (body instanceof ArrayBuffer) { + this.body = body.byteLength ? Buffer.from(body) : null + } else if (typeof body === 'string') { + this.body = body.length ? Buffer.from(body) : null + } else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) { + this.body = body + } else { + throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') + } + + this.completed = false + + this.aborted = false + + this.upgrade = upgrade || null + + this.path = query ? util.buildURL(path, query) : path + + this.origin = origin + + this.idempotent = idempotent == null + ? method === 'HEAD' || method === 'GET' + : idempotent + + this.blocking = blocking == null ? false : blocking + + this.reset = reset == null ? null : reset + + this.host = null + + this.contentLength = null + + this.contentType = null + + this.headers = '' + + // Only for H2 + this.expectContinue = expectContinue != null ? expectContinue : false + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(this, headers[i], headers[i + 1]) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(this, key, headers[key]) + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') + } + + if (util.isFormDataLike(this.body)) { + if (util.nodeMajor < 16 || (util.nodeMajor === 16 && util.nodeMinor < 8)) { + throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.') + } + + if (!extractBody) { + extractBody = (__nccwpck_require__(1472).extractBody) + } + + const [bodyStream, contentType] = extractBody(body) + if (this.contentType == null) { + this.contentType = contentType + this.headers += `content-type: ${contentType}\r\n` + } + this.body = bodyStream.stream + this.contentLength = bodyStream.length + } else if (util.isBlobLike(body) && this.contentType == null && body.type) { + this.contentType = body.type + this.headers += `content-type: ${body.type}\r\n` + } + + util.validateHandler(handler, method, upgrade) + + this.servername = util.getServerName(this.host) + + this[kHandler] = handler + + if (channels.create.hasSubscribers) { + channels.create.publish({ request: this }) + } + } + + onBodySent (chunk) { + if (this[kHandler].onBodySent) { + try { + return this[kHandler].onBodySent(chunk) + } catch (err) { + this.abort(err) + } + } + } + + onRequestSent () { + if (channels.bodySent.hasSubscribers) { + channels.bodySent.publish({ request: this }) + } + + if (this[kHandler].onRequestSent) { + try { + return this[kHandler].onRequestSent() + } catch (err) { + this.abort(err) + } + } + } + + onConnect (abort) { + assert(!this.aborted) + assert(!this.completed) + + if (this.error) { + abort(this.error) + } else { + this.abort = abort + return this[kHandler].onConnect(abort) + } + } + + onHeaders (statusCode, headers, resume, statusText) { + assert(!this.aborted) + assert(!this.completed) + + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) + } + + try { + return this[kHandler].onHeaders(statusCode, headers, resume, statusText) + } catch (err) { + this.abort(err) + } + } + + onData (chunk) { + assert(!this.aborted) + assert(!this.completed) + + try { + return this[kHandler].onData(chunk) + } catch (err) { + this.abort(err) + return false + } + } + + onUpgrade (statusCode, headers, socket) { + assert(!this.aborted) + assert(!this.completed) + + return this[kHandler].onUpgrade(statusCode, headers, socket) + } + + onComplete (trailers) { + this.onFinally() + + assert(!this.aborted) + + this.completed = true + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers }) + } + + try { + return this[kHandler].onComplete(trailers) + } catch (err) { + // TODO (fix): This might be a bad idea? + this.onError(err) + } + } + + onError (error) { + this.onFinally() + + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error }) + } + + if (this.aborted) { + return + } + this.aborted = true + + return this[kHandler].onError(error) + } + + onFinally () { + if (this.errorHandler) { + this.body.off('error', this.errorHandler) + this.errorHandler = null + } + + if (this.endHandler) { + this.body.off('end', this.endHandler) + this.endHandler = null + } + } + + // TODO: adjust to support H2 + addHeader (key, value) { + processHeader(this, key, value) + return this + } + + static [kHTTP1BuildRequest] (origin, opts, handler) { + // TODO: Migrate header parsing here, to make Requests + // HTTP agnostic + return new Request(origin, opts, handler) + } + + static [kHTTP2BuildRequest] (origin, opts, handler) { + const headers = opts.headers + opts = { ...opts, headers: null } + + const request = new Request(origin, opts, handler) + + request.headers = {} + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(request, headers[i], headers[i + 1], true) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(request, key, headers[key], true) + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') + } + + return request + } + + static [kHTTP2CopyHeaders] (raw) { + const rawHeaders = raw.split('\r\n') + const headers = {} + + for (const header of rawHeaders) { + const [key, value] = header.split(': ') + + if (value == null || value.length === 0) continue + + if (headers[key]) headers[key] += `,${value}` + else headers[key] = value + } + + return headers + } +} + +function processHeaderValue (key, val, skipAppend) { + if (val && typeof val === 'object') { + throw new InvalidArgumentError(`invalid ${key} header`) + } + + val = val != null ? `${val}` : '' + + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + + return skipAppend ? val : `${key}: ${val}\r\n` +} + +function processHeader (request, key, val, skipAppend = false) { + if (val && (typeof val === 'object' && !Array.isArray(val))) { + throw new InvalidArgumentError(`invalid ${key} header`) + } else if (val === undefined) { + return + } + + if ( + request.host === null && + key.length === 4 && + key.toLowerCase() === 'host' + ) { + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + // Consumed by Client + request.host = val + } else if ( + request.contentLength === null && + key.length === 14 && + key.toLowerCase() === 'content-length' + ) { + request.contentLength = parseInt(val, 10) + if (!Number.isFinite(request.contentLength)) { + throw new InvalidArgumentError('invalid content-length header') + } + } else if ( + request.contentType === null && + key.length === 12 && + key.toLowerCase() === 'content-type' + ) { + request.contentType = val + if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) + } else if ( + key.length === 17 && + key.toLowerCase() === 'transfer-encoding' + ) { + throw new InvalidArgumentError('invalid transfer-encoding header') + } else if ( + key.length === 10 && + key.toLowerCase() === 'connection' + ) { + const value = typeof val === 'string' ? val.toLowerCase() : null + if (value !== 'close' && value !== 'keep-alive') { + throw new InvalidArgumentError('invalid connection header') + } else if (value === 'close') { + request.reset = true + } + } else if ( + key.length === 10 && + key.toLowerCase() === 'keep-alive' + ) { + throw new InvalidArgumentError('invalid keep-alive header') + } else if ( + key.length === 7 && + key.toLowerCase() === 'upgrade' + ) { + throw new InvalidArgumentError('invalid upgrade header') + } else if ( + key.length === 6 && + key.toLowerCase() === 'expect' + ) { + throw new NotSupportedError('expect header not supported') + } else if (tokenRegExp.exec(key) === null) { + throw new InvalidArgumentError('invalid header key') + } else { + if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + if (skipAppend) { + if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` + else request.headers[key] = processHeaderValue(key, val[i], skipAppend) + } else { + request.headers += processHeaderValue(key, val[i]) + } + } + } else { + if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) + } + } +} + +module.exports = Request + + +/***/ }), + +/***/ 2785: +/***/ ((module) => { + +module.exports = { + kClose: Symbol('close'), + kDestroy: Symbol('destroy'), + kDispatch: Symbol('dispatch'), + kUrl: Symbol('url'), + kWriting: Symbol('writing'), + kResuming: Symbol('resuming'), + kQueue: Symbol('queue'), + kConnect: Symbol('connect'), + kConnecting: Symbol('connecting'), + kHeadersList: Symbol('headers list'), + kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), + kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), + kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), + kKeepAliveTimeoutValue: Symbol('keep alive timeout'), + kKeepAlive: Symbol('keep alive'), + kHeadersTimeout: Symbol('headers timeout'), + kBodyTimeout: Symbol('body timeout'), + kServerName: Symbol('server name'), + kLocalAddress: Symbol('local address'), + kHost: Symbol('host'), + kNoRef: Symbol('no ref'), + kBodyUsed: Symbol('used'), + kRunning: Symbol('running'), + kBlocking: Symbol('blocking'), + kPending: Symbol('pending'), + kSize: Symbol('size'), + kBusy: Symbol('busy'), + kQueued: Symbol('queued'), + kFree: Symbol('free'), + kConnected: Symbol('connected'), + kClosed: Symbol('closed'), + kNeedDrain: Symbol('need drain'), + kReset: Symbol('reset'), + kDestroyed: Symbol.for('nodejs.stream.destroyed'), + kMaxHeadersSize: Symbol('max headers size'), + kRunningIdx: Symbol('running index'), + kPendingIdx: Symbol('pending index'), + kError: Symbol('error'), + kClients: Symbol('clients'), + kClient: Symbol('client'), + kParser: Symbol('parser'), + kOnDestroyed: Symbol('destroy callbacks'), + kPipelining: Symbol('pipelining'), + kSocket: Symbol('socket'), + kHostHeader: Symbol('host header'), + kConnector: Symbol('connector'), + kStrictContentLength: Symbol('strict content length'), + kMaxRedirections: Symbol('maxRedirections'), + kMaxRequests: Symbol('maxRequestsPerClient'), + kProxy: Symbol('proxy agent options'), + kCounter: Symbol('socket request counter'), + kInterceptors: Symbol('dispatch interceptors'), + kMaxResponseSize: Symbol('max response size'), + kHTTP2Session: Symbol('http2Session'), + kHTTP2SessionState: Symbol('http2Session state'), + kHTTP2BuildRequest: Symbol('http2 build request'), + kHTTP1BuildRequest: Symbol('http1 build request'), + kHTTP2CopyHeaders: Symbol('http2 copy headers'), + kHTTPConnVersion: Symbol('http connection version'), + kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), + kConstruct: Symbol('constructable') +} + + +/***/ }), + +/***/ 3983: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const assert = __nccwpck_require__(9491) +const { kDestroyed, kBodyUsed } = __nccwpck_require__(2785) +const { IncomingMessage } = __nccwpck_require__(3685) +const stream = __nccwpck_require__(2781) +const net = __nccwpck_require__(1808) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { Blob } = __nccwpck_require__(4300) +const nodeUtil = __nccwpck_require__(3837) +const { stringify } = __nccwpck_require__(3477) + +const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)) + +function nop () {} + +function isStream (obj) { + return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' +} + +// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) +function isBlobLike (object) { + return (Blob && object instanceof Blob) || ( + object && + typeof object === 'object' && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + /^(Blob|File)$/.test(object[Symbol.toStringTag]) + ) +} + +function buildURL (url, queryParams) { + if (url.includes('?') || url.includes('#')) { + throw new Error('Query params cannot be passed when url already contains "?" or "#".') + } + + const stringified = stringify(queryParams) + + if (stringified) { + url += '?' + stringified + } + + return url +} + +function parseURL (url) { + if (typeof url === 'string') { + url = new URL(url) + + if (!/^https?:/.test(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } + + return url + } + + if (!url || typeof url !== 'object') { + throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') + } + + if (!/^https?:/.test(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } + + if (!(url instanceof URL)) { + if (url.port != null && url.port !== '' && !Number.isFinite(parseInt(url.port))) { + throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') + } + + if (url.path != null && typeof url.path !== 'string') { + throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') + } + + if (url.pathname != null && typeof url.pathname !== 'string') { + throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') + } + + if (url.hostname != null && typeof url.hostname !== 'string') { + throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') + } + + if (url.origin != null && typeof url.origin !== 'string') { + throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') + } + + const port = url.port != null + ? url.port + : (url.protocol === 'https:' ? 443 : 80) + let origin = url.origin != null + ? url.origin + : `${url.protocol}//${url.hostname}:${port}` + let path = url.path != null + ? url.path + : `${url.pathname || ''}${url.search || ''}` + + if (origin.endsWith('/')) { + origin = origin.substring(0, origin.length - 1) + } + + if (path && !path.startsWith('/')) { + path = `/${path}` + } + // new URL(path, origin) is unsafe when `path` contains an absolute URL + // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: + // If first parameter is a relative URL, second param is required, and will be used as the base URL. + // If first parameter is an absolute URL, a given second param will be ignored. + url = new URL(origin + path) + } + + return url +} + +function parseOrigin (url) { + url = parseURL(url) + + if (url.pathname !== '/' || url.search || url.hash) { + throw new InvalidArgumentError('invalid url') + } + + return url +} + +function getHostname (host) { + if (host[0] === '[') { + const idx = host.indexOf(']') + + assert(idx !== -1) + return host.substring(1, idx) + } + + const idx = host.indexOf(':') + if (idx === -1) return host + + return host.substring(0, idx) +} + +// IP addresses are not valid server names per RFC6066 +// > Currently, the only server names supported are DNS hostnames +function getServerName (host) { + if (!host) { + return null + } + + assert.strictEqual(typeof host, 'string') + + const servername = getHostname(host) + if (net.isIP(servername)) { + return '' + } + + return servername +} + +function deepClone (obj) { + return JSON.parse(JSON.stringify(obj)) +} + +function isAsyncIterable (obj) { + return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') +} + +function isIterable (obj) { + return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) +} + +function bodyLength (body) { + if (body == null) { + return 0 + } else if (isStream(body)) { + const state = body._readableState + return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) + ? state.length + : null + } else if (isBlobLike(body)) { + return body.size != null ? body.size : null + } else if (isBuffer(body)) { + return body.byteLength + } + + return null +} + +function isDestroyed (stream) { + return !stream || !!(stream.destroyed || stream[kDestroyed]) +} + +function isReadableAborted (stream) { + const state = stream && stream._readableState + return isDestroyed(stream) && state && !state.endEmitted +} + +function destroy (stream, err) { + if (stream == null || !isStream(stream) || isDestroyed(stream)) { + return + } + + if (typeof stream.destroy === 'function') { + if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { + // See: https://github.com/nodejs/node/pull/38505/files + stream.socket = null + } + + stream.destroy(err) + } else if (err) { + process.nextTick((stream, err) => { + stream.emit('error', err) + }, stream, err) + } + + if (stream.destroyed !== true) { + stream[kDestroyed] = true + } +} + +const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/ +function parseKeepAliveTimeout (val) { + const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR) + return m ? parseInt(m[1], 10) * 1000 : null +} + +function parseHeaders (headers, obj = {}) { + // For H2 support + if (!Array.isArray(headers)) return headers + + for (let i = 0; i < headers.length; i += 2) { + const key = headers[i].toString().toLowerCase() + let val = obj[key] + + if (!val) { + if (Array.isArray(headers[i + 1])) { + obj[key] = headers[i + 1].map(x => x.toString('utf8')) + } else { + obj[key] = headers[i + 1].toString('utf8') + } + } else { + if (!Array.isArray(val)) { + val = [val] + obj[key] = val + } + val.push(headers[i + 1].toString('utf8')) + } + } + + // See https://github.com/nodejs/node/pull/46528 + if ('content-length' in obj && 'content-disposition' in obj) { + obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1') + } + + return obj +} + +function parseRawHeaders (headers) { + const ret = [] + let hasContentLength = false + let contentDispositionIdx = -1 + + for (let n = 0; n < headers.length; n += 2) { + const key = headers[n + 0].toString() + const val = headers[n + 1].toString('utf8') + + if (key.length === 14 && (key === 'content-length' || key.toLowerCase() === 'content-length')) { + ret.push(key, val) + hasContentLength = true + } else if (key.length === 19 && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) { + contentDispositionIdx = ret.push(key, val) - 1 + } else { + ret.push(key, val) + } + } + + // See https://github.com/nodejs/node/pull/46528 + if (hasContentLength && contentDispositionIdx !== -1) { + ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1') + } + + return ret +} + +function isBuffer (buffer) { + // See, https://github.com/mcollina/undici/pull/319 + return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) +} + +function validateHandler (handler, method, upgrade) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + if (typeof handler.onConnect !== 'function') { + throw new InvalidArgumentError('invalid onConnect method') + } + + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') + } + + if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { + throw new InvalidArgumentError('invalid onBodySent method') + } + + if (upgrade || method === 'CONNECT') { + if (typeof handler.onUpgrade !== 'function') { + throw new InvalidArgumentError('invalid onUpgrade method') + } + } else { + if (typeof handler.onHeaders !== 'function') { + throw new InvalidArgumentError('invalid onHeaders method') + } + + if (typeof handler.onData !== 'function') { + throw new InvalidArgumentError('invalid onData method') + } + + if (typeof handler.onComplete !== 'function') { + throw new InvalidArgumentError('invalid onComplete method') + } + } +} + +// A body is disturbed if it has been read from and it cannot +// be re-used without losing state or data. +function isDisturbed (body) { + return !!(body && ( + stream.isDisturbed + ? stream.isDisturbed(body) || body[kBodyUsed] // TODO (fix): Why is body[kBodyUsed] needed? + : body[kBodyUsed] || + body.readableDidRead || + (body._readableState && body._readableState.dataEmitted) || + isReadableAborted(body) + )) +} + +function isErrored (body) { + return !!(body && ( + stream.isErrored + ? stream.isErrored(body) + : /state: 'errored'/.test(nodeUtil.inspect(body) + ))) +} + +function isReadable (body) { + return !!(body && ( + stream.isReadable + ? stream.isReadable(body) + : /state: 'readable'/.test(nodeUtil.inspect(body) + ))) +} + +function getSocketInfo (socket) { + return { + localAddress: socket.localAddress, + localPort: socket.localPort, + remoteAddress: socket.remoteAddress, + remotePort: socket.remotePort, + remoteFamily: socket.remoteFamily, + timeout: socket.timeout, + bytesWritten: socket.bytesWritten, + bytesRead: socket.bytesRead + } +} + +async function * convertIterableToBuffer (iterable) { + for await (const chunk of iterable) { + yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) + } +} + +let ReadableStream +function ReadableStreamFrom (iterable) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } + + if (ReadableStream.from) { + return ReadableStream.from(convertIterableToBuffer(iterable)) + } + + let iterator + return new ReadableStream( + { + async start () { + iterator = iterable[Symbol.asyncIterator]() + }, + async pull (controller) { + const { done, value } = await iterator.next() + if (done) { + queueMicrotask(() => { + controller.close() + }) + } else { + const buf = Buffer.isBuffer(value) ? value : Buffer.from(value) + controller.enqueue(new Uint8Array(buf)) + } + return controller.desiredSize > 0 + }, + async cancel (reason) { + await iterator.return() + } + }, + 0 + ) +} + +// The chunk should be a FormData instance and contains +// all the required methods. +function isFormDataLike (object) { + return ( + object && + typeof object === 'object' && + typeof object.append === 'function' && + typeof object.delete === 'function' && + typeof object.get === 'function' && + typeof object.getAll === 'function' && + typeof object.has === 'function' && + typeof object.set === 'function' && + object[Symbol.toStringTag] === 'FormData' + ) +} + +function throwIfAborted (signal) { + if (!signal) { return } + if (typeof signal.throwIfAborted === 'function') { + signal.throwIfAborted() + } else { + if (signal.aborted) { + // DOMException not available < v17.0.0 + const err = new Error('The operation was aborted') + err.name = 'AbortError' + throw err + } + } +} + +function addAbortListener (signal, listener) { + if ('addEventListener' in signal) { + signal.addEventListener('abort', listener, { once: true }) + return () => signal.removeEventListener('abort', listener) + } + signal.addListener('abort', listener) + return () => signal.removeListener('abort', listener) +} + +const hasToWellFormed = !!String.prototype.toWellFormed + +/** + * @param {string} val + */ +function toUSVString (val) { + if (hasToWellFormed) { + return `${val}`.toWellFormed() + } else if (nodeUtil.toUSVString) { + return nodeUtil.toUSVString(val) + } + + return `${val}` +} + +// Parsed accordingly to RFC 9110 +// https://www.rfc-editor.org/rfc/rfc9110#field.content-range +function parseRangeHeader (range) { + if (range == null || range === '') return { start: 0, end: null, size: null } + + const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null + return m + ? { + start: parseInt(m[1]), + end: m[2] ? parseInt(m[2]) : null, + size: m[3] ? parseInt(m[3]) : null + } + : null +} + +const kEnumerableProperty = Object.create(null) +kEnumerableProperty.enumerable = true + +module.exports = { + kEnumerableProperty, + nop, + isDisturbed, + isErrored, + isReadable, + toUSVString, + isReadableAborted, + isBlobLike, + parseOrigin, + parseURL, + getServerName, + isStream, + isIterable, + isAsyncIterable, + isDestroyed, + parseRawHeaders, + parseHeaders, + parseKeepAliveTimeout, + destroy, + bodyLength, + deepClone, + ReadableStreamFrom, + isBuffer, + validateHandler, + getSocketInfo, + isFormDataLike, + buildURL, + throwIfAborted, + addAbortListener, + parseRangeHeader, + nodeMajor, + nodeMinor, + nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13), + safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'] +} + + +/***/ }), + +/***/ 4839: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Dispatcher = __nccwpck_require__(412) +const { + ClientDestroyedError, + ClientClosedError, + InvalidArgumentError +} = __nccwpck_require__(8045) +const { kDestroy, kClose, kDispatch, kInterceptors } = __nccwpck_require__(2785) + +const kDestroyed = Symbol('destroyed') +const kClosed = Symbol('closed') +const kOnDestroyed = Symbol('onDestroyed') +const kOnClosed = Symbol('onClosed') +const kInterceptedDispatch = Symbol('Intercepted Dispatch') + +class DispatcherBase extends Dispatcher { + constructor () { + super() + + this[kDestroyed] = false + this[kOnDestroyed] = null + this[kClosed] = false + this[kOnClosed] = [] + } + + get destroyed () { + return this[kDestroyed] + } + + get closed () { + return this[kClosed] + } + + get interceptors () { + return this[kInterceptors] + } + + set interceptors (newInterceptors) { + if (newInterceptors) { + for (let i = newInterceptors.length - 1; i >= 0; i--) { + const interceptor = this[kInterceptors][i] + if (typeof interceptor !== 'function') { + throw new InvalidArgumentError('interceptor must be an function') + } + } + } + + this[kInterceptors] = newInterceptors + } + + close (callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.close((err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (this[kDestroyed]) { + queueMicrotask(() => callback(new ClientDestroyedError(), null)) + return + } + + if (this[kClosed]) { + if (this[kOnClosed]) { + this[kOnClosed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return + } + + this[kClosed] = true + this[kOnClosed].push(callback) + + const onClosed = () => { + const callbacks = this[kOnClosed] + this[kOnClosed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } + + // Should not error. + this[kClose]() + .then(() => this.destroy()) + .then(() => { + queueMicrotask(onClosed) + }) + } + + destroy (err, callback) { + if (typeof err === 'function') { + callback = err + err = null + } + + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.destroy(err, (err, data) => { + return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) + }) + }) + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (this[kDestroyed]) { + if (this[kOnDestroyed]) { + this[kOnDestroyed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return + } + + if (!err) { + err = new ClientDestroyedError() + } + + this[kDestroyed] = true + this[kOnDestroyed] = this[kOnDestroyed] || [] + this[kOnDestroyed].push(callback) + + const onDestroyed = () => { + const callbacks = this[kOnDestroyed] + this[kOnDestroyed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } + + // Should not error. + this[kDestroy](err).then(() => { + queueMicrotask(onDestroyed) + }) + } + + [kInterceptedDispatch] (opts, handler) { + if (!this[kInterceptors] || this[kInterceptors].length === 0) { + this[kInterceptedDispatch] = this[kDispatch] + return this[kDispatch](opts, handler) + } + + let dispatch = this[kDispatch].bind(this) + for (let i = this[kInterceptors].length - 1; i >= 0; i--) { + dispatch = this[kInterceptors][i](dispatch) + } + this[kInterceptedDispatch] = dispatch + return dispatch(opts, handler) + } + + dispatch (opts, handler) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + try { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object.') + } + + if (this[kDestroyed] || this[kOnDestroyed]) { + throw new ClientDestroyedError() + } + + if (this[kClosed]) { + throw new ClientClosedError() + } + + return this[kInterceptedDispatch](opts, handler) + } catch (err) { + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') + } + + handler.onError(err) + + return false + } + } +} + +module.exports = DispatcherBase + + +/***/ }), + +/***/ 412: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const EventEmitter = __nccwpck_require__(2361) + +class Dispatcher extends EventEmitter { + dispatch () { + throw new Error('not implemented') + } + + close () { + throw new Error('not implemented') + } + + destroy () { + throw new Error('not implemented') + } +} + +module.exports = Dispatcher + + +/***/ }), + +/***/ 1472: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const Busboy = __nccwpck_require__(727) +const util = __nccwpck_require__(3983) +const { + ReadableStreamFrom, + isBlobLike, + isReadableStreamLike, + readableStreamClose, + createDeferredPromise, + fullyReadBody +} = __nccwpck_require__(2538) +const { FormData } = __nccwpck_require__(2015) +const { kState } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { DOMException, structuredClone } = __nccwpck_require__(1037) +const { Blob, File: NativeFile } = __nccwpck_require__(4300) +const { kBodyUsed } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { isErrored } = __nccwpck_require__(3983) +const { isUint8Array, isArrayBuffer } = __nccwpck_require__(9830) +const { File: UndiciFile } = __nccwpck_require__(8511) +const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) + +let ReadableStream = globalThis.ReadableStream + +/** @type {globalThis['File']} */ +const File = NativeFile ?? UndiciFile +const textEncoder = new TextEncoder() +const textDecoder = new TextDecoder() + +// https://fetch.spec.whatwg.org/#concept-bodyinit-extract +function extractBody (object, keepalive = false) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } + + // 1. Let stream be null. + let stream = null + + // 2. If object is a ReadableStream object, then set stream to object. + if (object instanceof ReadableStream) { + stream = object + } else if (isBlobLike(object)) { + // 3. Otherwise, if object is a Blob object, set stream to the + // result of running object’s get stream. + stream = object.stream() + } else { + // 4. Otherwise, set stream to a new ReadableStream object, and set + // up stream. + stream = new ReadableStream({ + async pull (controller) { + controller.enqueue( + typeof source === 'string' ? textEncoder.encode(source) : source + ) + queueMicrotask(() => readableStreamClose(controller)) + }, + start () {}, + type: undefined + }) + } + + // 5. Assert: stream is a ReadableStream object. + assert(isReadableStreamLike(stream)) + + // 6. Let action be null. + let action = null + + // 7. Let source be null. + let source = null + + // 8. Let length be null. + let length = null + + // 9. Let type be null. + let type = null + + // 10. Switch on object: + if (typeof object === 'string') { + // Set source to the UTF-8 encoding of object. + // Note: setting source to a Uint8Array here breaks some mocking assumptions. + source = object + + // Set type to `text/plain;charset=UTF-8`. + type = 'text/plain;charset=UTF-8' + } else if (object instanceof URLSearchParams) { + // URLSearchParams + + // spec says to run application/x-www-form-urlencoded on body.list + // this is implemented in Node.js as apart of an URLSearchParams instance toString method + // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490 + // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100 + + // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. + source = object.toString() + + // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. + type = 'application/x-www-form-urlencoded;charset=UTF-8' + } else if (isArrayBuffer(object)) { + // BufferSource/ArrayBuffer + + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.slice()) + } else if (ArrayBuffer.isView(object)) { + // BufferSource/ArrayBufferView + + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) + } else if (util.isFormDataLike(object)) { + const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` + const prefix = `--${boundary}\r\nContent-Disposition: form-data` + + /*! formdata-polyfill. MIT License. Jimmy Wärting */ + const escape = (str) => + str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22') + const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n') + + // Set action to this step: run the multipart/form-data + // encoding algorithm, with object’s entry list and UTF-8. + // - This ensures that the body is immutable and can't be changed afterwords + // - That the content-length is calculated in advance. + // - And that all parts are pre-encoded and ready to be sent. + + const blobParts = [] + const rn = new Uint8Array([13, 10]) // '\r\n' + length = 0 + let hasUnknownSizeValue = false + + for (const [name, value] of object) { + if (typeof value === 'string') { + const chunk = textEncoder.encode(prefix + + `; name="${escape(normalizeLinefeeds(name))}"` + + `\r\n\r\n${normalizeLinefeeds(value)}\r\n`) + blobParts.push(chunk) + length += chunk.byteLength + } else { + const chunk = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + + (value.name ? `; filename="${escape(value.name)}"` : '') + '\r\n' + + `Content-Type: ${ + value.type || 'application/octet-stream' + }\r\n\r\n`) + blobParts.push(chunk, value, rn) + if (typeof value.size === 'number') { + length += chunk.byteLength + value.size + rn.byteLength + } else { + hasUnknownSizeValue = true + } + } + } + + const chunk = textEncoder.encode(`--${boundary}--`) + blobParts.push(chunk) + length += chunk.byteLength + if (hasUnknownSizeValue) { + length = null + } + + // Set source to object. + source = object + + action = async function * () { + for (const part of blobParts) { + if (part.stream) { + yield * part.stream() + } else { + yield part + } + } + } + + // Set type to `multipart/form-data; boundary=`, + // followed by the multipart/form-data boundary string generated + // by the multipart/form-data encoding algorithm. + type = 'multipart/form-data; boundary=' + boundary + } else if (isBlobLike(object)) { + // Blob + + // Set source to object. + source = object + + // Set length to object’s size. + length = object.size + + // If object’s type attribute is not the empty byte sequence, set + // type to its value. + if (object.type) { + type = object.type + } + } else if (typeof object[Symbol.asyncIterator] === 'function') { + // If keepalive is true, then throw a TypeError. + if (keepalive) { + throw new TypeError('keepalive') + } + + // If object is disturbed or locked, then throw a TypeError. + if (util.isDisturbed(object) || object.locked) { + throw new TypeError( + 'Response body object should not be disturbed or locked' + ) + } + + stream = + object instanceof ReadableStream ? object : ReadableStreamFrom(object) + } + + // 11. If source is a byte sequence, then set action to a + // step that returns source and length to source’s length. + if (typeof source === 'string' || util.isBuffer(source)) { + length = Buffer.byteLength(source) + } + + // 12. If action is non-null, then run these steps in in parallel: + if (action != null) { + // Run action. + let iterator + stream = new ReadableStream({ + async start () { + iterator = action(object)[Symbol.asyncIterator]() + }, + async pull (controller) { + const { value, done } = await iterator.next() + if (done) { + // When running action is done, close stream. + queueMicrotask(() => { + controller.close() + }) + } else { + // Whenever one or more bytes are available and stream is not errored, + // enqueue a Uint8Array wrapping an ArrayBuffer containing the available + // bytes into stream. + if (!isErrored(stream)) { + controller.enqueue(new Uint8Array(value)) + } + } + return controller.desiredSize > 0 + }, + async cancel (reason) { + await iterator.return() + }, + type: undefined + }) + } + + // 13. Let body be a body whose stream is stream, source is source, + // and length is length. + const body = { stream, source, length } + + // 14. Return (body, type). + return [body, type] +} + +// https://fetch.spec.whatwg.org/#bodyinit-safely-extract +function safelyExtractBody (object, keepalive = false) { + if (!ReadableStream) { + // istanbul ignore next + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } + + // To safely extract a body and a `Content-Type` value from + // a byte sequence or BodyInit object object, run these steps: + + // 1. If object is a ReadableStream object, then: + if (object instanceof ReadableStream) { + // Assert: object is neither disturbed nor locked. + // istanbul ignore next + assert(!util.isDisturbed(object), 'The body has already been consumed.') + // istanbul ignore next + assert(!object.locked, 'The stream is locked.') + } + + // 2. Return the results of extracting object. + return extractBody(object, keepalive) +} + +function cloneBody (body) { + // To clone a body body, run these steps: + + // https://fetch.spec.whatwg.org/#concept-body-clone + + // 1. Let « out1, out2 » be the result of teeing body’s stream. + const [out1, out2] = body.stream.tee() + const out2Clone = structuredClone(out2, { transfer: [out2] }) + // This, for whatever reasons, unrefs out2Clone which allows + // the process to exit by itself. + const [, finalClone] = out2Clone.tee() + + // 2. Set body’s stream to out1. + body.stream = out1 + + // 3. Return a body whose stream is out2 and other members are copied from body. + return { + stream: finalClone, + length: body.length, + source: body.source + } +} + +async function * consumeBody (body) { + if (body) { + if (isUint8Array(body)) { + yield body + } else { + const stream = body.stream + + if (util.isDisturbed(stream)) { + throw new TypeError('The body has already been consumed.') + } + + if (stream.locked) { + throw new TypeError('The stream is locked.') + } + + // Compat. + stream[kBodyUsed] = true + + yield * stream + } + } +} + +function throwIfAborted (state) { + if (state.aborted) { + throw new DOMException('The operation was aborted.', 'AbortError') + } +} + +function bodyMixinMethods (instance) { + const methods = { + blob () { + // The blob() method steps are to return the result of + // running consume body with this and the following step + // given a byte sequence bytes: return a Blob whose + // contents are bytes and whose type attribute is this’s + // MIME type. + return specConsumeBody(this, (bytes) => { + let mimeType = bodyMimeType(this) + + if (mimeType === 'failure') { + mimeType = '' + } else if (mimeType) { + mimeType = serializeAMimeType(mimeType) + } + + // Return a Blob whose contents are bytes and type attribute + // is mimeType. + return new Blob([bytes], { type: mimeType }) + }, instance) + }, + + arrayBuffer () { + // The arrayBuffer() method steps are to return the result + // of running consume body with this and the following step + // given a byte sequence bytes: return a new ArrayBuffer + // whose contents are bytes. + return specConsumeBody(this, (bytes) => { + return new Uint8Array(bytes).buffer + }, instance) + }, + + text () { + // The text() method steps are to return the result of running + // consume body with this and UTF-8 decode. + return specConsumeBody(this, utf8DecodeBytes, instance) + }, + + json () { + // The json() method steps are to return the result of running + // consume body with this and parse JSON from bytes. + return specConsumeBody(this, parseJSONFromBytes, instance) + }, + + async formData () { + webidl.brandCheck(this, instance) + + throwIfAborted(this[kState]) + + const contentType = this.headers.get('Content-Type') + + // If mimeType’s essence is "multipart/form-data", then: + if (/multipart\/form-data/.test(contentType)) { + const headers = {} + for (const [key, value] of this.headers) headers[key.toLowerCase()] = value + + const responseFormData = new FormData() + + let busboy + + try { + busboy = new Busboy({ + headers, + preservePath: true + }) + } catch (err) { + throw new DOMException(`${err}`, 'AbortError') + } + + busboy.on('field', (name, value) => { + responseFormData.append(name, value) + }) + busboy.on('file', (name, value, filename, encoding, mimeType) => { + const chunks = [] + + if (encoding === 'base64' || encoding.toLowerCase() === 'base64') { + let base64chunk = '' + + value.on('data', (chunk) => { + base64chunk += chunk.toString().replace(/[\r\n]/gm, '') + + const end = base64chunk.length - base64chunk.length % 4 + chunks.push(Buffer.from(base64chunk.slice(0, end), 'base64')) + + base64chunk = base64chunk.slice(end) + }) + value.on('end', () => { + chunks.push(Buffer.from(base64chunk, 'base64')) + responseFormData.append(name, new File(chunks, filename, { type: mimeType })) + }) + } else { + value.on('data', (chunk) => { + chunks.push(chunk) + }) + value.on('end', () => { + responseFormData.append(name, new File(chunks, filename, { type: mimeType })) + }) + } + }) + + const busboyResolve = new Promise((resolve, reject) => { + busboy.on('finish', resolve) + busboy.on('error', (err) => reject(new TypeError(err))) + }) + + if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk) + busboy.end() + await busboyResolve + + return responseFormData + } else if (/application\/x-www-form-urlencoded/.test(contentType)) { + // Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then: + + // 1. Let entries be the result of parsing bytes. + let entries + try { + let text = '' + // application/x-www-form-urlencoded parser will keep the BOM. + // https://url.spec.whatwg.org/#concept-urlencoded-parser + // Note that streaming decoder is stateful and cannot be reused + const streamingDecoder = new TextDecoder('utf-8', { ignoreBOM: true }) + + for await (const chunk of consumeBody(this[kState].body)) { + if (!isUint8Array(chunk)) { + throw new TypeError('Expected Uint8Array chunk') + } + text += streamingDecoder.decode(chunk, { stream: true }) + } + text += streamingDecoder.decode() + entries = new URLSearchParams(text) + } catch (err) { + // istanbul ignore next: Unclear when new URLSearchParams can fail on a string. + // 2. If entries is failure, then throw a TypeError. + throw Object.assign(new TypeError(), { cause: err }) + } + + // 3. Return a new FormData object whose entries are entries. + const formData = new FormData() + for (const [name, value] of entries) { + formData.append(name, value) + } + return formData + } else { + // Wait a tick before checking if the request has been aborted. + // Otherwise, a TypeError can be thrown when an AbortError should. + await Promise.resolve() + + throwIfAborted(this[kState]) + + // Otherwise, throw a TypeError. + throw webidl.errors.exception({ + header: `${instance.name}.formData`, + message: 'Could not parse content as FormData.' + }) + } + } + } + + return methods +} + +function mixinBody (prototype) { + Object.assign(prototype.prototype, bodyMixinMethods(prototype)) +} + +/** + * @see https://fetch.spec.whatwg.org/#concept-body-consume-body + * @param {Response|Request} object + * @param {(value: unknown) => unknown} convertBytesToJSValue + * @param {Response|Request} instance + */ +async function specConsumeBody (object, convertBytesToJSValue, instance) { + webidl.brandCheck(object, instance) + + throwIfAborted(object[kState]) + + // 1. If object is unusable, then return a promise rejected + // with a TypeError. + if (bodyUnusable(object[kState].body)) { + throw new TypeError('Body is unusable') + } + + // 2. Let promise be a new promise. + const promise = createDeferredPromise() + + // 3. Let errorSteps given error be to reject promise with error. + const errorSteps = (error) => promise.reject(error) + + // 4. Let successSteps given a byte sequence data be to resolve + // promise with the result of running convertBytesToJSValue + // with data. If that threw an exception, then run errorSteps + // with that exception. + const successSteps = (data) => { + try { + promise.resolve(convertBytesToJSValue(data)) + } catch (e) { + errorSteps(e) + } + } + + // 5. If object’s body is null, then run successSteps with an + // empty byte sequence. + if (object[kState].body == null) { + successSteps(new Uint8Array()) + return promise.promise + } + + // 6. Otherwise, fully read object’s body given successSteps, + // errorSteps, and object’s relevant global object. + await fullyReadBody(object[kState].body, successSteps, errorSteps) + + // 7. Return promise. + return promise.promise +} + +// https://fetch.spec.whatwg.org/#body-unusable +function bodyUnusable (body) { + // An object including the Body interface mixin is + // said to be unusable if its body is non-null and + // its body’s stream is disturbed or locked. + return body != null && (body.stream.locked || util.isDisturbed(body.stream)) +} + +/** + * @see https://encoding.spec.whatwg.org/#utf-8-decode + * @param {Buffer} buffer + */ +function utf8DecodeBytes (buffer) { + if (buffer.length === 0) { + return '' + } + + // 1. Let buffer be the result of peeking three bytes from + // ioQueue, converted to a byte sequence. + + // 2. If buffer is 0xEF 0xBB 0xBF, then read three + // bytes from ioQueue. (Do nothing with those bytes.) + if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { + buffer = buffer.subarray(3) + } + + // 3. Process a queue with an instance of UTF-8’s + // decoder, ioQueue, output, and "replacement". + const output = textDecoder.decode(buffer) + + // 4. Return output. + return output +} + +/** + * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value + * @param {Uint8Array} bytes + */ +function parseJSONFromBytes (bytes) { + return JSON.parse(utf8DecodeBytes(bytes)) +} + +/** + * @see https://fetch.spec.whatwg.org/#concept-body-mime-type + * @param {import('./response').Response|import('./request').Request} object + */ +function bodyMimeType (object) { + const { headersList } = object[kState] + const contentType = headersList.get('content-type') + + if (contentType === null) { + return 'failure' + } + + return parseMIMEType(contentType) +} + +module.exports = { + extractBody, + safelyExtractBody, + cloneBody, + mixinBody +} + + +/***/ }), + +/***/ 1037: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { MessageChannel, receiveMessageOnPort } = __nccwpck_require__(1267) + +const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] +const corsSafeListedMethodsSet = new Set(corsSafeListedMethods) + +const nullBodyStatus = [101, 204, 205, 304] + +const redirectStatus = [301, 302, 303, 307, 308] +const redirectStatusSet = new Set(redirectStatus) + +// https://fetch.spec.whatwg.org/#block-bad-port +const badPorts = [ + '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79', + '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137', + '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532', + '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723', + '2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6697', + '10080' +] + +const badPortsSet = new Set(badPorts) + +// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies +const referrerPolicy = [ + '', + 'no-referrer', + 'no-referrer-when-downgrade', + 'same-origin', + 'origin', + 'strict-origin', + 'origin-when-cross-origin', + 'strict-origin-when-cross-origin', + 'unsafe-url' +] +const referrerPolicySet = new Set(referrerPolicy) + +const requestRedirect = ['follow', 'manual', 'error'] + +const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE'] +const safeMethodsSet = new Set(safeMethods) + +const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors'] + +const requestCredentials = ['omit', 'same-origin', 'include'] + +const requestCache = [ + 'default', + 'no-store', + 'reload', + 'no-cache', + 'force-cache', + 'only-if-cached' +] + +// https://fetch.spec.whatwg.org/#request-body-header-name +const requestBodyHeader = [ + 'content-encoding', + 'content-language', + 'content-location', + 'content-type', + // See https://github.com/nodejs/undici/issues/2021 + // 'Content-Length' is a forbidden header name, which is typically + // removed in the Headers implementation. However, undici doesn't + // filter out headers, so we add it here. + 'content-length' +] + +// https://fetch.spec.whatwg.org/#enumdef-requestduplex +const requestDuplex = [ + 'half' +] + +// http://fetch.spec.whatwg.org/#forbidden-method +const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK'] +const forbiddenMethodsSet = new Set(forbiddenMethods) + +const subresource = [ + 'audio', + 'audioworklet', + 'font', + 'image', + 'manifest', + 'paintworklet', + 'script', + 'style', + 'track', + 'video', + 'xslt', + '' +] +const subresourceSet = new Set(subresource) + +/** @type {globalThis['DOMException']} */ +const DOMException = globalThis.DOMException ?? (() => { + // DOMException was only made a global in Node v17.0.0, + // but fetch supports >= v16.8. + try { + atob('~') + } catch (err) { + return Object.getPrototypeOf(err).constructor + } +})() + +let channel + +/** @type {globalThis['structuredClone']} */ +const structuredClone = + globalThis.structuredClone ?? + // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js + // structuredClone was added in v17.0.0, but fetch supports v16.8 + function structuredClone (value, options = undefined) { + if (arguments.length === 0) { + throw new TypeError('missing argument') + } + + if (!channel) { + channel = new MessageChannel() + } + channel.port1.unref() + channel.port2.unref() + channel.port1.postMessage(value, options?.transfer) + return receiveMessageOnPort(channel.port2).message + } + +module.exports = { + DOMException, + structuredClone, + subresource, + forbiddenMethods, + requestBodyHeader, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + redirectStatus, + corsSafeListedMethods, + nullBodyStatus, + safeMethods, + badPorts, + requestDuplex, + subresourceSet, + badPortsSet, + redirectStatusSet, + corsSafeListedMethodsSet, + safeMethodsSet, + forbiddenMethodsSet, + referrerPolicySet +} + + +/***/ }), + +/***/ 685: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +const assert = __nccwpck_require__(9491) +const { atob } = __nccwpck_require__(4300) +const { isomorphicDecode } = __nccwpck_require__(2538) + +const encoder = new TextEncoder() + +/** + * @see https://mimesniff.spec.whatwg.org/#http-token-code-point + */ +const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ +const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line +/** + * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point + */ +const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line + +// https://fetch.spec.whatwg.org/#data-url-processor +/** @param {URL} dataURL */ +function dataURLProcessor (dataURL) { + // 1. Assert: dataURL’s scheme is "data". + assert(dataURL.protocol === 'data:') + + // 2. Let input be the result of running the URL + // serializer on dataURL with exclude fragment + // set to true. + let input = URLSerializer(dataURL, true) + + // 3. Remove the leading "data:" string from input. + input = input.slice(5) + + // 4. Let position point at the start of input. + const position = { position: 0 } + + // 5. Let mimeType be the result of collecting a + // sequence of code points that are not equal + // to U+002C (,), given position. + let mimeType = collectASequenceOfCodePointsFast( + ',', + input, + position + ) + + // 6. Strip leading and trailing ASCII whitespace + // from mimeType. + // Undici implementation note: we need to store the + // length because if the mimetype has spaces removed, + // the wrong amount will be sliced from the input in + // step #9 + const mimeTypeLength = mimeType.length + mimeType = removeASCIIWhitespace(mimeType, true, true) + + // 7. If position is past the end of input, then + // return failure + if (position.position >= input.length) { + return 'failure' + } + + // 8. Advance position by 1. + position.position++ + + // 9. Let encodedBody be the remainder of input. + const encodedBody = input.slice(mimeTypeLength + 1) + + // 10. Let body be the percent-decoding of encodedBody. + let body = stringPercentDecode(encodedBody) + + // 11. If mimeType ends with U+003B (;), followed by + // zero or more U+0020 SPACE, followed by an ASCII + // case-insensitive match for "base64", then: + if (/;(\u0020){0,}base64$/i.test(mimeType)) { + // 1. Let stringBody be the isomorphic decode of body. + const stringBody = isomorphicDecode(body) + + // 2. Set body to the forgiving-base64 decode of + // stringBody. + body = forgivingBase64(stringBody) + + // 3. If body is failure, then return failure. + if (body === 'failure') { + return 'failure' + } + + // 4. Remove the last 6 code points from mimeType. + mimeType = mimeType.slice(0, -6) + + // 5. Remove trailing U+0020 SPACE code points from mimeType, + // if any. + mimeType = mimeType.replace(/(\u0020)+$/, '') + + // 6. Remove the last U+003B (;) code point from mimeType. + mimeType = mimeType.slice(0, -1) + } + + // 12. If mimeType starts with U+003B (;), then prepend + // "text/plain" to mimeType. + if (mimeType.startsWith(';')) { + mimeType = 'text/plain' + mimeType + } + + // 13. Let mimeTypeRecord be the result of parsing + // mimeType. + let mimeTypeRecord = parseMIMEType(mimeType) + + // 14. If mimeTypeRecord is failure, then set + // mimeTypeRecord to text/plain;charset=US-ASCII. + if (mimeTypeRecord === 'failure') { + mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII') + } + + // 15. Return a new data: URL struct whose MIME + // type is mimeTypeRecord and body is body. + // https://fetch.spec.whatwg.org/#data-url-struct + return { mimeType: mimeTypeRecord, body } +} + +// https://url.spec.whatwg.org/#concept-url-serializer +/** + * @param {URL} url + * @param {boolean} excludeFragment + */ +function URLSerializer (url, excludeFragment = false) { + if (!excludeFragment) { + return url.href + } + + const href = url.href + const hashLength = url.hash.length + + return hashLength === 0 ? href : href.substring(0, href.length - hashLength) +} + +// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points +/** + * @param {(char: string) => boolean} condition + * @param {string} input + * @param {{ position: number }} position + */ +function collectASequenceOfCodePoints (condition, input, position) { + // 1. Let result be the empty string. + let result = '' + + // 2. While position doesn’t point past the end of input and the + // code point at position within input meets the condition condition: + while (position.position < input.length && condition(input[position.position])) { + // 1. Append that code point to the end of result. + result += input[position.position] + + // 2. Advance position by 1. + position.position++ + } + + // 3. Return result. + return result +} + +/** + * A faster collectASequenceOfCodePoints that only works when comparing a single character. + * @param {string} char + * @param {string} input + * @param {{ position: number }} position + */ +function collectASequenceOfCodePointsFast (char, input, position) { + const idx = input.indexOf(char, position.position) + const start = position.position + + if (idx === -1) { + position.position = input.length + return input.slice(start) + } + + position.position = idx + return input.slice(start, position.position) +} + +// https://url.spec.whatwg.org/#string-percent-decode +/** @param {string} input */ +function stringPercentDecode (input) { + // 1. Let bytes be the UTF-8 encoding of input. + const bytes = encoder.encode(input) + + // 2. Return the percent-decoding of bytes. + return percentDecode(bytes) +} + +// https://url.spec.whatwg.org/#percent-decode +/** @param {Uint8Array} input */ +function percentDecode (input) { + // 1. Let output be an empty byte sequence. + /** @type {number[]} */ + const output = [] + + // 2. For each byte byte in input: + for (let i = 0; i < input.length; i++) { + const byte = input[i] + + // 1. If byte is not 0x25 (%), then append byte to output. + if (byte !== 0x25) { + output.push(byte) + + // 2. Otherwise, if byte is 0x25 (%) and the next two bytes + // after byte in input are not in the ranges + // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F), + // and 0x61 (a) to 0x66 (f), all inclusive, append byte + // to output. + } else if ( + byte === 0x25 && + !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2])) + ) { + output.push(0x25) + + // 3. Otherwise: + } else { + // 1. Let bytePoint be the two bytes after byte in input, + // decoded, and then interpreted as hexadecimal number. + const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2]) + const bytePoint = Number.parseInt(nextTwoBytes, 16) + + // 2. Append a byte whose value is bytePoint to output. + output.push(bytePoint) + + // 3. Skip the next two bytes in input. + i += 2 + } + } + + // 3. Return output. + return Uint8Array.from(output) +} + +// https://mimesniff.spec.whatwg.org/#parse-a-mime-type +/** @param {string} input */ +function parseMIMEType (input) { + // 1. Remove any leading and trailing HTTP whitespace + // from input. + input = removeHTTPWhitespace(input, true, true) + + // 2. Let position be a position variable for input, + // initially pointing at the start of input. + const position = { position: 0 } + + // 3. Let type be the result of collecting a sequence + // of code points that are not U+002F (/) from + // input, given position. + const type = collectASequenceOfCodePointsFast( + '/', + input, + position + ) + + // 4. If type is the empty string or does not solely + // contain HTTP token code points, then return failure. + // https://mimesniff.spec.whatwg.org/#http-token-code-point + if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { + return 'failure' + } + + // 5. If position is past the end of input, then return + // failure + if (position.position > input.length) { + return 'failure' + } + + // 6. Advance position by 1. (This skips past U+002F (/).) + position.position++ + + // 7. Let subtype be the result of collecting a sequence of + // code points that are not U+003B (;) from input, given + // position. + let subtype = collectASequenceOfCodePointsFast( + ';', + input, + position + ) + + // 8. Remove any trailing HTTP whitespace from subtype. + subtype = removeHTTPWhitespace(subtype, false, true) + + // 9. If subtype is the empty string or does not solely + // contain HTTP token code points, then return failure. + if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { + return 'failure' + } + + const typeLowercase = type.toLowerCase() + const subtypeLowercase = subtype.toLowerCase() + + // 10. Let mimeType be a new MIME type record whose type + // is type, in ASCII lowercase, and subtype is subtype, + // in ASCII lowercase. + // https://mimesniff.spec.whatwg.org/#mime-type + const mimeType = { + type: typeLowercase, + subtype: subtypeLowercase, + /** @type {Map} */ + parameters: new Map(), + // https://mimesniff.spec.whatwg.org/#mime-type-essence + essence: `${typeLowercase}/${subtypeLowercase}` + } + + // 11. While position is not past the end of input: + while (position.position < input.length) { + // 1. Advance position by 1. (This skips past U+003B (;).) + position.position++ + + // 2. Collect a sequence of code points that are HTTP + // whitespace from input given position. + collectASequenceOfCodePoints( + // https://fetch.spec.whatwg.org/#http-whitespace + char => HTTP_WHITESPACE_REGEX.test(char), + input, + position + ) + + // 3. Let parameterName be the result of collecting a + // sequence of code points that are not U+003B (;) + // or U+003D (=) from input, given position. + let parameterName = collectASequenceOfCodePoints( + (char) => char !== ';' && char !== '=', + input, + position + ) + + // 4. Set parameterName to parameterName, in ASCII + // lowercase. + parameterName = parameterName.toLowerCase() + + // 5. If position is not past the end of input, then: + if (position.position < input.length) { + // 1. If the code point at position within input is + // U+003B (;), then continue. + if (input[position.position] === ';') { + continue + } + + // 2. Advance position by 1. (This skips past U+003D (=).) + position.position++ + } + + // 6. If position is past the end of input, then break. + if (position.position > input.length) { + break + } + + // 7. Let parameterValue be null. + let parameterValue = null + + // 8. If the code point at position within input is + // U+0022 ("), then: + if (input[position.position] === '"') { + // 1. Set parameterValue to the result of collecting + // an HTTP quoted string from input, given position + // and the extract-value flag. + parameterValue = collectAnHTTPQuotedString(input, position, true) + + // 2. Collect a sequence of code points that are not + // U+003B (;) from input, given position. + collectASequenceOfCodePointsFast( + ';', + input, + position + ) + + // 9. Otherwise: + } else { + // 1. Set parameterValue to the result of collecting + // a sequence of code points that are not U+003B (;) + // from input, given position. + parameterValue = collectASequenceOfCodePointsFast( + ';', + input, + position + ) + + // 2. Remove any trailing HTTP whitespace from parameterValue. + parameterValue = removeHTTPWhitespace(parameterValue, false, true) + + // 3. If parameterValue is the empty string, then continue. + if (parameterValue.length === 0) { + continue + } + } + + // 10. If all of the following are true + // - parameterName is not the empty string + // - parameterName solely contains HTTP token code points + // - parameterValue solely contains HTTP quoted-string token code points + // - mimeType’s parameters[parameterName] does not exist + // then set mimeType’s parameters[parameterName] to parameterValue. + if ( + parameterName.length !== 0 && + HTTP_TOKEN_CODEPOINTS.test(parameterName) && + (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && + !mimeType.parameters.has(parameterName) + ) { + mimeType.parameters.set(parameterName, parameterValue) + } + } + + // 12. Return mimeType. + return mimeType +} + +// https://infra.spec.whatwg.org/#forgiving-base64-decode +/** @param {string} data */ +function forgivingBase64 (data) { + // 1. Remove all ASCII whitespace from data. + data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line + + // 2. If data’s code point length divides by 4 leaving + // no remainder, then: + if (data.length % 4 === 0) { + // 1. If data ends with one or two U+003D (=) code points, + // then remove them from data. + data = data.replace(/=?=$/, '') + } + + // 3. If data’s code point length divides by 4 leaving + // a remainder of 1, then return failure. + if (data.length % 4 === 1) { + return 'failure' + } + + // 4. If data contains a code point that is not one of + // U+002B (+) + // U+002F (/) + // ASCII alphanumeric + // then return failure. + if (/[^+/0-9A-Za-z]/.test(data)) { + return 'failure' + } + + const binary = atob(data) + const bytes = new Uint8Array(binary.length) + + for (let byte = 0; byte < binary.length; byte++) { + bytes[byte] = binary.charCodeAt(byte) + } + + return bytes +} + +// https://fetch.spec.whatwg.org/#collect-an-http-quoted-string +// tests: https://fetch.spec.whatwg.org/#example-http-quoted-string +/** + * @param {string} input + * @param {{ position: number }} position + * @param {boolean?} extractValue + */ +function collectAnHTTPQuotedString (input, position, extractValue) { + // 1. Let positionStart be position. + const positionStart = position.position + + // 2. Let value be the empty string. + let value = '' + + // 3. Assert: the code point at position within input + // is U+0022 ("). + assert(input[position.position] === '"') + + // 4. Advance position by 1. + position.position++ + + // 5. While true: + while (true) { + // 1. Append the result of collecting a sequence of code points + // that are not U+0022 (") or U+005C (\) from input, given + // position, to value. + value += collectASequenceOfCodePoints( + (char) => char !== '"' && char !== '\\', + input, + position + ) + + // 2. If position is past the end of input, then break. + if (position.position >= input.length) { + break + } + + // 3. Let quoteOrBackslash be the code point at position within + // input. + const quoteOrBackslash = input[position.position] + + // 4. Advance position by 1. + position.position++ + + // 5. If quoteOrBackslash is U+005C (\), then: + if (quoteOrBackslash === '\\') { + // 1. If position is past the end of input, then append + // U+005C (\) to value and break. + if (position.position >= input.length) { + value += '\\' + break + } + + // 2. Append the code point at position within input to value. + value += input[position.position] + + // 3. Advance position by 1. + position.position++ + + // 6. Otherwise: + } else { + // 1. Assert: quoteOrBackslash is U+0022 ("). + assert(quoteOrBackslash === '"') + + // 2. Break. + break + } + } + + // 6. If the extract-value flag is set, then return value. + if (extractValue) { + return value + } + + // 7. Return the code points from positionStart to position, + // inclusive, within input. + return input.slice(positionStart, position.position) +} + +/** + * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type + */ +function serializeAMimeType (mimeType) { + assert(mimeType !== 'failure') + const { parameters, essence } = mimeType + + // 1. Let serialization be the concatenation of mimeType’s + // type, U+002F (/), and mimeType’s subtype. + let serialization = essence + + // 2. For each name → value of mimeType’s parameters: + for (let [name, value] of parameters.entries()) { + // 1. Append U+003B (;) to serialization. + serialization += ';' + + // 2. Append name to serialization. + serialization += name + + // 3. Append U+003D (=) to serialization. + serialization += '=' + + // 4. If value does not solely contain HTTP token code + // points or value is the empty string, then: + if (!HTTP_TOKEN_CODEPOINTS.test(value)) { + // 1. Precede each occurence of U+0022 (") or + // U+005C (\) in value with U+005C (\). + value = value.replace(/(\\|")/g, '\\$1') + + // 2. Prepend U+0022 (") to value. + value = '"' + value + + // 3. Append U+0022 (") to value. + value += '"' + } + + // 5. Append value to serialization. + serialization += value + } + + // 3. Return serialization. + return serialization +} + +/** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} char + */ +function isHTTPWhiteSpace (char) { + return char === '\r' || char === '\n' || char === '\t' || char === ' ' +} + +/** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} str + */ +function removeHTTPWhitespace (str, leading = true, trailing = true) { + let lead = 0 + let trail = str.length - 1 + + if (leading) { + for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++); + } + + if (trailing) { + for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--); + } + + return str.slice(lead, trail + 1) +} + +/** + * @see https://infra.spec.whatwg.org/#ascii-whitespace + * @param {string} char + */ +function isASCIIWhitespace (char) { + return char === '\r' || char === '\n' || char === '\t' || char === '\f' || char === ' ' +} + +/** + * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace + */ +function removeASCIIWhitespace (str, leading = true, trailing = true) { + let lead = 0 + let trail = str.length - 1 + + if (leading) { + for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++); + } + + if (trailing) { + for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--); + } + + return str.slice(lead, trail + 1) +} + +module.exports = { + dataURLProcessor, + URLSerializer, + collectASequenceOfCodePoints, + collectASequenceOfCodePointsFast, + stringPercentDecode, + parseMIMEType, + collectAnHTTPQuotedString, + serializeAMimeType +} + + +/***/ }), + +/***/ 8511: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { Blob, File: NativeFile } = __nccwpck_require__(4300) +const { types } = __nccwpck_require__(3837) +const { kState } = __nccwpck_require__(5861) +const { isBlobLike } = __nccwpck_require__(2538) +const { webidl } = __nccwpck_require__(1744) +const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const encoder = new TextEncoder() + +class File extends Blob { + constructor (fileBits, fileName, options = {}) { + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: + webidl.argumentLengthCheck(arguments, 2, { header: 'File constructor' }) + + fileBits = webidl.converters['sequence'](fileBits) + fileName = webidl.converters.USVString(fileName) + options = webidl.converters.FilePropertyBag(options) + + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. + // Note: Blob handles this for us + + // 2. Let n be the fileName argument to the constructor. + const n = fileName + + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: + + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // 2. Convert every character in t to ASCII lowercase. + let t = options.type + let d + + // eslint-disable-next-line no-labels + substep: { + if (t) { + t = parseMIMEType(t) + + if (t === 'failure') { + t = '' + // eslint-disable-next-line no-labels + break substep + } + + t = serializeAMimeType(t).toLowerCase() + } + + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + d = options.lastModified + } + + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + super(processBlobParts(fileBits, options), { type: t }) + this[kState] = { + name: n, + lastModified: d, + type: t + } + } + + get name () { + webidl.brandCheck(this, File) + + return this[kState].name + } + + get lastModified () { + webidl.brandCheck(this, File) + + return this[kState].lastModified + } + + get type () { + webidl.brandCheck(this, File) + + return this[kState].type + } +} + +class FileLike { + constructor (blobLike, fileName, options = {}) { + // TODO: argument idl type check + + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: + + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. + + // 2. Let n be the fileName argument to the constructor. + const n = fileName + + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: + + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // TODO + const t = options.type + + // 2. Convert every character in t to ASCII lowercase. + // TODO + + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + const d = options.lastModified ?? Date.now() + + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + this[kState] = { + blobLike, + name: n, + type: t, + lastModified: d + } + } + + stream (...args) { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.stream(...args) + } + + arrayBuffer (...args) { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.arrayBuffer(...args) + } + + slice (...args) { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.slice(...args) + } + + text (...args) { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.text(...args) + } + + get size () { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.size + } + + get type () { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.type + } + + get name () { + webidl.brandCheck(this, FileLike) + + return this[kState].name + } + + get lastModified () { + webidl.brandCheck(this, FileLike) + + return this[kState].lastModified + } + + get [Symbol.toStringTag] () { + return 'File' + } +} + +Object.defineProperties(File.prototype, { + [Symbol.toStringTag]: { + value: 'File', + configurable: true + }, + name: kEnumerableProperty, + lastModified: kEnumerableProperty +}) + +webidl.converters.Blob = webidl.interfaceConverter(Blob) + +webidl.converters.BlobPart = function (V, opts) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } + + if ( + ArrayBuffer.isView(V) || + types.isAnyArrayBuffer(V) + ) { + return webidl.converters.BufferSource(V, opts) + } + } + + return webidl.converters.USVString(V, opts) +} + +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.BlobPart +) + +// https://www.w3.org/TR/FileAPI/#dfn-FilePropertyBag +webidl.converters.FilePropertyBag = webidl.dictionaryConverter([ + { + key: 'lastModified', + converter: webidl.converters['long long'], + get defaultValue () { + return Date.now() + } + }, + { + key: 'type', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'endings', + converter: (value) => { + value = webidl.converters.DOMString(value) + value = value.toLowerCase() + + if (value !== 'native') { + value = 'transparent' + } + + return value + }, + defaultValue: 'transparent' + } +]) + +/** + * @see https://www.w3.org/TR/FileAPI/#process-blob-parts + * @param {(NodeJS.TypedArray|Blob|string)[]} parts + * @param {{ type: string, endings: string }} options + */ +function processBlobParts (parts, options) { + // 1. Let bytes be an empty sequence of bytes. + /** @type {NodeJS.TypedArray[]} */ + const bytes = [] + + // 2. For each element in parts: + for (const element of parts) { + // 1. If element is a USVString, run the following substeps: + if (typeof element === 'string') { + // 1. Let s be element. + let s = element + + // 2. If the endings member of options is "native", set s + // to the result of converting line endings to native + // of element. + if (options.endings === 'native') { + s = convertLineEndingsNative(s) + } + + // 3. Append the result of UTF-8 encoding s to bytes. + bytes.push(encoder.encode(s)) + } else if ( + types.isAnyArrayBuffer(element) || + types.isTypedArray(element) + ) { + // 2. If element is a BufferSource, get a copy of the + // bytes held by the buffer source, and append those + // bytes to bytes. + if (!element.buffer) { // ArrayBuffer + bytes.push(new Uint8Array(element)) + } else { + bytes.push( + new Uint8Array(element.buffer, element.byteOffset, element.byteLength) + ) + } + } else if (isBlobLike(element)) { + // 3. If element is a Blob, append the bytes it represents + // to bytes. + bytes.push(element) + } + } + + // 3. Return bytes. + return bytes +} + +/** + * @see https://www.w3.org/TR/FileAPI/#convert-line-endings-to-native + * @param {string} s + */ +function convertLineEndingsNative (s) { + // 1. Let native line ending be be the code point U+000A LF. + let nativeLineEnding = '\n' + + // 2. If the underlying platform’s conventions are to + // represent newlines as a carriage return and line feed + // sequence, set native line ending to the code point + // U+000D CR followed by the code point U+000A LF. + if (process.platform === 'win32') { + nativeLineEnding = '\r\n' + } + + return s.replace(/\r?\n/g, nativeLineEnding) +} + +// If this function is moved to ./util.js, some tools (such as +// rollup) will warn about circular dependencies. See: +// https://github.com/nodejs/undici/issues/1629 +function isFileLike (object) { + return ( + (NativeFile && object instanceof NativeFile) || + object instanceof File || ( + object && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + object[Symbol.toStringTag] === 'File' + ) + ) +} + +module.exports = { File, FileLike, isFileLike } + + +/***/ }), + +/***/ 2015: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { isBlobLike, toUSVString, makeIterator } = __nccwpck_require__(2538) +const { kState } = __nccwpck_require__(5861) +const { File: UndiciFile, FileLike, isFileLike } = __nccwpck_require__(8511) +const { webidl } = __nccwpck_require__(1744) +const { Blob, File: NativeFile } = __nccwpck_require__(4300) + +/** @type {globalThis['File']} */ +const File = NativeFile ?? UndiciFile + +// https://xhr.spec.whatwg.org/#formdata +class FormData { + constructor (form) { + if (form !== undefined) { + throw webidl.errors.conversionFailed({ + prefix: 'FormData constructor', + argument: 'Argument 1', + types: ['undefined'] + }) + } + + this[kState] = [] + } + + append (name, value, filename = undefined) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.append' }) + + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" + ) + } + + // 1. Let value be value if given; otherwise blobValue. + + name = webidl.converters.USVString(name) + value = isBlobLike(value) + ? webidl.converters.Blob(value, { strict: false }) + : webidl.converters.USVString(value) + filename = arguments.length === 3 + ? webidl.converters.USVString(filename) + : undefined + + // 2. Let entry be the result of creating an entry with + // name, value, and filename if given. + const entry = makeEntry(name, value, filename) + + // 3. Append entry to this’s entry list. + this[kState].push(entry) + } + + delete (name) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.delete' }) + + name = webidl.converters.USVString(name) + + // The delete(name) method steps are to remove all entries whose name + // is name from this’s entry list. + this[kState] = this[kState].filter(entry => entry.name !== name) + } + + get (name) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.get' }) + + name = webidl.converters.USVString(name) + + // 1. If there is no entry whose name is name in this’s entry list, + // then return null. + const idx = this[kState].findIndex((entry) => entry.name === name) + if (idx === -1) { + return null + } + + // 2. Return the value of the first entry whose name is name from + // this’s entry list. + return this[kState][idx].value + } + + getAll (name) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.getAll' }) + + name = webidl.converters.USVString(name) + + // 1. If there is no entry whose name is name in this’s entry list, + // then return the empty list. + // 2. Return the values of all entries whose name is name, in order, + // from this’s entry list. + return this[kState] + .filter((entry) => entry.name === name) + .map((entry) => entry.value) + } + + has (name) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.has' }) + + name = webidl.converters.USVString(name) + + // The has(name) method steps are to return true if there is an entry + // whose name is name in this’s entry list; otherwise false. + return this[kState].findIndex((entry) => entry.name === name) !== -1 + } + + set (name, value, filename = undefined) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.set' }) + + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" + ) + } + + // The set(name, value) and set(name, blobValue, filename) method steps + // are: + + // 1. Let value be value if given; otherwise blobValue. + + name = webidl.converters.USVString(name) + value = isBlobLike(value) + ? webidl.converters.Blob(value, { strict: false }) + : webidl.converters.USVString(value) + filename = arguments.length === 3 + ? toUSVString(filename) + : undefined + + // 2. Let entry be the result of creating an entry with name, value, and + // filename if given. + const entry = makeEntry(name, value, filename) + + // 3. If there are entries in this’s entry list whose name is name, then + // replace the first such entry with entry and remove the others. + const idx = this[kState].findIndex((entry) => entry.name === name) + if (idx !== -1) { + this[kState] = [ + ...this[kState].slice(0, idx), + entry, + ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name) + ] + } else { + // 4. Otherwise, append entry to this’s entry list. + this[kState].push(entry) + } + } + + entries () { + webidl.brandCheck(this, FormData) + + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'key+value' + ) + } + + keys () { + webidl.brandCheck(this, FormData) + + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'key' + ) + } + + values () { + webidl.brandCheck(this, FormData) + + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'value' + ) + } + + /** + * @param {(value: string, key: string, self: FormData) => void} callbackFn + * @param {unknown} thisArg + */ + forEach (callbackFn, thisArg = globalThis) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.forEach' }) + + if (typeof callbackFn !== 'function') { + throw new TypeError( + "Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'." + ) + } + + for (const [key, value] of this) { + callbackFn.apply(thisArg, [value, key, this]) + } + } +} + +FormData.prototype[Symbol.iterator] = FormData.prototype.entries + +Object.defineProperties(FormData.prototype, { + [Symbol.toStringTag]: { + value: 'FormData', + configurable: true + } +}) + +/** + * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry + * @param {string} name + * @param {string|Blob} value + * @param {?string} filename + * @returns + */ +function makeEntry (name, value, filename) { + // 1. Set name to the result of converting name into a scalar value string. + // "To convert a string into a scalar value string, replace any surrogates + // with U+FFFD." + // see: https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#buftostringencoding-start-end + name = Buffer.from(name).toString('utf8') + + // 2. If value is a string, then set value to the result of converting + // value into a scalar value string. + if (typeof value === 'string') { + value = Buffer.from(value).toString('utf8') + } else { + // 3. Otherwise: + + // 1. If value is not a File object, then set value to a new File object, + // representing the same bytes, whose name attribute value is "blob" + if (!isFileLike(value)) { + value = value instanceof Blob + ? new File([value], 'blob', { type: value.type }) + : new FileLike(value, 'blob', { type: value.type }) + } + + // 2. If filename is given, then set value to a new File object, + // representing the same bytes, whose name attribute is filename. + if (filename !== undefined) { + /** @type {FilePropertyBag} */ + const options = { + type: value.type, + lastModified: value.lastModified + } + + value = (NativeFile && value instanceof NativeFile) || value instanceof UndiciFile + ? new File([value], filename, options) + : new FileLike(value, filename, options) + } + } + + // 4. Return an entry whose name is name and whose value is value. + return { name, value } +} + +module.exports = { FormData } + + +/***/ }), + +/***/ 1246: +/***/ ((module) => { + +"use strict"; + + +// In case of breaking changes, increase the version +// number to avoid conflicts. +const globalOrigin = Symbol.for('undici.globalOrigin.1') + +function getGlobalOrigin () { + return globalThis[globalOrigin] +} + +function setGlobalOrigin (newOrigin) { + if (newOrigin === undefined) { + Object.defineProperty(globalThis, globalOrigin, { + value: undefined, + writable: true, + enumerable: false, + configurable: false + }) + + return + } + + const parsedURL = new URL(newOrigin) + + if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') { + throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`) + } + + Object.defineProperty(globalThis, globalOrigin, { + value: parsedURL, + writable: true, + enumerable: false, + configurable: false + }) +} + +module.exports = { + getGlobalOrigin, + setGlobalOrigin +} + + +/***/ }), + +/***/ 554: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// https://github.com/Ethan-Arrowood/undici-fetch + + + +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const { kGuard } = __nccwpck_require__(5861) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const { + makeIterator, + isValidHeaderName, + isValidHeaderValue +} = __nccwpck_require__(2538) +const { webidl } = __nccwpck_require__(1744) +const assert = __nccwpck_require__(9491) + +const kHeadersMap = Symbol('headers map') +const kHeadersSortedMap = Symbol('headers map sorted') + +/** + * @param {number} code + */ +function isHTTPWhiteSpaceCharCode (code) { + return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020 +} + +/** + * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize + * @param {string} potentialValue + */ +function headerValueNormalize (potentialValue) { + // To normalize a byte sequence potentialValue, remove + // any leading and trailing HTTP whitespace bytes from + // potentialValue. + let i = 0; let j = potentialValue.length + + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i + + return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j) +} + +function fill (headers, object) { + // To fill a Headers object headers with a given object object, run these steps: + + // 1. If object is a sequence, then for each header in object: + // Note: webidl conversion to array has already been done. + if (Array.isArray(object)) { + for (let i = 0; i < object.length; ++i) { + const header = object[i] + // 1. If header does not contain exactly two items, then throw a TypeError. + if (header.length !== 2) { + throw webidl.errors.exception({ + header: 'Headers constructor', + message: `expected name/value pair to be length 2, found ${header.length}.` + }) + } + + // 2. Append (header’s first item, header’s second item) to headers. + appendHeader(headers, header[0], header[1]) + } + } else if (typeof object === 'object' && object !== null) { + // Note: null should throw + + // 2. Otherwise, object is a record, then for each key → value in object, + // append (key, value) to headers + const keys = Object.keys(object) + for (let i = 0; i < keys.length; ++i) { + appendHeader(headers, keys[i], object[keys[i]]) + } + } else { + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: ['sequence>', 'record'] + }) + } +} + +/** + * @see https://fetch.spec.whatwg.org/#concept-headers-append + */ +function appendHeader (headers, name, value) { + // 1. Normalize value. + value = headerValueNormalize(value) + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value, + type: 'header value' + }) + } + + // 3. If headers’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if headers’s guard is "request" and name is a + // forbidden header name, return. + // Note: undici does not implement forbidden header names + if (headers[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (headers[kGuard] === 'request-no-cors') { + // 5. Otherwise, if headers’s guard is "request-no-cors": + // TODO + } + + // 6. Otherwise, if headers’s guard is "response" and name is a + // forbidden response-header name, return. + + // 7. Append (name, value) to headers’s header list. + return headers[kHeadersList].append(name, value) + + // 8. If headers’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from headers +} + +class HeadersList { + /** @type {[string, string][]|null} */ + cookies = null + + constructor (init) { + if (init instanceof HeadersList) { + this[kHeadersMap] = new Map(init[kHeadersMap]) + this[kHeadersSortedMap] = init[kHeadersSortedMap] + this.cookies = init.cookies === null ? null : [...init.cookies] + } else { + this[kHeadersMap] = new Map(init) + this[kHeadersSortedMap] = null + } + } + + // https://fetch.spec.whatwg.org/#header-list-contains + contains (name) { + // A header list list contains a header name name if list + // contains a header whose name is a byte-case-insensitive + // match for name. + name = name.toLowerCase() + + return this[kHeadersMap].has(name) + } + + clear () { + this[kHeadersMap].clear() + this[kHeadersSortedMap] = null + this.cookies = null + } + + // https://fetch.spec.whatwg.org/#concept-header-list-append + append (name, value) { + this[kHeadersSortedMap] = null + + // 1. If list contains name, then set name to the first such + // header’s name. + const lowercaseName = name.toLowerCase() + const exists = this[kHeadersMap].get(lowercaseName) + + // 2. Append (name, value) to list. + if (exists) { + const delimiter = lowercaseName === 'cookie' ? '; ' : ', ' + this[kHeadersMap].set(lowercaseName, { + name: exists.name, + value: `${exists.value}${delimiter}${value}` + }) + } else { + this[kHeadersMap].set(lowercaseName, { name, value }) + } + + if (lowercaseName === 'set-cookie') { + this.cookies ??= [] + this.cookies.push(value) + } + } + + // https://fetch.spec.whatwg.org/#concept-header-list-set + set (name, value) { + this[kHeadersSortedMap] = null + const lowercaseName = name.toLowerCase() + + if (lowercaseName === 'set-cookie') { + this.cookies = [value] + } + + // 1. If list contains name, then set the value of + // the first such header to value and remove the + // others. + // 2. Otherwise, append header (name, value) to list. + this[kHeadersMap].set(lowercaseName, { name, value }) + } + + // https://fetch.spec.whatwg.org/#concept-header-list-delete + delete (name) { + this[kHeadersSortedMap] = null + + name = name.toLowerCase() + + if (name === 'set-cookie') { + this.cookies = null + } + + this[kHeadersMap].delete(name) + } + + // https://fetch.spec.whatwg.org/#concept-header-list-get + get (name) { + const value = this[kHeadersMap].get(name.toLowerCase()) + + // 1. If list does not contain name, then return null. + // 2. Return the values of all headers in list whose name + // is a byte-case-insensitive match for name, + // separated from each other by 0x2C 0x20, in order. + return value === undefined ? null : value.value + } + + * [Symbol.iterator] () { + // use the lowercased name + for (const [name, { value }] of this[kHeadersMap]) { + yield [name, value] + } + } + + get entries () { + const headers = {} + + if (this[kHeadersMap].size) { + for (const { name, value } of this[kHeadersMap].values()) { + headers[name] = value + } + } + + return headers + } +} + +// https://fetch.spec.whatwg.org/#headers-class +class Headers { + constructor (init = undefined) { + if (init === kConstruct) { + return + } + this[kHeadersList] = new HeadersList() + + // The new Headers(init) constructor steps are: + + // 1. Set this’s guard to "none". + this[kGuard] = 'none' + + // 2. If init is given, then fill this with init. + if (init !== undefined) { + init = webidl.converters.HeadersInit(init) + fill(this, init) + } + } + + // https://fetch.spec.whatwg.org/#dom-headers-append + append (name, value) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.append' }) + + name = webidl.converters.ByteString(name) + value = webidl.converters.ByteString(value) + + return appendHeader(this, name, value) + } + + // https://fetch.spec.whatwg.org/#dom-headers-delete + delete (name) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.delete' }) + + name = webidl.converters.ByteString(name) + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.delete', + value: name, + type: 'header name' + }) + } + + // 2. If this’s guard is "immutable", then throw a TypeError. + // 3. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 4. Otherwise, if this’s guard is "request-no-cors", name + // is not a no-CORS-safelisted request-header name, and + // name is not a privileged no-CORS request-header name, + // return. + // 5. Otherwise, if this’s guard is "response" and name is + // a forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // TODO + } + + // 6. If this’s header list does not contain name, then + // return. + if (!this[kHeadersList].contains(name)) { + return + } + + // 7. Delete name from this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this. + this[kHeadersList].delete(name) + } + + // https://fetch.spec.whatwg.org/#dom-headers-get + get (name) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.get' }) + + name = webidl.converters.ByteString(name) + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.get', + value: name, + type: 'header name' + }) + } + + // 2. Return the result of getting name from this’s header + // list. + return this[kHeadersList].get(name) + } + + // https://fetch.spec.whatwg.org/#dom-headers-has + has (name) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.has' }) + + name = webidl.converters.ByteString(name) + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.has', + value: name, + type: 'header name' + }) + } + + // 2. Return true if this’s header list contains name; + // otherwise false. + return this[kHeadersList].contains(name) + } + + // https://fetch.spec.whatwg.org/#dom-headers-set + set (name, value) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.set' }) + + name = webidl.converters.ByteString(name) + value = webidl.converters.ByteString(value) + + // 1. Normalize value. + value = headerValueNormalize(value) + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.set', + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.set', + value, + type: 'header value' + }) + } + + // 3. If this’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 5. Otherwise, if this’s guard is "request-no-cors" and + // name/value is not a no-CORS-safelisted request-header, + // return. + // 6. Otherwise, if this’s guard is "response" and name is a + // forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // TODO + } + + // 7. Set (name, value) in this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this + this[kHeadersList].set(name, value) + } + + // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie + getSetCookie () { + webidl.brandCheck(this, Headers) + + // 1. If this’s header list does not contain `Set-Cookie`, then return « ». + // 2. Return the values of all headers in this’s header list whose name is + // a byte-case-insensitive match for `Set-Cookie`, in order. + + const list = this[kHeadersList].cookies + + if (list) { + return [...list] + } + + return [] + } + + // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine + get [kHeadersSortedMap] () { + if (this[kHeadersList][kHeadersSortedMap]) { + return this[kHeadersList][kHeadersSortedMap] + } + + // 1. Let headers be an empty list of headers with the key being the name + // and value the value. + const headers = [] + + // 2. Let names be the result of convert header names to a sorted-lowercase + // set with all the names of the headers in list. + const names = [...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1) + const cookies = this[kHeadersList].cookies + + // 3. For each name of names: + for (let i = 0; i < names.length; ++i) { + const [name, value] = names[i] + // 1. If name is `set-cookie`, then: + if (name === 'set-cookie') { + // 1. Let values be a list of all values of headers in list whose name + // is a byte-case-insensitive match for name, in order. + + // 2. For each value of values: + // 1. Append (name, value) to headers. + for (let j = 0; j < cookies.length; ++j) { + headers.push([name, cookies[j]]) + } + } else { + // 2. Otherwise: + + // 1. Let value be the result of getting name from list. + + // 2. Assert: value is non-null. + assert(value !== null) + + // 3. Append (name, value) to headers. + headers.push([name, value]) + } + } + + this[kHeadersList][kHeadersSortedMap] = headers + + // 4. Return headers. + return headers + } + + keys () { + webidl.brandCheck(this, Headers) + + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'key') + } + + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'key' + ) + } + + values () { + webidl.brandCheck(this, Headers) + + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'value') + } + + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'value' + ) + } + + entries () { + webidl.brandCheck(this, Headers) + + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'key+value') + } + + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'key+value' + ) + } + + /** + * @param {(value: string, key: string, self: Headers) => void} callbackFn + * @param {unknown} thisArg + */ + forEach (callbackFn, thisArg = globalThis) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.forEach' }) + + if (typeof callbackFn !== 'function') { + throw new TypeError( + "Failed to execute 'forEach' on 'Headers': parameter 1 is not of type 'Function'." + ) + } + + for (const [key, value] of this) { + callbackFn.apply(thisArg, [value, key, this]) + } + } + + [Symbol.for('nodejs.util.inspect.custom')] () { + webidl.brandCheck(this, Headers) + + return this[kHeadersList] + } +} + +Headers.prototype[Symbol.iterator] = Headers.prototype.entries + +Object.defineProperties(Headers.prototype, { + append: kEnumerableProperty, + delete: kEnumerableProperty, + get: kEnumerableProperty, + has: kEnumerableProperty, + set: kEnumerableProperty, + getSetCookie: kEnumerableProperty, + keys: kEnumerableProperty, + values: kEnumerableProperty, + entries: kEnumerableProperty, + forEach: kEnumerableProperty, + [Symbol.iterator]: { enumerable: false }, + [Symbol.toStringTag]: { + value: 'Headers', + configurable: true + } +}) + +webidl.converters.HeadersInit = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (V[Symbol.iterator]) { + return webidl.converters['sequence>'](V) + } + + return webidl.converters['record'](V) + } + + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: ['sequence>', 'record'] + }) +} + +module.exports = { + fill, + Headers, + HeadersList +} + + +/***/ }), + +/***/ 4881: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// https://github.com/Ethan-Arrowood/undici-fetch + + + +const { + Response, + makeNetworkError, + makeAppropriateNetworkError, + filterResponse, + makeResponse +} = __nccwpck_require__(7823) +const { Headers } = __nccwpck_require__(554) +const { Request, makeRequest } = __nccwpck_require__(8359) +const zlib = __nccwpck_require__(9796) +const { + bytesMatch, + makePolicyContainer, + clonePolicyContainer, + requestBadPort, + TAOCheck, + appendRequestOriginHeader, + responseLocationURL, + requestCurrentURL, + setRequestReferrerPolicyOnRedirect, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + createOpaqueTimingInfo, + appendFetchMetadata, + corsCheck, + crossOriginResourcePolicyCheck, + determineRequestsReferrer, + coarsenedSharedCurrentTime, + createDeferredPromise, + isBlobLike, + sameOrigin, + isCancelled, + isAborted, + isErrorLike, + fullyReadBody, + readableStreamClose, + isomorphicEncode, + urlIsLocal, + urlIsHttpHttpsScheme, + urlHasHttpsScheme +} = __nccwpck_require__(2538) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const assert = __nccwpck_require__(9491) +const { safelyExtractBody } = __nccwpck_require__(1472) +const { + redirectStatusSet, + nullBodyStatus, + safeMethodsSet, + requestBodyHeader, + subresourceSet, + DOMException +} = __nccwpck_require__(1037) +const { kHeadersList } = __nccwpck_require__(2785) +const EE = __nccwpck_require__(2361) +const { Readable, pipeline } = __nccwpck_require__(2781) +const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = __nccwpck_require__(3983) +const { dataURLProcessor, serializeAMimeType } = __nccwpck_require__(685) +const { TransformStream } = __nccwpck_require__(5356) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { webidl } = __nccwpck_require__(1744) +const { STATUS_CODES } = __nccwpck_require__(3685) +const GET_OR_HEAD = ['GET', 'HEAD'] + +/** @type {import('buffer').resolveObjectURL} */ +let resolveObjectURL +let ReadableStream = globalThis.ReadableStream + +class Fetch extends EE { + constructor (dispatcher) { + super() + + this.dispatcher = dispatcher + this.connection = null + this.dump = false + this.state = 'ongoing' + // 2 terminated listeners get added per request, + // but only 1 gets removed. If there are 20 redirects, + // 21 listeners will be added. + // See https://github.com/nodejs/undici/issues/1711 + // TODO (fix): Find and fix root cause for leaked listener. + this.setMaxListeners(21) + } + + terminate (reason) { + if (this.state !== 'ongoing') { + return + } + + this.state = 'terminated' + this.connection?.destroy(reason) + this.emit('terminated', reason) + } + + // https://fetch.spec.whatwg.org/#fetch-controller-abort + abort (error) { + if (this.state !== 'ongoing') { + return + } + + // 1. Set controller’s state to "aborted". + this.state = 'aborted' + + // 2. Let fallbackError be an "AbortError" DOMException. + // 3. Set error to fallbackError if it is not given. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError') + } + + // 4. Let serializedError be StructuredSerialize(error). + // If that threw an exception, catch it, and let + // serializedError be StructuredSerialize(fallbackError). + + // 5. Set controller’s serialized abort reason to serializedError. + this.serializedAbortReason = error + + this.connection?.destroy(error) + this.emit('terminated', error) + } +} + +// https://fetch.spec.whatwg.org/#fetch-method +function fetch (input, init = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'globalThis.fetch' }) + + // 1. Let p be a new promise. + const p = createDeferredPromise() + + // 2. Let requestObject be the result of invoking the initial value of + // Request as constructor with input and init as arguments. If this throws + // an exception, reject p with it and return p. + let requestObject + + try { + requestObject = new Request(input, init) + } catch (e) { + p.reject(e) + return p.promise + } + + // 3. Let request be requestObject’s request. + const request = requestObject[kState] + + // 4. If requestObject’s signal’s aborted flag is set, then: + if (requestObject.signal.aborted) { + // 1. Abort the fetch() call with p, request, null, and + // requestObject’s signal’s abort reason. + abortFetch(p, request, null, requestObject.signal.reason) + + // 2. Return p. + return p.promise + } + + // 5. Let globalObject be request’s client’s global object. + const globalObject = request.client.globalObject + + // 6. If globalObject is a ServiceWorkerGlobalScope object, then set + // request’s service-workers mode to "none". + if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') { + request.serviceWorkers = 'none' + } + + // 7. Let responseObject be null. + let responseObject = null + + // 8. Let relevantRealm be this’s relevant Realm. + const relevantRealm = null + + // 9. Let locallyAborted be false. + let locallyAborted = false + + // 10. Let controller be null. + let controller = null + + // 11. Add the following abort steps to requestObject’s signal: + addAbortListener( + requestObject.signal, + () => { + // 1. Set locallyAborted to true. + locallyAborted = true + + // 2. Assert: controller is non-null. + assert(controller != null) + + // 3. Abort controller with requestObject’s signal’s abort reason. + controller.abort(requestObject.signal.reason) + + // 4. Abort the fetch() call with p, request, responseObject, + // and requestObject’s signal’s abort reason. + abortFetch(p, request, responseObject, requestObject.signal.reason) + } + ) + + // 12. Let handleFetchDone given response response be to finalize and + // report timing with response, globalObject, and "fetch". + const handleFetchDone = (response) => + finalizeAndReportTiming(response, 'fetch') + + // 13. Set controller to the result of calling fetch given request, + // with processResponseEndOfBody set to handleFetchDone, and processResponse + // given response being these substeps: + + const processResponse = (response) => { + // 1. If locallyAborted is true, terminate these substeps. + if (locallyAborted) { + return Promise.resolve() + } + + // 2. If response’s aborted flag is set, then: + if (response.aborted) { + // 1. Let deserializedError be the result of deserialize a serialized + // abort reason given controller’s serialized abort reason and + // relevantRealm. + + // 2. Abort the fetch() call with p, request, responseObject, and + // deserializedError. + + abortFetch(p, request, responseObject, controller.serializedAbortReason) + return Promise.resolve() + } + + // 3. If response is a network error, then reject p with a TypeError + // and terminate these substeps. + if (response.type === 'error') { + p.reject( + Object.assign(new TypeError('fetch failed'), { cause: response.error }) + ) + return Promise.resolve() + } + + // 4. Set responseObject to the result of creating a Response object, + // given response, "immutable", and relevantRealm. + responseObject = new Response() + responseObject[kState] = response + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kHeadersList] = response.headersList + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + + // 5. Resolve p with responseObject. + p.resolve(responseObject) + } + + controller = fetching({ + request, + processResponseEndOfBody: handleFetchDone, + processResponse, + dispatcher: init.dispatcher ?? getGlobalDispatcher() // undici + }) + + // 14. Return p. + return p.promise +} + +// https://fetch.spec.whatwg.org/#finalize-and-report-timing +function finalizeAndReportTiming (response, initiatorType = 'other') { + // 1. If response is an aborted network error, then return. + if (response.type === 'error' && response.aborted) { + return + } + + // 2. If response’s URL list is null or empty, then return. + if (!response.urlList?.length) { + return + } + + // 3. Let originalURL be response’s URL list[0]. + const originalURL = response.urlList[0] + + // 4. Let timingInfo be response’s timing info. + let timingInfo = response.timingInfo + + // 5. Let cacheState be response’s cache state. + let cacheState = response.cacheState + + // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return. + if (!urlIsHttpHttpsScheme(originalURL)) { + return + } + + // 7. If timingInfo is null, then return. + if (timingInfo === null) { + return + } + + // 8. If response’s timing allow passed flag is not set, then: + if (!response.timingAllowPassed) { + // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo. + timingInfo = createOpaqueTimingInfo({ + startTime: timingInfo.startTime + }) + + // 2. Set cacheState to the empty string. + cacheState = '' + } + + // 9. Set timingInfo’s end time to the coarsened shared current time + // given global’s relevant settings object’s cross-origin isolated + // capability. + // TODO: given global’s relevant settings object’s cross-origin isolated + // capability? + timingInfo.endTime = coarsenedSharedCurrentTime() + + // 10. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo + + // 11. Mark resource timing for timingInfo, originalURL, initiatorType, + // global, and cacheState. + markResourceTiming( + timingInfo, + originalURL, + initiatorType, + globalThis, + cacheState + ) +} + +// https://w3c.github.io/resource-timing/#dfn-mark-resource-timing +function markResourceTiming (timingInfo, originalURL, initiatorType, globalThis, cacheState) { + if (nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 2)) { + performance.markResourceTiming(timingInfo, originalURL.href, initiatorType, globalThis, cacheState) + } +} + +// https://fetch.spec.whatwg.org/#abort-fetch +function abortFetch (p, request, responseObject, error) { + // Note: AbortSignal.reason was added in node v17.2.0 + // which would give us an undefined error to reject with. + // Remove this once node v16 is no longer supported. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError') + } + + // 1. Reject promise with error. + p.reject(error) + + // 2. If request’s body is not null and is readable, then cancel request’s + // body with error. + if (request.body != null && isReadable(request.body?.stream)) { + request.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }) + } + + // 3. If responseObject is null, then return. + if (responseObject == null) { + return + } + + // 4. Let response be responseObject’s response. + const response = responseObject[kState] + + // 5. If response’s body is not null and is readable, then error response’s + // body with error. + if (response.body != null && isReadable(response.body?.stream)) { + response.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }) + } +} + +// https://fetch.spec.whatwg.org/#fetching +function fetching ({ + request, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseEndOfBody, + processResponseConsumeBody, + useParallelQueue = false, + dispatcher // undici +}) { + // 1. Let taskDestination be null. + let taskDestination = null + + // 2. Let crossOriginIsolatedCapability be false. + let crossOriginIsolatedCapability = false + + // 3. If request’s client is non-null, then: + if (request.client != null) { + // 1. Set taskDestination to request’s client’s global object. + taskDestination = request.client.globalObject + + // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin + // isolated capability. + crossOriginIsolatedCapability = + request.client.crossOriginIsolatedCapability + } + + // 4. If useParallelQueue is true, then set taskDestination to the result of + // starting a new parallel queue. + // TODO + + // 5. Let timingInfo be a new fetch timing info whose start time and + // post-redirect start time are the coarsened shared current time given + // crossOriginIsolatedCapability. + const currenTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability) + const timingInfo = createOpaqueTimingInfo({ + startTime: currenTime + }) + + // 6. Let fetchParams be a new fetch params whose + // request is request, + // timing info is timingInfo, + // process request body chunk length is processRequestBodyChunkLength, + // process request end-of-body is processRequestEndOfBody, + // process response is processResponse, + // process response consume body is processResponseConsumeBody, + // process response end-of-body is processResponseEndOfBody, + // task destination is taskDestination, + // and cross-origin isolated capability is crossOriginIsolatedCapability. + const fetchParams = { + controller: new Fetch(dispatcher), + request, + timingInfo, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseConsumeBody, + processResponseEndOfBody, + taskDestination, + crossOriginIsolatedCapability + } + + // 7. If request’s body is a byte sequence, then set request’s body to + // request’s body as a body. + // NOTE: Since fetching is only called from fetch, body should already be + // extracted. + assert(!request.body || request.body.stream) + + // 8. If request’s window is "client", then set request’s window to request’s + // client, if request’s client’s global object is a Window object; otherwise + // "no-window". + if (request.window === 'client') { + // TODO: What if request.client is null? + request.window = + request.client?.globalObject?.constructor?.name === 'Window' + ? request.client + : 'no-window' + } + + // 9. If request’s origin is "client", then set request’s origin to request’s + // client’s origin. + if (request.origin === 'client') { + // TODO: What if request.client is null? + request.origin = request.client?.origin + } + + // 10. If all of the following conditions are true: + // TODO + + // 11. If request’s policy container is "client", then: + if (request.policyContainer === 'client') { + // 1. If request’s client is non-null, then set request’s policy + // container to a clone of request’s client’s policy container. [HTML] + if (request.client != null) { + request.policyContainer = clonePolicyContainer( + request.client.policyContainer + ) + } else { + // 2. Otherwise, set request’s policy container to a new policy + // container. + request.policyContainer = makePolicyContainer() + } + } + + // 12. If request’s header list does not contain `Accept`, then: + if (!request.headersList.contains('accept')) { + // 1. Let value be `*/*`. + const value = '*/*' + + // 2. A user agent should set value to the first matching statement, if + // any, switching on request’s destination: + // "document" + // "frame" + // "iframe" + // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` + // "image" + // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5` + // "style" + // `text/css,*/*;q=0.1` + // TODO + + // 3. Append `Accept`/value to request’s header list. + request.headersList.append('accept', value) + } + + // 13. If request’s header list does not contain `Accept-Language`, then + // user agents should append `Accept-Language`/an appropriate value to + // request’s header list. + if (!request.headersList.contains('accept-language')) { + request.headersList.append('accept-language', '*') + } + + // 14. If request’s priority is null, then use request’s initiator and + // destination appropriately in setting request’s priority to a + // user-agent-defined object. + if (request.priority === null) { + // TODO + } + + // 15. If request is a subresource request, then: + if (subresourceSet.has(request.destination)) { + // TODO + } + + // 16. Run main fetch given fetchParams. + mainFetch(fetchParams) + .catch(err => { + fetchParams.controller.terminate(err) + }) + + // 17. Return fetchParam's controller + return fetchParams.controller +} + +// https://fetch.spec.whatwg.org/#concept-main-fetch +async function mainFetch (fetchParams, recursive = false) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let response be null. + let response = null + + // 3. If request’s local-URLs-only flag is set and request’s current URL is + // not local, then set response to a network error. + if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { + response = makeNetworkError('local URLs only') + } + + // 4. Run report Content Security Policy violations for request. + // TODO + + // 5. Upgrade request to a potentially trustworthy URL, if appropriate. + tryUpgradeRequestToAPotentiallyTrustworthyURL(request) + + // 6. If should request be blocked due to a bad port, should fetching request + // be blocked as mixed content, or should request be blocked by Content + // Security Policy returns blocked, then set response to a network error. + if (requestBadPort(request) === 'blocked') { + response = makeNetworkError('bad port') + } + // TODO: should fetching request be blocked as mixed content? + // TODO: should request be blocked by Content Security Policy? + + // 7. If request’s referrer policy is the empty string, then set request’s + // referrer policy to request’s policy container’s referrer policy. + if (request.referrerPolicy === '') { + request.referrerPolicy = request.policyContainer.referrerPolicy + } + + // 8. If request’s referrer is not "no-referrer", then set request’s + // referrer to the result of invoking determine request’s referrer. + if (request.referrer !== 'no-referrer') { + request.referrer = determineRequestsReferrer(request) + } + + // 9. Set request’s current URL’s scheme to "https" if all of the following + // conditions are true: + // - request’s current URL’s scheme is "http" + // - request’s current URL’s host is a domain + // - Matching request’s current URL’s host per Known HSTS Host Domain Name + // Matching results in either a superdomain match with an asserted + // includeSubDomains directive or a congruent match (with or without an + // asserted includeSubDomains directive). [HSTS] + // TODO + + // 10. If recursive is false, then run the remaining steps in parallel. + // TODO + + // 11. If response is null, then set response to the result of running + // the steps corresponding to the first matching statement: + if (response === null) { + response = await (async () => { + const currentURL = requestCurrentURL(request) + + if ( + // - request’s current URL’s origin is same origin with request’s origin, + // and request’s response tainting is "basic" + (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') || + // request’s current URL’s scheme is "data" + (currentURL.protocol === 'data:') || + // - request’s mode is "navigate" or "websocket" + (request.mode === 'navigate' || request.mode === 'websocket') + ) { + // 1. Set request’s response tainting to "basic". + request.responseTainting = 'basic' + + // 2. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } + + // request’s mode is "same-origin" + if (request.mode === 'same-origin') { + // 1. Return a network error. + return makeNetworkError('request mode cannot be "same-origin"') + } + + // request’s mode is "no-cors" + if (request.mode === 'no-cors') { + // 1. If request’s redirect mode is not "follow", then return a network + // error. + if (request.redirect !== 'follow') { + return makeNetworkError( + 'redirect mode cannot be "follow" for "no-cors" request' + ) + } + + // 2. Set request’s response tainting to "opaque". + request.responseTainting = 'opaque' + + // 3. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } + + // request’s current URL’s scheme is not an HTTP(S) scheme + if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { + // Return a network error. + return makeNetworkError('URL scheme must be a HTTP(S) scheme') + } + + // - request’s use-CORS-preflight flag is set + // - request’s unsafe-request flag is set and either request’s method is + // not a CORS-safelisted method or CORS-unsafe request-header names with + // request’s header list is not empty + // 1. Set request’s response tainting to "cors". + // 2. Let corsWithPreflightResponse be the result of running HTTP fetch + // given fetchParams and true. + // 3. If corsWithPreflightResponse is a network error, then clear cache + // entries using request. + // 4. Return corsWithPreflightResponse. + // TODO + + // Otherwise + // 1. Set request’s response tainting to "cors". + request.responseTainting = 'cors' + + // 2. Return the result of running HTTP fetch given fetchParams. + return await httpFetch(fetchParams) + })() + } + + // 12. If recursive is true, then return response. + if (recursive) { + return response + } + + // 13. If response is not a network error and response is not a filtered + // response, then: + if (response.status !== 0 && !response.internalResponse) { + // If request’s response tainting is "cors", then: + if (request.responseTainting === 'cors') { + // 1. Let headerNames be the result of extracting header list values + // given `Access-Control-Expose-Headers` and response’s header list. + // TODO + // 2. If request’s credentials mode is not "include" and headerNames + // contains `*`, then set response’s CORS-exposed header-name list to + // all unique header names in response’s header list. + // TODO + // 3. Otherwise, if headerNames is not null or failure, then set + // response’s CORS-exposed header-name list to headerNames. + // TODO + } + + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (request.responseTainting === 'basic') { + response = filterResponse(response, 'basic') + } else if (request.responseTainting === 'cors') { + response = filterResponse(response, 'cors') + } else if (request.responseTainting === 'opaque') { + response = filterResponse(response, 'opaque') + } else { + assert(false) + } + } + + // 14. Let internalResponse be response, if response is a network error, + // and response’s internal response otherwise. + let internalResponse = + response.status === 0 ? response : response.internalResponse + + // 15. If internalResponse’s URL list is empty, then set it to a clone of + // request’s URL list. + if (internalResponse.urlList.length === 0) { + internalResponse.urlList.push(...request.urlList) + } + + // 16. If request’s timing allow failed flag is unset, then set + // internalResponse’s timing allow passed flag. + if (!request.timingAllowFailed) { + response.timingAllowPassed = true + } + + // 17. If response is not a network error and any of the following returns + // blocked + // - should internalResponse to request be blocked as mixed content + // - should internalResponse to request be blocked by Content Security Policy + // - should internalResponse to request be blocked due to its MIME type + // - should internalResponse to request be blocked due to nosniff + // TODO + + // 18. If response’s type is "opaque", internalResponse’s status is 206, + // internalResponse’s range-requested flag is set, and request’s header + // list does not contain `Range`, then set response and internalResponse + // to a network error. + if ( + response.type === 'opaque' && + internalResponse.status === 206 && + internalResponse.rangeRequested && + !request.headers.contains('range') + ) { + response = internalResponse = makeNetworkError() + } + + // 19. If response is not a network error and either request’s method is + // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, + // set internalResponse’s body to null and disregard any enqueuing toward + // it (if any). + if ( + response.status !== 0 && + (request.method === 'HEAD' || + request.method === 'CONNECT' || + nullBodyStatus.includes(internalResponse.status)) + ) { + internalResponse.body = null + fetchParams.controller.dump = true + } + + // 20. If request’s integrity metadata is not the empty string, then: + if (request.integrity) { + // 1. Let processBodyError be this step: run fetch finale given fetchParams + // and a network error. + const processBodyError = (reason) => + fetchFinale(fetchParams, makeNetworkError(reason)) + + // 2. If request’s response tainting is "opaque", or response’s body is null, + // then run processBodyError and abort these steps. + if (request.responseTainting === 'opaque' || response.body == null) { + processBodyError(response.error) + return + } + + // 3. Let processBody given bytes be these steps: + const processBody = (bytes) => { + // 1. If bytes do not match request’s integrity metadata, + // then run processBodyError and abort these steps. [SRI] + if (!bytesMatch(bytes, request.integrity)) { + processBodyError('integrity mismatch') + return + } + + // 2. Set response’s body to bytes as a body. + response.body = safelyExtractBody(bytes)[0] + + // 3. Run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response) + } + + // 4. Fully read response’s body given processBody and processBodyError. + await fullyReadBody(response.body, processBody, processBodyError) + } else { + // 21. Otherwise, run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response) + } +} + +// https://fetch.spec.whatwg.org/#concept-scheme-fetch +// given a fetch params fetchParams +function schemeFetch (fetchParams) { + // Note: since the connection is destroyed on redirect, which sets fetchParams to a + // cancelled state, we do not want this condition to trigger *unless* there have been + // no redirects. See https://github.com/nodejs/undici/issues/1776 + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { + return Promise.resolve(makeAppropriateNetworkError(fetchParams)) + } + + // 2. Let request be fetchParams’s request. + const { request } = fetchParams + + const { protocol: scheme } = requestCurrentURL(request) + + // 3. Switch on request’s current URL’s scheme and run the associated steps: + switch (scheme) { + case 'about:': { + // If request’s current URL’s path is the string "blank", then return a new response + // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) », + // and body is the empty byte sequence as a body. + + // Otherwise, return a network error. + return Promise.resolve(makeNetworkError('about scheme is not supported')) + } + case 'blob:': { + if (!resolveObjectURL) { + resolveObjectURL = (__nccwpck_require__(4300).resolveObjectURL) + } + + // 1. Let blobURLEntry be request’s current URL’s blob URL entry. + const blobURLEntry = requestCurrentURL(request) + + // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 + // Buffer.resolveObjectURL does not ignore URL queries. + if (blobURLEntry.search.length !== 0) { + return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) + } + + const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()) + + // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s + // object is not a Blob object, then return a network error. + if (request.method !== 'GET' || !isBlobLike(blobURLEntryObject)) { + return Promise.resolve(makeNetworkError('invalid method')) + } + + // 3. Let bodyWithType be the result of safely extracting blobURLEntry’s object. + const bodyWithType = safelyExtractBody(blobURLEntryObject) + + // 4. Let body be bodyWithType’s body. + const body = bodyWithType[0] + + // 5. Let length be body’s length, serialized and isomorphic encoded. + const length = isomorphicEncode(`${body.length}`) + + // 6. Let type be bodyWithType’s type if it is non-null; otherwise the empty byte sequence. + const type = bodyWithType[1] ?? '' + + // 7. Return a new response whose status message is `OK`, header list is + // « (`Content-Length`, length), (`Content-Type`, type) », and body is body. + const response = makeResponse({ + statusText: 'OK', + headersList: [ + ['content-length', { name: 'Content-Length', value: length }], + ['content-type', { name: 'Content-Type', value: type }] + ] + }) + + response.body = body + + return Promise.resolve(response) + } + case 'data:': { + // 1. Let dataURLStruct be the result of running the + // data: URL processor on request’s current URL. + const currentURL = requestCurrentURL(request) + const dataURLStruct = dataURLProcessor(currentURL) + + // 2. If dataURLStruct is failure, then return a + // network error. + if (dataURLStruct === 'failure') { + return Promise.resolve(makeNetworkError('failed to fetch the data URL')) + } + + // 3. Let mimeType be dataURLStruct’s MIME type, serialized. + const mimeType = serializeAMimeType(dataURLStruct.mimeType) + + // 4. Return a response whose status message is `OK`, + // header list is « (`Content-Type`, mimeType) », + // and body is dataURLStruct’s body as a body. + return Promise.resolve(makeResponse({ + statusText: 'OK', + headersList: [ + ['content-type', { name: 'Content-Type', value: mimeType }] + ], + body: safelyExtractBody(dataURLStruct.body)[0] + })) + } + case 'file:': { + // For now, unfortunate as it is, file URLs are left as an exercise for the reader. + // When in doubt, return a network error. + return Promise.resolve(makeNetworkError('not implemented... yet...')) + } + case 'http:': + case 'https:': { + // Return the result of running HTTP fetch given fetchParams. + + return httpFetch(fetchParams) + .catch((err) => makeNetworkError(err)) + } + default: { + return Promise.resolve(makeNetworkError('unknown scheme')) + } + } +} + +// https://fetch.spec.whatwg.org/#finalize-response +function finalizeResponse (fetchParams, response) { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true + + // 2, If fetchParams’s process response done is not null, then queue a fetch + // task to run fetchParams’s process response done given response, with + // fetchParams’s task destination. + if (fetchParams.processResponseDone != null) { + queueMicrotask(() => fetchParams.processResponseDone(response)) + } +} + +// https://fetch.spec.whatwg.org/#fetch-finale +function fetchFinale (fetchParams, response) { + // 1. If response is a network error, then: + if (response.type === 'error') { + // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ». + response.urlList = [fetchParams.request.urlList[0]] + + // 2. Set response’s timing info to the result of creating an opaque timing + // info for fetchParams’s timing info. + response.timingInfo = createOpaqueTimingInfo({ + startTime: fetchParams.timingInfo.startTime + }) + } + + // 2. Let processResponseEndOfBody be the following steps: + const processResponseEndOfBody = () => { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true + + // If fetchParams’s process response end-of-body is not null, + // then queue a fetch task to run fetchParams’s process response + // end-of-body given response with fetchParams’s task destination. + if (fetchParams.processResponseEndOfBody != null) { + queueMicrotask(() => fetchParams.processResponseEndOfBody(response)) + } + } + + // 3. If fetchParams’s process response is non-null, then queue a fetch task + // to run fetchParams’s process response given response, with fetchParams’s + // task destination. + if (fetchParams.processResponse != null) { + queueMicrotask(() => fetchParams.processResponse(response)) + } + + // 4. If response’s body is null, then run processResponseEndOfBody. + if (response.body == null) { + processResponseEndOfBody() + } else { + // 5. Otherwise: + + // 1. Let transformStream be a new a TransformStream. + + // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, + // enqueues chunk in transformStream. + const identityTransformAlgorithm = (chunk, controller) => { + controller.enqueue(chunk) + } + + // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm + // and flushAlgorithm set to processResponseEndOfBody. + const transformStream = new TransformStream({ + start () {}, + transform: identityTransformAlgorithm, + flush: processResponseEndOfBody + }, { + size () { + return 1 + } + }, { + size () { + return 1 + } + }) + + // 4. Set response’s body to the result of piping response’s body through transformStream. + response.body = { stream: response.body.stream.pipeThrough(transformStream) } + } + + // 6. If fetchParams’s process response consume body is non-null, then: + if (fetchParams.processResponseConsumeBody != null) { + // 1. Let processBody given nullOrBytes be this step: run fetchParams’s + // process response consume body given response and nullOrBytes. + const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes) + + // 2. Let processBodyError be this step: run fetchParams’s process + // response consume body given response and failure. + const processBodyError = (failure) => fetchParams.processResponseConsumeBody(response, failure) + + // 3. If response’s body is null, then queue a fetch task to run processBody + // given null, with fetchParams’s task destination. + if (response.body == null) { + queueMicrotask(() => processBody(null)) + } else { + // 4. Otherwise, fully read response’s body given processBody, processBodyError, + // and fetchParams’s task destination. + return fullyReadBody(response.body, processBody, processBodyError) + } + return Promise.resolve() + } +} + +// https://fetch.spec.whatwg.org/#http-fetch +async function httpFetch (fetchParams) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let response be null. + let response = null + + // 3. Let actualResponse be null. + let actualResponse = null + + // 4. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo + + // 5. If request’s service-workers mode is "all", then: + if (request.serviceWorkers === 'all') { + // TODO + } + + // 6. If response is null, then: + if (response === null) { + // 1. If makeCORSPreflight is true and one of these conditions is true: + // TODO + + // 2. If request’s redirect mode is "follow", then set request’s + // service-workers mode to "none". + if (request.redirect === 'follow') { + request.serviceWorkers = 'none' + } + + // 3. Set response and actualResponse to the result of running + // HTTP-network-or-cache fetch given fetchParams. + actualResponse = response = await httpNetworkOrCacheFetch(fetchParams) + + // 4. If request’s response tainting is "cors" and a CORS check + // for request and response returns failure, then return a network error. + if ( + request.responseTainting === 'cors' && + corsCheck(request, response) === 'failure' + ) { + return makeNetworkError('cors failure') + } + + // 5. If the TAO check for request and response returns failure, then set + // request’s timing allow failed flag. + if (TAOCheck(request, response) === 'failure') { + request.timingAllowFailed = true + } + } + + // 7. If either request’s response tainting or response’s type + // is "opaque", and the cross-origin resource policy check with + // request’s origin, request’s client, request’s destination, + // and actualResponse returns blocked, then return a network error. + if ( + (request.responseTainting === 'opaque' || response.type === 'opaque') && + crossOriginResourcePolicyCheck( + request.origin, + request.client, + request.destination, + actualResponse + ) === 'blocked' + ) { + return makeNetworkError('blocked') + } + + // 8. If actualResponse’s status is a redirect status, then: + if (redirectStatusSet.has(actualResponse.status)) { + // 1. If actualResponse’s status is not 303, request’s body is not null, + // and the connection uses HTTP/2, then user agents may, and are even + // encouraged to, transmit an RST_STREAM frame. + // See, https://github.com/whatwg/fetch/issues/1288 + if (request.redirect !== 'manual') { + fetchParams.controller.connection.destroy() + } + + // 2. Switch on request’s redirect mode: + if (request.redirect === 'error') { + // Set response to a network error. + response = makeNetworkError('unexpected redirect') + } else if (request.redirect === 'manual') { + // Set response to an opaque-redirect filtered response whose internal + // response is actualResponse. + // NOTE(spec): On the web this would return an `opaqueredirect` response, + // but that doesn't make sense server side. + // See https://github.com/nodejs/undici/issues/1193. + response = actualResponse + } else if (request.redirect === 'follow') { + // Set response to the result of running HTTP-redirect fetch given + // fetchParams and response. + response = await httpRedirectFetch(fetchParams, response) + } else { + assert(false) + } + } + + // 9. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo + + // 10. Return response. + return response +} + +// https://fetch.spec.whatwg.org/#http-redirect-fetch +function httpRedirectFetch (fetchParams, response) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let actualResponse be response, if response is not a filtered response, + // and response’s internal response otherwise. + const actualResponse = response.internalResponse + ? response.internalResponse + : response + + // 3. Let locationURL be actualResponse’s location URL given request’s current + // URL’s fragment. + let locationURL + + try { + locationURL = responseLocationURL( + actualResponse, + requestCurrentURL(request).hash + ) + + // 4. If locationURL is null, then return response. + if (locationURL == null) { + return response + } + } catch (err) { + // 5. If locationURL is failure, then return a network error. + return Promise.resolve(makeNetworkError(err)) + } + + // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network + // error. + if (!urlIsHttpHttpsScheme(locationURL)) { + return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme')) + } + + // 7. If request’s redirect count is 20, then return a network error. + if (request.redirectCount === 20) { + return Promise.resolve(makeNetworkError('redirect count exceeded')) + } + + // 8. Increase request’s redirect count by 1. + request.redirectCount += 1 + + // 9. If request’s mode is "cors", locationURL includes credentials, and + // request’s origin is not same origin with locationURL’s origin, then return + // a network error. + if ( + request.mode === 'cors' && + (locationURL.username || locationURL.password) && + !sameOrigin(request, locationURL) + ) { + return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')) + } + + // 10. If request’s response tainting is "cors" and locationURL includes + // credentials, then return a network error. + if ( + request.responseTainting === 'cors' && + (locationURL.username || locationURL.password) + ) { + return Promise.resolve(makeNetworkError( + 'URL cannot contain credentials for request mode "cors"' + )) + } + + // 11. If actualResponse’s status is not 303, request’s body is non-null, + // and request’s body’s source is null, then return a network error. + if ( + actualResponse.status !== 303 && + request.body != null && + request.body.source == null + ) { + return Promise.resolve(makeNetworkError()) + } + + // 12. If one of the following is true + // - actualResponse’s status is 301 or 302 and request’s method is `POST` + // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD` + if ( + ([301, 302].includes(actualResponse.status) && request.method === 'POST') || + (actualResponse.status === 303 && + !GET_OR_HEAD.includes(request.method)) + ) { + // then: + // 1. Set request’s method to `GET` and request’s body to null. + request.method = 'GET' + request.body = null + + // 2. For each headerName of request-body-header name, delete headerName from + // request’s header list. + for (const headerName of requestBodyHeader) { + request.headersList.delete(headerName) + } + } + + // 13. If request’s current URL’s origin is not same origin with locationURL’s + // origin, then for each headerName of CORS non-wildcard request-header name, + // delete headerName from request’s header list. + if (!sameOrigin(requestCurrentURL(request), locationURL)) { + // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name + request.headersList.delete('authorization') + + // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. + request.headersList.delete('cookie') + request.headersList.delete('host') + } + + // 14. If request’s body is non-null, then set request’s body to the first return + // value of safely extracting request’s body’s source. + if (request.body != null) { + assert(request.body.source != null) + request.body = safelyExtractBody(request.body.source)[0] + } + + // 15. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo + + // 16. Set timingInfo’s redirect end time and post-redirect start time to the + // coarsened shared current time given fetchParams’s cross-origin isolated + // capability. + timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = + coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) + + // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s + // redirect start time to timingInfo’s start time. + if (timingInfo.redirectStartTime === 0) { + timingInfo.redirectStartTime = timingInfo.startTime + } + + // 18. Append locationURL to request’s URL list. + request.urlList.push(locationURL) + + // 19. Invoke set request’s referrer policy on redirect on request and + // actualResponse. + setRequestReferrerPolicyOnRedirect(request, actualResponse) + + // 20. Return the result of running main fetch given fetchParams and true. + return mainFetch(fetchParams, true) +} + +// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch +async function httpNetworkOrCacheFetch ( + fetchParams, + isAuthenticationFetch = false, + isNewConnectionFetch = false +) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let httpFetchParams be null. + let httpFetchParams = null + + // 3. Let httpRequest be null. + let httpRequest = null + + // 4. Let response be null. + let response = null + + // 5. Let storedResponse be null. + // TODO: cache + + // 6. Let httpCache be null. + const httpCache = null + + // 7. Let the revalidatingFlag be unset. + const revalidatingFlag = false + + // 8. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. If request’s window is "no-window" and request’s redirect mode is + // "error", then set httpFetchParams to fetchParams and httpRequest to + // request. + if (request.window === 'no-window' && request.redirect === 'error') { + httpFetchParams = fetchParams + httpRequest = request + } else { + // Otherwise: + + // 1. Set httpRequest to a clone of request. + httpRequest = makeRequest(request) + + // 2. Set httpFetchParams to a copy of fetchParams. + httpFetchParams = { ...fetchParams } + + // 3. Set httpFetchParams’s request to httpRequest. + httpFetchParams.request = httpRequest + } + + // 3. Let includeCredentials be true if one of + const includeCredentials = + request.credentials === 'include' || + (request.credentials === 'same-origin' && + request.responseTainting === 'basic') + + // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s + // body is non-null; otherwise null. + const contentLength = httpRequest.body ? httpRequest.body.length : null + + // 5. Let contentLengthHeaderValue be null. + let contentLengthHeaderValue = null + + // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or + // `PUT`, then set contentLengthHeaderValue to `0`. + if ( + httpRequest.body == null && + ['POST', 'PUT'].includes(httpRequest.method) + ) { + contentLengthHeaderValue = '0' + } + + // 7. If contentLength is non-null, then set contentLengthHeaderValue to + // contentLength, serialized and isomorphic encoded. + if (contentLength != null) { + contentLengthHeaderValue = isomorphicEncode(`${contentLength}`) + } + + // 8. If contentLengthHeaderValue is non-null, then append + // `Content-Length`/contentLengthHeaderValue to httpRequest’s header + // list. + if (contentLengthHeaderValue != null) { + httpRequest.headersList.append('content-length', contentLengthHeaderValue) + } + + // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, + // contentLengthHeaderValue) to httpRequest’s header list. + + // 10. If contentLength is non-null and httpRequest’s keepalive is true, + // then: + if (contentLength != null && httpRequest.keepalive) { + // NOTE: keepalive is a noop outside of browser context. + } + + // 11. If httpRequest’s referrer is a URL, then append + // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, + // to httpRequest’s header list. + if (httpRequest.referrer instanceof URL) { + httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href)) + } + + // 12. Append a request `Origin` header for httpRequest. + appendRequestOriginHeader(httpRequest) + + // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA] + appendFetchMetadata(httpRequest) + + // 14. If httpRequest’s header list does not contain `User-Agent`, then + // user agents should append `User-Agent`/default `User-Agent` value to + // httpRequest’s header list. + if (!httpRequest.headersList.contains('user-agent')) { + httpRequest.headersList.append('user-agent', typeof esbuildDetection === 'undefined' ? 'undici' : 'node') + } + + // 15. If httpRequest’s cache mode is "default" and httpRequest’s header + // list contains `If-Modified-Since`, `If-None-Match`, + // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set + // httpRequest’s cache mode to "no-store". + if ( + httpRequest.cache === 'default' && + (httpRequest.headersList.contains('if-modified-since') || + httpRequest.headersList.contains('if-none-match') || + httpRequest.headersList.contains('if-unmodified-since') || + httpRequest.headersList.contains('if-match') || + httpRequest.headersList.contains('if-range')) + ) { + httpRequest.cache = 'no-store' + } + + // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent + // no-cache cache-control header modification flag is unset, and + // httpRequest’s header list does not contain `Cache-Control`, then append + // `Cache-Control`/`max-age=0` to httpRequest’s header list. + if ( + httpRequest.cache === 'no-cache' && + !httpRequest.preventNoCacheCacheControlHeaderModification && + !httpRequest.headersList.contains('cache-control') + ) { + httpRequest.headersList.append('cache-control', 'max-age=0') + } + + // 17. If httpRequest’s cache mode is "no-store" or "reload", then: + if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') { + // 1. If httpRequest’s header list does not contain `Pragma`, then append + // `Pragma`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('pragma')) { + httpRequest.headersList.append('pragma', 'no-cache') + } + + // 2. If httpRequest’s header list does not contain `Cache-Control`, + // then append `Cache-Control`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('cache-control')) { + httpRequest.headersList.append('cache-control', 'no-cache') + } + } + + // 18. If httpRequest’s header list contains `Range`, then append + // `Accept-Encoding`/`identity` to httpRequest’s header list. + if (httpRequest.headersList.contains('range')) { + httpRequest.headersList.append('accept-encoding', 'identity') + } + + // 19. Modify httpRequest’s header list per HTTP. Do not append a given + // header if httpRequest’s header list contains that header’s name. + // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 + if (!httpRequest.headersList.contains('accept-encoding')) { + if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { + httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate') + } else { + httpRequest.headersList.append('accept-encoding', 'gzip, deflate') + } + } + + httpRequest.headersList.delete('host') + + // 20. If includeCredentials is true, then: + if (includeCredentials) { + // 1. If the user agent is not configured to block cookies for httpRequest + // (see section 7 of [COOKIES]), then: + // TODO: credentials + // 2. If httpRequest’s header list does not contain `Authorization`, then: + // TODO: credentials + } + + // 21. If there’s a proxy-authentication entry, use it as appropriate. + // TODO: proxy-authentication + + // 22. Set httpCache to the result of determining the HTTP cache + // partition, given httpRequest. + // TODO: cache + + // 23. If httpCache is null, then set httpRequest’s cache mode to + // "no-store". + if (httpCache == null) { + httpRequest.cache = 'no-store' + } + + // 24. If httpRequest’s cache mode is neither "no-store" nor "reload", + // then: + if (httpRequest.mode !== 'no-store' && httpRequest.mode !== 'reload') { + // TODO: cache + } + + // 9. If aborted, then return the appropriate network error for fetchParams. + // TODO + + // 10. If response is null, then: + if (response == null) { + // 1. If httpRequest’s cache mode is "only-if-cached", then return a + // network error. + if (httpRequest.mode === 'only-if-cached') { + return makeNetworkError('only if cached') + } + + // 2. Let forwardResponse be the result of running HTTP-network fetch + // given httpFetchParams, includeCredentials, and isNewConnectionFetch. + const forwardResponse = await httpNetworkFetch( + httpFetchParams, + includeCredentials, + isNewConnectionFetch + ) + + // 3. If httpRequest’s method is unsafe and forwardResponse’s status is + // in the range 200 to 399, inclusive, invalidate appropriate stored + // responses in httpCache, as per the "Invalidation" chapter of HTTP + // Caching, and set storedResponse to null. [HTTP-CACHING] + if ( + !safeMethodsSet.has(httpRequest.method) && + forwardResponse.status >= 200 && + forwardResponse.status <= 399 + ) { + // TODO: cache + } + + // 4. If the revalidatingFlag is set and forwardResponse’s status is 304, + // then: + if (revalidatingFlag && forwardResponse.status === 304) { + // TODO: cache + } + + // 5. If response is null, then: + if (response == null) { + // 1. Set response to forwardResponse. + response = forwardResponse + + // 2. Store httpRequest and forwardResponse in httpCache, as per the + // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING] + // TODO: cache + } + } + + // 11. Set response’s URL list to a clone of httpRequest’s URL list. + response.urlList = [...httpRequest.urlList] + + // 12. If httpRequest’s header list contains `Range`, then set response’s + // range-requested flag. + if (httpRequest.headersList.contains('range')) { + response.rangeRequested = true + } + + // 13. Set response’s request-includes-credentials to includeCredentials. + response.requestIncludesCredentials = includeCredentials + + // 14. If response’s status is 401, httpRequest’s response tainting is not + // "cors", includeCredentials is true, and request’s window is an environment + // settings object, then: + // TODO + + // 15. If response’s status is 407, then: + if (response.status === 407) { + // 1. If request’s window is "no-window", then return a network error. + if (request.window === 'no-window') { + return makeNetworkError() + } + + // 2. ??? + + // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) + } + + // 4. Prompt the end user as appropriate in request’s window and store + // the result as a proxy-authentication entry. [HTTP-AUTH] + // TODO: Invoke some kind of callback? + + // 5. Set response to the result of running HTTP-network-or-cache fetch given + // fetchParams. + // TODO + return makeNetworkError('proxy authentication required') + } + + // 16. If all of the following are true + if ( + // response’s status is 421 + response.status === 421 && + // isNewConnectionFetch is false + !isNewConnectionFetch && + // request’s body is null, or request’s body is non-null and request’s body’s source is non-null + (request.body == null || request.body.source != null) + ) { + // then: + + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) + } + + // 2. Set response to the result of running HTTP-network-or-cache + // fetch given fetchParams, isAuthenticationFetch, and true. + + // TODO (spec): The spec doesn't specify this but we need to cancel + // the active response before we can start a new one. + // https://github.com/whatwg/fetch/issues/1293 + fetchParams.controller.connection.destroy() + + response = await httpNetworkOrCacheFetch( + fetchParams, + isAuthenticationFetch, + true + ) + } + + // 17. If isAuthenticationFetch is true, then create an authentication entry + if (isAuthenticationFetch) { + // TODO + } + + // 18. Return response. + return response +} + +// https://fetch.spec.whatwg.org/#http-network-fetch +async function httpNetworkFetch ( + fetchParams, + includeCredentials = false, + forceNewConnection = false +) { + assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed) + + fetchParams.controller.connection = { + abort: null, + destroyed: false, + destroy (err) { + if (!this.destroyed) { + this.destroyed = true + this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')) + } + } + } + + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let response be null. + let response = null + + // 3. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo + + // 4. Let httpCache be the result of determining the HTTP cache partition, + // given request. + // TODO: cache + const httpCache = null + + // 5. If httpCache is null, then set request’s cache mode to "no-store". + if (httpCache == null) { + request.cache = 'no-store' + } + + // 6. Let networkPartitionKey be the result of determining the network + // partition key given request. + // TODO + + // 7. Let newConnection be "yes" if forceNewConnection is true; otherwise + // "no". + const newConnection = forceNewConnection ? 'yes' : 'no' // eslint-disable-line no-unused-vars + + // 8. Switch on request’s mode: + if (request.mode === 'websocket') { + // Let connection be the result of obtaining a WebSocket connection, + // given request’s current URL. + // TODO + } else { + // Let connection be the result of obtaining a connection, given + // networkPartitionKey, request’s current URL’s origin, + // includeCredentials, and forceNewConnection. + // TODO + } + + // 9. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. If connection is failure, then return a network error. + + // 2. Set timingInfo’s final connection timing info to the result of + // calling clamp and coarsen connection timing info with connection’s + // timing info, timingInfo’s post-redirect start time, and fetchParams’s + // cross-origin isolated capability. + + // 3. If connection is not an HTTP/2 connection, request’s body is non-null, + // and request’s body’s source is null, then append (`Transfer-Encoding`, + // `chunked`) to request’s header list. + + // 4. Set timingInfo’s final network-request start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated + // capability. + + // 5. Set response to the result of making an HTTP request over connection + // using request with the following caveats: + + // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] + // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] + + // - If request’s body is non-null, and request’s body’s source is null, + // then the user agent may have a buffer of up to 64 kibibytes and store + // a part of request’s body in that buffer. If the user agent reads from + // request’s body beyond that buffer’s size and the user agent needs to + // resend request, then instead return a network error. + + // - Set timingInfo’s final network-response start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated capability, + // immediately after the user agent’s HTTP parser receives the first byte + // of the response (e.g., frame header bytes for HTTP/2 or response status + // line for HTTP/1.x). + + // - Wait until all the headers are transmitted. + + // - Any responses whose status is in the range 100 to 199, inclusive, + // and is not 101, are to be ignored, except for the purposes of setting + // timingInfo’s final network-response start time above. + + // - If request’s header list contains `Transfer-Encoding`/`chunked` and + // response is transferred via HTTP/1.0 or older, then return a network + // error. + + // - If the HTTP request results in a TLS client certificate dialog, then: + + // 1. If request’s window is an environment settings object, make the + // dialog available in request’s window. + + // 2. Otherwise, return a network error. + + // To transmit request’s body body, run these steps: + let requestBody = null + // 1. If body is null and fetchParams’s process request end-of-body is + // non-null, then queue a fetch task given fetchParams’s process request + // end-of-body and fetchParams’s task destination. + if (request.body == null && fetchParams.processRequestEndOfBody) { + queueMicrotask(() => fetchParams.processRequestEndOfBody()) + } else if (request.body != null) { + // 2. Otherwise, if body is non-null: + + // 1. Let processBodyChunk given bytes be these steps: + const processBodyChunk = async function * (bytes) { + // 1. If the ongoing fetch is terminated, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. Run this step in parallel: transmit bytes. + yield bytes + + // 3. If fetchParams’s process request body is non-null, then run + // fetchParams’s process request body given bytes’s length. + fetchParams.processRequestBodyChunkLength?.(bytes.byteLength) + } + + // 2. Let processEndOfBody be these steps: + const processEndOfBody = () => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. If fetchParams’s process request end-of-body is non-null, + // then run fetchParams’s process request end-of-body. + if (fetchParams.processRequestEndOfBody) { + fetchParams.processRequestEndOfBody() + } + } + + // 3. Let processBodyError given e be these steps: + const processBodyError = (e) => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller. + if (e.name === 'AbortError') { + fetchParams.controller.abort() + } else { + fetchParams.controller.terminate(e) + } + } + + // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody, + // processBodyError, and fetchParams’s task destination. + requestBody = (async function * () { + try { + for await (const bytes of request.body.stream) { + yield * processBodyChunk(bytes) + } + processEndOfBody() + } catch (err) { + processBodyError(err) + } + })() + } + + try { + // socket is only provided for websockets + const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody }) + + if (socket) { + response = makeResponse({ status, statusText, headersList, socket }) + } else { + const iterator = body[Symbol.asyncIterator]() + fetchParams.controller.next = () => iterator.next() + + response = makeResponse({ status, statusText, headersList }) + } + } catch (err) { + // 10. If aborted, then: + if (err.name === 'AbortError') { + // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame. + fetchParams.controller.connection.destroy() + + // 2. Return the appropriate network error for fetchParams. + return makeAppropriateNetworkError(fetchParams, err) + } + + return makeNetworkError(err) + } + + // 11. Let pullAlgorithm be an action that resumes the ongoing fetch + // if it is suspended. + const pullAlgorithm = () => { + fetchParams.controller.resume() + } + + // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s + // controller with reason, given reason. + const cancelAlgorithm = (reason) => { + fetchParams.controller.abort(reason) + } + + // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by + // the user agent. + // TODO + + // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object + // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent. + // TODO + + // 15. Let stream be a new ReadableStream. + // 16. Set up stream with pullAlgorithm set to pullAlgorithm, + // cancelAlgorithm set to cancelAlgorithm, highWaterMark set to + // highWaterMark, and sizeAlgorithm set to sizeAlgorithm. + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } + + const stream = new ReadableStream( + { + async start (controller) { + fetchParams.controller.controller = controller + }, + async pull (controller) { + await pullAlgorithm(controller) + }, + async cancel (reason) { + await cancelAlgorithm(reason) + } + }, + { + highWaterMark: 0, + size () { + return 1 + } + } + ) + + // 17. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. Set response’s body to a new body whose stream is stream. + response.body = { stream } + + // 2. If response is not a network error and request’s cache mode is + // not "no-store", then update response in httpCache for request. + // TODO + + // 3. If includeCredentials is true and the user agent is not configured + // to block cookies for request (see section 7 of [COOKIES]), then run the + // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on + // the value of each header whose name is a byte-case-insensitive match for + // `Set-Cookie` in response’s header list, if any, and request’s current URL. + // TODO + + // 18. If aborted, then: + // TODO + + // 19. Run these steps in parallel: + + // 1. Run these steps, but abort when fetchParams is canceled: + fetchParams.controller.on('terminated', onAborted) + fetchParams.controller.resume = async () => { + // 1. While true + while (true) { + // 1-3. See onData... + + // 4. Set bytes to the result of handling content codings given + // codings and bytes. + let bytes + let isFailure + try { + const { done, value } = await fetchParams.controller.next() + + if (isAborted(fetchParams)) { + break + } + + bytes = done ? undefined : value + } catch (err) { + if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { + // zlib doesn't like empty streams. + bytes = undefined + } else { + bytes = err + + // err may be propagated from the result of calling readablestream.cancel, + // which might not be an error. https://github.com/nodejs/undici/issues/2009 + isFailure = true + } + } + + if (bytes === undefined) { + // 2. Otherwise, if the bytes transmission for response’s message + // body is done normally and stream is readable, then close + // stream, finalize response for fetchParams and response, and + // abort these in-parallel steps. + readableStreamClose(fetchParams.controller.controller) + + finalizeResponse(fetchParams, response) + + return + } + + // 5. Increase timingInfo’s decoded body size by bytes’s length. + timingInfo.decodedBodySize += bytes?.byteLength ?? 0 + + // 6. If bytes is failure, then terminate fetchParams’s controller. + if (isFailure) { + fetchParams.controller.terminate(bytes) + return + } + + // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes + // into stream. + fetchParams.controller.controller.enqueue(new Uint8Array(bytes)) + + // 8. If stream is errored, then terminate the ongoing fetch. + if (isErrored(stream)) { + fetchParams.controller.terminate() + return + } + + // 9. If stream doesn’t need more data ask the user agent to suspend + // the ongoing fetch. + if (!fetchParams.controller.controller.desiredSize) { + return + } + } + } + + // 2. If aborted, then: + function onAborted (reason) { + // 2. If fetchParams is aborted, then: + if (isAborted(fetchParams)) { + // 1. Set response’s aborted flag. + response.aborted = true + + // 2. If stream is readable, then error stream with the result of + // deserialize a serialized abort reason given fetchParams’s + // controller’s serialized abort reason and an + // implementation-defined realm. + if (isReadable(stream)) { + fetchParams.controller.controller.error( + fetchParams.controller.serializedAbortReason + ) + } + } else { + // 3. Otherwise, if stream is readable, error stream with a TypeError. + if (isReadable(stream)) { + fetchParams.controller.controller.error(new TypeError('terminated', { + cause: isErrorLike(reason) ? reason : undefined + })) + } + } + + // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame. + // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so. + fetchParams.controller.connection.destroy() + } + + // 20. Return response. + return response + + async function dispatch ({ body }) { + const url = requestCurrentURL(request) + /** @type {import('../..').Agent} */ + const agent = fetchParams.controller.dispatcher + + return new Promise((resolve, reject) => agent.dispatch( + { + path: url.pathname + url.search, + origin: url.origin, + method: request.method, + body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, + headers: request.headersList.entries, + maxRedirections: 0, + upgrade: request.mode === 'websocket' ? 'websocket' : undefined + }, + { + body: null, + abort: null, + + onConnect (abort) { + // TODO (fix): Do we need connection here? + const { connection } = fetchParams.controller + + if (connection.destroyed) { + abort(new DOMException('The operation was aborted.', 'AbortError')) + } else { + fetchParams.controller.on('terminated', abort) + this.abort = connection.abort = abort + } + }, + + onHeaders (status, headersList, resume, statusText) { + if (status < 200) { + return + } + + let codings = [] + let location = '' + + const headers = new Headers() + + // For H2, the headers are a plain JS object + // We distinguish between them and iterate accordingly + if (Array.isArray(headersList)) { + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val.toLowerCase().split(',').map((x) => x.trim()) + } else if (key.toLowerCase() === 'location') { + location = val + } + + headers[kHeadersList].append(key, val) + } + } else { + const keys = Object.keys(headersList) + for (const key of keys) { + const val = headersList[key] + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val.toLowerCase().split(',').map((x) => x.trim()).reverse() + } else if (key.toLowerCase() === 'location') { + location = val + } + + headers[kHeadersList].append(key, val) + } + } + + this.body = new Readable({ read: resume }) + + const decoders = [] + + const willFollow = request.redirect === 'follow' && + location && + redirectStatusSet.has(status) + + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { + for (const coding of codings) { + // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 + if (coding === 'x-gzip' || coding === 'gzip') { + decoders.push(zlib.createGunzip({ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH + })) + } else if (coding === 'deflate') { + decoders.push(zlib.createInflate()) + } else if (coding === 'br') { + decoders.push(zlib.createBrotliDecompress()) + } else { + decoders.length = 0 + break + } + } + } + + resolve({ + status, + statusText, + headersList: headers[kHeadersList], + body: decoders.length + ? pipeline(this.body, ...decoders, () => { }) + : this.body.on('error', () => {}) + }) + + return true + }, + + onData (chunk) { + if (fetchParams.controller.dump) { + return + } + + // 1. If one or more bytes have been transmitted from response’s + // message body, then: + + // 1. Let bytes be the transmitted bytes. + const bytes = chunk + + // 2. Let codings be the result of extracting header list values + // given `Content-Encoding` and response’s header list. + // See pullAlgorithm. + + // 3. Increase timingInfo’s encoded body size by bytes’s length. + timingInfo.encodedBodySize += bytes.byteLength + + // 4. See pullAlgorithm... + + return this.body.push(bytes) + }, + + onComplete () { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort) + } + + fetchParams.controller.ended = true + + this.body.push(null) + }, + + onError (error) { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort) + } + + this.body?.destroy(error) + + fetchParams.controller.terminate(error) + + reject(error) + }, + + onUpgrade (status, headersList, socket) { + if (status !== 101) { + return + } + + const headers = new Headers() + + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') + + headers[kHeadersList].append(key, val) + } + + resolve({ + status, + statusText: STATUS_CODES[status], + headersList: headers[kHeadersList], + socket + }) + + return true + } + } + )) + } +} + +module.exports = { + fetch, + Fetch, + fetching, + finalizeAndReportTiming +} + + +/***/ }), + +/***/ 8359: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +/* globals AbortController */ + + + +const { extractBody, mixinBody, cloneBody } = __nccwpck_require__(1472) +const { Headers, fill: fillHeaders, HeadersList } = __nccwpck_require__(554) +const { FinalizationRegistry } = __nccwpck_require__(6436)() +const util = __nccwpck_require__(3983) +const { + isValidHTTPToken, + sameOrigin, + normalizeMethod, + makePolicyContainer, + normalizeMethodRecord +} = __nccwpck_require__(2538) +const { + forbiddenMethodsSet, + corsSafeListedMethodsSet, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + requestDuplex +} = __nccwpck_require__(1037) +const { kEnumerableProperty } = util +const { kHeaders, kSignal, kState, kGuard, kRealm } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { URLSerializer } = __nccwpck_require__(685) +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = __nccwpck_require__(2361) + +let TransformStream = globalThis.TransformStream + +const kAbortController = Symbol('abortController') + +const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { + signal.removeEventListener('abort', abort) +}) + +// https://fetch.spec.whatwg.org/#request-class +class Request { + // https://fetch.spec.whatwg.org/#dom-request + constructor (input, init = {}) { + if (input === kConstruct) { + return + } + + webidl.argumentLengthCheck(arguments, 1, { header: 'Request constructor' }) + + input = webidl.converters.RequestInfo(input) + init = webidl.converters.RequestInit(init) + + // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object + this[kRealm] = { + settingsObject: { + baseUrl: getGlobalOrigin(), + get origin () { + return this.baseUrl?.origin + }, + policyContainer: makePolicyContainer() + } + } + + // 1. Let request be null. + let request = null + + // 2. Let fallbackMode be null. + let fallbackMode = null + + // 3. Let baseURL be this’s relevant settings object’s API base URL. + const baseUrl = this[kRealm].settingsObject.baseUrl + + // 4. Let signal be null. + let signal = null + + // 5. If input is a string, then: + if (typeof input === 'string') { + // 1. Let parsedURL be the result of parsing input with baseURL. + // 2. If parsedURL is failure, then throw a TypeError. + let parsedURL + try { + parsedURL = new URL(input, baseUrl) + } catch (err) { + throw new TypeError('Failed to parse URL from ' + input, { cause: err }) + } + + // 3. If parsedURL includes credentials, then throw a TypeError. + if (parsedURL.username || parsedURL.password) { + throw new TypeError( + 'Request cannot be constructed from a URL that includes credentials: ' + + input + ) + } + + // 4. Set request to a new request whose URL is parsedURL. + request = makeRequest({ urlList: [parsedURL] }) + + // 5. Set fallbackMode to "cors". + fallbackMode = 'cors' + } else { + // 6. Otherwise: + + // 7. Assert: input is a Request object. + assert(input instanceof Request) + + // 8. Set request to input’s request. + request = input[kState] + + // 9. Set signal to input’s signal. + signal = input[kSignal] + } + + // 7. Let origin be this’s relevant settings object’s origin. + const origin = this[kRealm].settingsObject.origin + + // 8. Let window be "client". + let window = 'client' + + // 9. If request’s window is an environment settings object and its origin + // is same origin with origin, then set window to request’s window. + if ( + request.window?.constructor?.name === 'EnvironmentSettingsObject' && + sameOrigin(request.window, origin) + ) { + window = request.window + } + + // 10. If init["window"] exists and is non-null, then throw a TypeError. + if (init.window != null) { + throw new TypeError(`'window' option '${window}' must be null`) + } + + // 11. If init["window"] exists, then set window to "no-window". + if ('window' in init) { + window = 'no-window' + } + + // 12. Set request to a new request with the following properties: + request = makeRequest({ + // URL request’s URL. + // undici implementation note: this is set as the first item in request's urlList in makeRequest + // method request’s method. + method: request.method, + // header list A copy of request’s header list. + // undici implementation note: headersList is cloned in makeRequest + headersList: request.headersList, + // unsafe-request flag Set. + unsafeRequest: request.unsafeRequest, + // client This’s relevant settings object. + client: this[kRealm].settingsObject, + // window window. + window, + // priority request’s priority. + priority: request.priority, + // origin request’s origin. The propagation of the origin is only significant for navigation requests + // being handled by a service worker. In this scenario a request can have an origin that is different + // from the current client. + origin: request.origin, + // referrer request’s referrer. + referrer: request.referrer, + // referrer policy request’s referrer policy. + referrerPolicy: request.referrerPolicy, + // mode request’s mode. + mode: request.mode, + // credentials mode request’s credentials mode. + credentials: request.credentials, + // cache mode request’s cache mode. + cache: request.cache, + // redirect mode request’s redirect mode. + redirect: request.redirect, + // integrity metadata request’s integrity metadata. + integrity: request.integrity, + // keepalive request’s keepalive. + keepalive: request.keepalive, + // reload-navigation flag request’s reload-navigation flag. + reloadNavigation: request.reloadNavigation, + // history-navigation flag request’s history-navigation flag. + historyNavigation: request.historyNavigation, + // URL list A clone of request’s URL list. + urlList: [...request.urlList] + }) + + const initHasKey = Object.keys(init).length !== 0 + + // 13. If init is not empty, then: + if (initHasKey) { + // 1. If request’s mode is "navigate", then set it to "same-origin". + if (request.mode === 'navigate') { + request.mode = 'same-origin' + } + + // 2. Unset request’s reload-navigation flag. + request.reloadNavigation = false + + // 3. Unset request’s history-navigation flag. + request.historyNavigation = false + + // 4. Set request’s origin to "client". + request.origin = 'client' + + // 5. Set request’s referrer to "client" + request.referrer = 'client' + + // 6. Set request’s referrer policy to the empty string. + request.referrerPolicy = '' + + // 7. Set request’s URL to request’s current URL. + request.url = request.urlList[request.urlList.length - 1] + + // 8. Set request’s URL list to « request’s URL ». + request.urlList = [request.url] + } + + // 14. If init["referrer"] exists, then: + if (init.referrer !== undefined) { + // 1. Let referrer be init["referrer"]. + const referrer = init.referrer + + // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". + if (referrer === '') { + request.referrer = 'no-referrer' + } else { + // 1. Let parsedReferrer be the result of parsing referrer with + // baseURL. + // 2. If parsedReferrer is failure, then throw a TypeError. + let parsedReferrer + try { + parsedReferrer = new URL(referrer, baseUrl) + } catch (err) { + throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }) + } + + // 3. If one of the following is true + // - parsedReferrer’s scheme is "about" and path is the string "client" + // - parsedReferrer’s origin is not same origin with origin + // then set request’s referrer to "client". + if ( + (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || + (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl)) + ) { + request.referrer = 'client' + } else { + // 4. Otherwise, set request’s referrer to parsedReferrer. + request.referrer = parsedReferrer + } + } + } + + // 15. If init["referrerPolicy"] exists, then set request’s referrer policy + // to it. + if (init.referrerPolicy !== undefined) { + request.referrerPolicy = init.referrerPolicy + } + + // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. + let mode + if (init.mode !== undefined) { + mode = init.mode + } else { + mode = fallbackMode + } + + // 17. If mode is "navigate", then throw a TypeError. + if (mode === 'navigate') { + throw webidl.errors.exception({ + header: 'Request constructor', + message: 'invalid request mode navigate.' + }) + } + + // 18. If mode is non-null, set request’s mode to mode. + if (mode != null) { + request.mode = mode + } + + // 19. If init["credentials"] exists, then set request’s credentials mode + // to it. + if (init.credentials !== undefined) { + request.credentials = init.credentials + } + + // 18. If init["cache"] exists, then set request’s cache mode to it. + if (init.cache !== undefined) { + request.cache = init.cache + } + + // 21. If request’s cache mode is "only-if-cached" and request’s mode is + // not "same-origin", then throw a TypeError. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + throw new TypeError( + "'only-if-cached' can be set only with 'same-origin' mode" + ) + } + + // 22. If init["redirect"] exists, then set request’s redirect mode to it. + if (init.redirect !== undefined) { + request.redirect = init.redirect + } + + // 23. If init["integrity"] exists, then set request’s integrity metadata to it. + if (init.integrity != null) { + request.integrity = String(init.integrity) + } + + // 24. If init["keepalive"] exists, then set request’s keepalive to it. + if (init.keepalive !== undefined) { + request.keepalive = Boolean(init.keepalive) + } + + // 25. If init["method"] exists, then: + if (init.method !== undefined) { + // 1. Let method be init["method"]. + let method = init.method + + // 2. If method is not a method or method is a forbidden method, then + // throw a TypeError. + if (!isValidHTTPToken(method)) { + throw new TypeError(`'${method}' is not a valid HTTP method.`) + } + + if (forbiddenMethodsSet.has(method.toUpperCase())) { + throw new TypeError(`'${method}' HTTP method is unsupported.`) + } + + // 3. Normalize method. + method = normalizeMethodRecord[method] ?? normalizeMethod(method) + + // 4. Set request’s method to method. + request.method = method + } + + // 26. If init["signal"] exists, then set signal to it. + if (init.signal !== undefined) { + signal = init.signal + } + + // 27. Set this’s request to request. + this[kState] = request + + // 28. Set this’s signal to a new AbortSignal object with this’s relevant + // Realm. + // TODO: could this be simplified with AbortSignal.any + // (https://dom.spec.whatwg.org/#dom-abortsignal-any) + const ac = new AbortController() + this[kSignal] = ac.signal + this[kSignal][kRealm] = this[kRealm] + + // 29. If signal is not null, then make this’s signal follow signal. + if (signal != null) { + if ( + !signal || + typeof signal.aborted !== 'boolean' || + typeof signal.addEventListener !== 'function' + ) { + throw new TypeError( + "Failed to construct 'Request': member signal is not of type AbortSignal." + ) + } + + if (signal.aborted) { + ac.abort(signal.reason) + } else { + // Keep a strong ref to ac while request object + // is alive. This is needed to prevent AbortController + // from being prematurely garbage collected. + // See, https://github.com/nodejs/undici/issues/1926. + this[kAbortController] = ac + + const acRef = new WeakRef(ac) + const abort = function () { + const ac = acRef.deref() + if (ac !== undefined) { + ac.abort(this.reason) + } + } + + // Third-party AbortControllers may not work with these. + // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. + try { + // If the max amount of listeners is equal to the default, increase it + // This is only available in node >= v19.9.0 + if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) { + setMaxListeners(100, signal) + } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) { + setMaxListeners(100, signal) + } + } catch {} + + util.addAbortListener(signal, abort) + requestFinalizer.register(ac, { signal, abort }) + } + } + + // 30. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is request’s header list and guard is + // "request". + this[kHeaders] = new Headers(kConstruct) + this[kHeaders][kHeadersList] = request.headersList + this[kHeaders][kGuard] = 'request' + this[kHeaders][kRealm] = this[kRealm] + + // 31. If this’s request’s mode is "no-cors", then: + if (mode === 'no-cors') { + // 1. If this’s request’s method is not a CORS-safelisted method, + // then throw a TypeError. + if (!corsSafeListedMethodsSet.has(request.method)) { + throw new TypeError( + `'${request.method} is unsupported in no-cors mode.` + ) + } + + // 2. Set this’s headers’s guard to "request-no-cors". + this[kHeaders][kGuard] = 'request-no-cors' + } + + // 32. If init is not empty, then: + if (initHasKey) { + /** @type {HeadersList} */ + const headersList = this[kHeaders][kHeadersList] + // 1. Let headers be a copy of this’s headers and its associated header + // list. + // 2. If init["headers"] exists, then set headers to init["headers"]. + const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList) + + // 3. Empty this’s headers’s header list. + headersList.clear() + + // 4. If headers is a Headers object, then for each header in its header + // list, append header’s name/header’s value to this’s headers. + if (headers instanceof HeadersList) { + for (const [key, val] of headers) { + headersList.append(key, val) + } + // Note: Copy the `set-cookie` meta-data. + headersList.cookies = headers.cookies + } else { + // 5. Otherwise, fill this’s headers with headers. + fillHeaders(this[kHeaders], headers) + } + } + + // 33. Let inputBody be input’s request’s body if input is a Request + // object; otherwise null. + const inputBody = input instanceof Request ? input[kState].body : null + + // 34. If either init["body"] exists and is non-null or inputBody is + // non-null, and request’s method is `GET` or `HEAD`, then throw a + // TypeError. + if ( + (init.body != null || inputBody != null) && + (request.method === 'GET' || request.method === 'HEAD') + ) { + throw new TypeError('Request with GET/HEAD method cannot have body.') + } + + // 35. Let initBody be null. + let initBody = null + + // 36. If init["body"] exists and is non-null, then: + if (init.body != null) { + // 1. Let Content-Type be null. + // 2. Set initBody and Content-Type to the result of extracting + // init["body"], with keepalive set to request’s keepalive. + const [extractedBody, contentType] = extractBody( + init.body, + request.keepalive + ) + initBody = extractedBody + + // 3, If Content-Type is non-null and this’s headers’s header list does + // not contain `Content-Type`, then append `Content-Type`/Content-Type to + // this’s headers. + if (contentType && !this[kHeaders][kHeadersList].contains('content-type')) { + this[kHeaders].append('content-type', contentType) + } + } + + // 37. Let inputOrInitBody be initBody if it is non-null; otherwise + // inputBody. + const inputOrInitBody = initBody ?? inputBody + + // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is + // null, then: + if (inputOrInitBody != null && inputOrInitBody.source == null) { + // 1. If initBody is non-null and init["duplex"] does not exist, + // then throw a TypeError. + if (initBody != null && init.duplex == null) { + throw new TypeError('RequestInit: duplex option is required when sending a body.') + } + + // 2. If this’s request’s mode is neither "same-origin" nor "cors", + // then throw a TypeError. + if (request.mode !== 'same-origin' && request.mode !== 'cors') { + throw new TypeError( + 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' + ) + } + + // 3. Set this’s request’s use-CORS-preflight flag. + request.useCORSPreflightFlag = true + } + + // 39. Let finalBody be inputOrInitBody. + let finalBody = inputOrInitBody + + // 40. If initBody is null and inputBody is non-null, then: + if (initBody == null && inputBody != null) { + // 1. If input is unusable, then throw a TypeError. + if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { + throw new TypeError( + 'Cannot construct a Request with a Request object that has already been used.' + ) + } + + // 2. Set finalBody to the result of creating a proxy for inputBody. + if (!TransformStream) { + TransformStream = (__nccwpck_require__(5356).TransformStream) + } + + // https://streams.spec.whatwg.org/#readablestream-create-a-proxy + const identityTransform = new TransformStream() + inputBody.stream.pipeThrough(identityTransform) + finalBody = { + source: inputBody.source, + length: inputBody.length, + stream: identityTransform.readable + } + } + + // 41. Set this’s request’s body to finalBody. + this[kState].body = finalBody + } + + // Returns request’s HTTP method, which is "GET" by default. + get method () { + webidl.brandCheck(this, Request) + + // The method getter steps are to return this’s request’s method. + return this[kState].method + } + + // Returns the URL of request as a string. + get url () { + webidl.brandCheck(this, Request) + + // The url getter steps are to return this’s request’s URL, serialized. + return URLSerializer(this[kState].url) + } + + // Returns a Headers object consisting of the headers associated with request. + // Note that headers added in the network layer by the user agent will not + // be accounted for in this object, e.g., the "Host" header. + get headers () { + webidl.brandCheck(this, Request) + + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } + + // Returns the kind of resource requested by request, e.g., "document" + // or "script". + get destination () { + webidl.brandCheck(this, Request) + + // The destination getter are to return this’s request’s destination. + return this[kState].destination + } + + // Returns the referrer of request. Its value can be a same-origin URL if + // explicitly set in init, the empty string to indicate no referrer, and + // "about:client" when defaulting to the global’s default. This is used + // during fetching to determine the value of the `Referer` header of the + // request being made. + get referrer () { + webidl.brandCheck(this, Request) + + // 1. If this’s request’s referrer is "no-referrer", then return the + // empty string. + if (this[kState].referrer === 'no-referrer') { + return '' + } + + // 2. If this’s request’s referrer is "client", then return + // "about:client". + if (this[kState].referrer === 'client') { + return 'about:client' + } + + // Return this’s request’s referrer, serialized. + return this[kState].referrer.toString() + } + + // Returns the referrer policy associated with request. + // This is used during fetching to compute the value of the request’s + // referrer. + get referrerPolicy () { + webidl.brandCheck(this, Request) + + // The referrerPolicy getter steps are to return this’s request’s referrer policy. + return this[kState].referrerPolicy + } + + // Returns the mode associated with request, which is a string indicating + // whether the request will use CORS, or will be restricted to same-origin + // URLs. + get mode () { + webidl.brandCheck(this, Request) + + // The mode getter steps are to return this’s request’s mode. + return this[kState].mode + } + + // Returns the credentials mode associated with request, + // which is a string indicating whether credentials will be sent with the + // request always, never, or only when sent to a same-origin URL. + get credentials () { + // The credentials getter steps are to return this’s request’s credentials mode. + return this[kState].credentials + } + + // Returns the cache mode associated with request, + // which is a string indicating how the request will + // interact with the browser’s cache when fetching. + get cache () { + webidl.brandCheck(this, Request) + + // The cache getter steps are to return this’s request’s cache mode. + return this[kState].cache + } + + // Returns the redirect mode associated with request, + // which is a string indicating how redirects for the + // request will be handled during fetching. A request + // will follow redirects by default. + get redirect () { + webidl.brandCheck(this, Request) + + // The redirect getter steps are to return this’s request’s redirect mode. + return this[kState].redirect + } + + // Returns request’s subresource integrity metadata, which is a + // cryptographic hash of the resource being fetched. Its value + // consists of multiple hashes separated by whitespace. [SRI] + get integrity () { + webidl.brandCheck(this, Request) + + // The integrity getter steps are to return this’s request’s integrity + // metadata. + return this[kState].integrity + } + + // Returns a boolean indicating whether or not request can outlive the + // global in which it was created. + get keepalive () { + webidl.brandCheck(this, Request) + + // The keepalive getter steps are to return this’s request’s keepalive. + return this[kState].keepalive + } + + // Returns a boolean indicating whether or not request is for a reload + // navigation. + get isReloadNavigation () { + webidl.brandCheck(this, Request) + + // The isReloadNavigation getter steps are to return true if this’s + // request’s reload-navigation flag is set; otherwise false. + return this[kState].reloadNavigation + } + + // Returns a boolean indicating whether or not request is for a history + // navigation (a.k.a. back-foward navigation). + get isHistoryNavigation () { + webidl.brandCheck(this, Request) + + // The isHistoryNavigation getter steps are to return true if this’s request’s + // history-navigation flag is set; otherwise false. + return this[kState].historyNavigation + } + + // Returns the signal associated with request, which is an AbortSignal + // object indicating whether or not request has been aborted, and its + // abort event handler. + get signal () { + webidl.brandCheck(this, Request) + + // The signal getter steps are to return this’s signal. + return this[kSignal] + } + + get body () { + webidl.brandCheck(this, Request) + + return this[kState].body ? this[kState].body.stream : null + } + + get bodyUsed () { + webidl.brandCheck(this, Request) + + return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + } + + get duplex () { + webidl.brandCheck(this, Request) + + return 'half' + } + + // Returns a clone of request. + clone () { + webidl.brandCheck(this, Request) + + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || this.body?.locked) { + throw new TypeError('unusable') + } + + // 2. Let clonedRequest be the result of cloning this’s request. + const clonedRequest = cloneRequest(this[kState]) + + // 3. Let clonedRequestObject be the result of creating a Request object, + // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. + const clonedRequestObject = new Request(kConstruct) + clonedRequestObject[kState] = clonedRequest + clonedRequestObject[kRealm] = this[kRealm] + clonedRequestObject[kHeaders] = new Headers(kConstruct) + clonedRequestObject[kHeaders][kHeadersList] = clonedRequest.headersList + clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard] + clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm] + + // 4. Make clonedRequestObject’s signal follow this’s signal. + const ac = new AbortController() + if (this.signal.aborted) { + ac.abort(this.signal.reason) + } else { + util.addAbortListener( + this.signal, + () => { + ac.abort(this.signal.reason) + } + ) + } + clonedRequestObject[kSignal] = ac.signal + + // 4. Return clonedRequestObject. + return clonedRequestObject + } +} + +mixinBody(Request) + +function makeRequest (init) { + // https://fetch.spec.whatwg.org/#requests + const request = { + method: 'GET', + localURLsOnly: false, + unsafeRequest: false, + body: null, + client: null, + reservedClient: null, + replacesClientId: '', + window: 'client', + keepalive: false, + serviceWorkers: 'all', + initiator: '', + destination: '', + priority: null, + origin: 'client', + policyContainer: 'client', + referrer: 'client', + referrerPolicy: '', + mode: 'no-cors', + useCORSPreflightFlag: false, + credentials: 'same-origin', + useCredentials: false, + cache: 'default', + redirect: 'follow', + integrity: '', + cryptoGraphicsNonceMetadata: '', + parserMetadata: '', + reloadNavigation: false, + historyNavigation: false, + userActivation: false, + taintedOrigin: false, + redirectCount: 0, + responseTainting: 'basic', + preventNoCacheCacheControlHeaderModification: false, + done: false, + timingAllowFailed: false, + ...init, + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList() + } + request.url = request.urlList[0] + return request +} + +// https://fetch.spec.whatwg.org/#concept-request-clone +function cloneRequest (request) { + // To clone a request request, run these steps: + + // 1. Let newRequest be a copy of request, except for its body. + const newRequest = makeRequest({ ...request, body: null }) + + // 2. If request’s body is non-null, set newRequest’s body to the + // result of cloning request’s body. + if (request.body != null) { + newRequest.body = cloneBody(request.body) + } + + // 3. Return newRequest. + return newRequest +} + +Object.defineProperties(Request.prototype, { + method: kEnumerableProperty, + url: kEnumerableProperty, + headers: kEnumerableProperty, + redirect: kEnumerableProperty, + clone: kEnumerableProperty, + signal: kEnumerableProperty, + duplex: kEnumerableProperty, + destination: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + isHistoryNavigation: kEnumerableProperty, + isReloadNavigation: kEnumerableProperty, + keepalive: kEnumerableProperty, + integrity: kEnumerableProperty, + cache: kEnumerableProperty, + credentials: kEnumerableProperty, + attribute: kEnumerableProperty, + referrerPolicy: kEnumerableProperty, + referrer: kEnumerableProperty, + mode: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Request', + configurable: true + } +}) + +webidl.converters.Request = webidl.interfaceConverter( + Request +) + +// https://fetch.spec.whatwg.org/#requestinfo +webidl.converters.RequestInfo = function (V) { + if (typeof V === 'string') { + return webidl.converters.USVString(V) + } + + if (V instanceof Request) { + return webidl.converters.Request(V) + } + + return webidl.converters.USVString(V) +} + +webidl.converters.AbortSignal = webidl.interfaceConverter( + AbortSignal +) + +// https://fetch.spec.whatwg.org/#requestinit +webidl.converters.RequestInit = webidl.dictionaryConverter([ + { + key: 'method', + converter: webidl.converters.ByteString + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit + }, + { + key: 'body', + converter: webidl.nullableConverter( + webidl.converters.BodyInit + ) + }, + { + key: 'referrer', + converter: webidl.converters.USVString + }, + { + key: 'referrerPolicy', + converter: webidl.converters.DOMString, + // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy + allowedValues: referrerPolicy + }, + { + key: 'mode', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#concept-request-mode + allowedValues: requestMode + }, + { + key: 'credentials', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcredentials + allowedValues: requestCredentials + }, + { + key: 'cache', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcache + allowedValues: requestCache + }, + { + key: 'redirect', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestredirect + allowedValues: requestRedirect + }, + { + key: 'integrity', + converter: webidl.converters.DOMString + }, + { + key: 'keepalive', + converter: webidl.converters.boolean + }, + { + key: 'signal', + converter: webidl.nullableConverter( + (signal) => webidl.converters.AbortSignal( + signal, + { strict: false } + ) + ) + }, + { + key: 'window', + converter: webidl.converters.any + }, + { + key: 'duplex', + converter: webidl.converters.DOMString, + allowedValues: requestDuplex + } +]) + +module.exports = { Request, makeRequest } + + +/***/ }), + +/***/ 7823: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { Headers, HeadersList, fill } = __nccwpck_require__(554) +const { extractBody, cloneBody, mixinBody } = __nccwpck_require__(1472) +const util = __nccwpck_require__(3983) +const { kEnumerableProperty } = util +const { + isValidReasonPhrase, + isCancelled, + isAborted, + isBlobLike, + serializeJavascriptValueToJSONString, + isErrorLike, + isomorphicEncode +} = __nccwpck_require__(2538) +const { + redirectStatusSet, + nullBodyStatus, + DOMException +} = __nccwpck_require__(1037) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { FormData } = __nccwpck_require__(2015) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { URLSerializer } = __nccwpck_require__(685) +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { types } = __nccwpck_require__(3837) + +const ReadableStream = globalThis.ReadableStream || (__nccwpck_require__(5356).ReadableStream) +const textEncoder = new TextEncoder('utf-8') + +// https://fetch.spec.whatwg.org/#response-class +class Response { + // Creates network error Response. + static error () { + // TODO + const relevantRealm = { settingsObject: {} } + + // The static error() method steps are to return the result of creating a + // Response object, given a new network error, "immutable", and this’s + // relevant Realm. + const responseObject = new Response() + responseObject[kState] = makeNetworkError() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response-json + static json (data, init = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'Response.json' }) + + if (init !== null) { + init = webidl.converters.ResponseInit(init) + } + + // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. + const bytes = textEncoder.encode( + serializeJavascriptValueToJSONString(data) + ) + + // 2. Let body be the result of extracting bytes. + const body = extractBody(bytes) + + // 3. Let responseObject be the result of creating a Response object, given a new response, + // "response", and this’s relevant Realm. + const relevantRealm = { settingsObject: {} } + const responseObject = new Response() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kGuard] = 'response' + responseObject[kHeaders][kRealm] = relevantRealm + + // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). + initializeResponse(responseObject, init, { body: body[0], type: 'application/json' }) + + // 5. Return responseObject. + return responseObject + } + + // Creates a redirect Response that redirects to url with status status. + static redirect (url, status = 302) { + const relevantRealm = { settingsObject: {} } + + webidl.argumentLengthCheck(arguments, 1, { header: 'Response.redirect' }) + + url = webidl.converters.USVString(url) + status = webidl.converters['unsigned short'](status) + + // 1. Let parsedURL be the result of parsing url with current settings + // object’s API base URL. + // 2. If parsedURL is failure, then throw a TypeError. + // TODO: base-URL? + let parsedURL + try { + parsedURL = new URL(url, getGlobalOrigin()) + } catch (err) { + throw Object.assign(new TypeError('Failed to parse URL from ' + url), { + cause: err + }) + } + + // 3. If status is not a redirect status, then throw a RangeError. + if (!redirectStatusSet.has(status)) { + throw new RangeError('Invalid status code ' + status) + } + + // 4. Let responseObject be the result of creating a Response object, + // given a new response, "immutable", and this’s relevant Realm. + const responseObject = new Response() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + + // 5. Set responseObject’s response’s status to status. + responseObject[kState].status = status + + // 6. Let value be parsedURL, serialized and isomorphic encoded. + const value = isomorphicEncode(URLSerializer(parsedURL)) + + // 7. Append `Location`/value to responseObject’s response’s header list. + responseObject[kState].headersList.append('location', value) + + // 8. Return responseObject. + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response + constructor (body = null, init = {}) { + if (body !== null) { + body = webidl.converters.BodyInit(body) + } + + init = webidl.converters.ResponseInit(init) + + // TODO + this[kRealm] = { settingsObject: {} } + + // 1. Set this’s response to a new response. + this[kState] = makeResponse({}) + + // 2. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is this’s response’s header list and guard + // is "response". + this[kHeaders] = new Headers(kConstruct) + this[kHeaders][kGuard] = 'response' + this[kHeaders][kHeadersList] = this[kState].headersList + this[kHeaders][kRealm] = this[kRealm] + + // 3. Let bodyWithType be null. + let bodyWithType = null + + // 4. If body is non-null, then set bodyWithType to the result of extracting body. + if (body != null) { + const [extractedBody, type] = extractBody(body) + bodyWithType = { body: extractedBody, type } + } + + // 5. Perform initialize a response given this, init, and bodyWithType. + initializeResponse(this, init, bodyWithType) + } + + // Returns response’s type, e.g., "cors". + get type () { + webidl.brandCheck(this, Response) + + // The type getter steps are to return this’s response’s type. + return this[kState].type + } + + // Returns response’s URL, if it has one; otherwise the empty string. + get url () { + webidl.brandCheck(this, Response) + + const urlList = this[kState].urlList + + // The url getter steps are to return the empty string if this’s + // response’s URL is null; otherwise this’s response’s URL, + // serialized with exclude fragment set to true. + const url = urlList[urlList.length - 1] ?? null + + if (url === null) { + return '' + } + + return URLSerializer(url, true) + } + + // Returns whether response was obtained through a redirect. + get redirected () { + webidl.brandCheck(this, Response) + + // The redirected getter steps are to return true if this’s response’s URL + // list has more than one item; otherwise false. + return this[kState].urlList.length > 1 + } + + // Returns response’s status. + get status () { + webidl.brandCheck(this, Response) + + // The status getter steps are to return this’s response’s status. + return this[kState].status + } + + // Returns whether response’s status is an ok status. + get ok () { + webidl.brandCheck(this, Response) + + // The ok getter steps are to return true if this’s response’s status is an + // ok status; otherwise false. + return this[kState].status >= 200 && this[kState].status <= 299 + } + + // Returns response’s status message. + get statusText () { + webidl.brandCheck(this, Response) + + // The statusText getter steps are to return this’s response’s status + // message. + return this[kState].statusText + } + + // Returns response’s headers as Headers. + get headers () { + webidl.brandCheck(this, Response) + + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } + + get body () { + webidl.brandCheck(this, Response) + + return this[kState].body ? this[kState].body.stream : null + } + + get bodyUsed () { + webidl.brandCheck(this, Response) + + return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + } + + // Returns a clone of response. + clone () { + webidl.brandCheck(this, Response) + + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || (this.body && this.body.locked)) { + throw webidl.errors.exception({ + header: 'Response.clone', + message: 'Body has already been consumed.' + }) + } + + // 2. Let clonedResponse be the result of cloning this’s response. + const clonedResponse = cloneResponse(this[kState]) + + // 3. Return the result of creating a Response object, given + // clonedResponse, this’s headers’s guard, and this’s relevant Realm. + const clonedResponseObject = new Response() + clonedResponseObject[kState] = clonedResponse + clonedResponseObject[kRealm] = this[kRealm] + clonedResponseObject[kHeaders][kHeadersList] = clonedResponse.headersList + clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard] + clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm] + + return clonedResponseObject + } +} + +mixinBody(Response) + +Object.defineProperties(Response.prototype, { + type: kEnumerableProperty, + url: kEnumerableProperty, + status: kEnumerableProperty, + ok: kEnumerableProperty, + redirected: kEnumerableProperty, + statusText: kEnumerableProperty, + headers: kEnumerableProperty, + clone: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Response', + configurable: true + } +}) + +Object.defineProperties(Response, { + json: kEnumerableProperty, + redirect: kEnumerableProperty, + error: kEnumerableProperty +}) + +// https://fetch.spec.whatwg.org/#concept-response-clone +function cloneResponse (response) { + // To clone a response response, run these steps: + + // 1. If response is a filtered response, then return a new identical + // filtered response whose internal response is a clone of response’s + // internal response. + if (response.internalResponse) { + return filterResponse( + cloneResponse(response.internalResponse), + response.type + ) + } + + // 2. Let newResponse be a copy of response, except for its body. + const newResponse = makeResponse({ ...response, body: null }) + + // 3. If response’s body is non-null, then set newResponse’s body to the + // result of cloning response’s body. + if (response.body != null) { + newResponse.body = cloneBody(response.body) + } + + // 4. Return newResponse. + return newResponse +} + +function makeResponse (init) { + return { + aborted: false, + rangeRequested: false, + timingAllowPassed: false, + requestIncludesCredentials: false, + type: 'default', + status: 200, + timingInfo: null, + cacheState: '', + statusText: '', + ...init, + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList(), + urlList: init.urlList ? [...init.urlList] : [] + } +} + +function makeNetworkError (reason) { + const isError = isErrorLike(reason) + return makeResponse({ + type: 'error', + status: 0, + error: isError + ? reason + : new Error(reason ? String(reason) : reason), + aborted: reason && reason.name === 'AbortError' + }) +} + +function makeFilteredResponse (response, state) { + state = { + internalResponse: response, + ...state + } + + return new Proxy(response, { + get (target, p) { + return p in state ? state[p] : target[p] + }, + set (target, p, value) { + assert(!(p in state)) + target[p] = value + return true + } + }) +} + +// https://fetch.spec.whatwg.org/#concept-filtered-response +function filterResponse (response, type) { + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (type === 'basic') { + // A basic filtered response is a filtered response whose type is "basic" + // and header list excludes any headers in internal response’s header list + // whose name is a forbidden response-header name. + + // Note: undici does not implement forbidden response-header names + return makeFilteredResponse(response, { + type: 'basic', + headersList: response.headersList + }) + } else if (type === 'cors') { + // A CORS filtered response is a filtered response whose type is "cors" + // and header list excludes any headers in internal response’s header + // list whose name is not a CORS-safelisted response-header name, given + // internal response’s CORS-exposed header-name list. + + // Note: undici does not implement CORS-safelisted response-header names + return makeFilteredResponse(response, { + type: 'cors', + headersList: response.headersList + }) + } else if (type === 'opaque') { + // An opaque filtered response is a filtered response whose type is + // "opaque", URL list is the empty list, status is 0, status message + // is the empty byte sequence, header list is empty, and body is null. + + return makeFilteredResponse(response, { + type: 'opaque', + urlList: Object.freeze([]), + status: 0, + statusText: '', + body: null + }) + } else if (type === 'opaqueredirect') { + // An opaque-redirect filtered response is a filtered response whose type + // is "opaqueredirect", status is 0, status message is the empty byte + // sequence, header list is empty, and body is null. + + return makeFilteredResponse(response, { + type: 'opaqueredirect', + status: 0, + statusText: '', + headersList: [], + body: null + }) + } else { + assert(false) + } +} + +// https://fetch.spec.whatwg.org/#appropriate-network-error +function makeAppropriateNetworkError (fetchParams, err = null) { + // 1. Assert: fetchParams is canceled. + assert(isCancelled(fetchParams)) + + // 2. Return an aborted network error if fetchParams is aborted; + // otherwise return a network error. + return isAborted(fetchParams) + ? makeNetworkError(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err })) + : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err })) +} + +// https://whatpr.org/fetch/1392.html#initialize-a-response +function initializeResponse (response, init, body) { + // 1. If init["status"] is not in the range 200 to 599, inclusive, then + // throw a RangeError. + if (init.status !== null && (init.status < 200 || init.status > 599)) { + throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.') + } + + // 2. If init["statusText"] does not match the reason-phrase token production, + // then throw a TypeError. + if ('statusText' in init && init.statusText != null) { + // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2: + // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) + if (!isValidReasonPhrase(String(init.statusText))) { + throw new TypeError('Invalid statusText') + } + } + + // 3. Set response’s response’s status to init["status"]. + if ('status' in init && init.status != null) { + response[kState].status = init.status + } + + // 4. Set response’s response’s status message to init["statusText"]. + if ('statusText' in init && init.statusText != null) { + response[kState].statusText = init.statusText + } + + // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. + if ('headers' in init && init.headers != null) { + fill(response[kHeaders], init.headers) + } + + // 6. If body was given, then: + if (body) { + // 1. If response's status is a null body status, then throw a TypeError. + if (nullBodyStatus.includes(response.status)) { + throw webidl.errors.exception({ + header: 'Response constructor', + message: 'Invalid response status code ' + response.status + }) + } + + // 2. Set response's body to body's body. + response[kState].body = body.body + + // 3. If body's type is non-null and response's header list does not contain + // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. + if (body.type != null && !response[kState].headersList.contains('Content-Type')) { + response[kState].headersList.append('content-type', body.type) + } + } +} + +webidl.converters.ReadableStream = webidl.interfaceConverter( + ReadableStream +) + +webidl.converters.FormData = webidl.interfaceConverter( + FormData +) + +webidl.converters.URLSearchParams = webidl.interfaceConverter( + URLSearchParams +) + +// https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit +webidl.converters.XMLHttpRequestBodyInit = function (V) { + if (typeof V === 'string') { + return webidl.converters.USVString(V) + } + + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } + + if (types.isArrayBuffer(V) || types.isTypedArray(V) || types.isDataView(V)) { + return webidl.converters.BufferSource(V) + } + + if (util.isFormDataLike(V)) { + return webidl.converters.FormData(V, { strict: false }) + } + + if (V instanceof URLSearchParams) { + return webidl.converters.URLSearchParams(V) + } + + return webidl.converters.DOMString(V) +} + +// https://fetch.spec.whatwg.org/#bodyinit +webidl.converters.BodyInit = function (V) { + if (V instanceof ReadableStream) { + return webidl.converters.ReadableStream(V) + } + + // Note: the spec doesn't include async iterables, + // this is an undici extension. + if (V?.[Symbol.asyncIterator]) { + return V + } + + return webidl.converters.XMLHttpRequestBodyInit(V) +} + +webidl.converters.ResponseInit = webidl.dictionaryConverter([ + { + key: 'status', + converter: webidl.converters['unsigned short'], + defaultValue: 200 + }, + { + key: 'statusText', + converter: webidl.converters.ByteString, + defaultValue: '' + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit + } +]) + +module.exports = { + makeNetworkError, + makeResponse, + makeAppropriateNetworkError, + filterResponse, + Response, + cloneResponse +} + + +/***/ }), + +/***/ 5861: +/***/ ((module) => { + +"use strict"; + + +module.exports = { + kUrl: Symbol('url'), + kHeaders: Symbol('headers'), + kSignal: Symbol('signal'), + kState: Symbol('state'), + kGuard: Symbol('guard'), + kRealm: Symbol('realm') +} + + +/***/ }), + +/***/ 2538: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = __nccwpck_require__(1037) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { performance } = __nccwpck_require__(4074) +const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983) +const assert = __nccwpck_require__(9491) +const { isUint8Array } = __nccwpck_require__(9830) + +// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable +/** @type {import('crypto')|undefined} */ +let crypto + +try { + crypto = __nccwpck_require__(6113) +} catch { + +} + +function responseURL (response) { + // https://fetch.spec.whatwg.org/#responses + // A response has an associated URL. It is a pointer to the last URL + // in response’s URL list and null if response’s URL list is empty. + const urlList = response.urlList + const length = urlList.length + return length === 0 ? null : urlList[length - 1].toString() +} + +// https://fetch.spec.whatwg.org/#concept-response-location-url +function responseLocationURL (response, requestFragment) { + // 1. If response’s status is not a redirect status, then return null. + if (!redirectStatusSet.has(response.status)) { + return null + } + + // 2. Let location be the result of extracting header list values given + // `Location` and response’s header list. + let location = response.headersList.get('location') + + // 3. If location is a header value, then set location to the result of + // parsing location with response’s URL. + if (location !== null && isValidHeaderValue(location)) { + location = new URL(location, responseURL(response)) + } + + // 4. If location is a URL whose fragment is null, then set location’s + // fragment to requestFragment. + if (location && !location.hash) { + location.hash = requestFragment + } + + // 5. Return location. + return location +} + +/** @returns {URL} */ +function requestCurrentURL (request) { + return request.urlList[request.urlList.length - 1] +} + +function requestBadPort (request) { + // 1. Let url be request’s current URL. + const url = requestCurrentURL(request) + + // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, + // then return blocked. + if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { + return 'blocked' + } + + // 3. Return allowed. + return 'allowed' +} + +function isErrorLike (object) { + return object instanceof Error || ( + object?.constructor?.name === 'Error' || + object?.constructor?.name === 'DOMException' + ) +} + +// Check whether |statusText| is a ByteString and +// matches the Reason-Phrase token production. +// RFC 2616: https://tools.ietf.org/html/rfc2616 +// RFC 7230: https://tools.ietf.org/html/rfc7230 +// "reason-phrase = *( HTAB / SP / VCHAR / obs-text )" +// https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116 +function isValidReasonPhrase (statusText) { + for (let i = 0; i < statusText.length; ++i) { + const c = statusText.charCodeAt(i) + if ( + !( + ( + c === 0x09 || // HTAB + (c >= 0x20 && c <= 0x7e) || // SP / VCHAR + (c >= 0x80 && c <= 0xff) + ) // obs-text + ) + ) { + return false + } + } + return true +} + +/** + * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 + * @param {number} c + */ +function isTokenCharCode (c) { + switch (c) { + case 0x22: + case 0x28: + case 0x29: + case 0x2c: + case 0x2f: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x40: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x7b: + case 0x7d: + // DQUOTE and "(),/:;<=>?@[\]{}" + return false + default: + // VCHAR %x21-7E + return c >= 0x21 && c <= 0x7e + } +} + +/** + * @param {string} characters + */ +function isValidHTTPToken (characters) { + if (characters.length === 0) { + return false + } + for (let i = 0; i < characters.length; ++i) { + if (!isTokenCharCode(characters.charCodeAt(i))) { + return false + } + } + return true +} + +/** + * @see https://fetch.spec.whatwg.org/#header-name + * @param {string} potentialValue + */ +function isValidHeaderName (potentialValue) { + return isValidHTTPToken(potentialValue) +} + +/** + * @see https://fetch.spec.whatwg.org/#header-value + * @param {string} potentialValue + */ +function isValidHeaderValue (potentialValue) { + // - Has no leading or trailing HTTP tab or space bytes. + // - Contains no 0x00 (NUL) or HTTP newline bytes. + if ( + potentialValue.startsWith('\t') || + potentialValue.startsWith(' ') || + potentialValue.endsWith('\t') || + potentialValue.endsWith(' ') + ) { + return false + } + + if ( + potentialValue.includes('\0') || + potentialValue.includes('\r') || + potentialValue.includes('\n') + ) { + return false + } + + return true +} + +// https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect +function setRequestReferrerPolicyOnRedirect (request, actualResponse) { + // Given a request request and a response actualResponse, this algorithm + // updates request’s referrer policy according to the Referrer-Policy + // header (if any) in actualResponse. + + // 1. Let policy be the result of executing § 8.1 Parse a referrer policy + // from a Referrer-Policy header on actualResponse. + + // 8.1 Parse a referrer policy from a Referrer-Policy header + // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list. + const { headersList } = actualResponse + // 2. Let policy be the empty string. + // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. + // 4. Return policy. + const policyHeader = (headersList.get('referrer-policy') ?? '').split(',') + + // Note: As the referrer-policy can contain multiple policies + // separated by comma, we need to loop through all of them + // and pick the first valid one. + // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy + let policy = '' + if (policyHeader.length > 0) { + // The right-most policy takes precedence. + // The left-most policy is the fallback. + for (let i = policyHeader.length; i !== 0; i--) { + const token = policyHeader[i - 1].trim() + if (referrerPolicyTokens.has(token)) { + policy = token + break + } + } + } + + // 2. If policy is not the empty string, then set request’s referrer policy to policy. + if (policy !== '') { + request.referrerPolicy = policy + } +} + +// https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check +function crossOriginResourcePolicyCheck () { + // TODO + return 'allowed' +} + +// https://fetch.spec.whatwg.org/#concept-cors-check +function corsCheck () { + // TODO + return 'success' +} + +// https://fetch.spec.whatwg.org/#concept-tao-check +function TAOCheck () { + // TODO + return 'success' +} + +function appendFetchMetadata (httpRequest) { + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header + // TODO + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header + + // 1. Assert: r’s url is a potentially trustworthy URL. + // TODO + + // 2. Let header be a Structured Header whose value is a token. + let header = null + + // 3. Set header’s value to r’s mode. + header = httpRequest.mode + + // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. + httpRequest.headersList.set('sec-fetch-mode', header) + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header + // TODO + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header + // TODO +} + +// https://fetch.spec.whatwg.org/#append-a-request-origin-header +function appendRequestOriginHeader (request) { + // 1. Let serializedOrigin be the result of byte-serializing a request origin with request. + let serializedOrigin = request.origin + + // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list. + if (request.responseTainting === 'cors' || request.mode === 'websocket') { + if (serializedOrigin) { + request.headersList.append('origin', serializedOrigin) + } + + // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: + } else if (request.method !== 'GET' && request.method !== 'HEAD') { + // 1. Switch on request’s referrer policy: + switch (request.referrerPolicy) { + case 'no-referrer': + // Set serializedOrigin to `null`. + serializedOrigin = null + break + case 'no-referrer-when-downgrade': + case 'strict-origin': + case 'strict-origin-when-cross-origin': + // If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`. + if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { + serializedOrigin = null + } + break + case 'same-origin': + // If request’s origin is not same origin with request’s current URL’s origin, then set serializedOrigin to `null`. + if (!sameOrigin(request, requestCurrentURL(request))) { + serializedOrigin = null + } + break + default: + // Do nothing. + } + + if (serializedOrigin) { + // 2. Append (`Origin`, serializedOrigin) to request’s header list. + request.headersList.append('origin', serializedOrigin) + } + } +} + +function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { + // TODO + return performance.now() +} + +// https://fetch.spec.whatwg.org/#create-an-opaque-timing-info +function createOpaqueTimingInfo (timingInfo) { + return { + startTime: timingInfo.startTime ?? 0, + redirectStartTime: 0, + redirectEndTime: 0, + postRedirectStartTime: timingInfo.startTime ?? 0, + finalServiceWorkerStartTime: 0, + finalNetworkResponseStartTime: 0, + finalNetworkRequestStartTime: 0, + endTime: 0, + encodedBodySize: 0, + decodedBodySize: 0, + finalConnectionTimingInfo: null + } +} + +// https://html.spec.whatwg.org/multipage/origin.html#policy-container +function makePolicyContainer () { + // Note: the fetch spec doesn't make use of embedder policy or CSP list + return { + referrerPolicy: 'strict-origin-when-cross-origin' + } +} + +// https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container +function clonePolicyContainer (policyContainer) { + return { + referrerPolicy: policyContainer.referrerPolicy + } +} + +// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer +function determineRequestsReferrer (request) { + // 1. Let policy be request's referrer policy. + const policy = request.referrerPolicy + + // Note: policy cannot (shouldn't) be null or an empty string. + assert(policy) + + // 2. Let environment be request’s client. + + let referrerSource = null + + // 3. Switch on request’s referrer: + if (request.referrer === 'client') { + // Note: node isn't a browser and doesn't implement document/iframes, + // so we bypass this step and replace it with our own. + + const globalOrigin = getGlobalOrigin() + + if (!globalOrigin || globalOrigin.origin === 'null') { + return 'no-referrer' + } + + // note: we need to clone it as it's mutated + referrerSource = new URL(globalOrigin) + } else if (request.referrer instanceof URL) { + // Let referrerSource be request’s referrer. + referrerSource = request.referrer + } + + // 4. Let request’s referrerURL be the result of stripping referrerSource for + // use as a referrer. + let referrerURL = stripURLForReferrer(referrerSource) + + // 5. Let referrerOrigin be the result of stripping referrerSource for use as + // a referrer, with the origin-only flag set to true. + const referrerOrigin = stripURLForReferrer(referrerSource, true) + + // 6. If the result of serializing referrerURL is a string whose length is + // greater than 4096, set referrerURL to referrerOrigin. + if (referrerURL.toString().length > 4096) { + referrerURL = referrerOrigin + } + + const areSameOrigin = sameOrigin(request, referrerURL) + const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) && + !isURLPotentiallyTrustworthy(request.url) + + // 8. Execute the switch statements corresponding to the value of policy: + switch (policy) { + case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true) + case 'unsafe-url': return referrerURL + case 'same-origin': + return areSameOrigin ? referrerOrigin : 'no-referrer' + case 'origin-when-cross-origin': + return areSameOrigin ? referrerURL : referrerOrigin + case 'strict-origin-when-cross-origin': { + const currentURL = requestCurrentURL(request) + + // 1. If the origin of referrerURL and the origin of request’s current + // URL are the same, then return referrerURL. + if (sameOrigin(referrerURL, currentURL)) { + return referrerURL + } + + // 2. If referrerURL is a potentially trustworthy URL and request’s + // current URL is not a potentially trustworthy URL, then return no + // referrer. + if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) { + return 'no-referrer' + } + + // 3. Return referrerOrigin. + return referrerOrigin + } + case 'strict-origin': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ + case 'no-referrer-when-downgrade': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ + + default: // eslint-disable-line + return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin + } +} + +/** + * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url + * @param {URL} url + * @param {boolean|undefined} originOnly + */ +function stripURLForReferrer (url, originOnly) { + // 1. Assert: url is a URL. + assert(url instanceof URL) + + // 2. If url’s scheme is a local scheme, then return no referrer. + if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'blank:') { + return 'no-referrer' + } + + // 3. Set url’s username to the empty string. + url.username = '' + + // 4. Set url’s password to the empty string. + url.password = '' + + // 5. Set url’s fragment to null. + url.hash = '' + + // 6. If the origin-only flag is true, then: + if (originOnly) { + // 1. Set url’s path to « the empty string ». + url.pathname = '' + + // 2. Set url’s query to null. + url.search = '' + } + + // 7. Return url. + return url +} + +function isURLPotentiallyTrustworthy (url) { + if (!(url instanceof URL)) { + return false + } + + // If child of about, return true + if (url.href === 'about:blank' || url.href === 'about:srcdoc') { + return true + } + + // If scheme is data, return true + if (url.protocol === 'data:') return true + + // If file, return true + if (url.protocol === 'file:') return true + + return isOriginPotentiallyTrustworthy(url.origin) + + function isOriginPotentiallyTrustworthy (origin) { + // If origin is explicitly null, return false + if (origin == null || origin === 'null') return false + + const originAsURL = new URL(origin) + + // If secure, return true + if (originAsURL.protocol === 'https:' || originAsURL.protocol === 'wss:') { + return true + } + + // If localhost or variants, return true + if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) || + (originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) || + (originAsURL.hostname.endsWith('.localhost'))) { + return true + } + + // If any other, return false + return false + } +} + +/** + * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist + * @param {Uint8Array} bytes + * @param {string} metadataList + */ +function bytesMatch (bytes, metadataList) { + // If node is not built with OpenSSL support, we cannot check + // a request's integrity, so allow it by default (the spec will + // allow requests if an invalid hash is given, as precedence). + /* istanbul ignore if: only if node is built with --without-ssl */ + if (crypto === undefined) { + return true + } + + // 1. Let parsedMetadata be the result of parsing metadataList. + const parsedMetadata = parseMetadata(metadataList) + + // 2. If parsedMetadata is no metadata, return true. + if (parsedMetadata === 'no metadata') { + return true + } + + // 3. If parsedMetadata is the empty set, return true. + if (parsedMetadata.length === 0) { + return true + } + + // 4. Let metadata be the result of getting the strongest + // metadata from parsedMetadata. + const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo)) + // get the strongest algorithm + const strongest = list[0].algo + // get all entries that use the strongest algorithm; ignore weaker + const metadata = list.filter((item) => item.algo === strongest) + + // 5. For each item in metadata: + for (const item of metadata) { + // 1. Let algorithm be the alg component of item. + const algorithm = item.algo + + // 2. Let expectedValue be the val component of item. + let expectedValue = item.hash + + // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e + // "be liberal with padding". This is annoying, and it's not even in the spec. + + if (expectedValue.endsWith('==')) { + expectedValue = expectedValue.slice(0, -2) + } + + // 3. Let actualValue be the result of applying algorithm to bytes. + let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64') + + if (actualValue.endsWith('==')) { + actualValue = actualValue.slice(0, -2) + } + + // 4. If actualValue is a case-sensitive match for expectedValue, + // return true. + if (actualValue === expectedValue) { + return true + } + + let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url') + + if (actualBase64URL.endsWith('==')) { + actualBase64URL = actualBase64URL.slice(0, -2) + } + + if (actualBase64URL === expectedValue) { + return true + } + } + + // 6. Return false. + return false +} + +// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options +// https://www.w3.org/TR/CSP2/#source-list-syntax +// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 +const parseHashWithOptions = /((?sha256|sha384|sha512)-(?[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i + +/** + * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata + * @param {string} metadata + */ +function parseMetadata (metadata) { + // 1. Let result be the empty set. + /** @type {{ algo: string, hash: string }[]} */ + const result = [] + + // 2. Let empty be equal to true. + let empty = true + + const supportedHashes = crypto.getHashes() + + // 3. For each token returned by splitting metadata on spaces: + for (const token of metadata.split(' ')) { + // 1. Set empty to false. + empty = false + + // 2. Parse token as a hash-with-options. + const parsedToken = parseHashWithOptions.exec(token) + + // 3. If token does not parse, continue to the next token. + if (parsedToken === null || parsedToken.groups === undefined) { + // Note: Chromium blocks the request at this point, but Firefox + // gives a warning that an invalid integrity was given. The + // correct behavior is to ignore these, and subsequently not + // check the integrity of the resource. + continue + } + + // 4. Let algorithm be the hash-algo component of token. + const algorithm = parsedToken.groups.algo + + // 5. If algorithm is a hash function recognized by the user + // agent, add the parsed token to result. + if (supportedHashes.includes(algorithm.toLowerCase())) { + result.push(parsedToken.groups) + } + } + + // 4. Return no metadata if empty is true, otherwise return result. + if (empty === true) { + return 'no metadata' + } + + return result +} + +// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request +function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) { + // TODO +} + +/** + * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin} + * @param {URL} A + * @param {URL} B + */ +function sameOrigin (A, B) { + // 1. If A and B are the same opaque origin, then return true. + if (A.origin === B.origin && A.origin === 'null') { + return true + } + + // 2. If A and B are both tuple origins and their schemes, + // hosts, and port are identical, then return true. + if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) { + return true + } + + // 3. Return false. + return false +} + +function createDeferredPromise () { + let res + let rej + const promise = new Promise((resolve, reject) => { + res = resolve + rej = reject + }) + + return { promise, resolve: res, reject: rej } +} + +function isAborted (fetchParams) { + return fetchParams.controller.state === 'aborted' +} + +function isCancelled (fetchParams) { + return fetchParams.controller.state === 'aborted' || + fetchParams.controller.state === 'terminated' +} + +const normalizeMethodRecord = { + delete: 'DELETE', + DELETE: 'DELETE', + get: 'GET', + GET: 'GET', + head: 'HEAD', + HEAD: 'HEAD', + options: 'OPTIONS', + OPTIONS: 'OPTIONS', + post: 'POST', + POST: 'POST', + put: 'PUT', + PUT: 'PUT' +} + +// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. +Object.setPrototypeOf(normalizeMethodRecord, null) + +/** + * @see https://fetch.spec.whatwg.org/#concept-method-normalize + * @param {string} method + */ +function normalizeMethod (method) { + return normalizeMethodRecord[method.toLowerCase()] ?? method +} + +// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string +function serializeJavascriptValueToJSONString (value) { + // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »). + const result = JSON.stringify(value) + + // 2. If result is undefined, then throw a TypeError. + if (result === undefined) { + throw new TypeError('Value is not JSON serializable') + } + + // 3. Assert: result is a string. + assert(typeof result === 'string') + + // 4. Return result. + return result +} + +// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object +const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())) + +/** + * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object + * @param {() => unknown[]} iterator + * @param {string} name name of the instance + * @param {'key'|'value'|'key+value'} kind + */ +function makeIterator (iterator, name, kind) { + const object = { + index: 0, + kind, + target: iterator + } + + const i = { + next () { + // 1. Let interface be the interface for which the iterator prototype object exists. + + // 2. Let thisValue be the this value. + + // 3. Let object be ? ToObject(thisValue). + + // 4. If object is a platform object, then perform a security + // check, passing: + + // 5. If object is not a default iterator object for interface, + // then throw a TypeError. + if (Object.getPrototypeOf(this) !== i) { + throw new TypeError( + `'next' called on an object that does not implement interface ${name} Iterator.` + ) + } + + // 6. Let index be object’s index. + // 7. Let kind be object’s kind. + // 8. Let values be object’s target's value pairs to iterate over. + const { index, kind, target } = object + const values = target() + + // 9. Let len be the length of values. + const len = values.length + + // 10. If index is greater than or equal to len, then return + // CreateIterResultObject(undefined, true). + if (index >= len) { + return { value: undefined, done: true } + } + + // 11. Let pair be the entry in values at index index. + const pair = values[index] + + // 12. Set object’s index to index + 1. + object.index = index + 1 + + // 13. Return the iterator result for pair and kind. + return iteratorResult(pair, kind) + }, + // The class string of an iterator prototype object for a given interface is the + // result of concatenating the identifier of the interface and the string " Iterator". + [Symbol.toStringTag]: `${name} Iterator` + } + + // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%. + Object.setPrototypeOf(i, esIteratorPrototype) + // esIteratorPrototype needs to be the prototype of i + // which is the prototype of an empty object. Yes, it's confusing. + return Object.setPrototypeOf({}, i) +} + +// https://webidl.spec.whatwg.org/#iterator-result +function iteratorResult (pair, kind) { + let result + + // 1. Let result be a value determined by the value of kind: + switch (kind) { + case 'key': { + // 1. Let idlKey be pair’s key. + // 2. Let key be the result of converting idlKey to an + // ECMAScript value. + // 3. result is key. + result = pair[0] + break + } + case 'value': { + // 1. Let idlValue be pair’s value. + // 2. Let value be the result of converting idlValue to + // an ECMAScript value. + // 3. result is value. + result = pair[1] + break + } + case 'key+value': { + // 1. Let idlKey be pair’s key. + // 2. Let idlValue be pair’s value. + // 3. Let key be the result of converting idlKey to an + // ECMAScript value. + // 4. Let value be the result of converting idlValue to + // an ECMAScript value. + // 5. Let array be ! ArrayCreate(2). + // 6. Call ! CreateDataProperty(array, "0", key). + // 7. Call ! CreateDataProperty(array, "1", value). + // 8. result is array. + result = pair + break + } + } + + // 2. Return CreateIterResultObject(result, false). + return { value: result, done: false } +} + +/** + * @see https://fetch.spec.whatwg.org/#body-fully-read + */ +async function fullyReadBody (body, processBody, processBodyError) { + // 1. If taskDestination is null, then set taskDestination to + // the result of starting a new parallel queue. + + // 2. Let successSteps given a byte sequence bytes be to queue a + // fetch task to run processBody given bytes, with taskDestination. + const successSteps = processBody + + // 3. Let errorSteps be to queue a fetch task to run processBodyError, + // with taskDestination. + const errorSteps = processBodyError + + // 4. Let reader be the result of getting a reader for body’s stream. + // If that threw an exception, then run errorSteps with that + // exception and return. + let reader + + try { + reader = body.stream.getReader() + } catch (e) { + errorSteps(e) + return + } + + // 5. Read all bytes from reader, given successSteps and errorSteps. + try { + const result = await readAllBytes(reader) + successSteps(result) + } catch (e) { + errorSteps(e) + } +} + +/** @type {ReadableStream} */ +let ReadableStream = globalThis.ReadableStream + +function isReadableStreamLike (stream) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } + + return stream instanceof ReadableStream || ( + stream[Symbol.toStringTag] === 'ReadableStream' && + typeof stream.tee === 'function' + ) +} + +const MAXIMUM_ARGUMENT_LENGTH = 65535 + +/** + * @see https://infra.spec.whatwg.org/#isomorphic-decode + * @param {number[]|Uint8Array} input + */ +function isomorphicDecode (input) { + // 1. To isomorphic decode a byte sequence input, return a string whose code point + // length is equal to input’s length and whose code points have the same values + // as the values of input’s bytes, in the same order. + + if (input.length < MAXIMUM_ARGUMENT_LENGTH) { + return String.fromCharCode(...input) + } + + return input.reduce((previous, current) => previous + String.fromCharCode(current), '') +} + +/** + * @param {ReadableStreamController} controller + */ +function readableStreamClose (controller) { + try { + controller.close() + } catch (err) { + // TODO: add comment explaining why this error occurs. + if (!err.message.includes('Controller is already closed')) { + throw err + } + } +} + +/** + * @see https://infra.spec.whatwg.org/#isomorphic-encode + * @param {string} input + */ +function isomorphicEncode (input) { + // 1. Assert: input contains no code points greater than U+00FF. + for (let i = 0; i < input.length; i++) { + assert(input.charCodeAt(i) <= 0xFF) + } + + // 2. Return a byte sequence whose length is equal to input’s code + // point length and whose bytes have the same values as the + // values of input’s code points, in the same order + return input +} + +/** + * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes + * @see https://streams.spec.whatwg.org/#read-loop + * @param {ReadableStreamDefaultReader} reader + */ +async function readAllBytes (reader) { + const bytes = [] + let byteLength = 0 + + while (true) { + const { done, value: chunk } = await reader.read() + + if (done) { + // 1. Call successSteps with bytes. + return Buffer.concat(bytes, byteLength) + } + + // 1. If chunk is not a Uint8Array object, call failureSteps + // with a TypeError and abort these steps. + if (!isUint8Array(chunk)) { + throw new TypeError('Received non-Uint8Array chunk') + } + + // 2. Append the bytes represented by chunk to bytes. + bytes.push(chunk) + byteLength += chunk.length + + // 3. Read-loop given reader, bytes, successSteps, and failureSteps. + } +} + +/** + * @see https://fetch.spec.whatwg.org/#is-local + * @param {URL} url + */ +function urlIsLocal (url) { + assert('protocol' in url) // ensure it's a url object + + const protocol = url.protocol + + return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:' +} + +/** + * @param {string|URL} url + */ +function urlHasHttpsScheme (url) { + if (typeof url === 'string') { + return url.startsWith('https:') + } + + return url.protocol === 'https:' +} + +/** + * @see https://fetch.spec.whatwg.org/#http-scheme + * @param {URL} url + */ +function urlIsHttpHttpsScheme (url) { + assert('protocol' in url) // ensure it's a url object + + const protocol = url.protocol + + return protocol === 'http:' || protocol === 'https:' +} + +/** + * Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0. + */ +const hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)) + +module.exports = { + isAborted, + isCancelled, + createDeferredPromise, + ReadableStreamFrom, + toUSVString, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + coarsenedSharedCurrentTime, + determineRequestsReferrer, + makePolicyContainer, + clonePolicyContainer, + appendFetchMetadata, + appendRequestOriginHeader, + TAOCheck, + corsCheck, + crossOriginResourcePolicyCheck, + createOpaqueTimingInfo, + setRequestReferrerPolicyOnRedirect, + isValidHTTPToken, + requestBadPort, + requestCurrentURL, + responseURL, + responseLocationURL, + isBlobLike, + isURLPotentiallyTrustworthy, + isValidReasonPhrase, + sameOrigin, + normalizeMethod, + serializeJavascriptValueToJSONString, + makeIterator, + isValidHeaderName, + isValidHeaderValue, + hasOwn, + isErrorLike, + fullyReadBody, + bytesMatch, + isReadableStreamLike, + readableStreamClose, + isomorphicEncode, + isomorphicDecode, + urlIsLocal, + urlHasHttpsScheme, + urlIsHttpHttpsScheme, + readAllBytes, + normalizeMethodRecord +} + + +/***/ }), + +/***/ 1744: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { types } = __nccwpck_require__(3837) +const { hasOwn, toUSVString } = __nccwpck_require__(2538) + +/** @type {import('../../types/webidl').Webidl} */ +const webidl = {} +webidl.converters = {} +webidl.util = {} +webidl.errors = {} + +webidl.errors.exception = function (message) { + return new TypeError(`${message.header}: ${message.message}`) +} + +webidl.errors.conversionFailed = function (context) { + const plural = context.types.length === 1 ? '' : ' one of' + const message = + `${context.argument} could not be converted to` + + `${plural}: ${context.types.join(', ')}.` + + return webidl.errors.exception({ + header: context.prefix, + message + }) +} + +webidl.errors.invalidArgument = function (context) { + return webidl.errors.exception({ + header: context.prefix, + message: `"${context.value}" is an invalid ${context.type}.` + }) +} + +// https://webidl.spec.whatwg.org/#implements +webidl.brandCheck = function (V, I, opts = undefined) { + if (opts?.strict !== false && !(V instanceof I)) { + throw new TypeError('Illegal invocation') + } else { + return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag] + } +} + +webidl.argumentLengthCheck = function ({ length }, min, ctx) { + if (length < min) { + throw webidl.errors.exception({ + message: `${min} argument${min !== 1 ? 's' : ''} required, ` + + `but${length ? ' only' : ''} ${length} found.`, + ...ctx + }) + } +} + +webidl.illegalConstructor = function () { + throw webidl.errors.exception({ + header: 'TypeError', + message: 'Illegal constructor' + }) +} + +// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values +webidl.util.Type = function (V) { + switch (typeof V) { + case 'undefined': return 'Undefined' + case 'boolean': return 'Boolean' + case 'string': return 'String' + case 'symbol': return 'Symbol' + case 'number': return 'Number' + case 'bigint': return 'BigInt' + case 'function': + case 'object': { + if (V === null) { + return 'Null' + } + + return 'Object' + } + } +} + +// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint +webidl.util.ConvertToInt = function (V, bitLength, signedness, opts = {}) { + let upperBound + let lowerBound + + // 1. If bitLength is 64, then: + if (bitLength === 64) { + // 1. Let upperBound be 2^53 − 1. + upperBound = Math.pow(2, 53) - 1 + + // 2. If signedness is "unsigned", then let lowerBound be 0. + if (signedness === 'unsigned') { + lowerBound = 0 + } else { + // 3. Otherwise let lowerBound be −2^53 + 1. + lowerBound = Math.pow(-2, 53) + 1 + } + } else if (signedness === 'unsigned') { + // 2. Otherwise, if signedness is "unsigned", then: + + // 1. Let lowerBound be 0. + lowerBound = 0 + + // 2. Let upperBound be 2^bitLength − 1. + upperBound = Math.pow(2, bitLength) - 1 + } else { + // 3. Otherwise: + + // 1. Let lowerBound be -2^bitLength − 1. + lowerBound = Math.pow(-2, bitLength) - 1 + + // 2. Let upperBound be 2^bitLength − 1 − 1. + upperBound = Math.pow(2, bitLength - 1) - 1 + } + + // 4. Let x be ? ToNumber(V). + let x = Number(V) + + // 5. If x is −0, then set x to +0. + if (x === 0) { + x = 0 + } + + // 6. If the conversion is to an IDL type associated + // with the [EnforceRange] extended attribute, then: + if (opts.enforceRange === true) { + // 1. If x is NaN, +∞, or −∞, then throw a TypeError. + if ( + Number.isNaN(x) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY + ) { + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Could not convert ${V} to an integer.` + }) + } + + // 2. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x) + + // 3. If x < lowerBound or x > upperBound, then + // throw a TypeError. + if (x < lowerBound || x > upperBound) { + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.` + }) + } + + // 4. Return x. + return x + } + + // 7. If x is not NaN and the conversion is to an IDL + // type associated with the [Clamp] extended + // attribute, then: + if (!Number.isNaN(x) && opts.clamp === true) { + // 1. Set x to min(max(x, lowerBound), upperBound). + x = Math.min(Math.max(x, lowerBound), upperBound) + + // 2. Round x to the nearest integer, choosing the + // even integer if it lies halfway between two, + // and choosing +0 rather than −0. + if (Math.floor(x) % 2 === 0) { + x = Math.floor(x) + } else { + x = Math.ceil(x) + } + + // 3. Return x. + return x + } + + // 8. If x is NaN, +0, +∞, or −∞, then return +0. + if ( + Number.isNaN(x) || + (x === 0 && Object.is(0, x)) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY + ) { + return 0 + } + + // 9. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x) + + // 10. Set x to x modulo 2^bitLength. + x = x % Math.pow(2, bitLength) + + // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, + // then return x − 2^bitLength. + if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { + return x - Math.pow(2, bitLength) + } + + // 12. Otherwise, return x. + return x +} + +// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart +webidl.util.IntegerPart = function (n) { + // 1. Let r be floor(abs(n)). + const r = Math.floor(Math.abs(n)) + + // 2. If n < 0, then return -1 × r. + if (n < 0) { + return -1 * r + } + + // 3. Otherwise, return r. + return r +} + +// https://webidl.spec.whatwg.org/#es-sequence +webidl.sequenceConverter = function (converter) { + return (V) => { + // 1. If Type(V) is not Object, throw a TypeError. + if (webidl.util.Type(V) !== 'Object') { + throw webidl.errors.exception({ + header: 'Sequence', + message: `Value of type ${webidl.util.Type(V)} is not an Object.` + }) + } + + // 2. Let method be ? GetMethod(V, @@iterator). + /** @type {Generator} */ + const method = V?.[Symbol.iterator]?.() + const seq = [] + + // 3. If method is undefined, throw a TypeError. + if ( + method === undefined || + typeof method.next !== 'function' + ) { + throw webidl.errors.exception({ + header: 'Sequence', + message: 'Object is not an iterator.' + }) + } + + // https://webidl.spec.whatwg.org/#create-sequence-from-iterable + while (true) { + const { done, value } = method.next() + + if (done) { + break + } + + seq.push(converter(value)) + } + + return seq + } +} + +// https://webidl.spec.whatwg.org/#es-to-record +webidl.recordConverter = function (keyConverter, valueConverter) { + return (O) => { + // 1. If Type(O) is not Object, throw a TypeError. + if (webidl.util.Type(O) !== 'Object') { + throw webidl.errors.exception({ + header: 'Record', + message: `Value of type ${webidl.util.Type(O)} is not an Object.` + }) + } + + // 2. Let result be a new empty instance of record. + const result = {} + + if (!types.isProxy(O)) { + // Object.keys only returns enumerable properties + const keys = Object.keys(O) + + for (const key of keys) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key) + + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key]) + + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue + } + + // 5. Return result. + return result + } + + // 3. Let keys be ? O.[[OwnPropertyKeys]](). + const keys = Reflect.ownKeys(O) + + // 4. For each key of keys. + for (const key of keys) { + // 1. Let desc be ? O.[[GetOwnProperty]](key). + const desc = Reflect.getOwnPropertyDescriptor(O, key) + + // 2. If desc is not undefined and desc.[[Enumerable]] is true: + if (desc?.enumerable) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key) + + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key]) + + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue + } + } + + // 5. Return result. + return result + } +} + +webidl.interfaceConverter = function (i) { + return (V, opts = {}) => { + if (opts.strict !== false && !(V instanceof i)) { + throw webidl.errors.exception({ + header: i.name, + message: `Expected ${V} to be an instance of ${i.name}.` + }) + } + + return V + } +} + +webidl.dictionaryConverter = function (converters) { + return (dictionary) => { + const type = webidl.util.Type(dictionary) + const dict = {} + + if (type === 'Null' || type === 'Undefined') { + return dict + } else if (type !== 'Object') { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `Expected ${dictionary} to be one of: Null, Undefined, Object.` + }) + } + + for (const options of converters) { + const { key, defaultValue, required, converter } = options + + if (required === true) { + if (!hasOwn(dictionary, key)) { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `Missing required key "${key}".` + }) + } + } + + let value = dictionary[key] + const hasDefault = hasOwn(options, 'defaultValue') + + // Only use defaultValue if value is undefined and + // a defaultValue options was provided. + if (hasDefault && value !== null) { + value = value ?? defaultValue + } + + // A key can be optional and have no default value. + // When this happens, do not perform a conversion, + // and do not assign the key a value. + if (required || hasDefault || value !== undefined) { + value = converter(value) + + if ( + options.allowedValues && + !options.allowedValues.includes(value) + ) { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.` + }) + } + + dict[key] = value + } + } + + return dict + } +} + +webidl.nullableConverter = function (converter) { + return (V) => { + if (V === null) { + return V + } + + return converter(V) + } +} + +// https://webidl.spec.whatwg.org/#es-DOMString +webidl.converters.DOMString = function (V, opts = {}) { + // 1. If V is null and the conversion is to an IDL type + // associated with the [LegacyNullToEmptyString] + // extended attribute, then return the DOMString value + // that represents the empty string. + if (V === null && opts.legacyNullToEmptyString) { + return '' + } + + // 2. Let x be ? ToString(V). + if (typeof V === 'symbol') { + throw new TypeError('Could not convert argument of type symbol to string.') + } + + // 3. Return the IDL DOMString value that represents the + // same sequence of code units as the one the + // ECMAScript String value x represents. + return String(V) +} + +// https://webidl.spec.whatwg.org/#es-ByteString +webidl.converters.ByteString = function (V) { + // 1. Let x be ? ToString(V). + // Note: DOMString converter perform ? ToString(V) + const x = webidl.converters.DOMString(V) + + // 2. If the value of any element of x is greater than + // 255, then throw a TypeError. + for (let index = 0; index < x.length; index++) { + if (x.charCodeAt(index) > 255) { + throw new TypeError( + 'Cannot convert argument to a ByteString because the character at ' + + `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` + ) + } + } + + // 3. Return an IDL ByteString value whose length is the + // length of x, and where the value of each element is + // the value of the corresponding element of x. + return x +} + +// https://webidl.spec.whatwg.org/#es-USVString +webidl.converters.USVString = toUSVString + +// https://webidl.spec.whatwg.org/#es-boolean +webidl.converters.boolean = function (V) { + // 1. Let x be the result of computing ToBoolean(V). + const x = Boolean(V) + + // 2. Return the IDL boolean value that is the one that represents + // the same truth value as the ECMAScript Boolean value x. + return x +} + +// https://webidl.spec.whatwg.org/#es-any +webidl.converters.any = function (V) { + return V +} + +// https://webidl.spec.whatwg.org/#es-long-long +webidl.converters['long long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 64, "signed"). + const x = webidl.util.ConvertToInt(V, 64, 'signed') + + // 2. Return the IDL long long value that represents + // the same numeric value as x. + return x +} + +// https://webidl.spec.whatwg.org/#es-unsigned-long-long +webidl.converters['unsigned long long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 64, "unsigned"). + const x = webidl.util.ConvertToInt(V, 64, 'unsigned') + + // 2. Return the IDL unsigned long long value that + // represents the same numeric value as x. + return x +} + +// https://webidl.spec.whatwg.org/#es-unsigned-long +webidl.converters['unsigned long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 32, "unsigned"). + const x = webidl.util.ConvertToInt(V, 32, 'unsigned') + + // 2. Return the IDL unsigned long value that + // represents the same numeric value as x. + return x +} + +// https://webidl.spec.whatwg.org/#es-unsigned-short +webidl.converters['unsigned short'] = function (V, opts) { + // 1. Let x be ? ConvertToInt(V, 16, "unsigned"). + const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts) + + // 2. Return the IDL unsigned short value that represents + // the same numeric value as x. + return x +} + +// https://webidl.spec.whatwg.org/#idl-ArrayBuffer +webidl.converters.ArrayBuffer = function (V, opts = {}) { + // 1. If Type(V) is not Object, or V does not have an + // [[ArrayBufferData]] internal slot, then throw a + // TypeError. + // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances + // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances + if ( + webidl.util.Type(V) !== 'Object' || + !types.isAnyArrayBuffer(V) + ) { + throw webidl.errors.conversionFailed({ + prefix: `${V}`, + argument: `${V}`, + types: ['ArrayBuffer'] + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V) is true, then throw a + // TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V) is true, then throw a + // TypeError. + // Note: resizable ArrayBuffers are currently a proposal. + + // 4. Return the IDL ArrayBuffer value that is a + // reference to the same object as V. + return V +} + +webidl.converters.TypedArray = function (V, T, opts = {}) { + // 1. Let T be the IDL type V is being converted to. + + // 2. If Type(V) is not Object, or V does not have a + // [[TypedArrayName]] internal slot with a value + // equal to T’s name, then throw a TypeError. + if ( + webidl.util.Type(V) !== 'Object' || + !types.isTypedArray(V) || + V.constructor.name !== T.name + ) { + throw webidl.errors.conversionFailed({ + prefix: `${T.name}`, + argument: `${V}`, + types: [T.name] + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 4. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + // Note: resizable array buffers are currently a proposal + + // 5. Return the IDL value of type T that is a reference + // to the same object as V. + return V +} + +webidl.converters.DataView = function (V, opts = {}) { + // 1. If Type(V) is not Object, or V does not have a + // [[DataView]] internal slot, then throw a TypeError. + if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) { + throw webidl.errors.exception({ + header: 'DataView', + message: 'Object is not a DataView.' + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, + // then throw a TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + // Note: resizable ArrayBuffers are currently a proposal + + // 4. Return the IDL DataView value that is a reference + // to the same object as V. + return V +} + +// https://webidl.spec.whatwg.org/#BufferSource +webidl.converters.BufferSource = function (V, opts = {}) { + if (types.isAnyArrayBuffer(V)) { + return webidl.converters.ArrayBuffer(V, opts) + } + + if (types.isTypedArray(V)) { + return webidl.converters.TypedArray(V, V.constructor) + } + + if (types.isDataView(V)) { + return webidl.converters.DataView(V, opts) + } + + throw new TypeError(`Could not convert ${V} to a BufferSource.`) +} + +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.ByteString +) + +webidl.converters['sequence>'] = webidl.sequenceConverter( + webidl.converters['sequence'] +) + +webidl.converters['record'] = webidl.recordConverter( + webidl.converters.ByteString, + webidl.converters.ByteString +) + +module.exports = { + webidl +} + + +/***/ }), + +/***/ 4854: +/***/ ((module) => { + +"use strict"; + + +/** + * @see https://encoding.spec.whatwg.org/#concept-encoding-get + * @param {string|undefined} label + */ +function getEncoding (label) { + if (!label) { + return 'failure' + } + + // 1. Remove any leading and trailing ASCII whitespace from label. + // 2. If label is an ASCII case-insensitive match for any of the + // labels listed in the table below, then return the + // corresponding encoding; otherwise return failure. + switch (label.trim().toLowerCase()) { + case 'unicode-1-1-utf-8': + case 'unicode11utf8': + case 'unicode20utf8': + case 'utf-8': + case 'utf8': + case 'x-unicode20utf8': + return 'UTF-8' + case '866': + case 'cp866': + case 'csibm866': + case 'ibm866': + return 'IBM866' + case 'csisolatin2': + case 'iso-8859-2': + case 'iso-ir-101': + case 'iso8859-2': + case 'iso88592': + case 'iso_8859-2': + case 'iso_8859-2:1987': + case 'l2': + case 'latin2': + return 'ISO-8859-2' + case 'csisolatin3': + case 'iso-8859-3': + case 'iso-ir-109': + case 'iso8859-3': + case 'iso88593': + case 'iso_8859-3': + case 'iso_8859-3:1988': + case 'l3': + case 'latin3': + return 'ISO-8859-3' + case 'csisolatin4': + case 'iso-8859-4': + case 'iso-ir-110': + case 'iso8859-4': + case 'iso88594': + case 'iso_8859-4': + case 'iso_8859-4:1988': + case 'l4': + case 'latin4': + return 'ISO-8859-4' + case 'csisolatincyrillic': + case 'cyrillic': + case 'iso-8859-5': + case 'iso-ir-144': + case 'iso8859-5': + case 'iso88595': + case 'iso_8859-5': + case 'iso_8859-5:1988': + return 'ISO-8859-5' + case 'arabic': + case 'asmo-708': + case 'csiso88596e': + case 'csiso88596i': + case 'csisolatinarabic': + case 'ecma-114': + case 'iso-8859-6': + case 'iso-8859-6-e': + case 'iso-8859-6-i': + case 'iso-ir-127': + case 'iso8859-6': + case 'iso88596': + case 'iso_8859-6': + case 'iso_8859-6:1987': + return 'ISO-8859-6' + case 'csisolatingreek': + case 'ecma-118': + case 'elot_928': + case 'greek': + case 'greek8': + case 'iso-8859-7': + case 'iso-ir-126': + case 'iso8859-7': + case 'iso88597': + case 'iso_8859-7': + case 'iso_8859-7:1987': + case 'sun_eu_greek': + return 'ISO-8859-7' + case 'csiso88598e': + case 'csisolatinhebrew': + case 'hebrew': + case 'iso-8859-8': + case 'iso-8859-8-e': + case 'iso-ir-138': + case 'iso8859-8': + case 'iso88598': + case 'iso_8859-8': + case 'iso_8859-8:1988': + case 'visual': + return 'ISO-8859-8' + case 'csiso88598i': + case 'iso-8859-8-i': + case 'logical': + return 'ISO-8859-8-I' + case 'csisolatin6': + case 'iso-8859-10': + case 'iso-ir-157': + case 'iso8859-10': + case 'iso885910': + case 'l6': + case 'latin6': + return 'ISO-8859-10' + case 'iso-8859-13': + case 'iso8859-13': + case 'iso885913': + return 'ISO-8859-13' + case 'iso-8859-14': + case 'iso8859-14': + case 'iso885914': + return 'ISO-8859-14' + case 'csisolatin9': + case 'iso-8859-15': + case 'iso8859-15': + case 'iso885915': + case 'iso_8859-15': + case 'l9': + return 'ISO-8859-15' + case 'iso-8859-16': + return 'ISO-8859-16' + case 'cskoi8r': + case 'koi': + case 'koi8': + case 'koi8-r': + case 'koi8_r': + return 'KOI8-R' + case 'koi8-ru': + case 'koi8-u': + return 'KOI8-U' + case 'csmacintosh': + case 'mac': + case 'macintosh': + case 'x-mac-roman': + return 'macintosh' + case 'iso-8859-11': + case 'iso8859-11': + case 'iso885911': + case 'tis-620': + case 'windows-874': + return 'windows-874' + case 'cp1250': + case 'windows-1250': + case 'x-cp1250': + return 'windows-1250' + case 'cp1251': + case 'windows-1251': + case 'x-cp1251': + return 'windows-1251' + case 'ansi_x3.4-1968': + case 'ascii': + case 'cp1252': + case 'cp819': + case 'csisolatin1': + case 'ibm819': + case 'iso-8859-1': + case 'iso-ir-100': + case 'iso8859-1': + case 'iso88591': + case 'iso_8859-1': + case 'iso_8859-1:1987': + case 'l1': + case 'latin1': + case 'us-ascii': + case 'windows-1252': + case 'x-cp1252': + return 'windows-1252' + case 'cp1253': + case 'windows-1253': + case 'x-cp1253': + return 'windows-1253' + case 'cp1254': + case 'csisolatin5': + case 'iso-8859-9': + case 'iso-ir-148': + case 'iso8859-9': + case 'iso88599': + case 'iso_8859-9': + case 'iso_8859-9:1989': + case 'l5': + case 'latin5': + case 'windows-1254': + case 'x-cp1254': + return 'windows-1254' + case 'cp1255': + case 'windows-1255': + case 'x-cp1255': + return 'windows-1255' + case 'cp1256': + case 'windows-1256': + case 'x-cp1256': + return 'windows-1256' + case 'cp1257': + case 'windows-1257': + case 'x-cp1257': + return 'windows-1257' + case 'cp1258': + case 'windows-1258': + case 'x-cp1258': + return 'windows-1258' + case 'x-mac-cyrillic': + case 'x-mac-ukrainian': + return 'x-mac-cyrillic' + case 'chinese': + case 'csgb2312': + case 'csiso58gb231280': + case 'gb2312': + case 'gb_2312': + case 'gb_2312-80': + case 'gbk': + case 'iso-ir-58': + case 'x-gbk': + return 'GBK' + case 'gb18030': + return 'gb18030' + case 'big5': + case 'big5-hkscs': + case 'cn-big5': + case 'csbig5': + case 'x-x-big5': + return 'Big5' + case 'cseucpkdfmtjapanese': + case 'euc-jp': + case 'x-euc-jp': + return 'EUC-JP' + case 'csiso2022jp': + case 'iso-2022-jp': + return 'ISO-2022-JP' + case 'csshiftjis': + case 'ms932': + case 'ms_kanji': + case 'shift-jis': + case 'shift_jis': + case 'sjis': + case 'windows-31j': + case 'x-sjis': + return 'Shift_JIS' + case 'cseuckr': + case 'csksc56011987': + case 'euc-kr': + case 'iso-ir-149': + case 'korean': + case 'ks_c_5601-1987': + case 'ks_c_5601-1989': + case 'ksc5601': + case 'ksc_5601': + case 'windows-949': + return 'EUC-KR' + case 'csiso2022kr': + case 'hz-gb-2312': + case 'iso-2022-cn': + case 'iso-2022-cn-ext': + case 'iso-2022-kr': + case 'replacement': + return 'replacement' + case 'unicodefffe': + case 'utf-16be': + return 'UTF-16BE' + case 'csunicode': + case 'iso-10646-ucs-2': + case 'ucs-2': + case 'unicode': + case 'unicodefeff': + case 'utf-16': + case 'utf-16le': + return 'UTF-16LE' + case 'x-user-defined': + return 'x-user-defined' + default: return 'failure' + } +} + +module.exports = { + getEncoding +} + + +/***/ }), + +/***/ 1446: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + staticPropertyDescriptors, + readOperation, + fireAProgressEvent +} = __nccwpck_require__(7530) +const { + kState, + kError, + kResult, + kEvents, + kAborted +} = __nccwpck_require__(9054) +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) + +class FileReader extends EventTarget { + constructor () { + super() + + this[kState] = 'empty' + this[kResult] = null + this[kError] = null + this[kEvents] = { + loadend: null, + error: null, + abort: null, + load: null, + progress: null, + loadstart: null + } + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer + * @param {import('buffer').Blob} blob + */ + readAsArrayBuffer (blob) { + webidl.brandCheck(this, FileReader) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsArrayBuffer' }) + + blob = webidl.converters.Blob(blob, { strict: false }) + + // The readAsArrayBuffer(blob) method, when invoked, + // must initiate a read operation for blob with ArrayBuffer. + readOperation(this, blob, 'ArrayBuffer') + } + + /** + * @see https://w3c.github.io/FileAPI/#readAsBinaryString + * @param {import('buffer').Blob} blob + */ + readAsBinaryString (blob) { + webidl.brandCheck(this, FileReader) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsBinaryString' }) + + blob = webidl.converters.Blob(blob, { strict: false }) + + // The readAsBinaryString(blob) method, when invoked, + // must initiate a read operation for blob with BinaryString. + readOperation(this, blob, 'BinaryString') + } + + /** + * @see https://w3c.github.io/FileAPI/#readAsDataText + * @param {import('buffer').Blob} blob + * @param {string?} encoding + */ + readAsText (blob, encoding = undefined) { + webidl.brandCheck(this, FileReader) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsText' }) + + blob = webidl.converters.Blob(blob, { strict: false }) + + if (encoding !== undefined) { + encoding = webidl.converters.DOMString(encoding) + } + + // The readAsText(blob, encoding) method, when invoked, + // must initiate a read operation for blob with Text and encoding. + readOperation(this, blob, 'Text', encoding) + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL + * @param {import('buffer').Blob} blob + */ + readAsDataURL (blob) { + webidl.brandCheck(this, FileReader) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsDataURL' }) + + blob = webidl.converters.Blob(blob, { strict: false }) + + // The readAsDataURL(blob) method, when invoked, must + // initiate a read operation for blob with DataURL. + readOperation(this, blob, 'DataURL') + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-abort + */ + abort () { + // 1. If this's state is "empty" or if this's state is + // "done" set this's result to null and terminate + // this algorithm. + if (this[kState] === 'empty' || this[kState] === 'done') { + this[kResult] = null + return + } + + // 2. If this's state is "loading" set this's state to + // "done" and set this's result to null. + if (this[kState] === 'loading') { + this[kState] = 'done' + this[kResult] = null + } + + // 3. If there are any tasks from this on the file reading + // task source in an affiliated task queue, then remove + // those tasks from that task queue. + this[kAborted] = true + + // 4. Terminate the algorithm for the read method being processed. + // TODO + + // 5. Fire a progress event called abort at this. + fireAProgressEvent('abort', this) + + // 6. If this's state is not "loading", fire a progress + // event called loadend at this. + if (this[kState] !== 'loading') { + fireAProgressEvent('loadend', this) + } + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate + */ + get readyState () { + webidl.brandCheck(this, FileReader) + + switch (this[kState]) { + case 'empty': return this.EMPTY + case 'loading': return this.LOADING + case 'done': return this.DONE + } + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-result + */ + get result () { + webidl.brandCheck(this, FileReader) + + // The result attribute’s getter, when invoked, must return + // this's result. + return this[kResult] + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-error + */ + get error () { + webidl.brandCheck(this, FileReader) + + // The error attribute’s getter, when invoked, must return + // this's error. + return this[kError] + } + + get onloadend () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].loadend + } + + set onloadend (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].loadend) { + this.removeEventListener('loadend', this[kEvents].loadend) + } + + if (typeof fn === 'function') { + this[kEvents].loadend = fn + this.addEventListener('loadend', fn) + } else { + this[kEvents].loadend = null + } + } + + get onerror () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].error + } + + set onerror (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].error) { + this.removeEventListener('error', this[kEvents].error) + } + + if (typeof fn === 'function') { + this[kEvents].error = fn + this.addEventListener('error', fn) + } else { + this[kEvents].error = null + } + } + + get onloadstart () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].loadstart + } + + set onloadstart (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].loadstart) { + this.removeEventListener('loadstart', this[kEvents].loadstart) + } + + if (typeof fn === 'function') { + this[kEvents].loadstart = fn + this.addEventListener('loadstart', fn) + } else { + this[kEvents].loadstart = null + } + } + + get onprogress () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].progress + } + + set onprogress (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].progress) { + this.removeEventListener('progress', this[kEvents].progress) + } + + if (typeof fn === 'function') { + this[kEvents].progress = fn + this.addEventListener('progress', fn) + } else { + this[kEvents].progress = null + } + } + + get onload () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].load + } + + set onload (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].load) { + this.removeEventListener('load', this[kEvents].load) + } + + if (typeof fn === 'function') { + this[kEvents].load = fn + this.addEventListener('load', fn) + } else { + this[kEvents].load = null + } + } + + get onabort () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].abort + } + + set onabort (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].abort) { + this.removeEventListener('abort', this[kEvents].abort) + } + + if (typeof fn === 'function') { + this[kEvents].abort = fn + this.addEventListener('abort', fn) + } else { + this[kEvents].abort = null + } + } +} + +// https://w3c.github.io/FileAPI/#dom-filereader-empty +FileReader.EMPTY = FileReader.prototype.EMPTY = 0 +// https://w3c.github.io/FileAPI/#dom-filereader-loading +FileReader.LOADING = FileReader.prototype.LOADING = 1 +// https://w3c.github.io/FileAPI/#dom-filereader-done +FileReader.DONE = FileReader.prototype.DONE = 2 + +Object.defineProperties(FileReader.prototype, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors, + readAsArrayBuffer: kEnumerableProperty, + readAsBinaryString: kEnumerableProperty, + readAsText: kEnumerableProperty, + readAsDataURL: kEnumerableProperty, + abort: kEnumerableProperty, + readyState: kEnumerableProperty, + result: kEnumerableProperty, + error: kEnumerableProperty, + onloadstart: kEnumerableProperty, + onprogress: kEnumerableProperty, + onload: kEnumerableProperty, + onabort: kEnumerableProperty, + onerror: kEnumerableProperty, + onloadend: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'FileReader', + writable: false, + enumerable: false, + configurable: true + } +}) + +Object.defineProperties(FileReader, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors +}) + +module.exports = { + FileReader +} + + +/***/ }), + +/***/ 5504: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { webidl } = __nccwpck_require__(1744) + +const kState = Symbol('ProgressEvent state') + +/** + * @see https://xhr.spec.whatwg.org/#progressevent + */ +class ProgressEvent extends Event { + constructor (type, eventInitDict = {}) { + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.ProgressEventInit(eventInitDict ?? {}) + + super(type, eventInitDict) + + this[kState] = { + lengthComputable: eventInitDict.lengthComputable, + loaded: eventInitDict.loaded, + total: eventInitDict.total + } + } + + get lengthComputable () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].lengthComputable + } + + get loaded () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].loaded + } + + get total () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].total + } +} + +webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ + { + key: 'lengthComputable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'loaded', + converter: webidl.converters['unsigned long long'], + defaultValue: 0 + }, + { + key: 'total', + converter: webidl.converters['unsigned long long'], + defaultValue: 0 + }, + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: false + } +]) + +module.exports = { + ProgressEvent +} + + +/***/ }), + +/***/ 9054: +/***/ ((module) => { + +"use strict"; + + +module.exports = { + kState: Symbol('FileReader state'), + kResult: Symbol('FileReader result'), + kError: Symbol('FileReader error'), + kLastProgressEventFired: Symbol('FileReader last progress event fired timestamp'), + kEvents: Symbol('FileReader events'), + kAborted: Symbol('FileReader aborted') +} + + +/***/ }), + +/***/ 7530: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + kState, + kError, + kResult, + kAborted, + kLastProgressEventFired +} = __nccwpck_require__(9054) +const { ProgressEvent } = __nccwpck_require__(5504) +const { getEncoding } = __nccwpck_require__(4854) +const { DOMException } = __nccwpck_require__(1037) +const { serializeAMimeType, parseMIMEType } = __nccwpck_require__(685) +const { types } = __nccwpck_require__(3837) +const { StringDecoder } = __nccwpck_require__(1576) +const { btoa } = __nccwpck_require__(4300) + +/** @type {PropertyDescriptor} */ +const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false +} + +/** + * @see https://w3c.github.io/FileAPI/#readOperation + * @param {import('./filereader').FileReader} fr + * @param {import('buffer').Blob} blob + * @param {string} type + * @param {string?} encodingName + */ +function readOperation (fr, blob, type, encodingName) { + // 1. If fr’s state is "loading", throw an InvalidStateError + // DOMException. + if (fr[kState] === 'loading') { + throw new DOMException('Invalid state', 'InvalidStateError') + } + + // 2. Set fr’s state to "loading". + fr[kState] = 'loading' + + // 3. Set fr’s result to null. + fr[kResult] = null + + // 4. Set fr’s error to null. + fr[kError] = null + + // 5. Let stream be the result of calling get stream on blob. + /** @type {import('stream/web').ReadableStream} */ + const stream = blob.stream() + + // 6. Let reader be the result of getting a reader from stream. + const reader = stream.getReader() + + // 7. Let bytes be an empty byte sequence. + /** @type {Uint8Array[]} */ + const bytes = [] + + // 8. Let chunkPromise be the result of reading a chunk from + // stream with reader. + let chunkPromise = reader.read() + + // 9. Let isFirstChunk be true. + let isFirstChunk = true + + // 10. In parallel, while true: + // Note: "In parallel" just means non-blocking + // Note 2: readOperation itself cannot be async as double + // reading the body would then reject the promise, instead + // of throwing an error. + ;(async () => { + while (!fr[kAborted]) { + // 1. Wait for chunkPromise to be fulfilled or rejected. + try { + const { done, value } = await chunkPromise + + // 2. If chunkPromise is fulfilled, and isFirstChunk is + // true, queue a task to fire a progress event called + // loadstart at fr. + if (isFirstChunk && !fr[kAborted]) { + queueMicrotask(() => { + fireAProgressEvent('loadstart', fr) + }) + } + + // 3. Set isFirstChunk to false. + isFirstChunk = false + + // 4. If chunkPromise is fulfilled with an object whose + // done property is false and whose value property is + // a Uint8Array object, run these steps: + if (!done && types.isUint8Array(value)) { + // 1. Let bs be the byte sequence represented by the + // Uint8Array object. + + // 2. Append bs to bytes. + bytes.push(value) + + // 3. If roughly 50ms have passed since these steps + // were last invoked, queue a task to fire a + // progress event called progress at fr. + if ( + ( + fr[kLastProgressEventFired] === undefined || + Date.now() - fr[kLastProgressEventFired] >= 50 + ) && + !fr[kAborted] + ) { + fr[kLastProgressEventFired] = Date.now() + queueMicrotask(() => { + fireAProgressEvent('progress', fr) + }) + } + + // 4. Set chunkPromise to the result of reading a + // chunk from stream with reader. + chunkPromise = reader.read() + } else if (done) { + // 5. Otherwise, if chunkPromise is fulfilled with an + // object whose done property is true, queue a task + // to run the following steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done' + + // 2. Let result be the result of package data given + // bytes, type, blob’s type, and encodingName. + try { + const result = packageData(bytes, type, blob.type, encodingName) + + // 4. Else: + + if (fr[kAborted]) { + return + } + + // 1. Set fr’s result to result. + fr[kResult] = result + + // 2. Fire a progress event called load at the fr. + fireAProgressEvent('load', fr) + } catch (error) { + // 3. If package data threw an exception error: + + // 1. Set fr’s error to error. + fr[kError] = error + + // 2. Fire a progress event called error at fr. + fireAProgressEvent('error', fr) + } + + // 5. If fr’s state is not "loading", fire a progress + // event called loadend at the fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr) + } + }) + + break + } + } catch (error) { + if (fr[kAborted]) { + return + } + + // 6. Otherwise, if chunkPromise is rejected with an + // error error, queue a task to run the following + // steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done' + + // 2. Set fr’s error to error. + fr[kError] = error + + // 3. Fire a progress event called error at fr. + fireAProgressEvent('error', fr) + + // 4. If fr’s state is not "loading", fire a progress + // event called loadend at fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr) + } + }) + + break + } + } + })() +} + +/** + * @see https://w3c.github.io/FileAPI/#fire-a-progress-event + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e The name of the event + * @param {import('./filereader').FileReader} reader + */ +function fireAProgressEvent (e, reader) { + // The progress event e does not bubble. e.bubbles must be false + // The progress event e is NOT cancelable. e.cancelable must be false + const event = new ProgressEvent(e, { + bubbles: false, + cancelable: false + }) + + reader.dispatchEvent(event) +} + +/** + * @see https://w3c.github.io/FileAPI/#blob-package-data + * @param {Uint8Array[]} bytes + * @param {string} type + * @param {string?} mimeType + * @param {string?} encodingName + */ +function packageData (bytes, type, mimeType, encodingName) { + // 1. A Blob has an associated package data algorithm, given + // bytes, a type, a optional mimeType, and a optional + // encodingName, which switches on type and runs the + // associated steps: + + switch (type) { + case 'DataURL': { + // 1. Return bytes as a DataURL [RFC2397] subject to + // the considerations below: + // * Use mimeType as part of the Data URL if it is + // available in keeping with the Data URL + // specification [RFC2397]. + // * If mimeType is not available return a Data URL + // without a media-type. [RFC2397]. + + // https://datatracker.ietf.org/doc/html/rfc2397#section-3 + // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + // mediatype := [ type "/" subtype ] *( ";" parameter ) + // data := *urlchar + // parameter := attribute "=" value + let dataURL = 'data:' + + const parsed = parseMIMEType(mimeType || 'application/octet-stream') + + if (parsed !== 'failure') { + dataURL += serializeAMimeType(parsed) + } + + dataURL += ';base64,' + + const decoder = new StringDecoder('latin1') + + for (const chunk of bytes) { + dataURL += btoa(decoder.write(chunk)) + } + + dataURL += btoa(decoder.end()) + + return dataURL + } + case 'Text': { + // 1. Let encoding be failure + let encoding = 'failure' + + // 2. If the encodingName is present, set encoding to the + // result of getting an encoding from encodingName. + if (encodingName) { + encoding = getEncoding(encodingName) + } + + // 3. If encoding is failure, and mimeType is present: + if (encoding === 'failure' && mimeType) { + // 1. Let type be the result of parse a MIME type + // given mimeType. + const type = parseMIMEType(mimeType) + + // 2. If type is not failure, set encoding to the result + // of getting an encoding from type’s parameters["charset"]. + if (type !== 'failure') { + encoding = getEncoding(type.parameters.get('charset')) + } + } + + // 4. If encoding is failure, then set encoding to UTF-8. + if (encoding === 'failure') { + encoding = 'UTF-8' + } + + // 5. Decode bytes using fallback encoding encoding, and + // return the result. + return decode(bytes, encoding) + } + case 'ArrayBuffer': { + // Return a new ArrayBuffer whose contents are bytes. + const sequence = combineByteSequences(bytes) + + return sequence.buffer + } + case 'BinaryString': { + // Return bytes as a binary string, in which every byte + // is represented by a code unit of equal value [0..255]. + let binaryString = '' + + const decoder = new StringDecoder('latin1') + + for (const chunk of bytes) { + binaryString += decoder.write(chunk) + } + + binaryString += decoder.end() + + return binaryString + } + } +} + +/** + * @see https://encoding.spec.whatwg.org/#decode + * @param {Uint8Array[]} ioQueue + * @param {string} encoding + */ +function decode (ioQueue, encoding) { + const bytes = combineByteSequences(ioQueue) + + // 1. Let BOMEncoding be the result of BOM sniffing ioQueue. + const BOMEncoding = BOMSniffing(bytes) + + let slice = 0 + + // 2. If BOMEncoding is non-null: + if (BOMEncoding !== null) { + // 1. Set encoding to BOMEncoding. + encoding = BOMEncoding + + // 2. Read three bytes from ioQueue, if BOMEncoding is + // UTF-8; otherwise read two bytes. + // (Do nothing with those bytes.) + slice = BOMEncoding === 'UTF-8' ? 3 : 2 + } + + // 3. Process a queue with an instance of encoding’s + // decoder, ioQueue, output, and "replacement". + + // 4. Return output. + + const sliced = bytes.slice(slice) + return new TextDecoder(encoding).decode(sliced) +} + +/** + * @see https://encoding.spec.whatwg.org/#bom-sniff + * @param {Uint8Array} ioQueue + */ +function BOMSniffing (ioQueue) { + // 1. Let BOM be the result of peeking 3 bytes from ioQueue, + // converted to a byte sequence. + const [a, b, c] = ioQueue + + // 2. For each of the rows in the table below, starting with + // the first one and going down, if BOM starts with the + // bytes given in the first column, then return the + // encoding given in the cell in the second column of that + // row. Otherwise, return null. + if (a === 0xEF && b === 0xBB && c === 0xBF) { + return 'UTF-8' + } else if (a === 0xFE && b === 0xFF) { + return 'UTF-16BE' + } else if (a === 0xFF && b === 0xFE) { + return 'UTF-16LE' + } + + return null +} + +/** + * @param {Uint8Array[]} sequences + */ +function combineByteSequences (sequences) { + const size = sequences.reduce((a, b) => { + return a + b.byteLength + }, 0) + + let offset = 0 + + return sequences.reduce((a, b) => { + a.set(b, offset) + offset += b.byteLength + return a + }, new Uint8Array(size)) +} + +module.exports = { + staticPropertyDescriptors, + readOperation, + fireAProgressEvent +} + + +/***/ }), + +/***/ 1892: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +// We include a version number for the Dispatcher API. In case of breaking changes, +// this version number must be increased to avoid conflicts. +const globalDispatcher = Symbol.for('undici.globalDispatcher.1') +const { InvalidArgumentError } = __nccwpck_require__(8045) +const Agent = __nccwpck_require__(7890) + +if (getGlobalDispatcher() === undefined) { + setGlobalDispatcher(new Agent()) +} + +function setGlobalDispatcher (agent) { + if (!agent || typeof agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument agent must implement Agent') + } + Object.defineProperty(globalThis, globalDispatcher, { + value: agent, + writable: true, + enumerable: false, + configurable: false + }) +} + +function getGlobalDispatcher () { + return globalThis[globalDispatcher] +} + +module.exports = { + setGlobalDispatcher, + getGlobalDispatcher +} + + +/***/ }), + +/***/ 6930: +/***/ ((module) => { + +"use strict"; + + +module.exports = class DecoratorHandler { + constructor (handler) { + this.handler = handler + } + + onConnect (...args) { + return this.handler.onConnect(...args) + } + + onError (...args) { + return this.handler.onError(...args) + } + + onUpgrade (...args) { + return this.handler.onUpgrade(...args) + } + + onHeaders (...args) { + return this.handler.onHeaders(...args) + } + + onData (...args) { + return this.handler.onData(...args) + } + + onComplete (...args) { + return this.handler.onComplete(...args) + } + + onBodySent (...args) { + return this.handler.onBodySent(...args) + } +} + + +/***/ }), + +/***/ 2860: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const util = __nccwpck_require__(3983) +const { kBodyUsed } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const EE = __nccwpck_require__(2361) + +const redirectableStatusCodes = [300, 301, 302, 303, 307, 308] + +const kBody = Symbol('body') + +class BodyAsyncIterable { + constructor (body) { + this[kBody] = body + this[kBodyUsed] = false + } + + async * [Symbol.asyncIterator] () { + assert(!this[kBodyUsed], 'disturbed') + this[kBodyUsed] = true + yield * this[kBody] + } +} + +class RedirectHandler { + constructor (dispatch, maxRedirections, opts, handler) { + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } + + util.validateHandler(handler, opts.method, opts.upgrade) + + this.dispatch = dispatch + this.location = null + this.abort = null + this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy + this.maxRedirections = maxRedirections + this.handler = handler + this.history = [] + + if (util.isStream(this.opts.body)) { + // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp + // so that it can be dispatched again? + // TODO (fix): Do we need 100-expect support to provide a way to do this properly? + if (util.bodyLength(this.opts.body) === 0) { + this.opts.body + .on('data', function () { + assert(false) + }) + } + + if (typeof this.opts.body.readableDidRead !== 'boolean') { + this.opts.body[kBodyUsed] = false + EE.prototype.on.call(this.opts.body, 'data', function () { + this[kBodyUsed] = true + }) + } + } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') { + // TODO (fix): We can't access ReadableStream internal state + // to determine whether or not it has been disturbed. This is just + // a workaround. + this.opts.body = new BodyAsyncIterable(this.opts.body) + } else if ( + this.opts.body && + typeof this.opts.body !== 'string' && + !ArrayBuffer.isView(this.opts.body) && + util.isIterable(this.opts.body) + ) { + // TODO: Should we allow re-using iterable if !this.opts.idempotent + // or through some other flag? + this.opts.body = new BodyAsyncIterable(this.opts.body) + } + } + + onConnect (abort) { + this.abort = abort + this.handler.onConnect(abort, { history: this.history }) + } + + onUpgrade (statusCode, headers, socket) { + this.handler.onUpgrade(statusCode, headers, socket) + } + + onError (error) { + this.handler.onError(error) + } + + onHeaders (statusCode, headers, resume, statusText) { + this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) + ? null + : parseLocation(statusCode, headers) + + if (this.opts.origin) { + this.history.push(new URL(this.opts.path, this.opts.origin)) + } + + if (!this.location) { + return this.handler.onHeaders(statusCode, headers, resume, statusText) + } + + const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))) + const path = search ? `${pathname}${search}` : pathname + + // Remove headers referring to the original URL. + // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. + // https://tools.ietf.org/html/rfc7231#section-6.4 + this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin) + this.opts.path = path + this.opts.origin = origin + this.opts.maxRedirections = 0 + this.opts.query = null + + // https://tools.ietf.org/html/rfc7231#section-6.4.4 + // In case of HTTP 303, always replace method to be either HEAD or GET + if (statusCode === 303 && this.opts.method !== 'HEAD') { + this.opts.method = 'GET' + this.opts.body = null + } + } + + onData (chunk) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 + + TLDR: undici always ignores 3xx response bodies. + + Redirection is used to serve the requested resource from another URL, so it is assumes that + no body is generated (and thus can be ignored). Even though generating a body is not prohibited. + + For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually + (which means it's optional and not mandated) contain just an hyperlink to the value of + the Location response header, so the body can be ignored safely. + + For status 300, which is "Multiple Choices", the spec mentions both generating a Location + response header AND a response body with the other possible location to follow. + Since the spec explicitily chooses not to specify a format for such body and leave it to + servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. + */ + } else { + return this.handler.onData(chunk) + } + } + + onComplete (trailers) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 + + TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections + and neither are useful if present. + + See comment on onData method above for more detailed informations. + */ + + this.location = null + this.abort = null + + this.dispatch(this.opts, this) + } else { + this.handler.onComplete(trailers) + } + } + + onBodySent (chunk) { + if (this.handler.onBodySent) { + this.handler.onBodySent(chunk) + } + } +} + +function parseLocation (statusCode, headers) { + if (redirectableStatusCodes.indexOf(statusCode) === -1) { + return null + } + + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toString().toLowerCase() === 'location') { + return headers[i + 1] + } + } +} + +// https://tools.ietf.org/html/rfc7231#section-6.4.4 +function shouldRemoveHeader (header, removeContent, unknownOrigin) { + return ( + (header.length === 4 && header.toString().toLowerCase() === 'host') || + (removeContent && header.toString().toLowerCase().indexOf('content-') === 0) || + (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') || + (unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie') + ) +} + +// https://tools.ietf.org/html/rfc7231#section-6.4 +function cleanRequestHeaders (headers, removeContent, unknownOrigin) { + const ret = [] + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { + ret.push(headers[i], headers[i + 1]) + } + } + } else if (headers && typeof headers === 'object') { + for (const key of Object.keys(headers)) { + if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { + ret.push(key, headers[key]) + } + } + } else { + assert(headers == null, 'headers must be an object or an array') + } + return ret +} + +module.exports = RedirectHandler + + +/***/ }), + +/***/ 2286: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +const assert = __nccwpck_require__(9491) + +const { kRetryHandlerDefaultRetry } = __nccwpck_require__(2785) +const { RequestRetryError } = __nccwpck_require__(8045) +const { isDisturbed, parseHeaders, parseRangeHeader } = __nccwpck_require__(3983) + +function calculateRetryAfterHeader (retryAfter) { + const current = Date.now() + const diff = new Date(retryAfter).getTime() - current + + return diff +} + +class RetryHandler { + constructor (opts, handlers) { + const { retryOptions, ...dispatchOpts } = opts + const { + // Retry scoped + retry: retryFn, + maxRetries, + maxTimeout, + minTimeout, + timeoutFactor, + // Response scoped + methods, + errorCodes, + retryAfter, + statusCodes + } = retryOptions ?? {} + + this.dispatch = handlers.dispatch + this.handler = handlers.handler + this.opts = dispatchOpts + this.abort = null + this.aborted = false + this.retryOpts = { + retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], + retryAfter: retryAfter ?? true, + maxTimeout: maxTimeout ?? 30 * 1000, // 30s, + timeout: minTimeout ?? 500, // .5s + timeoutFactor: timeoutFactor ?? 2, + maxRetries: maxRetries ?? 5, + // What errors we should retry + methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], + // Indicates which errors to retry + statusCodes: statusCodes ?? [500, 502, 503, 504, 429], + // List of errors to retry + errorCodes: errorCodes ?? [ + 'ECONNRESET', + 'ECONNREFUSED', + 'ENOTFOUND', + 'ENETDOWN', + 'ENETUNREACH', + 'EHOSTDOWN', + 'EHOSTUNREACH', + 'EPIPE' + ] + } + + this.retryCount = 0 + this.start = 0 + this.end = null + this.etag = null + this.resume = null + + // Handle possible onConnect duplication + this.handler.onConnect(reason => { + this.aborted = true + if (this.abort) { + this.abort(reason) + } else { + this.reason = reason + } + }) + } + + onRequestSent () { + if (this.handler.onRequestSent) { + this.handler.onRequestSent() + } + } + + onUpgrade (statusCode, headers, socket) { + if (this.handler.onUpgrade) { + this.handler.onUpgrade(statusCode, headers, socket) + } + } + + onConnect (abort) { + if (this.aborted) { + abort(this.reason) + } else { + this.abort = abort + } + } + + onBodySent (chunk) { + if (this.handler.onBodySent) return this.handler.onBodySent(chunk) + } + + static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { + const { statusCode, code, headers } = err + const { method, retryOptions } = opts + const { + maxRetries, + timeout, + maxTimeout, + timeoutFactor, + statusCodes, + errorCodes, + methods + } = retryOptions + let { counter, currentTimeout } = state + + currentTimeout = + currentTimeout != null && currentTimeout > 0 ? currentTimeout : timeout + + // Any code that is not a Undici's originated and allowed to retry + if ( + code && + code !== 'UND_ERR_REQ_RETRY' && + code !== 'UND_ERR_SOCKET' && + !errorCodes.includes(code) + ) { + cb(err) + return + } + + // If a set of method are provided and the current method is not in the list + if (Array.isArray(methods) && !methods.includes(method)) { + cb(err) + return + } + + // If a set of status code are provided and the current status code is not in the list + if ( + statusCode != null && + Array.isArray(statusCodes) && + !statusCodes.includes(statusCode) + ) { + cb(err) + return + } + + // If we reached the max number of retries + if (counter > maxRetries) { + cb(err) + return + } + + let retryAfterHeader = headers != null && headers['retry-after'] + if (retryAfterHeader) { + retryAfterHeader = Number(retryAfterHeader) + retryAfterHeader = isNaN(retryAfterHeader) + ? calculateRetryAfterHeader(retryAfterHeader) + : retryAfterHeader * 1e3 // Retry-After is in seconds + } + + const retryTimeout = + retryAfterHeader > 0 + ? Math.min(retryAfterHeader, maxTimeout) + : Math.min(currentTimeout * timeoutFactor ** counter, maxTimeout) + + state.currentTimeout = retryTimeout + + setTimeout(() => cb(null), retryTimeout) + } + + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const headers = parseHeaders(rawHeaders) + + this.retryCount += 1 + + if (statusCode >= 300) { + this.abort( + new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } + + // Checkpoint for resume from where we left it + if (this.resume != null) { + this.resume = null + + if (statusCode !== 206) { + return true + } + + const contentRange = parseRangeHeader(headers['content-range']) + // If no content range + if (!contentRange) { + this.abort( + new RequestRetryError('Content-Range mismatch', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } + + // Let's start with a weak etag check + if (this.etag != null && this.etag !== headers.etag) { + this.abort( + new RequestRetryError('ETag mismatch', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } + + const { start, size, end = size } = contentRange + + assert(this.start === start, 'content-range mismatch') + assert(this.end == null || this.end === end, 'content-range mismatch') + + this.resume = resume + return true + } + + if (this.end == null) { + if (statusCode === 206) { + // First time we receive 206 + const range = parseRangeHeader(headers['content-range']) + + if (range == null) { + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } + + const { start, size, end = size } = range + + assert( + start != null && Number.isFinite(start) && this.start !== start, + 'content-range mismatch' + ) + assert(Number.isFinite(start)) + assert( + end != null && Number.isFinite(end) && this.end !== end, + 'invalid content-length' + ) + + this.start = start + this.end = end + } + + // We make our best to checkpoint the body for further range headers + if (this.end == null) { + const contentLength = headers['content-length'] + this.end = contentLength != null ? Number(contentLength) : null + } + + assert(Number.isFinite(this.start)) + assert( + this.end == null || Number.isFinite(this.end), + 'invalid content-length' + ) + + this.resume = resume + this.etag = headers.etag != null ? headers.etag : null + + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } + + const err = new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount + }) + + this.abort(err) + + return false + } + + onData (chunk) { + this.start += chunk.length + + return this.handler.onData(chunk) + } + + onComplete (rawTrailers) { + this.retryCount = 0 + return this.handler.onComplete(rawTrailers) + } + + onError (err) { + if (this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) + } + + this.retryOpts.retry( + err, + { + state: { counter: this.retryCount++, currentTimeout: this.retryAfter }, + opts: { retryOptions: this.retryOpts, ...this.opts } + }, + onRetry.bind(this) + ) + + function onRetry (err) { + if (err != null || this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) + } + + if (this.start !== 0) { + this.opts = { + ...this.opts, + headers: { + ...this.opts.headers, + range: `bytes=${this.start}-${this.end ?? ''}` + } + } + } + + try { + this.dispatch(this.opts, this) + } catch (err) { + this.handler.onError(err) + } + } + } +} + +module.exports = RetryHandler + + +/***/ }), + +/***/ 8861: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const RedirectHandler = __nccwpck_require__(2860) + +function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }) { + return (dispatch) => { + return function Intercept (opts, handler) { + const { maxRedirections = defaultMaxRedirections } = opts + + if (!maxRedirections) { + return dispatch(opts, handler) + } + + const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler) + opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting. + return dispatch(opts, redirectHandler) + } + } +} + +module.exports = createRedirectInterceptor + + +/***/ }), + +/***/ 953: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; +const utils_1 = __nccwpck_require__(1891); +// C headers +var ERROR; +(function (ERROR) { + ERROR[ERROR["OK"] = 0] = "OK"; + ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL"; + ERROR[ERROR["STRICT"] = 2] = "STRICT"; + ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED"; + ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; + ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; + ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD"; + ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL"; + ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; + ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION"; + ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; + ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; + ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; + ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS"; + ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; + ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; + ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; + ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; + ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; + ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; + ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; + ERROR[ERROR["PAUSED"] = 21] = "PAUSED"; + ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; + ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; + ERROR[ERROR["USER"] = 24] = "USER"; +})(ERROR = exports.ERROR || (exports.ERROR = {})); +var TYPE; +(function (TYPE) { + TYPE[TYPE["BOTH"] = 0] = "BOTH"; + TYPE[TYPE["REQUEST"] = 1] = "REQUEST"; + TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE"; +})(TYPE = exports.TYPE || (exports.TYPE = {})); +var FLAGS; +(function (FLAGS) { + FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; + FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; + FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; + FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED"; + FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE"; + FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; + FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY"; + FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING"; + // 1 << 8 is unused + FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; +})(FLAGS = exports.FLAGS || (exports.FLAGS = {})); +var LENIENT_FLAGS; +(function (LENIENT_FLAGS) { + LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS"; + LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; + LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; +})(LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); +var METHODS; +(function (METHODS) { + METHODS[METHODS["DELETE"] = 0] = "DELETE"; + METHODS[METHODS["GET"] = 1] = "GET"; + METHODS[METHODS["HEAD"] = 2] = "HEAD"; + METHODS[METHODS["POST"] = 3] = "POST"; + METHODS[METHODS["PUT"] = 4] = "PUT"; + /* pathological */ + METHODS[METHODS["CONNECT"] = 5] = "CONNECT"; + METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS"; + METHODS[METHODS["TRACE"] = 7] = "TRACE"; + /* WebDAV */ + METHODS[METHODS["COPY"] = 8] = "COPY"; + METHODS[METHODS["LOCK"] = 9] = "LOCK"; + METHODS[METHODS["MKCOL"] = 10] = "MKCOL"; + METHODS[METHODS["MOVE"] = 11] = "MOVE"; + METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND"; + METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH"; + METHODS[METHODS["SEARCH"] = 14] = "SEARCH"; + METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK"; + METHODS[METHODS["BIND"] = 16] = "BIND"; + METHODS[METHODS["REBIND"] = 17] = "REBIND"; + METHODS[METHODS["UNBIND"] = 18] = "UNBIND"; + METHODS[METHODS["ACL"] = 19] = "ACL"; + /* subversion */ + METHODS[METHODS["REPORT"] = 20] = "REPORT"; + METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY"; + METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT"; + METHODS[METHODS["MERGE"] = 23] = "MERGE"; + /* upnp */ + METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH"; + METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY"; + METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE"; + METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; + /* RFC-5789 */ + METHODS[METHODS["PATCH"] = 28] = "PATCH"; + METHODS[METHODS["PURGE"] = 29] = "PURGE"; + /* CalDAV */ + METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR"; + /* RFC-2068, section 19.6.1.2 */ + METHODS[METHODS["LINK"] = 31] = "LINK"; + METHODS[METHODS["UNLINK"] = 32] = "UNLINK"; + /* icecast */ + METHODS[METHODS["SOURCE"] = 33] = "SOURCE"; + /* RFC-7540, section 11.6 */ + METHODS[METHODS["PRI"] = 34] = "PRI"; + /* RFC-2326 RTSP */ + METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE"; + METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE"; + METHODS[METHODS["SETUP"] = 37] = "SETUP"; + METHODS[METHODS["PLAY"] = 38] = "PLAY"; + METHODS[METHODS["PAUSE"] = 39] = "PAUSE"; + METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN"; + METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER"; + METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER"; + METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT"; + METHODS[METHODS["RECORD"] = 44] = "RECORD"; + /* RAOP */ + METHODS[METHODS["FLUSH"] = 45] = "FLUSH"; +})(METHODS = exports.METHODS || (exports.METHODS = {})); +exports.METHODS_HTTP = [ + METHODS.DELETE, + METHODS.GET, + METHODS.HEAD, + METHODS.POST, + METHODS.PUT, + METHODS.CONNECT, + METHODS.OPTIONS, + METHODS.TRACE, + METHODS.COPY, + METHODS.LOCK, + METHODS.MKCOL, + METHODS.MOVE, + METHODS.PROPFIND, + METHODS.PROPPATCH, + METHODS.SEARCH, + METHODS.UNLOCK, + METHODS.BIND, + METHODS.REBIND, + METHODS.UNBIND, + METHODS.ACL, + METHODS.REPORT, + METHODS.MKACTIVITY, + METHODS.CHECKOUT, + METHODS.MERGE, + METHODS['M-SEARCH'], + METHODS.NOTIFY, + METHODS.SUBSCRIBE, + METHODS.UNSUBSCRIBE, + METHODS.PATCH, + METHODS.PURGE, + METHODS.MKCALENDAR, + METHODS.LINK, + METHODS.UNLINK, + METHODS.PRI, + // TODO(indutny): should we allow it with HTTP? + METHODS.SOURCE, +]; +exports.METHODS_ICE = [ + METHODS.SOURCE, +]; +exports.METHODS_RTSP = [ + METHODS.OPTIONS, + METHODS.DESCRIBE, + METHODS.ANNOUNCE, + METHODS.SETUP, + METHODS.PLAY, + METHODS.PAUSE, + METHODS.TEARDOWN, + METHODS.GET_PARAMETER, + METHODS.SET_PARAMETER, + METHODS.REDIRECT, + METHODS.RECORD, + METHODS.FLUSH, + // For AirPlay + METHODS.GET, + METHODS.POST, +]; +exports.METHOD_MAP = utils_1.enumToMap(METHODS); +exports.H_METHOD_MAP = {}; +Object.keys(exports.METHOD_MAP).forEach((key) => { + if (/^H/.test(key)) { + exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; + } +}); +var FINISH; +(function (FINISH) { + FINISH[FINISH["SAFE"] = 0] = "SAFE"; + FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; + FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE"; +})(FINISH = exports.FINISH || (exports.FINISH = {})); +exports.ALPHA = []; +for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { + // Upper case + exports.ALPHA.push(String.fromCharCode(i)); + // Lower case + exports.ALPHA.push(String.fromCharCode(i + 0x20)); +} +exports.NUM_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, +}; +exports.HEX_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, + A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, + a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, +}; +exports.NUM = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', +]; +exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); +exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; +exports.USERINFO_CHARS = exports.ALPHANUM + .concat(exports.MARK) + .concat(['%', ';', ':', '&', '=', '+', '$', ',']); +// TODO(indutny): use RFC +exports.STRICT_URL_CHAR = [ + '!', '"', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + ':', ';', '<', '=', '>', + '@', '[', '\\', ']', '^', '_', + '`', + '{', '|', '}', '~', +].concat(exports.ALPHANUM); +exports.URL_CHAR = exports.STRICT_URL_CHAR + .concat(['\t', '\f']); +// All characters with 0x80 bit set to 1 +for (let i = 0x80; i <= 0xff; i++) { + exports.URL_CHAR.push(i); +} +exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +exports.STRICT_TOKEN = [ + '!', '#', '$', '%', '&', '\'', + '*', '+', '-', '.', + '^', '_', '`', + '|', '~', +].concat(exports.ALPHANUM); +exports.TOKEN = exports.STRICT_TOKEN.concat([' ']); +/* + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + */ +exports.HEADER_CHARS = ['\t']; +for (let i = 32; i <= 255; i++) { + if (i !== 127) { + exports.HEADER_CHARS.push(i); + } +} +// ',' = \x44 +exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); +exports.MAJOR = exports.NUM_MAP; +exports.MINOR = exports.MAJOR; +var HEADER_STATE; +(function (HEADER_STATE) { + HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL"; + HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION"; + HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; + HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; + HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE"; + HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; + HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; + HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; + HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; +})(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); +exports.SPECIAL_HEADERS = { + 'connection': HEADER_STATE.CONNECTION, + 'content-length': HEADER_STATE.CONTENT_LENGTH, + 'proxy-connection': HEADER_STATE.CONNECTION, + 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, + 'upgrade': HEADER_STATE.UPGRADE, +}; +//# sourceMappingURL=constants.js.map + +/***/ }), + +/***/ 1145: +/***/ ((module) => { + +module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ADcDACAAQShqQgA3AwAgAEEgakIANwMAIABBEGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvk8wEDDn8DfgR/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCHCIQQX9qDt0B2gEB2QECAwQFBgcICQoLDA0O2AEPENcBERLWARMUFRYXGBkaG+AB3wEcHR7VAR8gISIjJCXUASYnKCkqKyzTAdIBLS7RAdABLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVG2wFHSElKzwHOAUvNAUzMAU1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4ABgQGCAYMBhAGFAYYBhwGIAYkB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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FCAAIBA2AgxBACEQDLIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDLEBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxRCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLABCyAAQQA2AhwgACABNgIUIABBxoqAgAA2AhAgAEEHNgIMQQAhEAyvAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAyuAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAytAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMTQsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAysAQsgAEEANgIcIAAgATYCFCAAQdyIgIAANgIQIABBBzYCDEEAIRAMqwELIBBBP0cNASABQQFqIQELQQUhEAyQAQtBACEQIABBADYCHCAAIAE2AhQgAEH9koCAADYCECAAQQc2AgwMqAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMpwELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMpgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEYLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMpQELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0gA2AhwgACAUNgIUIAAgATYCDEEAIRAMpAELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0wA2AhwgACAUNgIUIAAgATYCDEEAIRAMowELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDEMLIABB5QA2AhwgACAU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YWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8=' + + +/***/ }), + +/***/ 5627: +/***/ ((module) => { + +module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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IAH9CwMAIABBMGogAf0LAwAgAEEgaiAB/QsDACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC+TzAQMOfwN+BH8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIhBBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4BS80BTMwBTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAOxwEAAQID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YWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsb3NlZWVwLWFsaXZlAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgAAAAAAAAAAAAAAAAAAAHJhbnNmZXItZW5jb2RpbmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==' + + +/***/ }), + +/***/ 1891: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.enumToMap = void 0; +function enumToMap(obj) { + const res = {}; + Object.keys(obj).forEach((key) => { + const value = obj[key]; + if (typeof value === 'number') { + res[key] = value; + } + }); + return res; +} +exports.enumToMap = enumToMap; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 6771: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { kClients } = __nccwpck_require__(2785) +const Agent = __nccwpck_require__(7890) +const { + kAgent, + kMockAgentSet, + kMockAgentGet, + kDispatches, + kIsMockActive, + kNetConnect, + kGetNetConnect, + kOptions, + kFactory +} = __nccwpck_require__(4347) +const MockClient = __nccwpck_require__(8687) +const MockPool = __nccwpck_require__(6193) +const { matchValue, buildMockOptions } = __nccwpck_require__(9323) +const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8045) +const Dispatcher = __nccwpck_require__(412) +const Pluralizer = __nccwpck_require__(8891) +const PendingInterceptorsFormatter = __nccwpck_require__(6823) + +class FakeWeakRef { + constructor (value) { + this.value = value + } + + deref () { + return this.value + } +} + +class MockAgent extends Dispatcher { + constructor (opts) { + super(opts) + + this[kNetConnect] = true + this[kIsMockActive] = true + + // Instantiate Agent and encapsulate + if ((opts && opts.agent && typeof opts.agent.dispatch !== 'function')) { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } + const agent = opts && opts.agent ? opts.agent : new Agent(opts) + this[kAgent] = agent + + this[kClients] = agent[kClients] + this[kOptions] = buildMockOptions(opts) + } + + get (origin) { + let dispatcher = this[kMockAgentGet](origin) + + if (!dispatcher) { + dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + } + return dispatcher + } + + dispatch (opts, handler) { + // Call MockAgent.get to perform additional setup before dispatching as normal + this.get(opts.origin) + return this[kAgent].dispatch(opts, handler) + } + + async close () { + await this[kAgent].close() + this[kClients].clear() + } + + deactivate () { + this[kIsMockActive] = false + } + + activate () { + this[kIsMockActive] = true + } + + enableNetConnect (matcher) { + if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { + if (Array.isArray(this[kNetConnect])) { + this[kNetConnect].push(matcher) + } else { + this[kNetConnect] = [matcher] + } + } else if (typeof matcher === 'undefined') { + this[kNetConnect] = true + } else { + throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') + } + } + + disableNetConnect () { + this[kNetConnect] = false + } + + // This is required to bypass issues caused by using global symbols - see: + // https://github.com/nodejs/undici/issues/1447 + get isMockActive () { + return this[kIsMockActive] + } + + [kMockAgentSet] (origin, dispatcher) { + this[kClients].set(origin, new FakeWeakRef(dispatcher)) + } + + [kFactory] (origin) { + const mockOptions = Object.assign({ agent: this }, this[kOptions]) + return this[kOptions] && this[kOptions].connections === 1 + ? new MockClient(origin, mockOptions) + : new MockPool(origin, mockOptions) + } + + [kMockAgentGet] (origin) { + // First check if we can immediately find it + const ref = this[kClients].get(origin) + if (ref) { + return ref.deref() + } + + // If the origin is not a string create a dummy parent pool and return to user + if (typeof origin !== 'string') { + const dispatcher = this[kFactory]('http://localhost:9999') + this[kMockAgentSet](origin, dispatcher) + return dispatcher + } + + // If we match, create a pool and assign the same dispatches + for (const [keyMatcher, nonExplicitRef] of Array.from(this[kClients])) { + const nonExplicitDispatcher = nonExplicitRef.deref() + if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { + const dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches] + return dispatcher + } + } + } + + [kGetNetConnect] () { + return this[kNetConnect] + } + + pendingInterceptors () { + const mockAgentClients = this[kClients] + + return Array.from(mockAgentClients.entries()) + .flatMap(([origin, scope]) => scope.deref()[kDispatches].map(dispatch => ({ ...dispatch, origin }))) + .filter(({ pending }) => pending) + } + + assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { + const pending = this.pendingInterceptors() + + if (pending.length === 0) { + return + } + + const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length) + + throw new UndiciError(` +${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: + +${pendingInterceptorsFormatter.format(pending)} +`.trim()) + } +} + +module.exports = MockAgent + + +/***/ }), + +/***/ 8687: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { promisify } = __nccwpck_require__(3837) +const Client = __nccwpck_require__(3598) +const { buildMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected +} = __nccwpck_require__(4347) +const { MockInterceptor } = __nccwpck_require__(410) +const Symbols = __nccwpck_require__(2785) +const { InvalidArgumentError } = __nccwpck_require__(8045) + +/** + * MockClient provides an API that extends the Client to influence the mockDispatches. + */ +class MockClient extends Client { + constructor (origin, opts) { + super(origin, opts) + + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } + + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) + + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] + } + + get [Symbols.kConnected] () { + return this[kConnected] + } + + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor(opts, this[kDispatches]) + } + + async [kClose] () { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + } +} + +module.exports = MockClient + + +/***/ }), + +/***/ 888: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { UndiciError } = __nccwpck_require__(8045) + +class MockNotMatchedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, MockNotMatchedError) + this.name = 'MockNotMatchedError' + this.message = message || 'The request does not match any registered mock dispatches' + this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED' + } +} + +module.exports = { + MockNotMatchedError +} + + +/***/ }), + +/***/ 410: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { getResponseData, buildKey, addMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kDispatchKey, + kDefaultHeaders, + kDefaultTrailers, + kContentLength, + kMockDispatch +} = __nccwpck_require__(4347) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { buildURL } = __nccwpck_require__(3983) + +/** + * Defines the scope API for an interceptor reply + */ +class MockScope { + constructor (mockDispatch) { + this[kMockDispatch] = mockDispatch + } + + /** + * Delay a reply by a set amount in ms. + */ + delay (waitInMs) { + if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { + throw new InvalidArgumentError('waitInMs must be a valid integer > 0') + } + + this[kMockDispatch].delay = waitInMs + return this + } + + /** + * For a defined reply, never mark as consumed. + */ + persist () { + this[kMockDispatch].persist = true + return this + } + + /** + * Allow one to define a reply for a set amount of matching requests. + */ + times (repeatTimes) { + if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { + throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') + } + + this[kMockDispatch].times = repeatTimes + return this + } +} + +/** + * Defines an interceptor for a Mock + */ +class MockInterceptor { + constructor (opts, mockDispatches) { + if (typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object') + } + if (typeof opts.path === 'undefined') { + throw new InvalidArgumentError('opts.path must be defined') + } + if (typeof opts.method === 'undefined') { + opts.method = 'GET' + } + // See https://github.com/nodejs/undici/issues/1245 + // As per RFC 3986, clients are not supposed to send URI + // fragments to servers when they retrieve a document, + if (typeof opts.path === 'string') { + if (opts.query) { + opts.path = buildURL(opts.path, opts.query) + } else { + // Matches https://github.com/nodejs/undici/blob/main/lib/fetch/index.js#L1811 + const parsedURL = new URL(opts.path, 'data://') + opts.path = parsedURL.pathname + parsedURL.search + } + } + if (typeof opts.method === 'string') { + opts.method = opts.method.toUpperCase() + } + + this[kDispatchKey] = buildKey(opts) + this[kDispatches] = mockDispatches + this[kDefaultHeaders] = {} + this[kDefaultTrailers] = {} + this[kContentLength] = false + } + + createMockScopeDispatchData (statusCode, data, responseOptions = {}) { + const responseData = getResponseData(data) + const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {} + const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers } + const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers } + + return { statusCode, data, headers, trailers } + } + + validateReplyParameters (statusCode, data, responseOptions) { + if (typeof statusCode === 'undefined') { + throw new InvalidArgumentError('statusCode must be defined') + } + if (typeof data === 'undefined') { + throw new InvalidArgumentError('data must be defined') + } + if (typeof responseOptions !== 'object') { + throw new InvalidArgumentError('responseOptions must be an object') + } + } + + /** + * Mock an undici request with a defined reply. + */ + reply (replyData) { + // Values of reply aren't available right now as they + // can only be available when the reply callback is invoked. + if (typeof replyData === 'function') { + // We'll first wrap the provided callback in another function, + // this function will properly resolve the data from the callback + // when invoked. + const wrappedDefaultsCallback = (opts) => { + // Our reply options callback contains the parameter for statusCode, data and options. + const resolvedData = replyData(opts) + + // Check if it is in the right format + if (typeof resolvedData !== 'object') { + throw new InvalidArgumentError('reply options callback must return an object') + } + + const { statusCode, data = '', responseOptions = {} } = resolvedData + this.validateReplyParameters(statusCode, data, responseOptions) + // Since the values can be obtained immediately we return them + // from this higher order function that will be resolved later. + return { + ...this.createMockScopeDispatchData(statusCode, data, responseOptions) + } + } + + // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback) + return new MockScope(newMockDispatch) + } + + // We can have either one or three parameters, if we get here, + // we should have 1-3 parameters. So we spread the arguments of + // this function to obtain the parameters, since replyData will always + // just be the statusCode. + const [statusCode, data = '', responseOptions = {}] = [...arguments] + this.validateReplyParameters(statusCode, data, responseOptions) + + // Send in-already provided data like usual + const dispatchData = this.createMockScopeDispatchData(statusCode, data, responseOptions) + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData) + return new MockScope(newMockDispatch) + } + + /** + * Mock an undici request with a defined error. + */ + replyWithError (error) { + if (typeof error === 'undefined') { + throw new InvalidArgumentError('error must be defined') + } + + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }) + return new MockScope(newMockDispatch) + } + + /** + * Set default reply headers on the interceptor for subsequent replies + */ + defaultReplyHeaders (headers) { + if (typeof headers === 'undefined') { + throw new InvalidArgumentError('headers must be defined') + } + + this[kDefaultHeaders] = headers + return this + } + + /** + * Set default reply trailers on the interceptor for subsequent replies + */ + defaultReplyTrailers (trailers) { + if (typeof trailers === 'undefined') { + throw new InvalidArgumentError('trailers must be defined') + } + + this[kDefaultTrailers] = trailers + return this + } + + /** + * Set reply content length header for replies on the interceptor + */ + replyContentLength () { + this[kContentLength] = true + return this + } +} + +module.exports.MockInterceptor = MockInterceptor +module.exports.MockScope = MockScope + + +/***/ }), + +/***/ 6193: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { promisify } = __nccwpck_require__(3837) +const Pool = __nccwpck_require__(4634) +const { buildMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected +} = __nccwpck_require__(4347) +const { MockInterceptor } = __nccwpck_require__(410) +const Symbols = __nccwpck_require__(2785) +const { InvalidArgumentError } = __nccwpck_require__(8045) + +/** + * MockPool provides an API that extends the Pool to influence the mockDispatches. + */ +class MockPool extends Pool { + constructor (origin, opts) { + super(origin, opts) + + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } + + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) + + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] + } + + get [Symbols.kConnected] () { + return this[kConnected] + } + + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor(opts, this[kDispatches]) + } + + async [kClose] () { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + } +} + +module.exports = MockPool + + +/***/ }), + +/***/ 4347: +/***/ ((module) => { + +"use strict"; + + +module.exports = { + kAgent: Symbol('agent'), + kOptions: Symbol('options'), + kFactory: Symbol('factory'), + kDispatches: Symbol('dispatches'), + kDispatchKey: Symbol('dispatch key'), + kDefaultHeaders: Symbol('default headers'), + kDefaultTrailers: Symbol('default trailers'), + kContentLength: Symbol('content length'), + kMockAgent: Symbol('mock agent'), + kMockAgentSet: Symbol('mock agent set'), + kMockAgentGet: Symbol('mock agent get'), + kMockDispatch: Symbol('mock dispatch'), + kClose: Symbol('close'), + kOriginalClose: Symbol('original agent close'), + kOrigin: Symbol('origin'), + kIsMockActive: Symbol('is mock active'), + kNetConnect: Symbol('net connect'), + kGetNetConnect: Symbol('get net connect'), + kConnected: Symbol('connected') +} + + +/***/ }), + +/***/ 9323: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { MockNotMatchedError } = __nccwpck_require__(888) +const { + kDispatches, + kMockAgent, + kOriginalDispatch, + kOrigin, + kGetNetConnect +} = __nccwpck_require__(4347) +const { buildURL, nop } = __nccwpck_require__(3983) +const { STATUS_CODES } = __nccwpck_require__(3685) +const { + types: { + isPromise + } +} = __nccwpck_require__(3837) + +function matchValue (match, value) { + if (typeof match === 'string') { + return match === value + } + if (match instanceof RegExp) { + return match.test(value) + } + if (typeof match === 'function') { + return match(value) === true + } + return false +} + +function lowerCaseEntries (headers) { + return Object.fromEntries( + Object.entries(headers).map(([headerName, headerValue]) => { + return [headerName.toLocaleLowerCase(), headerValue] + }) + ) +} + +/** + * @param {import('../../index').Headers|string[]|Record} headers + * @param {string} key + */ +function getHeaderByName (headers, key) { + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { + return headers[i + 1] + } + } + + return undefined + } else if (typeof headers.get === 'function') { + return headers.get(key) + } else { + return lowerCaseEntries(headers)[key.toLocaleLowerCase()] + } +} + +/** @param {string[]} headers */ +function buildHeadersFromArray (headers) { // fetch HeadersList + const clone = headers.slice() + const entries = [] + for (let index = 0; index < clone.length; index += 2) { + entries.push([clone[index], clone[index + 1]]) + } + return Object.fromEntries(entries) +} + +function matchHeaders (mockDispatch, headers) { + if (typeof mockDispatch.headers === 'function') { + if (Array.isArray(headers)) { // fetch HeadersList + headers = buildHeadersFromArray(headers) + } + return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) + } + if (typeof mockDispatch.headers === 'undefined') { + return true + } + if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { + return false + } + + for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { + const headerValue = getHeaderByName(headers, matchHeaderName) + + if (!matchValue(matchHeaderValue, headerValue)) { + return false + } + } + return true +} + +function safeUrl (path) { + if (typeof path !== 'string') { + return path + } + + const pathSegments = path.split('?') + + if (pathSegments.length !== 2) { + return path + } + + const qp = new URLSearchParams(pathSegments.pop()) + qp.sort() + return [...pathSegments, qp.toString()].join('?') +} + +function matchKey (mockDispatch, { path, method, body, headers }) { + const pathMatch = matchValue(mockDispatch.path, path) + const methodMatch = matchValue(mockDispatch.method, method) + const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true + const headersMatch = matchHeaders(mockDispatch, headers) + return pathMatch && methodMatch && bodyMatch && headersMatch +} + +function getResponseData (data) { + if (Buffer.isBuffer(data)) { + return data + } else if (typeof data === 'object') { + return JSON.stringify(data) + } else { + return data.toString() + } +} + +function getMockDispatch (mockDispatches, key) { + const basePath = key.query ? buildURL(key.path, key.query) : key.path + const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath + + // Match path + let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) + } + + // Match method + matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}'`) + } + + // Match body + matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}'`) + } + + // Match headers + matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for headers '${typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers}'`) + } + + return matchedMockDispatches[0] +} + +function addMockDispatch (mockDispatches, key, data) { + const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false } + const replyData = typeof data === 'function' ? { callback: data } : { ...data } + const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } } + mockDispatches.push(newMockDispatch) + return newMockDispatch +} + +function deleteMockDispatch (mockDispatches, key) { + const index = mockDispatches.findIndex(dispatch => { + if (!dispatch.consumed) { + return false + } + return matchKey(dispatch, key) + }) + if (index !== -1) { + mockDispatches.splice(index, 1) + } +} + +function buildKey (opts) { + const { path, method, body, headers, query } = opts + return { + path, + method, + body, + headers, + query + } +} + +function generateKeyValues (data) { + return Object.entries(data).reduce((keyValuePairs, [key, value]) => [ + ...keyValuePairs, + Buffer.from(`${key}`), + Array.isArray(value) ? value.map(x => Buffer.from(`${x}`)) : Buffer.from(`${value}`) + ], []) +} + +/** + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + * @param {number} statusCode + */ +function getStatusText (statusCode) { + return STATUS_CODES[statusCode] || 'unknown' +} + +async function getResponse (body) { + const buffers = [] + for await (const data of body) { + buffers.push(data) + } + return Buffer.concat(buffers).toString('utf8') +} + +/** + * Mock dispatch function used to simulate undici dispatches + */ +function mockDispatch (opts, handler) { + // Get mock dispatch from built key + const key = buildKey(opts) + const mockDispatch = getMockDispatch(this[kDispatches], key) + + mockDispatch.timesInvoked++ + + // Here's where we resolve a callback if a callback is present for the dispatch data. + if (mockDispatch.data.callback) { + mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) } + } + + // Parse mockDispatch data + const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch + const { timesInvoked, times } = mockDispatch + + // If it's used up and not persistent, mark as consumed + mockDispatch.consumed = !persist && timesInvoked >= times + mockDispatch.pending = timesInvoked < times + + // If specified, trigger dispatch error + if (error !== null) { + deleteMockDispatch(this[kDispatches], key) + handler.onError(error) + return true + } + + // Handle the request with a delay if necessary + if (typeof delay === 'number' && delay > 0) { + setTimeout(() => { + handleReply(this[kDispatches]) + }, delay) + } else { + handleReply(this[kDispatches]) + } + + function handleReply (mockDispatches, _data = data) { + // fetch's HeadersList is a 1D string array + const optsHeaders = Array.isArray(opts.headers) + ? buildHeadersFromArray(opts.headers) + : opts.headers + const body = typeof _data === 'function' + ? _data({ ...opts, headers: optsHeaders }) + : _data + + // util.types.isPromise is likely needed for jest. + if (isPromise(body)) { + // If handleReply is asynchronous, throwing an error + // in the callback will reject the promise, rather than + // synchronously throw the error, which breaks some tests. + // Rather, we wait for the callback to resolve if it is a + // promise, and then re-run handleReply with the new body. + body.then((newData) => handleReply(mockDispatches, newData)) + return + } + + const responseData = getResponseData(body) + const responseHeaders = generateKeyValues(headers) + const responseTrailers = generateKeyValues(trailers) + + handler.abort = nop + handler.onHeaders(statusCode, responseHeaders, resume, getStatusText(statusCode)) + handler.onData(Buffer.from(responseData)) + handler.onComplete(responseTrailers) + deleteMockDispatch(mockDispatches, key) + } + + function resume () {} + + return true +} + +function buildMockDispatch () { + const agent = this[kMockAgent] + const origin = this[kOrigin] + const originalDispatch = this[kOriginalDispatch] + + return function dispatch (opts, handler) { + if (agent.isMockActive) { + try { + mockDispatch.call(this, opts, handler) + } catch (error) { + if (error instanceof MockNotMatchedError) { + const netConnect = agent[kGetNetConnect]() + if (netConnect === false) { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`) + } + if (checkNetConnect(netConnect, origin)) { + originalDispatch.call(this, opts, handler) + } else { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`) + } + } else { + throw error + } + } + } else { + originalDispatch.call(this, opts, handler) + } + } +} + +function checkNetConnect (netConnect, origin) { + const url = new URL(origin) + if (netConnect === true) { + return true + } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { + return true + } + return false +} + +function buildMockOptions (opts) { + if (opts) { + const { agent, ...mockOptions } = opts + return mockOptions + } +} + +module.exports = { + getResponseData, + getMockDispatch, + addMockDispatch, + deleteMockDispatch, + buildKey, + generateKeyValues, + matchValue, + getResponse, + getStatusText, + mockDispatch, + buildMockDispatch, + checkNetConnect, + buildMockOptions, + getHeaderByName +} + + +/***/ }), + +/***/ 6823: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { Transform } = __nccwpck_require__(2781) +const { Console } = __nccwpck_require__(6206) + +/** + * Gets the output of `console.table(…)` as a string. + */ +module.exports = class PendingInterceptorsFormatter { + constructor ({ disableColors } = {}) { + this.transform = new Transform({ + transform (chunk, _enc, cb) { + cb(null, chunk) + } + }) + + this.logger = new Console({ + stdout: this.transform, + inspectOptions: { + colors: !disableColors && !process.env.CI + } + }) + } + + format (pendingInterceptors) { + const withPrettyHeaders = pendingInterceptors.map( + ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ + Method: method, + Origin: origin, + Path: path, + 'Status code': statusCode, + Persistent: persist ? '✅' : '❌', + Invocations: timesInvoked, + Remaining: persist ? Infinity : times - timesInvoked + })) + + this.logger.table(withPrettyHeaders) + return this.transform.read().toString() + } +} + + +/***/ }), + +/***/ 8891: +/***/ ((module) => { + +"use strict"; + + +const singulars = { + pronoun: 'it', + is: 'is', + was: 'was', + this: 'this' +} + +const plurals = { + pronoun: 'they', + is: 'are', + was: 'were', + this: 'these' +} + +module.exports = class Pluralizer { + constructor (singular, plural) { + this.singular = singular + this.plural = plural + } + + pluralize (count) { + const one = count === 1 + const keys = one ? singulars : plurals + const noun = one ? this.singular : this.plural + return { ...keys, count, noun } + } +} + + +/***/ }), + +/***/ 8266: +/***/ ((module) => { + +"use strict"; +/* eslint-disable */ + + + +// Extracted from node/lib/internal/fixed_queue.js + +// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. +const kSize = 2048; +const kMask = kSize - 1; + +// The FixedQueue is implemented as a singly-linked list of fixed-size +// circular buffers. It looks something like this: +// +// head tail +// | | +// v v +// +-----------+ <-----\ +-----------+ <------\ +-----------+ +// | [null] | \----- | next | \------- | next | +// +-----------+ +-----------+ +-----------+ +// | item | <-- bottom | item | <-- bottom | [empty] | +// | item | | item | | [empty] | +// | item | | item | | [empty] | +// | item | | item | | [empty] | +// | item | | item | bottom --> | item | +// | item | | item | | item | +// | ... | | ... | | ... | +// | item | | item | | item | +// | item | | item | | item | +// | [empty] | <-- top | item | | item | +// | [empty] | | item | | item | +// | [empty] | | [empty] | <-- top top --> | [empty] | +// +-----------+ +-----------+ +-----------+ +// +// Or, if there is only one circular buffer, it looks something +// like either of these: +// +// head tail head tail +// | | | | +// v v v v +// +-----------+ +-----------+ +// | [null] | | [null] | +// +-----------+ +-----------+ +// | [empty] | | item | +// | [empty] | | item | +// | item | <-- bottom top --> | [empty] | +// | item | | [empty] | +// | [empty] | <-- top bottom --> | item | +// | [empty] | | item | +// +-----------+ +-----------+ +// +// Adding a value means moving `top` forward by one, removing means +// moving `bottom` forward by one. After reaching the end, the queue +// wraps around. +// +// When `top === bottom` the current queue is empty and when +// `top + 1 === bottom` it's full. This wastes a single space of storage +// but allows much quicker checks. + +class FixedCircularBuffer { + constructor() { + this.bottom = 0; + this.top = 0; + this.list = new Array(kSize); + this.next = null; + } + + isEmpty() { + return this.top === this.bottom; + } + + isFull() { + return ((this.top + 1) & kMask) === this.bottom; + } + + push(data) { + this.list[this.top] = data; + this.top = (this.top + 1) & kMask; + } + + shift() { + const nextItem = this.list[this.bottom]; + if (nextItem === undefined) + return null; + this.list[this.bottom] = undefined; + this.bottom = (this.bottom + 1) & kMask; + return nextItem; + } +} + +module.exports = class FixedQueue { + constructor() { + this.head = this.tail = new FixedCircularBuffer(); + } + + isEmpty() { + return this.head.isEmpty(); + } + + push(data) { + if (this.head.isFull()) { + // Head is full: Creates a new queue, sets the old queue's `.next` to it, + // and sets it as the new main queue. + this.head = this.head.next = new FixedCircularBuffer(); + } + this.head.push(data); + } + + shift() { + const tail = this.tail; + const next = tail.shift(); + if (tail.isEmpty() && tail.next !== null) { + // If there is another queue, it forms the new tail. + this.tail = tail.next; + } + return next; + } +}; + + +/***/ }), + +/***/ 3198: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const DispatcherBase = __nccwpck_require__(4839) +const FixedQueue = __nccwpck_require__(8266) +const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = __nccwpck_require__(2785) +const PoolStats = __nccwpck_require__(9689) + +const kClients = Symbol('clients') +const kNeedDrain = Symbol('needDrain') +const kQueue = Symbol('queue') +const kClosedResolve = Symbol('closed resolve') +const kOnDrain = Symbol('onDrain') +const kOnConnect = Symbol('onConnect') +const kOnDisconnect = Symbol('onDisconnect') +const kOnConnectionError = Symbol('onConnectionError') +const kGetDispatcher = Symbol('get dispatcher') +const kAddClient = Symbol('add client') +const kRemoveClient = Symbol('remove client') +const kStats = Symbol('stats') + +class PoolBase extends DispatcherBase { + constructor () { + super() + + this[kQueue] = new FixedQueue() + this[kClients] = [] + this[kQueued] = 0 + + const pool = this + + this[kOnDrain] = function onDrain (origin, targets) { + const queue = pool[kQueue] + + let needDrain = false + + while (!needDrain) { + const item = queue.shift() + if (!item) { + break + } + pool[kQueued]-- + needDrain = !this.dispatch(item.opts, item.handler) + } + + this[kNeedDrain] = needDrain + + if (!this[kNeedDrain] && pool[kNeedDrain]) { + pool[kNeedDrain] = false + pool.emit('drain', origin, [pool, ...targets]) + } + + if (pool[kClosedResolve] && queue.isEmpty()) { + Promise + .all(pool[kClients].map(c => c.close())) + .then(pool[kClosedResolve]) + } + } + + this[kOnConnect] = (origin, targets) => { + pool.emit('connect', origin, [pool, ...targets]) + } + + this[kOnDisconnect] = (origin, targets, err) => { + pool.emit('disconnect', origin, [pool, ...targets], err) + } + + this[kOnConnectionError] = (origin, targets, err) => { + pool.emit('connectionError', origin, [pool, ...targets], err) + } + + this[kStats] = new PoolStats(this) + } + + get [kBusy] () { + return this[kNeedDrain] + } + + get [kConnected] () { + return this[kClients].filter(client => client[kConnected]).length + } + + get [kFree] () { + return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length + } + + get [kPending] () { + let ret = this[kQueued] + for (const { [kPending]: pending } of this[kClients]) { + ret += pending + } + return ret + } + + get [kRunning] () { + let ret = 0 + for (const { [kRunning]: running } of this[kClients]) { + ret += running + } + return ret + } + + get [kSize] () { + let ret = this[kQueued] + for (const { [kSize]: size } of this[kClients]) { + ret += size + } + return ret + } + + get stats () { + return this[kStats] + } + + async [kClose] () { + if (this[kQueue].isEmpty()) { + return Promise.all(this[kClients].map(c => c.close())) + } else { + return new Promise((resolve) => { + this[kClosedResolve] = resolve + }) + } + } + + async [kDestroy] (err) { + while (true) { + const item = this[kQueue].shift() + if (!item) { + break + } + item.handler.onError(err) + } + + return Promise.all(this[kClients].map(c => c.destroy(err))) + } + + [kDispatch] (opts, handler) { + const dispatcher = this[kGetDispatcher]() + + if (!dispatcher) { + this[kNeedDrain] = true + this[kQueue].push({ opts, handler }) + this[kQueued]++ + } else if (!dispatcher.dispatch(opts, handler)) { + dispatcher[kNeedDrain] = true + this[kNeedDrain] = !this[kGetDispatcher]() + } + + return !this[kNeedDrain] + } + + [kAddClient] (client) { + client + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) + + this[kClients].push(client) + + if (this[kNeedDrain]) { + process.nextTick(() => { + if (this[kNeedDrain]) { + this[kOnDrain](client[kUrl], [this, client]) + } + }) + } + + return this + } + + [kRemoveClient] (client) { + client.close(() => { + const idx = this[kClients].indexOf(client) + if (idx !== -1) { + this[kClients].splice(idx, 1) + } + }) + + this[kNeedDrain] = this[kClients].some(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )) + } +} + +module.exports = { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher +} + + +/***/ }), + +/***/ 9689: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = __nccwpck_require__(2785) +const kPool = Symbol('pool') + +class PoolStats { + constructor (pool) { + this[kPool] = pool + } + + get connected () { + return this[kPool][kConnected] + } + + get free () { + return this[kPool][kFree] + } + + get pending () { + return this[kPool][kPending] + } + + get queued () { + return this[kPool][kQueued] + } + + get running () { + return this[kPool][kRunning] + } + + get size () { + return this[kPool][kSize] + } +} + +module.exports = PoolStats + + +/***/ }), + +/***/ 4634: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kGetDispatcher +} = __nccwpck_require__(3198) +const Client = __nccwpck_require__(3598) +const { + InvalidArgumentError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { kUrl, kInterceptors } = __nccwpck_require__(2785) +const buildConnector = __nccwpck_require__(2067) + +const kOptions = Symbol('options') +const kConnections = Symbol('connections') +const kFactory = Symbol('factory') + +function defaultFactory (origin, opts) { + return new Client(origin, opts) +} + +class Pool extends PoolBase { + constructor (origin, { + connections, + factory = defaultFactory, + connect, + connectTimeout, + tls, + maxCachedSessions, + socketPath, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + allowH2, + ...options + } = {}) { + super() + + if (connections != null && (!Number.isFinite(connections) || connections < 0)) { + throw new InvalidArgumentError('invalid connections') + } + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } + + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) + } + + this[kInterceptors] = options.interceptors && options.interceptors.Pool && Array.isArray(options.interceptors.Pool) + ? options.interceptors.Pool + : [] + this[kConnections] = connections || null + this[kUrl] = util.parseOrigin(origin) + this[kOptions] = { ...util.deepClone(options), connect, allowH2 } + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined + this[kFactory] = factory + } + + [kGetDispatcher] () { + let dispatcher = this[kClients].find(dispatcher => !dispatcher[kNeedDrain]) + + if (dispatcher) { + return dispatcher + } + + if (!this[kConnections] || this[kClients].length < this[kConnections]) { + dispatcher = this[kFactory](this[kUrl], this[kOptions]) + this[kAddClient](dispatcher) + } + + return dispatcher + } +} + +module.exports = Pool + + +/***/ }), + +/***/ 7858: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { kProxy, kClose, kDestroy, kInterceptors } = __nccwpck_require__(2785) +const { URL } = __nccwpck_require__(7310) +const Agent = __nccwpck_require__(7890) +const Pool = __nccwpck_require__(4634) +const DispatcherBase = __nccwpck_require__(4839) +const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8045) +const buildConnector = __nccwpck_require__(2067) + +const kAgent = Symbol('proxy agent') +const kClient = Symbol('proxy client') +const kProxyHeaders = Symbol('proxy headers') +const kRequestTls = Symbol('request tls settings') +const kProxyTls = Symbol('proxy tls settings') +const kConnectEndpoint = Symbol('connect endpoint function') + +function defaultProtocolPort (protocol) { + return protocol === 'https:' ? 443 : 80 +} + +function buildProxyOptions (opts) { + if (typeof opts === 'string') { + opts = { uri: opts } + } + + if (!opts || !opts.uri) { + throw new InvalidArgumentError('Proxy opts.uri is mandatory') + } + + return { + uri: opts.uri, + protocol: opts.protocol || 'https' + } +} + +function defaultFactory (origin, opts) { + return new Pool(origin, opts) +} + +class ProxyAgent extends DispatcherBase { + constructor (opts) { + super(opts) + this[kProxy] = buildProxyOptions(opts) + this[kAgent] = new Agent(opts) + this[kInterceptors] = opts.interceptors && opts.interceptors.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) + ? opts.interceptors.ProxyAgent + : [] + + if (typeof opts === 'string') { + opts = { uri: opts } + } + + if (!opts || !opts.uri) { + throw new InvalidArgumentError('Proxy opts.uri is mandatory') + } + + const { clientFactory = defaultFactory } = opts + + if (typeof clientFactory !== 'function') { + throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') + } + + this[kRequestTls] = opts.requestTls + this[kProxyTls] = opts.proxyTls + this[kProxyHeaders] = opts.headers || {} + + const resolvedUrl = new URL(opts.uri) + const { origin, port, host, username, password } = resolvedUrl + + if (opts.auth && opts.token) { + throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') + } else if (opts.auth) { + /* @deprecated in favour of opts.token */ + this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}` + } else if (opts.token) { + this[kProxyHeaders]['proxy-authorization'] = opts.token + } else if (username && password) { + this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}` + } + + const connect = buildConnector({ ...opts.proxyTls }) + this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }) + this[kClient] = clientFactory(resolvedUrl, { connect }) + this[kAgent] = new Agent({ + ...opts, + connect: async (opts, callback) => { + let requestedHost = opts.host + if (!opts.port) { + requestedHost += `:${defaultProtocolPort(opts.protocol)}` + } + try { + const { socket, statusCode } = await this[kClient].connect({ + origin, + port, + path: requestedHost, + signal: opts.signal, + headers: { + ...this[kProxyHeaders], + host + } + }) + if (statusCode !== 200) { + socket.on('error', () => {}).destroy() + callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)) + } + if (opts.protocol !== 'https:') { + callback(null, socket) + return + } + let servername + if (this[kRequestTls]) { + servername = this[kRequestTls].servername + } else { + servername = opts.servername + } + this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback) + } catch (err) { + callback(err) + } + } + }) + } + + dispatch (opts, handler) { + const { host } = new URL(opts.origin) + const headers = buildHeaders(opts.headers) + throwIfProxyAuthIsSent(headers) + return this[kAgent].dispatch( + { + ...opts, + headers: { + ...headers, + host + } + }, + handler + ) + } + + async [kClose] () { + await this[kAgent].close() + await this[kClient].close() + } + + async [kDestroy] () { + await this[kAgent].destroy() + await this[kClient].destroy() + } +} + +/** + * @param {string[] | Record} headers + * @returns {Record} + */ +function buildHeaders (headers) { + // When using undici.fetch, the headers list is stored + // as an array. + if (Array.isArray(headers)) { + /** @type {Record} */ + const headersPair = {} + + for (let i = 0; i < headers.length; i += 2) { + headersPair[headers[i]] = headers[i + 1] + } + + return headersPair + } + + return headers +} + +/** + * @param {Record} headers + * + * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers + * Nevertheless, it was changed and to avoid a security vulnerability by end users + * this check was created. + * It should be removed in the next major version for performance reasons + */ +function throwIfProxyAuthIsSent (headers) { + const existProxyAuth = headers && Object.keys(headers) + .find((key) => key.toLowerCase() === 'proxy-authorization') + if (existProxyAuth) { + throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') + } +} + +module.exports = ProxyAgent + + +/***/ }), + +/***/ 9459: +/***/ ((module) => { + +"use strict"; + + +let fastNow = Date.now() +let fastNowTimeout + +const fastTimers = [] + +function onTimeout () { + fastNow = Date.now() + + let len = fastTimers.length + let idx = 0 + while (idx < len) { + const timer = fastTimers[idx] + + if (timer.state === 0) { + timer.state = fastNow + timer.delay + } else if (timer.state > 0 && fastNow >= timer.state) { + timer.state = -1 + timer.callback(timer.opaque) + } + + if (timer.state === -1) { + timer.state = -2 + if (idx !== len - 1) { + fastTimers[idx] = fastTimers.pop() + } else { + fastTimers.pop() + } + len -= 1 + } else { + idx += 1 + } + } + + if (fastTimers.length > 0) { + refreshTimeout() + } +} + +function refreshTimeout () { + if (fastNowTimeout && fastNowTimeout.refresh) { + fastNowTimeout.refresh() + } else { + clearTimeout(fastNowTimeout) + fastNowTimeout = setTimeout(onTimeout, 1e3) + if (fastNowTimeout.unref) { + fastNowTimeout.unref() + } + } +} + +class Timeout { + constructor (callback, delay, opaque) { + this.callback = callback + this.delay = delay + this.opaque = opaque + + // -2 not in timer list + // -1 in timer list but inactive + // 0 in timer list waiting for time + // > 0 in timer list waiting for time to expire + this.state = -2 + + this.refresh() + } + + refresh () { + if (this.state === -2) { + fastTimers.push(this) + if (!fastNowTimeout || fastTimers.length === 1) { + refreshTimeout() + } + } + + this.state = 0 + } + + clear () { + this.state = -1 + } +} + +module.exports = { + setTimeout (callback, delay, opaque) { + return delay < 1e3 + ? setTimeout(callback, delay, opaque) + : new Timeout(callback, delay, opaque) + }, + clearTimeout (timeout) { + if (timeout instanceof Timeout) { + timeout.clear() + } else { + clearTimeout(timeout) + } + } +} + + +/***/ }), + +/***/ 5354: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const diagnosticsChannel = __nccwpck_require__(7643) +const { uid, states } = __nccwpck_require__(9188) +const { + kReadyState, + kSentClose, + kByteParser, + kReceivedClose +} = __nccwpck_require__(7578) +const { fireEvent, failWebsocketConnection } = __nccwpck_require__(5515) +const { CloseEvent } = __nccwpck_require__(2611) +const { makeRequest } = __nccwpck_require__(8359) +const { fetching } = __nccwpck_require__(4881) +const { Headers } = __nccwpck_require__(554) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { kHeadersList } = __nccwpck_require__(2785) + +const channels = {} +channels.open = diagnosticsChannel.channel('undici:websocket:open') +channels.close = diagnosticsChannel.channel('undici:websocket:close') +channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') + +/** @type {import('crypto')} */ +let crypto +try { + crypto = __nccwpck_require__(6113) +} catch { + +} + +/** + * @see https://websockets.spec.whatwg.org/#concept-websocket-establish + * @param {URL} url + * @param {string|string[]} protocols + * @param {import('./websocket').WebSocket} ws + * @param {(response: any) => void} onEstablish + * @param {Partial} options + */ +function establishWebSocketConnection (url, protocols, ws, onEstablish, options) { + // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s + // scheme is "ws", and to "https" otherwise. + const requestURL = url + + requestURL.protocol = url.protocol === 'ws:' ? 'http:' : 'https:' + + // 2. Let request be a new request, whose URL is requestURL, client is client, + // service-workers mode is "none", referrer is "no-referrer", mode is + // "websocket", credentials mode is "include", cache mode is "no-store" , + // and redirect mode is "error". + const request = makeRequest({ + urlList: [requestURL], + serviceWorkers: 'none', + referrer: 'no-referrer', + mode: 'websocket', + credentials: 'include', + cache: 'no-store', + redirect: 'error' + }) + + // Note: undici extension, allow setting custom headers. + if (options.headers) { + const headersList = new Headers(options.headers)[kHeadersList] + + request.headersList = headersList + } + + // 3. Append (`Upgrade`, `websocket`) to request’s header list. + // 4. Append (`Connection`, `Upgrade`) to request’s header list. + // Note: both of these are handled by undici currently. + // https://github.com/nodejs/undici/blob/68c269c4144c446f3f1220951338daef4a6b5ec4/lib/client.js#L1397 + + // 5. Let keyValue be a nonce consisting of a randomly selected + // 16-byte value that has been forgiving-base64-encoded and + // isomorphic encoded. + const keyValue = crypto.randomBytes(16).toString('base64') + + // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s + // header list. + request.headersList.append('sec-websocket-key', keyValue) + + // 7. Append (`Sec-WebSocket-Version`, `13`) to request’s + // header list. + request.headersList.append('sec-websocket-version', '13') + + // 8. For each protocol in protocols, combine + // (`Sec-WebSocket-Protocol`, protocol) in request’s header + // list. + for (const protocol of protocols) { + request.headersList.append('sec-websocket-protocol', protocol) + } + + // 9. Let permessageDeflate be a user-agent defined + // "permessage-deflate" extension header value. + // https://github.com/mozilla/gecko-dev/blob/ce78234f5e653a5d3916813ff990f053510227bc/netwerk/protocol/websocket/WebSocketChannel.cpp#L2673 + // TODO: enable once permessage-deflate is supported + const permessageDeflate = '' // 'permessage-deflate; 15' + + // 10. Append (`Sec-WebSocket-Extensions`, permessageDeflate) to + // request’s header list. + // request.headersList.append('sec-websocket-extensions', permessageDeflate) + + // 11. Fetch request with useParallelQueue set to true, and + // processResponse given response being these steps: + const controller = fetching({ + request, + useParallelQueue: true, + dispatcher: options.dispatcher ?? getGlobalDispatcher(), + processResponse (response) { + // 1. If response is a network error or its status is not 101, + // fail the WebSocket connection. + if (response.type === 'error' || response.status !== 101) { + failWebsocketConnection(ws, 'Received network error or non-101 status code.') + return + } + + // 2. If protocols is not the empty list and extracting header + // list values given `Sec-WebSocket-Protocol` and response’s + // header list results in null, failure, or the empty byte + // sequence, then fail the WebSocket connection. + if (protocols.length !== 0 && !response.headersList.get('Sec-WebSocket-Protocol')) { + failWebsocketConnection(ws, 'Server did not respond with sent protocols.') + return + } + + // 3. Follow the requirements stated step 2 to step 6, inclusive, + // of the last set of steps in section 4.1 of The WebSocket + // Protocol to validate response. This either results in fail + // the WebSocket connection or the WebSocket connection is + // established. + + // 2. If the response lacks an |Upgrade| header field or the |Upgrade| + // header field contains a value that is not an ASCII case- + // insensitive match for the value "websocket", the client MUST + // _Fail the WebSocket Connection_. + if (response.headersList.get('Upgrade')?.toLowerCase() !== 'websocket') { + failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".') + return + } + + // 3. If the response lacks a |Connection| header field or the + // |Connection| header field doesn't contain a token that is an + // ASCII case-insensitive match for the value "Upgrade", the client + // MUST _Fail the WebSocket Connection_. + if (response.headersList.get('Connection')?.toLowerCase() !== 'upgrade') { + failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".') + return + } + + // 4. If the response lacks a |Sec-WebSocket-Accept| header field or + // the |Sec-WebSocket-Accept| contains a value other than the + // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- + // Key| (as a string, not base64-decoded) with the string "258EAFA5- + // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and + // trailing whitespace, the client MUST _Fail the WebSocket + // Connection_. + const secWSAccept = response.headersList.get('Sec-WebSocket-Accept') + const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64') + if (secWSAccept !== digest) { + failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.') + return + } + + // 5. If the response includes a |Sec-WebSocket-Extensions| header + // field and this header field indicates the use of an extension + // that was not present in the client's handshake (the server has + // indicated an extension not requested by the client), the client + // MUST _Fail the WebSocket Connection_. (The parsing of this + // header field to determine which extensions are requested is + // discussed in Section 9.1.) + const secExtension = response.headersList.get('Sec-WebSocket-Extensions') + + if (secExtension !== null && secExtension !== permessageDeflate) { + failWebsocketConnection(ws, 'Received different permessage-deflate than the one set.') + return + } + + // 6. If the response includes a |Sec-WebSocket-Protocol| header field + // and this header field indicates the use of a subprotocol that was + // not present in the client's handshake (the server has indicated a + // subprotocol not requested by the client), the client MUST _Fail + // the WebSocket Connection_. + const secProtocol = response.headersList.get('Sec-WebSocket-Protocol') + + if (secProtocol !== null && secProtocol !== request.headersList.get('Sec-WebSocket-Protocol')) { + failWebsocketConnection(ws, 'Protocol was not set in the opening handshake.') + return + } + + response.socket.on('data', onSocketData) + response.socket.on('close', onSocketClose) + response.socket.on('error', onSocketError) + + if (channels.open.hasSubscribers) { + channels.open.publish({ + address: response.socket.address(), + protocol: secProtocol, + extensions: secExtension + }) + } + + onEstablish(response) + } + }) + + return controller +} + +/** + * @param {Buffer} chunk + */ +function onSocketData (chunk) { + if (!this.ws[kByteParser].write(chunk)) { + this.pause() + } +} + +/** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 + */ +function onSocketClose () { + const { ws } = this + + // If the TCP connection was closed after the + // WebSocket closing handshake was completed, the WebSocket connection + // is said to have been closed _cleanly_. + const wasClean = ws[kSentClose] && ws[kReceivedClose] + + let code = 1005 + let reason = '' + + const result = ws[kByteParser].closingInfo + + if (result) { + code = result.code ?? 1005 + reason = result.reason + } else if (!ws[kSentClose]) { + // If _The WebSocket + // Connection is Closed_ and no Close control frame was received by the + // endpoint (such as could occur if the underlying transport connection + // is lost), _The WebSocket Connection Close Code_ is considered to be + // 1006. + code = 1006 + } + + // 1. Change the ready state to CLOSED (3). + ws[kReadyState] = states.CLOSED + + // 2. If the user agent was required to fail the WebSocket + // connection, or if the WebSocket connection was closed + // after being flagged as full, fire an event named error + // at the WebSocket object. + // TODO + + // 3. Fire an event named close at the WebSocket object, + // using CloseEvent, with the wasClean attribute + // initialized to true if the connection closed cleanly + // and false otherwise, the code attribute initialized to + // the WebSocket connection close code, and the reason + // attribute initialized to the result of applying UTF-8 + // decode without BOM to the WebSocket connection close + // reason. + fireEvent('close', ws, CloseEvent, { + wasClean, code, reason + }) + + if (channels.close.hasSubscribers) { + channels.close.publish({ + websocket: ws, + code, + reason + }) + } +} + +function onSocketError (error) { + const { ws } = this + + ws[kReadyState] = states.CLOSING + + if (channels.socketError.hasSubscribers) { + channels.socketError.publish(error) + } + + this.destroy() +} + +module.exports = { + establishWebSocketConnection +} + + +/***/ }), + +/***/ 9188: +/***/ ((module) => { + +"use strict"; + + +// This is a Globally Unique Identifier unique used +// to validate that the endpoint accepts websocket +// connections. +// See https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3 +const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' + +/** @type {PropertyDescriptor} */ +const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false +} + +const states = { + CONNECTING: 0, + OPEN: 1, + CLOSING: 2, + CLOSED: 3 +} + +const opcodes = { + CONTINUATION: 0x0, + TEXT: 0x1, + BINARY: 0x2, + CLOSE: 0x8, + PING: 0x9, + PONG: 0xA +} + +const maxUnsigned16Bit = 2 ** 16 - 1 // 65535 + +const parserStates = { + INFO: 0, + PAYLOADLENGTH_16: 2, + PAYLOADLENGTH_64: 3, + READ_DATA: 4 +} + +const emptyBuffer = Buffer.allocUnsafe(0) + +module.exports = { + uid, + staticPropertyDescriptors, + states, + opcodes, + maxUnsigned16Bit, + parserStates, + emptyBuffer +} + + +/***/ }), + +/***/ 2611: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const { MessagePort } = __nccwpck_require__(1267) + +/** + * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent + */ +class MessageEvent extends Event { + #eventInit + + constructor (type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent constructor' }) + + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.MessageEventInit(eventInitDict) + + super(type, eventInitDict) + + this.#eventInit = eventInitDict + } + + get data () { + webidl.brandCheck(this, MessageEvent) + + return this.#eventInit.data + } + + get origin () { + webidl.brandCheck(this, MessageEvent) + + return this.#eventInit.origin + } + + get lastEventId () { + webidl.brandCheck(this, MessageEvent) + + return this.#eventInit.lastEventId + } + + get source () { + webidl.brandCheck(this, MessageEvent) + + return this.#eventInit.source + } + + get ports () { + webidl.brandCheck(this, MessageEvent) + + if (!Object.isFrozen(this.#eventInit.ports)) { + Object.freeze(this.#eventInit.ports) + } + + return this.#eventInit.ports + } + + initMessageEvent ( + type, + bubbles = false, + cancelable = false, + data = null, + origin = '', + lastEventId = '', + source = null, + ports = [] + ) { + webidl.brandCheck(this, MessageEvent) + + webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent.initMessageEvent' }) + + return new MessageEvent(type, { + bubbles, cancelable, data, origin, lastEventId, source, ports + }) + } +} + +/** + * @see https://websockets.spec.whatwg.org/#the-closeevent-interface + */ +class CloseEvent extends Event { + #eventInit + + constructor (type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'CloseEvent constructor' }) + + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.CloseEventInit(eventInitDict) + + super(type, eventInitDict) + + this.#eventInit = eventInitDict + } + + get wasClean () { + webidl.brandCheck(this, CloseEvent) + + return this.#eventInit.wasClean + } + + get code () { + webidl.brandCheck(this, CloseEvent) + + return this.#eventInit.code + } + + get reason () { + webidl.brandCheck(this, CloseEvent) + + return this.#eventInit.reason + } +} + +// https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface +class ErrorEvent extends Event { + #eventInit + + constructor (type, eventInitDict) { + webidl.argumentLengthCheck(arguments, 1, { header: 'ErrorEvent constructor' }) + + super(type, eventInitDict) + + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}) + + this.#eventInit = eventInitDict + } + + get message () { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.message + } + + get filename () { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.filename + } + + get lineno () { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.lineno + } + + get colno () { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.colno + } + + get error () { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.error + } +} + +Object.defineProperties(MessageEvent.prototype, { + [Symbol.toStringTag]: { + value: 'MessageEvent', + configurable: true + }, + data: kEnumerableProperty, + origin: kEnumerableProperty, + lastEventId: kEnumerableProperty, + source: kEnumerableProperty, + ports: kEnumerableProperty, + initMessageEvent: kEnumerableProperty +}) + +Object.defineProperties(CloseEvent.prototype, { + [Symbol.toStringTag]: { + value: 'CloseEvent', + configurable: true + }, + reason: kEnumerableProperty, + code: kEnumerableProperty, + wasClean: kEnumerableProperty +}) + +Object.defineProperties(ErrorEvent.prototype, { + [Symbol.toStringTag]: { + value: 'ErrorEvent', + configurable: true + }, + message: kEnumerableProperty, + filename: kEnumerableProperty, + lineno: kEnumerableProperty, + colno: kEnumerableProperty, + error: kEnumerableProperty +}) + +webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort) + +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.MessagePort +) + +const eventInit = [ + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: false + } +] + +webidl.converters.MessageEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'data', + converter: webidl.converters.any, + defaultValue: null + }, + { + key: 'origin', + converter: webidl.converters.USVString, + defaultValue: '' + }, + { + key: 'lastEventId', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'source', + // Node doesn't implement WindowProxy or ServiceWorker, so the only + // valid value for source is a MessagePort. + converter: webidl.nullableConverter(webidl.converters.MessagePort), + defaultValue: null + }, + { + key: 'ports', + converter: webidl.converters['sequence'], + get defaultValue () { + return [] + } + } +]) + +webidl.converters.CloseEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'wasClean', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'code', + converter: webidl.converters['unsigned short'], + defaultValue: 0 + }, + { + key: 'reason', + converter: webidl.converters.USVString, + defaultValue: '' + } +]) + +webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'message', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'filename', + converter: webidl.converters.USVString, + defaultValue: '' + }, + { + key: 'lineno', + converter: webidl.converters['unsigned long'], + defaultValue: 0 + }, + { + key: 'colno', + converter: webidl.converters['unsigned long'], + defaultValue: 0 + }, + { + key: 'error', + converter: webidl.converters.any + } +]) + +module.exports = { + MessageEvent, + CloseEvent, + ErrorEvent +} + + +/***/ }), + +/***/ 5444: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { maxUnsigned16Bit } = __nccwpck_require__(9188) + +/** @type {import('crypto')} */ +let crypto +try { + crypto = __nccwpck_require__(6113) +} catch { + +} + +class WebsocketFrameSend { + /** + * @param {Buffer|undefined} data + */ + constructor (data) { + this.frameData = data + this.maskKey = crypto.randomBytes(4) + } + + createFrame (opcode) { + const bodyLength = this.frameData?.byteLength ?? 0 + + /** @type {number} */ + let payloadLength = bodyLength // 0-125 + let offset = 6 + + if (bodyLength > maxUnsigned16Bit) { + offset += 8 // payload length is next 8 bytes + payloadLength = 127 + } else if (bodyLength > 125) { + offset += 2 // payload length is next 2 bytes + payloadLength = 126 + } + + const buffer = Buffer.allocUnsafe(bodyLength + offset) + + // Clear first 2 bytes, everything else is overwritten + buffer[0] = buffer[1] = 0 + buffer[0] |= 0x80 // FIN + buffer[0] = (buffer[0] & 0xF0) + opcode // opcode + + /*! ws. MIT License. Einar Otto Stangvik */ + buffer[offset - 4] = this.maskKey[0] + buffer[offset - 3] = this.maskKey[1] + buffer[offset - 2] = this.maskKey[2] + buffer[offset - 1] = this.maskKey[3] + + buffer[1] = payloadLength + + if (payloadLength === 126) { + buffer.writeUInt16BE(bodyLength, 2) + } else if (payloadLength === 127) { + // Clear extended payload length + buffer[2] = buffer[3] = 0 + buffer.writeUIntBE(bodyLength, 4, 6) + } + + buffer[1] |= 0x80 // MASK + + // mask body + for (let i = 0; i < bodyLength; i++) { + buffer[offset + i] = this.frameData[i] ^ this.maskKey[i % 4] + } + + return buffer + } +} + +module.exports = { + WebsocketFrameSend +} + + +/***/ }), + +/***/ 1688: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { Writable } = __nccwpck_require__(2781) +const diagnosticsChannel = __nccwpck_require__(7643) +const { parserStates, opcodes, states, emptyBuffer } = __nccwpck_require__(9188) +const { kReadyState, kSentClose, kResponse, kReceivedClose } = __nccwpck_require__(7578) +const { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = __nccwpck_require__(5515) +const { WebsocketFrameSend } = __nccwpck_require__(5444) + +// This code was influenced by ws released under the MIT license. +// Copyright (c) 2011 Einar Otto Stangvik +// Copyright (c) 2013 Arnout Kazemier and contributors +// Copyright (c) 2016 Luigi Pinca and contributors + +const channels = {} +channels.ping = diagnosticsChannel.channel('undici:websocket:ping') +channels.pong = diagnosticsChannel.channel('undici:websocket:pong') + +class ByteParser extends Writable { + #buffers = [] + #byteOffset = 0 + + #state = parserStates.INFO + + #info = {} + #fragments = [] + + constructor (ws) { + super() + + this.ws = ws + } + + /** + * @param {Buffer} chunk + * @param {() => void} callback + */ + _write (chunk, _, callback) { + this.#buffers.push(chunk) + this.#byteOffset += chunk.length + + this.run(callback) + } + + /** + * Runs whenever a new chunk is received. + * Callback is called whenever there are no more chunks buffering, + * or not enough bytes are buffered to parse. + */ + run (callback) { + while (true) { + if (this.#state === parserStates.INFO) { + // If there aren't enough bytes to parse the payload length, etc. + if (this.#byteOffset < 2) { + return callback() + } + + const buffer = this.consume(2) + + this.#info.fin = (buffer[0] & 0x80) !== 0 + this.#info.opcode = buffer[0] & 0x0F + + // If we receive a fragmented message, we use the type of the first + // frame to parse the full message as binary/text, when it's terminated + this.#info.originalOpcode ??= this.#info.opcode + + this.#info.fragmented = !this.#info.fin && this.#info.opcode !== opcodes.CONTINUATION + + if (this.#info.fragmented && this.#info.opcode !== opcodes.BINARY && this.#info.opcode !== opcodes.TEXT) { + // Only text and binary frames can be fragmented + failWebsocketConnection(this.ws, 'Invalid frame type was fragmented.') + return + } + + const payloadLength = buffer[1] & 0x7F + + if (payloadLength <= 125) { + this.#info.payloadLength = payloadLength + this.#state = parserStates.READ_DATA + } else if (payloadLength === 126) { + this.#state = parserStates.PAYLOADLENGTH_16 + } else if (payloadLength === 127) { + this.#state = parserStates.PAYLOADLENGTH_64 + } + + if (this.#info.fragmented && payloadLength > 125) { + // A fragmented frame can't be fragmented itself + failWebsocketConnection(this.ws, 'Fragmented frame exceeded 125 bytes.') + return + } else if ( + (this.#info.opcode === opcodes.PING || + this.#info.opcode === opcodes.PONG || + this.#info.opcode === opcodes.CLOSE) && + payloadLength > 125 + ) { + // Control frames can have a payload length of 125 bytes MAX + failWebsocketConnection(this.ws, 'Payload length for control frame exceeded 125 bytes.') + return + } else if (this.#info.opcode === opcodes.CLOSE) { + if (payloadLength === 1) { + failWebsocketConnection(this.ws, 'Received close frame with a 1-byte body.') + return + } + + const body = this.consume(payloadLength) + + this.#info.closeInfo = this.parseCloseBody(false, body) + + if (!this.ws[kSentClose]) { + // If an endpoint receives a Close frame and did not previously send a + // Close frame, the endpoint MUST send a Close frame in response. (When + // sending a Close frame in response, the endpoint typically echos the + // status code it received.) + const body = Buffer.allocUnsafe(2) + body.writeUInt16BE(this.#info.closeInfo.code, 0) + const closeFrame = new WebsocketFrameSend(body) + + this.ws[kResponse].socket.write( + closeFrame.createFrame(opcodes.CLOSE), + (err) => { + if (!err) { + this.ws[kSentClose] = true + } + } + ) + } + + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this.ws[kReadyState] = states.CLOSING + this.ws[kReceivedClose] = true + + this.end() + + return + } else if (this.#info.opcode === opcodes.PING) { + // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in + // response, unless it already received a Close frame. + // A Pong frame sent in response to a Ping frame must have identical + // "Application data" + + const body = this.consume(payloadLength) + + if (!this.ws[kReceivedClose]) { + const frame = new WebsocketFrameSend(body) + + this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)) + + if (channels.ping.hasSubscribers) { + channels.ping.publish({ + payload: body + }) + } + } + + this.#state = parserStates.INFO + + if (this.#byteOffset > 0) { + continue + } else { + callback() + return + } + } else if (this.#info.opcode === opcodes.PONG) { + // A Pong frame MAY be sent unsolicited. This serves as a + // unidirectional heartbeat. A response to an unsolicited Pong frame is + // not expected. + + const body = this.consume(payloadLength) + + if (channels.pong.hasSubscribers) { + channels.pong.publish({ + payload: body + }) + } + + if (this.#byteOffset > 0) { + continue + } else { + callback() + return + } + } + } else if (this.#state === parserStates.PAYLOADLENGTH_16) { + if (this.#byteOffset < 2) { + return callback() + } + + const buffer = this.consume(2) + + this.#info.payloadLength = buffer.readUInt16BE(0) + this.#state = parserStates.READ_DATA + } else if (this.#state === parserStates.PAYLOADLENGTH_64) { + if (this.#byteOffset < 8) { + return callback() + } + + const buffer = this.consume(8) + const upper = buffer.readUInt32BE(0) + + // 2^31 is the maxinimum bytes an arraybuffer can contain + // on 32-bit systems. Although, on 64-bit systems, this is + // 2^53-1 bytes. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275 + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e + if (upper > 2 ** 31 - 1) { + failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.') + return + } + + const lower = buffer.readUInt32BE(4) + + this.#info.payloadLength = (upper << 8) + lower + this.#state = parserStates.READ_DATA + } else if (this.#state === parserStates.READ_DATA) { + if (this.#byteOffset < this.#info.payloadLength) { + // If there is still more data in this chunk that needs to be read + return callback() + } else if (this.#byteOffset >= this.#info.payloadLength) { + // If the server sent multiple frames in a single chunk + + const body = this.consume(this.#info.payloadLength) + + this.#fragments.push(body) + + // If the frame is unfragmented, or a fragmented frame was terminated, + // a message was received + if (!this.#info.fragmented || (this.#info.fin && this.#info.opcode === opcodes.CONTINUATION)) { + const fullMessage = Buffer.concat(this.#fragments) + + websocketMessageReceived(this.ws, this.#info.originalOpcode, fullMessage) + + this.#info = {} + this.#fragments.length = 0 + } + + this.#state = parserStates.INFO + } + } + + if (this.#byteOffset > 0) { + continue + } else { + callback() + break + } + } + } + + /** + * Take n bytes from the buffered Buffers + * @param {number} n + * @returns {Buffer|null} + */ + consume (n) { + if (n > this.#byteOffset) { + return null + } else if (n === 0) { + return emptyBuffer + } + + if (this.#buffers[0].length === n) { + this.#byteOffset -= this.#buffers[0].length + return this.#buffers.shift() + } + + const buffer = Buffer.allocUnsafe(n) + let offset = 0 + + while (offset !== n) { + const next = this.#buffers[0] + const { length } = next + + if (length + offset === n) { + buffer.set(this.#buffers.shift(), offset) + break + } else if (length + offset > n) { + buffer.set(next.subarray(0, n - offset), offset) + this.#buffers[0] = next.subarray(n - offset) + break + } else { + buffer.set(this.#buffers.shift(), offset) + offset += next.length + } + } + + this.#byteOffset -= n + + return buffer + } + + parseCloseBody (onlyCode, data) { + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 + /** @type {number|undefined} */ + let code + + if (data.length >= 2) { + // _The WebSocket Connection Close Code_ is + // defined as the status code (Section 7.4) contained in the first Close + // control frame received by the application + code = data.readUInt16BE(0) + } + + if (onlyCode) { + if (!isValidStatusCode(code)) { + return null + } + + return { code } + } + + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 + /** @type {Buffer} */ + let reason = data.subarray(2) + + // Remove BOM + if (reason[0] === 0xEF && reason[1] === 0xBB && reason[2] === 0xBF) { + reason = reason.subarray(3) + } + + if (code !== undefined && !isValidStatusCode(code)) { + return null + } + + try { + // TODO: optimize this + reason = new TextDecoder('utf-8', { fatal: true }).decode(reason) + } catch { + return null + } + + return { code, reason } + } + + get closingInfo () { + return this.#info.closeInfo + } +} + +module.exports = { + ByteParser +} + + +/***/ }), + +/***/ 7578: +/***/ ((module) => { + +"use strict"; + + +module.exports = { + kWebSocketURL: Symbol('url'), + kReadyState: Symbol('ready state'), + kController: Symbol('controller'), + kResponse: Symbol('response'), + kBinaryType: Symbol('binary type'), + kSentClose: Symbol('sent close'), + kReceivedClose: Symbol('received close'), + kByteParser: Symbol('byte parser') +} + + +/***/ }), + +/***/ 5515: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = __nccwpck_require__(7578) +const { states, opcodes } = __nccwpck_require__(9188) +const { MessageEvent, ErrorEvent } = __nccwpck_require__(2611) + +/* globals Blob */ + +/** + * @param {import('./websocket').WebSocket} ws + */ +function isEstablished (ws) { + // If the server's response is validated as provided for above, it is + // said that _The WebSocket Connection is Established_ and that the + // WebSocket Connection is in the OPEN state. + return ws[kReadyState] === states.OPEN +} + +/** + * @param {import('./websocket').WebSocket} ws + */ +function isClosing (ws) { + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + return ws[kReadyState] === states.CLOSING +} + +/** + * @param {import('./websocket').WebSocket} ws + */ +function isClosed (ws) { + return ws[kReadyState] === states.CLOSED +} + +/** + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e + * @param {EventTarget} target + * @param {EventInit | undefined} eventInitDict + */ +function fireEvent (e, target, eventConstructor = Event, eventInitDict) { + // 1. If eventConstructor is not given, then let eventConstructor be Event. + + // 2. Let event be the result of creating an event given eventConstructor, + // in the relevant realm of target. + // 3. Initialize event’s type attribute to e. + const event = new eventConstructor(e, eventInitDict) // eslint-disable-line new-cap + + // 4. Initialize any other IDL attributes of event as described in the + // invocation of this algorithm. + + // 5. Return the result of dispatching event at target, with legacy target + // override flag set if set. + target.dispatchEvent(event) +} + +/** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @param {import('./websocket').WebSocket} ws + * @param {number} type Opcode + * @param {Buffer} data application data + */ +function websocketMessageReceived (ws, type, data) { + // 1. If ready state is not OPEN (1), then return. + if (ws[kReadyState] !== states.OPEN) { + return + } + + // 2. Let dataForEvent be determined by switching on type and binary type: + let dataForEvent + + if (type === opcodes.TEXT) { + // -> type indicates that the data is Text + // a new DOMString containing data + try { + dataForEvent = new TextDecoder('utf-8', { fatal: true }).decode(data) + } catch { + failWebsocketConnection(ws, 'Received invalid UTF-8 in text frame.') + return + } + } else if (type === opcodes.BINARY) { + if (ws[kBinaryType] === 'blob') { + // -> type indicates that the data is Binary and binary type is "blob" + // a new Blob object, created in the relevant Realm of the WebSocket + // object, that represents data as its raw data + dataForEvent = new Blob([data]) + } else { + // -> type indicates that the data is Binary and binary type is "arraybuffer" + // a new ArrayBuffer object, created in the relevant Realm of the + // WebSocket object, whose contents are data + dataForEvent = new Uint8Array(data).buffer + } + } + + // 3. Fire an event named message at the WebSocket object, using MessageEvent, + // with the origin attribute initialized to the serialization of the WebSocket + // object’s url's origin, and the data attribute initialized to dataForEvent. + fireEvent('message', ws, MessageEvent, { + origin: ws[kWebSocketURL].origin, + data: dataForEvent + }) +} + +/** + * @see https://datatracker.ietf.org/doc/html/rfc6455 + * @see https://datatracker.ietf.org/doc/html/rfc2616 + * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 + * @param {string} protocol + */ +function isValidSubprotocol (protocol) { + // If present, this value indicates one + // or more comma-separated subprotocol the client wishes to speak, + // ordered by preference. The elements that comprise this value + // MUST be non-empty strings with characters in the range U+0021 to + // U+007E not including separator characters as defined in + // [RFC2616] and MUST all be unique strings. + if (protocol.length === 0) { + return false + } + + for (const char of protocol) { + const code = char.charCodeAt(0) + + if ( + code < 0x21 || + code > 0x7E || + char === '(' || + char === ')' || + char === '<' || + char === '>' || + char === '@' || + char === ',' || + char === ';' || + char === ':' || + char === '\\' || + char === '"' || + char === '/' || + char === '[' || + char === ']' || + char === '?' || + char === '=' || + char === '{' || + char === '}' || + code === 32 || // SP + code === 9 // HT + ) { + return false + } + } + + return true +} + +/** + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 + * @param {number} code + */ +function isValidStatusCode (code) { + if (code >= 1000 && code < 1015) { + return ( + code !== 1004 && // reserved + code !== 1005 && // "MUST NOT be set as a status code" + code !== 1006 // "MUST NOT be set as a status code" + ) + } + + return code >= 3000 && code <= 4999 +} + +/** + * @param {import('./websocket').WebSocket} ws + * @param {string|undefined} reason + */ +function failWebsocketConnection (ws, reason) { + const { [kController]: controller, [kResponse]: response } = ws + + controller.abort() + + if (response?.socket && !response.socket.destroyed) { + response.socket.destroy() + } + + if (reason) { + fireEvent('error', ws, ErrorEvent, { + error: new Error(reason) + }) + } +} + +module.exports = { + isEstablished, + isClosing, + isClosed, + fireEvent, + isValidSubprotocol, + isValidStatusCode, + failWebsocketConnection, + websocketMessageReceived +} + + +/***/ }), + +/***/ 4284: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const { webidl } = __nccwpck_require__(1744) +const { DOMException } = __nccwpck_require__(1037) +const { URLSerializer } = __nccwpck_require__(685) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = __nccwpck_require__(9188) +const { + kWebSocketURL, + kReadyState, + kController, + kBinaryType, + kResponse, + kSentClose, + kByteParser +} = __nccwpck_require__(7578) +const { isEstablished, isClosing, isValidSubprotocol, failWebsocketConnection, fireEvent } = __nccwpck_require__(5515) +const { establishWebSocketConnection } = __nccwpck_require__(5354) +const { WebsocketFrameSend } = __nccwpck_require__(5444) +const { ByteParser } = __nccwpck_require__(1688) +const { kEnumerableProperty, isBlobLike } = __nccwpck_require__(3983) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { types } = __nccwpck_require__(3837) + +let experimentalWarned = false + +// https://websockets.spec.whatwg.org/#interface-definition +class WebSocket extends EventTarget { + #events = { + open: null, + error: null, + close: null, + message: null + } + + #bufferedAmount = 0 + #protocol = '' + #extensions = '' + + /** + * @param {string} url + * @param {string|string[]} protocols + */ + constructor (url, protocols = []) { + super() + + webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket constructor' }) + + if (!experimentalWarned) { + experimentalWarned = true + process.emitWarning('WebSockets are experimental, expect them to change at any time.', { + code: 'UNDICI-WS' + }) + } + + const options = webidl.converters['DOMString or sequence or WebSocketInit'](protocols) + + url = webidl.converters.USVString(url) + protocols = options.protocols + + // 1. Let baseURL be this's relevant settings object's API base URL. + const baseURL = getGlobalOrigin() + + // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. + let urlRecord + + try { + urlRecord = new URL(url, baseURL) + } catch (e) { + // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. + throw new DOMException(e, 'SyntaxError') + } + + // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". + if (urlRecord.protocol === 'http:') { + urlRecord.protocol = 'ws:' + } else if (urlRecord.protocol === 'https:') { + // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". + urlRecord.protocol = 'wss:' + } + + // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. + if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { + throw new DOMException( + `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, + 'SyntaxError' + ) + } + + // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" + // DOMException. + if (urlRecord.hash || urlRecord.href.endsWith('#')) { + throw new DOMException('Got fragment', 'SyntaxError') + } + + // 8. If protocols is a string, set protocols to a sequence consisting + // of just that string. + if (typeof protocols === 'string') { + protocols = [protocols] + } + + // 9. If any of the values in protocols occur more than once or otherwise + // fail to match the requirements for elements that comprise the value + // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket + // protocol, then throw a "SyntaxError" DOMException. + if (protocols.length !== new Set(protocols.map(p => p.toLowerCase())).size) { + throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + } + + if (protocols.length > 0 && !protocols.every(p => isValidSubprotocol(p))) { + throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + } + + // 10. Set this's url to urlRecord. + this[kWebSocketURL] = new URL(urlRecord.href) + + // 11. Let client be this's relevant settings object. + + // 12. Run this step in parallel: + + // 1. Establish a WebSocket connection given urlRecord, protocols, + // and client. + this[kController] = establishWebSocketConnection( + urlRecord, + protocols, + this, + (response) => this.#onConnectionEstablished(response), + options + ) + + // Each WebSocket object has an associated ready state, which is a + // number representing the state of the connection. Initially it must + // be CONNECTING (0). + this[kReadyState] = WebSocket.CONNECTING + + // The extensions attribute must initially return the empty string. + + // The protocol attribute must initially return the empty string. + + // Each WebSocket object has an associated binary type, which is a + // BinaryType. Initially it must be "blob". + this[kBinaryType] = 'blob' + } + + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-close + * @param {number|undefined} code + * @param {string|undefined} reason + */ + close (code = undefined, reason = undefined) { + webidl.brandCheck(this, WebSocket) + + if (code !== undefined) { + code = webidl.converters['unsigned short'](code, { clamp: true }) + } + + if (reason !== undefined) { + reason = webidl.converters.USVString(reason) + } + + // 1. If code is present, but is neither an integer equal to 1000 nor an + // integer in the range 3000 to 4999, inclusive, throw an + // "InvalidAccessError" DOMException. + if (code !== undefined) { + if (code !== 1000 && (code < 3000 || code > 4999)) { + throw new DOMException('invalid code', 'InvalidAccessError') + } + } + + let reasonByteLength = 0 + + // 2. If reason is present, then run these substeps: + if (reason !== undefined) { + // 1. Let reasonBytes be the result of encoding reason. + // 2. If reasonBytes is longer than 123 bytes, then throw a + // "SyntaxError" DOMException. + reasonByteLength = Buffer.byteLength(reason) + + if (reasonByteLength > 123) { + throw new DOMException( + `Reason must be less than 123 bytes; received ${reasonByteLength}`, + 'SyntaxError' + ) + } + } + + // 3. Run the first matching steps from the following list: + if (this[kReadyState] === WebSocket.CLOSING || this[kReadyState] === WebSocket.CLOSED) { + // If this's ready state is CLOSING (2) or CLOSED (3) + // Do nothing. + } else if (!isEstablished(this)) { + // If the WebSocket connection is not yet established + // Fail the WebSocket connection and set this's ready state + // to CLOSING (2). + failWebsocketConnection(this, 'Connection was closed before it was established.') + this[kReadyState] = WebSocket.CLOSING + } else if (!isClosing(this)) { + // If the WebSocket closing handshake has not yet been started + // Start the WebSocket closing handshake and set this's ready + // state to CLOSING (2). + // - If neither code nor reason is present, the WebSocket Close + // message must not have a body. + // - If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + // - If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. + + const frame = new WebsocketFrameSend() + + // If neither code nor reason is present, the WebSocket Close + // message must not have a body. + + // If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + if (code !== undefined && reason === undefined) { + frame.frameData = Buffer.allocUnsafe(2) + frame.frameData.writeUInt16BE(code, 0) + } else if (code !== undefined && reason !== undefined) { + // If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. + frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength) + frame.frameData.writeUInt16BE(code, 0) + // the body MAY contain UTF-8-encoded data with value /reason/ + frame.frameData.write(reason, 2, 'utf-8') + } else { + frame.frameData = emptyBuffer + } + + /** @type {import('stream').Duplex} */ + const socket = this[kResponse].socket + + socket.write(frame.createFrame(opcodes.CLOSE), (err) => { + if (!err) { + this[kSentClose] = true + } + }) + + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this[kReadyState] = states.CLOSING + } else { + // Otherwise + // Set this's ready state to CLOSING (2). + this[kReadyState] = WebSocket.CLOSING + } + } + + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-send + * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data + */ + send (data) { + webidl.brandCheck(this, WebSocket) + + webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket.send' }) + + data = webidl.converters.WebSocketSendData(data) + + // 1. If this's ready state is CONNECTING, then throw an + // "InvalidStateError" DOMException. + if (this[kReadyState] === WebSocket.CONNECTING) { + throw new DOMException('Sent before connected.', 'InvalidStateError') + } + + // 2. Run the appropriate set of steps from the following list: + // https://datatracker.ietf.org/doc/html/rfc6455#section-6.1 + // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 + + if (!isEstablished(this) || isClosing(this)) { + return + } + + /** @type {import('stream').Duplex} */ + const socket = this[kResponse].socket + + // If data is a string + if (typeof data === 'string') { + // If the WebSocket connection is established and the WebSocket + // closing handshake has not yet started, then the user agent + // must send a WebSocket Message comprised of the data argument + // using a text frame opcode; if the data cannot be sent, e.g. + // because it would need to be buffered but the buffer is full, + // the user agent must flag the WebSocket as full and then close + // the WebSocket connection. Any invocation of this method with a + // string argument that does not throw an exception must increase + // the bufferedAmount attribute by the number of bytes needed to + // express the argument as UTF-8. + + const value = Buffer.from(data) + const frame = new WebsocketFrameSend(value) + const buffer = frame.createFrame(opcodes.TEXT) + + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + } else if (types.isArrayBuffer(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need + // to be buffered but the buffer is full, the user agent must flag + // the WebSocket as full and then close the WebSocket connection. + // The data to be sent is the data stored in the buffer described + // by the ArrayBuffer object. Any invocation of this method with an + // ArrayBuffer argument that does not throw an exception must + // increase the bufferedAmount attribute by the length of the + // ArrayBuffer in bytes. + + const value = Buffer.from(data) + const frame = new WebsocketFrameSend(value) + const buffer = frame.createFrame(opcodes.BINARY) + + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + } else if (ArrayBuffer.isView(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The + // data to be sent is the data stored in the section of the buffer + // described by the ArrayBuffer object that data references. Any + // invocation of this method with this kind of argument that does + // not throw an exception must increase the bufferedAmount attribute + // by the length of data’s buffer in bytes. + + const ab = Buffer.from(data, data.byteOffset, data.byteLength) + + const frame = new WebsocketFrameSend(ab) + const buffer = frame.createFrame(opcodes.BINARY) + + this.#bufferedAmount += ab.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= ab.byteLength + }) + } else if (isBlobLike(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The data + // to be sent is the raw data represented by the Blob object. Any + // invocation of this method with a Blob argument that does not throw + // an exception must increase the bufferedAmount attribute by the size + // of the Blob object’s raw data, in bytes. + + const frame = new WebsocketFrameSend() + + data.arrayBuffer().then((ab) => { + const value = Buffer.from(ab) + frame.frameData = value + const buffer = frame.createFrame(opcodes.BINARY) + + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + }) + } + } + + get readyState () { + webidl.brandCheck(this, WebSocket) + + // The readyState getter steps are to return this's ready state. + return this[kReadyState] + } + + get bufferedAmount () { + webidl.brandCheck(this, WebSocket) + + return this.#bufferedAmount + } + + get url () { + webidl.brandCheck(this, WebSocket) + + // The url getter steps are to return this's url, serialized. + return URLSerializer(this[kWebSocketURL]) + } + + get extensions () { + webidl.brandCheck(this, WebSocket) + + return this.#extensions + } + + get protocol () { + webidl.brandCheck(this, WebSocket) + + return this.#protocol + } + + get onopen () { + webidl.brandCheck(this, WebSocket) + + return this.#events.open + } + + set onopen (fn) { + webidl.brandCheck(this, WebSocket) + + if (this.#events.open) { + this.removeEventListener('open', this.#events.open) + } + + if (typeof fn === 'function') { + this.#events.open = fn + this.addEventListener('open', fn) + } else { + this.#events.open = null + } + } + + get onerror () { + webidl.brandCheck(this, WebSocket) + + return this.#events.error + } + + set onerror (fn) { + webidl.brandCheck(this, WebSocket) + + if (this.#events.error) { + this.removeEventListener('error', this.#events.error) + } + + if (typeof fn === 'function') { + this.#events.error = fn + this.addEventListener('error', fn) + } else { + this.#events.error = null + } + } + + get onclose () { + webidl.brandCheck(this, WebSocket) + + return this.#events.close + } + + set onclose (fn) { + webidl.brandCheck(this, WebSocket) + + if (this.#events.close) { + this.removeEventListener('close', this.#events.close) + } + + if (typeof fn === 'function') { + this.#events.close = fn + this.addEventListener('close', fn) + } else { + this.#events.close = null + } + } + + get onmessage () { + webidl.brandCheck(this, WebSocket) + + return this.#events.message + } + + set onmessage (fn) { + webidl.brandCheck(this, WebSocket) + + if (this.#events.message) { + this.removeEventListener('message', this.#events.message) + } + + if (typeof fn === 'function') { + this.#events.message = fn + this.addEventListener('message', fn) + } else { + this.#events.message = null + } + } + + get binaryType () { + webidl.brandCheck(this, WebSocket) + + return this[kBinaryType] + } + + set binaryType (type) { + webidl.brandCheck(this, WebSocket) + + if (type !== 'blob' && type !== 'arraybuffer') { + this[kBinaryType] = 'blob' + } else { + this[kBinaryType] = type + } + } + + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + */ + #onConnectionEstablished (response) { + // processResponse is called when the "response’s header list has been received and initialized." + // once this happens, the connection is open + this[kResponse] = response + + const parser = new ByteParser(this) + parser.on('drain', function onParserDrain () { + this.ws[kResponse].socket.resume() + }) + + response.socket.ws = this + this[kByteParser] = parser + + // 1. Change the ready state to OPEN (1). + this[kReadyState] = states.OPEN + + // 2. Change the extensions attribute’s value to the extensions in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 + const extensions = response.headersList.get('sec-websocket-extensions') + + if (extensions !== null) { + this.#extensions = extensions + } + + // 3. Change the protocol attribute’s value to the subprotocol in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-1.9 + const protocol = response.headersList.get('sec-websocket-protocol') + + if (protocol !== null) { + this.#protocol = protocol + } + + // 4. Fire an event named open at the WebSocket object. + fireEvent('open', this) + } +} + +// https://websockets.spec.whatwg.org/#dom-websocket-connecting +WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING +// https://websockets.spec.whatwg.org/#dom-websocket-open +WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN +// https://websockets.spec.whatwg.org/#dom-websocket-closing +WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING +// https://websockets.spec.whatwg.org/#dom-websocket-closed +WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED + +Object.defineProperties(WebSocket.prototype, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors, + url: kEnumerableProperty, + readyState: kEnumerableProperty, + bufferedAmount: kEnumerableProperty, + onopen: kEnumerableProperty, + onerror: kEnumerableProperty, + onclose: kEnumerableProperty, + close: kEnumerableProperty, + onmessage: kEnumerableProperty, + binaryType: kEnumerableProperty, + send: kEnumerableProperty, + extensions: kEnumerableProperty, + protocol: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'WebSocket', + writable: false, + enumerable: false, + configurable: true + } +}) + +Object.defineProperties(WebSocket, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors +}) + +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.DOMString +) + +webidl.converters['DOMString or sequence'] = function (V) { + if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) { + return webidl.converters['sequence'](V) + } + + return webidl.converters.DOMString(V) +} + +// This implements the propsal made in https://github.com/whatwg/websockets/issues/42 +webidl.converters.WebSocketInit = webidl.dictionaryConverter([ + { + key: 'protocols', + converter: webidl.converters['DOMString or sequence'], + get defaultValue () { + return [] + } + }, + { + key: 'dispatcher', + converter: (V) => V, + get defaultValue () { + return getGlobalDispatcher() + } + }, + { + key: 'headers', + converter: webidl.nullableConverter(webidl.converters.HeadersInit) + } +]) + +webidl.converters['DOMString or sequence or WebSocketInit'] = function (V) { + if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) { + return webidl.converters.WebSocketInit(V) + } + + return { protocols: webidl.converters['DOMString or sequence'](V) } +} + +webidl.converters.WebSocketSendData = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } + + if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) { + return webidl.converters.BufferSource(V) + } + } + + return webidl.converters.USVString(V) +} + +module.exports = { + WebSocket +} + + +/***/ }), + +/***/ 5840: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "v1", ({ + enumerable: true, + get: function () { + return _v.default; + } +})); +Object.defineProperty(exports, "v3", ({ + enumerable: true, + get: function () { + return _v2.default; + } +})); +Object.defineProperty(exports, "v4", ({ + enumerable: true, + get: function () { + return _v3.default; + } +})); +Object.defineProperty(exports, "v5", ({ + enumerable: true, + get: function () { + return _v4.default; + } +})); +Object.defineProperty(exports, "NIL", ({ + enumerable: true, + get: function () { + return _nil.default; + } +})); +Object.defineProperty(exports, "version", ({ + enumerable: true, + get: function () { + return _version.default; + } +})); +Object.defineProperty(exports, "validate", ({ + enumerable: true, + get: function () { + return _validate.default; + } +})); +Object.defineProperty(exports, "stringify", ({ + enumerable: true, + get: function () { + return _stringify.default; + } +})); +Object.defineProperty(exports, "parse", ({ + enumerable: true, + get: function () { + return _parse.default; + } +})); + +var _v = _interopRequireDefault(__nccwpck_require__(8628)); + +var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); + +var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); + +var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); + +var _nil = _interopRequireDefault(__nccwpck_require__(5332)); + +var _version = _interopRequireDefault(__nccwpck_require__(1595)); + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/***/ }), + +/***/ 4569: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return _crypto.default.createHash('md5').update(bytes).digest(); +} + +var _default = md5; +exports["default"] = _default; + +/***/ }), + +/***/ 5332: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports["default"] = _default; + +/***/ }), + +/***/ 2746: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +var _default = parse; +exports["default"] = _default; + +/***/ }), + +/***/ 814: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports["default"] = _default; + +/***/ }), + +/***/ 807: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = rng; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + +let poolPtr = rnds8Pool.length; + +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool); + + poolPtr = 0; + } + + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} + +/***/ }), + +/***/ 5274: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return _crypto.default.createHash('sha1').update(bytes).digest(); +} + +var _default = sha1; +exports["default"] = _default; + +/***/ }), + +/***/ 8950: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).substr(1)); +} + +function stringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +var _default = stringify; +exports["default"] = _default; + +/***/ }), + +/***/ 8628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + + + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + + + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested + + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + + msecs += 12219292800000; // `time_low` + + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` + + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` + + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf || (0, _stringify.default)(b); +} + +var _default = v1; +exports["default"] = _default; + +/***/ }), + +/***/ 6409: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _md = _interopRequireDefault(__nccwpck_require__(4569)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; +exports["default"] = _default; + +/***/ }), + +/***/ 5998: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = _default; +exports.URL = exports.DNS = void 0; + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 3922: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + module.exports = -/******/ (function(modules, runtime) { // webpackBootstrap -/******/ "use strict"; -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ __webpack_require__.ab = __dirname + "/"; -/******/ -/******/ // the startup function -/******/ function startup() { -/******/ // Load entry module and return exports -/******/ return __webpack_require__(104); -/******/ }; -/******/ -/******/ // run startup -/******/ return startup(); -/******/ }) -/************************************************************************/ -/******/ ({ +{ + parallel : __nccwpck_require__(3085), + serial : __nccwpck_require__(7380), + serialOrdered : __nccwpck_require__(7704) +}; + + +/***/ }), + +/***/ 94: +/***/ ((module) => { + +// API +module.exports = abort; + +/** + * Aborts leftover active jobs + * + * @param {object} state - current state object + */ +function abort(state) +{ + Object.keys(state.jobs).forEach(clean.bind(state)); + + // reset leftover jobs + state.jobs = {}; +} + +/** + * Cleans up leftover job by invoking abort function for the provided job id + * + * @this state + * @param {string|number} key - job id to abort + */ +function clean(key) +{ + if (typeof this.jobs[key] == 'function') + { + this.jobs[key](); + } +} + + +/***/ }), + +/***/ 2824: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var defer = __nccwpck_require__(4237); + +// API +module.exports = async; + +/** + * Runs provided callback asynchronously + * even if callback itself is not + * + * @param {function} callback - callback to invoke + * @returns {function} - augmented callback + */ +function async(callback) +{ + var isAsync = false; + + // check if async happened + defer(function() { isAsync = true; }); + + return function async_callback(err, result) + { + if (isAsync) + { + callback(err, result); + } + else + { + defer(function nextTick_callback() + { + callback(err, result); + }); + } + }; +} + + +/***/ }), + +/***/ 4237: +/***/ ((module) => { + +module.exports = defer; + +/** + * Runs provided function on next iteration of the event loop + * + * @param {function} fn - function to run + */ +function defer(fn) +{ + var nextTick = typeof setImmediate == 'function' + ? setImmediate + : ( + typeof process == 'object' && typeof process.nextTick == 'function' + ? process.nextTick + : null + ); + + if (nextTick) + { + nextTick(fn); + } + else + { + setTimeout(fn, 0); + } +} + + +/***/ }), + +/***/ 6600: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var async = __nccwpck_require__(2824) + , abort = __nccwpck_require__(94) + ; + +// API +module.exports = iterate; + +/** + * Iterates over each job object + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {object} state - current job status + * @param {function} callback - invoked when all elements processed + */ +function iterate(list, iterator, state, callback) +{ + // store current index + var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + + state.jobs[key] = runJob(iterator, key, list[key], function(error, output) + { + // don't repeat yourself + // skip secondary callbacks + if (!(key in state.jobs)) + { + return; + } + + // clean up jobs + delete state.jobs[key]; + + if (error) + { + // don't process rest of the results + // stop still active jobs + // and reset the list + abort(state); + } + else + { + state.results[key] = output; + } + + // return salvaged results + callback(error, state.results); + }); +} + +/** + * Runs iterator over provided job element + * + * @param {function} iterator - iterator to invoke + * @param {string|number} key - key/index of the element in the list of jobs + * @param {mixed} item - job description + * @param {function} callback - invoked after iterator is done with the job + * @returns {function|mixed} - job abort function or something else + */ +function runJob(iterator, key, item, callback) +{ + var aborter; + + // allow shortcut if iterator expects only two arguments + if (iterator.length == 2) + { + aborter = iterator(item, async(callback)); + } + // otherwise go with full three arguments + else + { + aborter = iterator(item, key, async(callback)); + } + + return aborter; +} + + +/***/ }), + +/***/ 1077: +/***/ ((module) => { + +// API +module.exports = state; + +/** + * Creates initial state object + * for iteration over list + * + * @param {array|object} list - list to iterate over + * @param {function|null} sortMethod - function to use for keys sort, + * or `null` to keep them as is + * @returns {object} - initial state object + */ +function state(list, sortMethod) +{ + var isNamedList = !Array.isArray(list) + , initState = + { + index : 0, + keyedList: isNamedList || sortMethod ? Object.keys(list) : null, + jobs : {}, + results : isNamedList ? {} : [], + size : isNamedList ? Object.keys(list).length : list.length + } + ; + + if (sortMethod) + { + // sort array keys based on it's values + // sort object's keys just on own merit + initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) + { + return sortMethod(list[a], list[b]); + }); + } + + return initState; +} + + +/***/ }), + +/***/ 4506: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var abort = __nccwpck_require__(94) + , async = __nccwpck_require__(2824) + ; + +// API +module.exports = terminator; + +/** + * Terminates jobs in the attached state context + * + * @this AsyncKitState# + * @param {function} callback - final callback to invoke after termination + */ +function terminator(callback) +{ + if (!Object.keys(this.jobs).length) + { + return; + } + + // fast forward iteration index + this.index = this.size; + + // abort jobs + abort(this); + + // send back results we have so far + async(callback)(null, this.results); +} + + +/***/ }), + +/***/ 3085: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var iterate = __nccwpck_require__(6600) + , initState = __nccwpck_require__(1077) + , terminator = __nccwpck_require__(4506) + ; + +// Public API +module.exports = parallel; + +/** + * Runs iterator over provided array elements in parallel + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function parallel(list, iterator, callback) +{ + var state = initState(list); + + while (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, function(error, result) + { + if (error) + { + callback(error, result); + return; + } + + // looks like it's the last one + if (Object.keys(state.jobs).length === 0) + { + callback(null, state.results); + return; + } + }); + + state.index++; + } + + return terminator.bind(state, callback); +} + + +/***/ }), + +/***/ 7380: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var serialOrdered = __nccwpck_require__(7704); + +// Public API +module.exports = serial; + +/** + * Runs iterator over provided array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serial(list, iterator, callback) +{ + return serialOrdered(list, iterator, null, callback); +} + + +/***/ }), + +/***/ 7704: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var iterate = __nccwpck_require__(6600) + , initState = __nccwpck_require__(1077) + , terminator = __nccwpck_require__(4506) + ; + +// Public API +module.exports = serialOrdered; +// sorting helpers +module.exports.ascending = ascending; +module.exports.descending = descending; + +/** + * Runs iterator over provided sorted array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serialOrdered(list, iterator, sortMethod, callback) +{ + var state = initState(list, sortMethod); + + iterate(list, iterator, state, function iteratorHandler(error, result) + { + if (error) + { + callback(error, result); + return; + } + + state.index++; + + // are we there yet? + if (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, iteratorHandler); + return; + } + + // done here + callback(null, state.results); + }); + + return terminator.bind(state, callback); +} + +/* + * -- Sort methods + */ + +/** + * sort helper to sort array elements in ascending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function ascending(a, b) +{ + return a < b ? -1 : a > b ? 1 : 0; +} + +/** + * sort helper to sort array elements in descending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function descending(a, b) +{ + return -1 * ascending(a, b); +} + + +/***/ }), + +/***/ 3141: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var util = __nccwpck_require__(3837); +var Stream = (__nccwpck_require__(2781).Stream); +var DelayedStream = __nccwpck_require__(2959); + +module.exports = CombinedStream; +function CombinedStream() { + this.writable = false; + this.readable = true; + this.dataSize = 0; + this.maxDataSize = 2 * 1024 * 1024; + this.pauseStreams = true; + + this._released = false; + this._streams = []; + this._currentStream = null; + this._insideLoop = false; + this._pendingNext = false; +} +util.inherits(CombinedStream, Stream); + +CombinedStream.create = function(options) { + var combinedStream = new this(); + + options = options || {}; + for (var option in options) { + combinedStream[option] = options[option]; + } + + return combinedStream; +}; + +CombinedStream.isStreamLike = function(stream) { + return (typeof stream !== 'function') + && (typeof stream !== 'string') + && (typeof stream !== 'boolean') + && (typeof stream !== 'number') + && (!Buffer.isBuffer(stream)); +}; + +CombinedStream.prototype.append = function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + + if (isStreamLike) { + if (!(stream instanceof DelayedStream)) { + var newStream = DelayedStream.create(stream, { + maxDataSize: Infinity, + pauseStream: this.pauseStreams, + }); + stream.on('data', this._checkDataSize.bind(this)); + stream = newStream; + } + + this._handleErrors(stream); + + if (this.pauseStreams) { + stream.pause(); + } + } + + this._streams.push(stream); + return this; +}; + +CombinedStream.prototype.pipe = function(dest, options) { + Stream.prototype.pipe.call(this, dest, options); + this.resume(); + return dest; +}; + +CombinedStream.prototype._getNext = function() { + this._currentStream = null; + + if (this._insideLoop) { + this._pendingNext = true; + return; // defer call + } + + this._insideLoop = true; + try { + do { + this._pendingNext = false; + this._realGetNext(); + } while (this._pendingNext); + } finally { + this._insideLoop = false; + } +}; + +CombinedStream.prototype._realGetNext = function() { + var stream = this._streams.shift(); + + + if (typeof stream == 'undefined') { + this.end(); + return; + } -/***/ 2: -/***/ (function(module, __unusedexports, __webpack_require__) { + if (typeof stream !== 'function') { + this._pipeNext(stream); + return; + } -var abort = __webpack_require__(762) - , async = __webpack_require__(792) - ; + var getStream = stream; + getStream(function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('data', this._checkDataSize.bind(this)); + this._handleErrors(stream); + } -// API -module.exports = terminator; + this._pipeNext(stream); + }.bind(this)); +}; -/** - * Terminates jobs in the attached state context - * - * @this AsyncKitState# - * @param {function} callback - final callback to invoke after termination - */ -function terminator(callback) -{ - if (!Object.keys(this.jobs).length) - { +CombinedStream.prototype._pipeNext = function(stream) { + this._currentStream = stream; + + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('end', this._getNext.bind(this)); + stream.pipe(this, {end: false}); return; } - // fast forward iteration index - this.index = this.size; + var value = stream; + this.write(value); + this._getNext(); +}; - // abort jobs - abort(this); +CombinedStream.prototype._handleErrors = function(stream) { + var self = this; + stream.on('error', function(err) { + self._emitError(err); + }); +}; - // send back results we have so far - async(callback)(null, this.results); -} +CombinedStream.prototype.write = function(data) { + this.emit('data', data); +}; +CombinedStream.prototype.pause = function() { + if (!this.pauseStreams) { + return; + } -/***/ }), + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); + this.emit('pause'); +}; -/***/ 70: -/***/ (function(module) { +CombinedStream.prototype.resume = function() { + if (!this._released) { + this._released = true; + this.writable = true; + this._getNext(); + } -// populates missing values -module.exports = function(dst, src) { + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); + this.emit('resume'); +}; - Object.keys(src).forEach(function(prop) - { - dst[prop] = dst[prop] || src[prop]; - }); +CombinedStream.prototype.end = function() { + this._reset(); + this.emit('end'); +}; - return dst; +CombinedStream.prototype.destroy = function() { + this._reset(); + this.emit('close'); }; +CombinedStream.prototype._reset = function() { + this.writable = false; + this._streams = []; + this._currentStream = null; +}; -/***/ }), +CombinedStream.prototype._checkDataSize = function() { + this._updateDataSize(); + if (this.dataSize <= this.maxDataSize) { + return; + } -/***/ 82: -/***/ (function(__unusedmodule, exports) { + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; + this._emitError(new Error(message)); +}; -"use strict"; +CombinedStream.prototype._updateDataSize = function() { + this.dataSize = 0; -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * Sanitizes an input into a string so it can be passed into issueCommand safely - * @param input input to sanitize into a string - */ -function toCommandValue(input) { - if (input === null || input === undefined) { - return ''; - } - else if (typeof input === 'string' || input instanceof String) { - return input; + var self = this; + this._streams.forEach(function(stream) { + if (!stream.dataSize) { + return; } - return JSON.stringify(input); -} -exports.toCommandValue = toCommandValue; -//# sourceMappingURL=utils.js.map -/***/ }), + self.dataSize += stream.dataSize; + }); -/***/ 87: -/***/ (function(module) { + if (this._currentStream && this._currentStream.dataSize) { + this.dataSize += this._currentStream.dataSize; + } +}; -module.exports = require("os"); +CombinedStream.prototype._emitError = function(err) { + this._reset(); + this.emit('error', err); +}; -/***/ }), -/***/ 89: -/***/ (function(module, __unusedexports, __webpack_require__) { +/***/ }), -var iterate = __webpack_require__(258) - , initState = __webpack_require__(125) - , terminator = __webpack_require__(2) - ; +/***/ 2959: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -// Public API -module.exports = parallel; +var Stream = (__nccwpck_require__(2781).Stream); +var util = __nccwpck_require__(3837); -/** - * Runs iterator over provided array elements in parallel - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator - */ -function parallel(list, iterator, callback) -{ - var state = initState(list); +module.exports = DelayedStream; +function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; - while (state.index < (state['keyedList'] || list).length) - { - iterate(list, iterator, state, function(error, result) - { - if (error) - { - callback(error, result); - return; - } + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; +} +util.inherits(DelayedStream, Stream); - // looks like it's the last one - if (Object.keys(state.jobs).length === 0) - { - callback(null, state.results); - return; - } - }); +DelayedStream.create = function(source, options) { + var delayedStream = new this(); - state.index++; + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; } - return terminator.bind(state, callback); -} + delayedStream.source = source; + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; -/***/ }), + source.on('error', function() {}); + if (delayedStream.pauseStream) { + source.pause(); + } -/***/ 102: -/***/ (function(__unusedmodule, exports, __webpack_require__) { + return delayedStream; +}; -"use strict"; +Object.defineProperty(DelayedStream.prototype, 'readable', { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; + } +}); -// For internal use, subject to change. -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; +DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); }; -Object.defineProperty(exports, "__esModule", { value: true }); -// We use any as a valid input type -/* eslint-disable @typescript-eslint/no-explicit-any */ -const fs = __importStar(__webpack_require__(747)); -const os = __importStar(__webpack_require__(87)); -const utils_1 = __webpack_require__(82); -function issueCommand(command, message) { - const filePath = process.env[`GITHUB_${command}`]; - if (!filePath) { - throw new Error(`Unable to find environment variable for file command ${command}`); - } - if (!fs.existsSync(filePath)) { - throw new Error(`Missing file at path: ${filePath}`); - } - fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { - encoding: 'utf8' - }); -} -exports.issueCommand = issueCommand; -//# sourceMappingURL=file-command.js.map -/***/ }), +DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } -/***/ 104: -/***/ (function(__unusedmodule, __unusedexports, __webpack_require__) { + this.source.resume(); +}; -/*! - * Copyright 2021 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +DelayedStream.prototype.pause = function() { + this.source.pause(); +}; -const core = __webpack_require__(470); -const formData = __webpack_require__(416); -const Mailgun = __webpack_require__(618); +DelayedStream.prototype.release = function() { + this._released = true; -const mailgun = new Mailgun(formData); -const optionalFields = ['cc', 'text', 'html']; + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; +}; -function loadConfig() { - return { - apiKey: core.getInput('api-key'), - domain: core.getInput('domain'), - to: core.getInput('to'), - from: core.getInput('from'), - cc: core.getInput('cc'), - subject: core.getInput('subject'), - text: core.getInput('text'), - html: core.getInput('html'), - } -} +DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; +}; -function validate(config) { - for (param in config) { - if (optionalFields.includes(param)) { - continue; - } - validateRequiredParameter(config[param], `'${param}'`); +DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; } -} -function validateRequiredParameter(value, name) { - if (!isNonEmptyString(value)) { - throw new Error(`${name} must be a non-empty string.`); + if (args[0] === 'data') { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); } -} -function sendEmail(config) { - const mg = mailgun.client({ - username: 'api', - key: config.apiKey, - }); + this._bufferedEvents.push(args); +}; - return mg.messages - .create(config.domain, { - from: config.from, - to: config.to, - cc: config.cc, - subject: config.subject, - text: config.text, - html: config.html, - }) - .then((resp) => { - core.setOutput('response', resp.message); - return; - }) - .catch((err) => { - core.setFailed(err.message); - }); -} +DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; + } -function isNonEmptyString(value) { - return typeof value === 'string' && value !== ''; -} + if (this.dataSize <= this.maxDataSize) { + return; + } -const config = loadConfig(); -validate(config); -sendEmail(config); + this._maxDataSizeExceeded = true; + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' + this.emit('error', new Error(message)); +}; /***/ }), -/***/ 118: -/***/ (function(module) { - -module.exports = {"application/1d-interleaved-parityfec":{"source":"iana"},"application/3gpdash-qoe-report+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/3gpp-ims+xml":{"source":"iana","compressible":true},"application/a2l":{"source":"iana"},"application/activemessage":{"source":"iana"},"application/activity+json":{"source":"iana","compressible":true},"application/alto-costmap+json":{"source":"iana","compressible":true},"application/alto-costmapfilter+json":{"source":"iana","compressible":true},"application/alto-directory+json":{"source":"iana","compressible":true},"application/alto-endpointcost+json":{"source":"iana","compressible":true},"application/alto-endpointcostparams+json":{"source":"iana","compressible":true},"application/alto-endpointprop+json":{"source":"iana","compressible":true},"application/alto-endpointpropparams+json":{"source":"iana","compressible":true},"application/alto-error+json":{"source":"iana","compressible":true},"application/alto-networkmap+json":{"source":"iana","compressible":true},"application/alto-networkmapfilter+json":{"source":"iana","compressible":true},"application/alto-updatestreamcontrol+json":{"source":"iana","compressible":true},"application/alto-updatestreamparams+json":{"source":"iana","compressible":true},"application/aml":{"source":"iana"},"application/andrew-inset":{"source":"iana","extensions":["ez"]},"application/applefile":{"source":"iana"},"application/applixware":{"source":"apache","extensions":["aw"]},"application/atf":{"source":"iana"},"application/atfx":{"source":"iana"},"application/atom+xml":{"source":"iana","compressible":true,"extensions":["atom"]},"application/atomcat+xml":{"source":"iana","compressible":true,"extensions":["atomcat"]},"application/atomdeleted+xml":{"source":"iana","compressible":true,"extensions":["atomdeleted"]},"application/atomicmail":{"source":"iana"},"application/atomsvc+xml":{"source":"iana","compressible":true,"extensions":["atomsvc"]},"application/atsc-dwd+xml":{"source":"iana","compressible":true,"extensions":["dwd"]},"application/atsc-dynamic-event-message":{"source":"iana"},"application/atsc-held+xml":{"source":"iana","compressible":true,"extensions":["held"]},"application/atsc-rdt+json":{"source":"iana","compressible":true},"application/atsc-rsat+xml":{"source":"iana","compressible":true,"extensions":["rsat"]},"application/atxml":{"source":"iana"},"application/auth-policy+xml":{"source":"iana","compressible":true},"application/bacnet-xdd+zip":{"source":"iana","compressible":false},"application/batch-smtp":{"source":"iana"},"application/bdoc":{"compressible":false,"extensions":["bdoc"]},"application/beep+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/calendar+json":{"source":"iana","compressible":true},"application/calendar+xml":{"source":"iana","compressible":true,"extensions":["xcs"]},"application/call-completion":{"source":"iana"},"application/cals-1840":{"source":"iana"},"application/cap+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/cbor":{"source":"iana"},"application/cbor-seq":{"source":"iana"},"application/cccex":{"source":"iana"},"application/ccmp+xml":{"source":"iana","compressible":true},"application/ccxml+xml":{"source":"iana","compressible":true,"extensions":["ccxml"]},"application/cdfx+xml":{"source":"iana","compressible":true,"extensions":["cdfx"]},"application/cdmi-capability":{"source":"iana","extensions":["cdmia"]},"application/cdmi-container":{"source":"iana","extensions":["cdmic"]},"application/cdmi-domain":{"source":"iana","extensions":["cdmid"]},"application/cdmi-object":{"source":"iana","extensions":["cdmio"]},"application/cdmi-queue":{"source":"iana","extensions":["cdmiq"]},"application/cdni":{"source":"iana"},"application/cea":{"source":"iana"},"application/cea-2018+xml":{"source":"iana","compressible":true},"application/cellml+xml":{"source":"iana","compressible":true},"application/cfw":{"source":"iana"},"application/clue+xml":{"source":"iana","compressible":true},"application/clue_info+xml":{"source":"iana","compressible":true},"application/cms":{"source":"iana"},"application/cnrp+xml":{"source":"iana","compressible":true},"application/coap-group+json":{"source":"iana","compressible":true},"application/coap-payload":{"source":"iana"},"application/commonground":{"source":"iana"},"application/conference-info+xml":{"source":"iana","compressible":true},"application/cose":{"source":"iana"},"application/cose-key":{"source":"iana"},"application/cose-key-set":{"source":"iana"},"application/cpl+xml":{"source":"iana","compressible":true},"application/csrattrs":{"source":"iana"},"application/csta+xml":{"source":"iana","compressible":true},"application/cstadata+xml":{"source":"iana","compressible":true},"application/csvm+json":{"source":"iana","compressible":true},"application/cu-seeme":{"source":"apache","extensions":["cu"]},"application/cwt":{"source":"iana"},"application/cybercash":{"source":"iana"},"application/dart":{"compressible":true},"application/dash+xml":{"source":"iana","compressible":true,"extensions":["mpd"]},"application/dashdelta":{"source":"iana"},"application/davmount+xml":{"source":"iana","compressible":true,"extensions":["davmount"]},"application/dca-rft":{"source":"iana"},"application/dcd":{"source":"iana"},"application/dec-dx":{"source":"iana"},"application/dialog-info+xml":{"source":"iana","compressible":true},"application/dicom":{"source":"iana"},"application/dicom+json":{"source":"iana","compressible":true},"application/dicom+xml":{"source":"iana","compressible":true},"application/dii":{"source":"iana"},"application/dit":{"source":"iana"},"application/dns":{"source":"iana"},"application/dns+json":{"source":"iana","compressible":true},"application/dns-message":{"source":"iana"},"application/docbook+xml":{"source":"apache","compressible":true,"extensions":["dbk"]},"application/dots+cbor":{"source":"iana"},"application/dskpp+xml":{"source":"iana","compressible":true},"application/dssc+der":{"source":"iana","extensions":["dssc"]},"application/dssc+xml":{"source":"iana","compressible":true,"extensions":["xdssc"]},"application/dvcs":{"source":"iana"},"application/ecmascript":{"source":"iana","compressible":true,"extensions":["ecma","es"]},"application/edi-consent":{"source":"iana"},"application/edi-x12":{"source":"iana","compressible":false},"application/edifact":{"source":"iana","compressible":false},"application/efi":{"source":"iana"},"application/emergencycalldata.comment+xml":{"source":"iana","compressible":true},"application/emergencycalldata.control+xml":{"source":"iana","compressible":true},"application/emergencycalldata.deviceinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.ecall.msd":{"source":"iana"},"application/emergencycalldata.providerinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.serviceinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.subscriberinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.veds+xml":{"source":"iana","compressible":true},"application/emma+xml":{"source":"iana","compressible":true,"extensions":["emma"]},"application/emotionml+xml":{"source":"iana","compressible":true,"extensions":["emotionml"]},"application/encaprtp":{"source":"iana"},"application/epp+xml":{"source":"iana","compressible":true},"application/epub+zip":{"source":"iana","compressible":false,"extensions":["epub"]},"application/eshop":{"source":"iana"},"application/exi":{"source":"iana","extensions":["exi"]},"application/expect-ct-report+json":{"source":"iana","compressible":true},"application/fastinfoset":{"source":"iana"},"application/fastsoap":{"source":"iana"},"application/fdt+xml":{"source":"iana","compressible":true,"extensions":["fdt"]},"application/fhir+json":{"source":"iana","charset":"UTF-8","compressible":true},"application/fhir+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/fido.trusted-apps+json":{"compressible":true},"application/fits":{"source":"iana"},"application/flexfec":{"source":"iana"},"application/font-sfnt":{"source":"iana"},"application/font-tdpfr":{"source":"iana","extensions":["pfr"]},"application/font-woff":{"source":"iana","compressible":false},"application/framework-attributes+xml":{"source":"iana","compressible":true},"application/geo+json":{"source":"iana","compressible":true,"extensions":["geojson"]},"application/geo+json-seq":{"source":"iana"},"application/geopackage+sqlite3":{"source":"iana"},"application/geoxacml+xml":{"source":"iana","compressible":true},"application/gltf-buffer":{"source":"iana"},"application/gml+xml":{"source":"iana","compressible":true,"extensions":["gml"]},"application/gpx+xml":{"source":"apache","compressible":true,"extensions":["gpx"]},"application/gxf":{"source":"apache","extensions":["gxf"]},"application/gzip":{"source":"iana","compressible":false,"extensions":["gz"]},"application/h224":{"source":"iana"},"application/held+xml":{"source":"iana","compressible":true},"application/hjson":{"extensions":["hjson"]},"application/http":{"source":"iana"},"application/hyperstudio":{"source":"iana","extensions":["stk"]},"application/ibe-key-request+xml":{"source":"iana","compressible":true},"application/ibe-pkg-reply+xml":{"source":"iana","compressible":true},"application/ibe-pp-data":{"source":"iana"},"application/iges":{"source":"iana"},"application/im-iscomposing+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/index":{"source":"iana"},"application/index.cmd":{"source":"iana"},"application/index.obj":{"source":"iana"},"application/index.response":{"source":"iana"},"application/index.vnd":{"source":"iana"},"application/inkml+xml":{"source":"iana","compressible":true,"extensions":["ink","inkml"]},"application/iotp":{"source":"iana"},"application/ipfix":{"source":"iana","extensions":["ipfix"]},"application/ipp":{"source":"iana"},"application/isup":{"source":"iana"},"application/its+xml":{"source":"iana","compressible":true,"extensions":["its"]},"application/java-archive":{"source":"apache","compressible":false,"extensions":["jar","war","ear"]},"application/java-serialized-object":{"source":"apache","compressible":false,"extensions":["ser"]},"application/java-vm":{"source":"apache","compressible":false,"extensions":["class"]},"application/javascript":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["js","mjs"]},"application/jf2feed+json":{"source":"iana","compressible":true},"application/jose":{"source":"iana"},"application/jose+json":{"source":"iana","compressible":true},"application/jrd+json":{"source":"iana","compressible":true},"application/json":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["json","map"]},"application/json-patch+json":{"source":"iana","compressible":true},"application/json-seq":{"source":"iana"},"application/json5":{"extensions":["json5"]},"application/jsonml+json":{"source":"apache","compressible":true,"extensions":["jsonml"]},"application/jwk+json":{"source":"iana","compressible":true},"application/jwk-set+json":{"source":"iana","compressible":true},"application/jwt":{"source":"iana"},"application/kpml-request+xml":{"source":"iana","compressible":true},"application/kpml-response+xml":{"source":"iana","compressible":true},"application/ld+json":{"source":"iana","compressible":true,"extensions":["jsonld"]},"application/lgr+xml":{"source":"iana","compressible":true,"extensions":["lgr"]},"application/link-format":{"source":"iana"},"application/load-control+xml":{"source":"iana","compressible":true},"application/lost+xml":{"source":"iana","compressible":true,"extensions":["lostxml"]},"application/lostsync+xml":{"source":"iana","compressible":true},"application/lpf+zip":{"source":"iana","compressible":false},"application/lxf":{"source":"iana"},"application/mac-binhex40":{"source":"iana","extensions":["hqx"]},"application/mac-compactpro":{"source":"apache","extensions":["cpt"]},"application/macwriteii":{"source":"iana"},"application/mads+xml":{"source":"iana","compressible":true,"extensions":["mads"]},"application/manifest+json":{"charset":"UTF-8","compressible":true,"extensions":["webmanifest"]},"application/marc":{"source":"iana","extensions":["mrc"]},"application/marcxml+xml":{"source":"iana","compressible":true,"extensions":["mrcx"]},"application/mathematica":{"source":"iana","extensions":["ma","nb","mb"]},"application/mathml+xml":{"source":"iana","compressible":true,"extensions":["mathml"]},"application/mathml-content+xml":{"source":"iana","compressible":true},"application/mathml-presentation+xml":{"source":"iana","compressible":true},"application/mbms-associated-procedure-description+xml":{"source":"iana","compressible":true},"application/mbms-deregister+xml":{"source":"iana","compressible":true},"application/mbms-envelope+xml":{"source":"iana","compressible":true},"application/mbms-msk+xml":{"source":"iana","compressible":true},"application/mbms-msk-response+xml":{"source":"iana","compressible":true},"application/mbms-protection-description+xml":{"source":"iana","compressible":true},"application/mbms-reception-report+xml":{"source":"iana","compressible":true},"application/mbms-register+xml":{"source":"iana","compressible":true},"application/mbms-register-response+xml":{"source":"iana","compressible":true},"application/mbms-schedule+xml":{"source":"iana","compressible":true},"application/mbms-user-service-description+xml":{"source":"iana","compressible":true},"application/mbox":{"source":"iana","extensions":["mbox"]},"application/media-policy-dataset+xml":{"source":"iana","compressible":true},"application/media_control+xml":{"source":"iana","compressible":true},"application/mediaservercontrol+xml":{"source":"iana","compressible":true,"extensions":["mscml"]},"application/merge-patch+json":{"source":"iana","compressible":true},"application/metalink+xml":{"source":"apache","compressible":true,"extensions":["metalink"]},"application/metalink4+xml":{"source":"iana","compressible":true,"extensions":["meta4"]},"application/mets+xml":{"source":"iana","compressible":true,"extensions":["mets"]},"application/mf4":{"source":"iana"},"application/mikey":{"source":"iana"},"application/mipc":{"source":"iana"},"application/mmt-aei+xml":{"source":"iana","compressible":true,"extensions":["maei"]},"application/mmt-usd+xml":{"source":"iana","compressible":true,"extensions":["musd"]},"application/mods+xml":{"source":"iana","compressible":true,"extensions":["mods"]},"application/moss-keys":{"source":"iana"},"application/moss-signature":{"source":"iana"},"application/mosskey-data":{"source":"iana"},"application/mosskey-request":{"source":"iana"},"application/mp21":{"source":"iana","extensions":["m21","mp21"]},"application/mp4":{"source":"iana","extensions":["mp4s","m4p"]},"application/mpeg4-generic":{"source":"iana"},"application/mpeg4-iod":{"source":"iana"},"application/mpeg4-iod-xmt":{"source":"iana"},"application/mrb-consumer+xml":{"source":"iana","compressible":true,"extensions":["xdf"]},"application/mrb-publish+xml":{"source":"iana","compressible":true,"extensions":["xdf"]},"application/msc-ivr+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/msc-mixer+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/msword":{"source":"iana","compressible":false,"extensions":["doc","dot"]},"application/mud+json":{"source":"iana","compressible":true},"application/multipart-core":{"source":"iana"},"application/mxf":{"source":"iana","extensions":["mxf"]},"application/n-quads":{"source":"iana","extensions":["nq"]},"application/n-triples":{"source":"iana","extensions":["nt"]},"application/nasdata":{"source":"iana"},"application/news-checkgroups":{"source":"iana","charset":"US-ASCII"},"application/news-groupinfo":{"source":"iana","charset":"US-ASCII"},"application/news-transmission":{"source":"iana"},"application/nlsml+xml":{"source":"iana","compressible":true},"application/node":{"source":"iana","extensions":["cjs"]},"application/nss":{"source":"iana"},"application/ocsp-request":{"source":"iana"},"application/ocsp-response":{"source":"iana"},"application/octet-stream":{"source":"iana","compressible":false,"extensions":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]},"application/oda":{"source":"iana","extensions":["oda"]},"application/odm+xml":{"source":"iana","compressible":true},"application/odx":{"source":"iana"},"application/oebps-package+xml":{"source":"iana","compressible":true,"extensions":["opf"]},"application/ogg":{"source":"iana","compressible":false,"extensions":["ogx"]},"application/omdoc+xml":{"source":"apache","compressible":true,"extensions":["omdoc"]},"application/onenote":{"source":"apache","extensions":["onetoc","onetoc2","onetmp","onepkg"]},"application/oscore":{"source":"iana"},"application/oxps":{"source":"iana","extensions":["oxps"]},"application/p2p-overlay+xml":{"source":"iana","compressible":true,"extensions":["relo"]},"application/parityfec":{"source":"iana"},"application/passport":{"source":"iana"},"application/patch-ops-error+xml":{"source":"iana","compressible":true,"extensions":["xer"]},"application/pdf":{"source":"iana","compressible":false,"extensions":["pdf"]},"application/pdx":{"source":"iana"},"application/pem-certificate-chain":{"source":"iana"},"application/pgp-encrypted":{"source":"iana","compressible":false,"extensions":["pgp"]},"application/pgp-keys":{"source":"iana"},"application/pgp-signature":{"source":"iana","extensions":["asc","sig"]},"application/pics-rules":{"source":"apache","extensions":["prf"]},"application/pidf+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/pidf-diff+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/pkcs10":{"source":"iana","extensions":["p10"]},"application/pkcs12":{"source":"iana"},"application/pkcs7-mime":{"source":"iana","extensions":["p7m","p7c"]},"application/pkcs7-signature":{"source":"iana","extensions":["p7s"]},"application/pkcs8":{"source":"iana","extensions":["p8"]},"application/pkcs8-encrypted":{"source":"iana"},"application/pkix-attr-cert":{"source":"iana","extensions":["ac"]},"application/pkix-cert":{"source":"iana","extensions":["cer"]},"application/pkix-crl":{"source":"iana","extensions":["crl"]},"application/pkix-pkipath":{"source":"iana","extensions":["pkipath"]},"application/pkixcmp":{"source":"iana","extensions":["pki"]},"application/pls+xml":{"source":"iana","compressible":true,"extensions":["pls"]},"application/poc-settings+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/postscript":{"source":"iana","compressible":true,"extensions":["ai","eps","ps"]},"application/ppsp-tracker+json":{"source":"iana","compressible":true},"application/problem+json":{"source":"iana","compressible":true},"application/problem+xml":{"source":"iana","compressible":true},"application/provenance+xml":{"source":"iana","compressible":true,"extensions":["provx"]},"application/prs.alvestrand.titrax-sheet":{"source":"iana"},"application/prs.cww":{"source":"iana","extensions":["cww"]},"application/prs.hpub+zip":{"source":"iana","compressible":false},"application/prs.nprend":{"source":"iana"},"application/prs.plucker":{"source":"iana"},"application/prs.rdf-xml-crypt":{"source":"iana"},"application/prs.xsf+xml":{"source":"iana","compressible":true},"application/pskc+xml":{"source":"iana","compressible":true,"extensions":["pskcxml"]},"application/pvd+json":{"source":"iana","compressible":true},"application/qsig":{"source":"iana"},"application/raml+yaml":{"compressible":true,"extensions":["raml"]},"application/raptorfec":{"source":"iana"},"application/rdap+json":{"source":"iana","compressible":true},"application/rdf+xml":{"source":"iana","compressible":true,"extensions":["rdf","owl"]},"application/reginfo+xml":{"source":"iana","compressible":true,"extensions":["rif"]},"application/relax-ng-compact-syntax":{"source":"iana","extensions":["rnc"]},"application/remote-printing":{"source":"iana"},"application/reputon+json":{"source":"iana","compressible":true},"application/resource-lists+xml":{"source":"iana","compressible":true,"extensions":["rl"]},"application/resource-lists-diff+xml":{"source":"iana","compressible":true,"extensions":["rld"]},"application/rfc+xml":{"source":"iana","compressible":true},"application/riscos":{"source":"iana"},"application/rlmi+xml":{"source":"iana","compressible":true},"application/rls-services+xml":{"source":"iana","compressible":true,"extensions":["rs"]},"application/route-apd+xml":{"source":"iana","compressible":true,"extensions":["rapd"]},"application/route-s-tsid+xml":{"source":"iana","compressible":true,"extensions":["sls"]},"application/route-usd+xml":{"source":"iana","compressible":true,"extensions":["rusd"]},"application/rpki-ghostbusters":{"source":"iana","extensions":["gbr"]},"application/rpki-manifest":{"source":"iana","extensions":["mft"]},"application/rpki-publication":{"source":"iana"},"application/rpki-roa":{"source":"iana","extensions":["roa"]},"application/rpki-updown":{"source":"iana"},"application/rsd+xml":{"source":"apache","compressible":true,"extensions":["rsd"]},"application/rss+xml":{"source":"apache","compressible":true,"extensions":["rss"]},"application/rtf":{"source":"iana","compressible":true,"extensions":["rtf"]},"application/rtploopback":{"source":"iana"},"application/rtx":{"source":"iana"},"application/samlassertion+xml":{"source":"iana","compressible":true},"application/samlmetadata+xml":{"source":"iana","compressible":true},"application/sbe":{"source":"iana"},"application/sbml+xml":{"source":"iana","compressible":true,"extensions":["sbml"]},"application/scaip+xml":{"source":"iana","compressible":true},"application/scim+json":{"source":"iana","compressible":true},"application/scvp-cv-request":{"source":"iana","extensions":["scq"]},"application/scvp-cv-response":{"source":"iana","extensions":["scs"]},"application/scvp-vp-request":{"source":"iana","extensions":["spq"]},"application/scvp-vp-response":{"source":"iana","extensions":["spp"]},"application/sdp":{"source":"iana","extensions":["sdp"]},"application/secevent+jwt":{"source":"iana"},"application/senml+cbor":{"source":"iana"},"application/senml+json":{"source":"iana","compressible":true},"application/senml+xml":{"source":"iana","compressible":true,"extensions":["senmlx"]},"application/senml-etch+cbor":{"source":"iana"},"application/senml-etch+json":{"source":"iana","compressible":true},"application/senml-exi":{"source":"iana"},"application/sensml+cbor":{"source":"iana"},"application/sensml+json":{"source":"iana","compressible":true},"application/sensml+xml":{"source":"iana","compressible":true,"extensions":["sensmlx"]},"application/sensml-exi":{"source":"iana"},"application/sep+xml":{"source":"iana","compressible":true},"application/sep-exi":{"source":"iana"},"application/session-info":{"source":"iana"},"application/set-payment":{"source":"iana"},"application/set-payment-initiation":{"source":"iana","extensions":["setpay"]},"application/set-registration":{"source":"iana"},"application/set-registration-initiation":{"source":"iana","extensions":["setreg"]},"application/sgml":{"source":"iana"},"application/sgml-open-catalog":{"source":"iana"},"application/shf+xml":{"source":"iana","compressible":true,"extensions":["shf"]},"application/sieve":{"source":"iana","extensions":["siv","sieve"]},"application/simple-filter+xml":{"source":"iana","compressible":true},"application/simple-message-summary":{"source":"iana"},"application/simplesymbolcontainer":{"source":"iana"},"application/sipc":{"source":"iana"},"application/slate":{"source":"iana"},"application/smil":{"source":"iana"},"application/smil+xml":{"source":"iana","compressible":true,"extensions":["smi","smil"]},"application/smpte336m":{"source":"iana"},"application/soap+fastinfoset":{"source":"iana"},"application/soap+xml":{"source":"iana","compressible":true},"application/sparql-query":{"source":"iana","extensions":["rq"]},"application/sparql-results+xml":{"source":"iana","compressible":true,"extensions":["srx"]},"application/spirits-event+xml":{"source":"iana","compressible":true},"application/sql":{"source":"iana"},"application/srgs":{"source":"iana","extensions":["gram"]},"application/srgs+xml":{"source":"iana","compressible":true,"extensions":["grxml"]},"application/sru+xml":{"source":"iana","compressible":true,"extensions":["sru"]},"application/ssdl+xml":{"source":"apache","compressible":true,"extensions":["ssdl"]},"application/ssml+xml":{"source":"iana","compressible":true,"extensions":["ssml"]},"application/stix+json":{"source":"iana","compressible":true},"application/swid+xml":{"source":"iana","compressible":true,"extensions":["swidtag"]},"application/tamp-apex-update":{"source":"iana"},"application/tamp-apex-update-confirm":{"source":"iana"},"application/tamp-community-update":{"source":"iana"},"application/tamp-community-update-confirm":{"source":"iana"},"application/tamp-error":{"source":"iana"},"application/tamp-sequence-adjust":{"source":"iana"},"application/tamp-sequence-adjust-confirm":{"source":"iana"},"application/tamp-status-query":{"source":"iana"},"application/tamp-status-response":{"source":"iana"},"application/tamp-update":{"source":"iana"},"application/tamp-update-confirm":{"source":"iana"},"application/tar":{"compressible":true},"application/taxii+json":{"source":"iana","compressible":true},"application/td+json":{"source":"iana","compressible":true},"application/tei+xml":{"source":"iana","compressible":true,"extensions":["tei","teicorpus"]},"application/tetra_isi":{"source":"iana"},"application/thraud+xml":{"source":"iana","compressible":true,"extensions":["tfi"]},"application/timestamp-query":{"source":"iana"},"application/timestamp-reply":{"source":"iana"},"application/timestamped-data":{"source":"iana","extensions":["tsd"]},"application/tlsrpt+gzip":{"source":"iana"},"application/tlsrpt+json":{"source":"iana","compressible":true},"application/tnauthlist":{"source":"iana"},"application/toml":{"compressible":true,"extensions":["toml"]},"application/trickle-ice-sdpfrag":{"source":"iana"},"application/trig":{"source":"iana"},"application/ttml+xml":{"source":"iana","compressible":true,"extensions":["ttml"]},"application/tve-trigger":{"source":"iana"},"application/tzif":{"source":"iana"},"application/tzif-leap":{"source":"iana"},"application/ulpfec":{"source":"iana"},"application/urc-grpsheet+xml":{"source":"iana","compressible":true},"application/urc-ressheet+xml":{"source":"iana","compressible":true,"extensions":["rsheet"]},"application/urc-targetdesc+xml":{"source":"iana","compressible":true},"application/urc-uisocketdesc+xml":{"source":"iana","compressible":true},"application/vcard+json":{"source":"iana","compressible":true},"application/vcard+xml":{"source":"iana","compressible":true},"application/vemmi":{"source":"iana"},"application/vividence.scriptfile":{"source":"apache"},"application/vnd.1000minds.decision-model+xml":{"source":"iana","compressible":true,"extensions":["1km"]},"application/vnd.3gpp-prose+xml":{"source":"iana","compressible":true},"application/vnd.3gpp-prose-pc3ch+xml":{"source":"iana","compressible":true},"application/vnd.3gpp-v2x-local-service-information":{"source":"iana"},"application/vnd.3gpp.access-transfer-events+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.bsf+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.gmop+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mc-signalling-ear":{"source":"iana"},"application/vnd.3gpp.mcdata-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-payload":{"source":"iana"},"application/vnd.3gpp.mcdata-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-signalling":{"source":"iana"},"application/vnd.3gpp.mcdata-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-floor-request+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-location-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-mbms-usage-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-signed+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-ue-init-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-affiliation-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-location-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-mbms-usage-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-transmission-request+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mid-call+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.pic-bw-large":{"source":"iana","extensions":["plb"]},"application/vnd.3gpp.pic-bw-small":{"source":"iana","extensions":["psb"]},"application/vnd.3gpp.pic-bw-var":{"source":"iana","extensions":["pvb"]},"application/vnd.3gpp.sms":{"source":"iana"},"application/vnd.3gpp.sms+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.srvcc-ext+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.srvcc-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.state-and-event-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.ussd+xml":{"source":"iana","compressible":true},"application/vnd.3gpp2.bcmcsinfo+xml":{"source":"iana","compressible":true},"application/vnd.3gpp2.sms":{"source":"iana"},"application/vnd.3gpp2.tcap":{"source":"iana","extensions":["tcap"]},"application/vnd.3lightssoftware.imagescal":{"source":"iana"},"application/vnd.3m.post-it-notes":{"source":"iana","extensions":["pwn"]},"application/vnd.accpac.simply.aso":{"source":"iana","extensions":["aso"]},"application/vnd.accpac.simply.imp":{"source":"iana","extensions":["imp"]},"application/vnd.acucobol":{"source":"iana","extensions":["acu"]},"application/vnd.acucorp":{"source":"iana","extensions":["atc","acutc"]},"application/vnd.adobe.air-application-installer-package+zip":{"source":"apache","compressible":false,"extensions":["air"]},"application/vnd.adobe.flash.movie":{"source":"iana"},"application/vnd.adobe.formscentral.fcdt":{"source":"iana","extensions":["fcdt"]},"application/vnd.adobe.fxp":{"source":"iana","extensions":["fxp","fxpl"]},"application/vnd.adobe.partial-upload":{"source":"iana"},"application/vnd.adobe.xdp+xml":{"source":"iana","compressible":true,"extensions":["xdp"]},"application/vnd.adobe.xfdf":{"source":"iana","extensions":["xfdf"]},"application/vnd.aether.imp":{"source":"iana"},"application/vnd.afpc.afplinedata":{"source":"iana"},"application/vnd.afpc.afplinedata-pagedef":{"source":"iana"},"application/vnd.afpc.foca-charset":{"source":"iana"},"application/vnd.afpc.foca-codedfont":{"source":"iana"},"application/vnd.afpc.foca-codepage":{"source":"iana"},"application/vnd.afpc.modca":{"source":"iana"},"application/vnd.afpc.modca-formdef":{"source":"iana"},"application/vnd.afpc.modca-mediummap":{"source":"iana"},"application/vnd.afpc.modca-objectcontainer":{"source":"iana"},"application/vnd.afpc.modca-overlay":{"source":"iana"},"application/vnd.afpc.modca-pagesegment":{"source":"iana"},"application/vnd.ah-barcode":{"source":"iana"},"application/vnd.ahead.space":{"source":"iana","extensions":["ahead"]},"application/vnd.airzip.filesecure.azf":{"source":"iana","extensions":["azf"]},"application/vnd.airzip.filesecure.azs":{"source":"iana","extensions":["azs"]},"application/vnd.amadeus+json":{"source":"iana","compressible":true},"application/vnd.amazon.ebook":{"source":"apache","extensions":["azw"]},"application/vnd.amazon.mobi8-ebook":{"source":"iana"},"application/vnd.americandynamics.acc":{"source":"iana","extensions":["acc"]},"application/vnd.amiga.ami":{"source":"iana","extensions":["ami"]},"application/vnd.amundsen.maze+xml":{"source":"iana","compressible":true},"application/vnd.android.ota":{"source":"iana"},"application/vnd.android.package-archive":{"source":"apache","compressible":false,"extensions":["apk"]},"application/vnd.anki":{"source":"iana"},"application/vnd.anser-web-certificate-issue-initiation":{"source":"iana","extensions":["cii"]},"application/vnd.anser-web-funds-transfer-initiation":{"source":"apache","extensions":["fti"]},"application/vnd.antix.game-component":{"source":"iana","extensions":["atx"]},"application/vnd.apache.thrift.binary":{"source":"iana"},"application/vnd.apache.thrift.compact":{"source":"iana"},"application/vnd.apache.thrift.json":{"source":"iana"},"application/vnd.api+json":{"source":"iana","compressible":true},"application/vnd.aplextor.warrp+json":{"source":"iana","compressible":true},"application/vnd.apothekende.reservation+json":{"source":"iana","compressible":true},"application/vnd.apple.installer+xml":{"source":"iana","compressible":true,"extensions":["mpkg"]},"application/vnd.apple.keynote":{"source":"iana","extensions":["keynote"]},"application/vnd.apple.mpegurl":{"source":"iana","extensions":["m3u8"]},"application/vnd.apple.numbers":{"source":"iana","extensions":["numbers"]},"application/vnd.apple.pages":{"source":"iana","extensions":["pages"]},"application/vnd.apple.pkpass":{"compressible":false,"extensions":["pkpass"]},"application/vnd.arastra.swi":{"source":"iana"},"application/vnd.aristanetworks.swi":{"source":"iana","extensions":["swi"]},"application/vnd.artisan+json":{"source":"iana","compressible":true},"application/vnd.artsquare":{"source":"iana"},"application/vnd.astraea-software.iota":{"source":"iana","extensions":["iota"]},"application/vnd.audiograph":{"source":"iana","extensions":["aep"]},"application/vnd.autopackage":{"source":"iana"},"application/vnd.avalon+json":{"source":"iana","compressible":true},"application/vnd.avistar+xml":{"source":"iana","compressible":true},"application/vnd.balsamiq.bmml+xml":{"source":"iana","compressible":true,"extensions":["bmml"]},"application/vnd.balsamiq.bmpr":{"source":"iana"},"application/vnd.banana-accounting":{"source":"iana"},"application/vnd.bbf.usp.error":{"source":"iana"},"application/vnd.bbf.usp.msg":{"source":"iana"},"application/vnd.bbf.usp.msg+json":{"source":"iana","compressible":true},"application/vnd.bekitzur-stech+json":{"source":"iana","compressible":true},"application/vnd.bint.med-content":{"source":"iana"},"application/vnd.biopax.rdf+xml":{"source":"iana","compressible":true},"application/vnd.blink-idb-value-wrapper":{"source":"iana"},"application/vnd.blueice.multipass":{"source":"iana","extensions":["mpm"]},"application/vnd.bluetooth.ep.oob":{"source":"iana"},"application/vnd.bluetooth.le.oob":{"source":"iana"},"application/vnd.bmi":{"source":"iana","extensions":["bmi"]},"application/vnd.bpf":{"source":"iana"},"application/vnd.bpf3":{"source":"iana"},"application/vnd.businessobjects":{"source":"iana","extensions":["rep"]},"application/vnd.byu.uapi+json":{"source":"iana","compressible":true},"application/vnd.cab-jscript":{"source":"iana"},"application/vnd.canon-cpdl":{"source":"iana"},"application/vnd.canon-lips":{"source":"iana"},"application/vnd.capasystems-pg+json":{"source":"iana","compressible":true},"application/vnd.cendio.thinlinc.clientconf":{"source":"iana"},"application/vnd.century-systems.tcp_stream":{"source":"iana"},"application/vnd.chemdraw+xml":{"source":"iana","compressible":true,"extensions":["cdxml"]},"application/vnd.chess-pgn":{"source":"iana"},"application/vnd.chipnuts.karaoke-mmd":{"source":"iana","extensions":["mmd"]},"application/vnd.ciedi":{"source":"iana"},"application/vnd.cinderella":{"source":"iana","extensions":["cdy"]},"application/vnd.cirpack.isdn-ext":{"source":"iana"},"application/vnd.citationstyles.style+xml":{"source":"iana","compressible":true,"extensions":["csl"]},"application/vnd.claymore":{"source":"iana","extensions":["cla"]},"application/vnd.cloanto.rp9":{"source":"iana","extensions":["rp9"]},"application/vnd.clonk.c4group":{"source":"iana","extensions":["c4g","c4d","c4f","c4p","c4u"]},"application/vnd.cluetrust.cartomobile-config":{"source":"iana","extensions":["c11amc"]},"application/vnd.cluetrust.cartomobile-config-pkg":{"source":"iana","extensions":["c11amz"]},"application/vnd.coffeescript":{"source":"iana"},"application/vnd.collabio.xodocuments.document":{"source":"iana"},"application/vnd.collabio.xodocuments.document-template":{"source":"iana"},"application/vnd.collabio.xodocuments.presentation":{"source":"iana"},"application/vnd.collabio.xodocuments.presentation-template":{"source":"iana"},"application/vnd.collabio.xodocuments.spreadsheet":{"source":"iana"},"application/vnd.collabio.xodocuments.spreadsheet-template":{"source":"iana"},"application/vnd.collection+json":{"source":"iana","compressible":true},"application/vnd.collection.doc+json":{"source":"iana","compressible":true},"application/vnd.collection.next+json":{"source":"iana","compressible":true},"application/vnd.comicbook+zip":{"source":"iana","compressible":false},"application/vnd.comicbook-rar":{"source":"iana"},"application/vnd.commerce-battelle":{"source":"iana"},"application/vnd.commonspace":{"source":"iana","extensions":["csp"]},"application/vnd.contact.cmsg":{"source":"iana","extensions":["cdbcmsg"]},"application/vnd.coreos.ignition+json":{"source":"iana","compressible":true},"application/vnd.cosmocaller":{"source":"iana","extensions":["cmc"]},"application/vnd.crick.clicker":{"source":"iana","extensions":["clkx"]},"application/vnd.crick.clicker.keyboard":{"source":"iana","extensions":["clkk"]},"application/vnd.crick.clicker.palette":{"source":"iana","extensions":["clkp"]},"application/vnd.crick.clicker.template":{"source":"iana","extensions":["clkt"]},"application/vnd.crick.clicker.wordbank":{"source":"iana","extensions":["clkw"]},"application/vnd.criticaltools.wbs+xml":{"source":"iana","compressible":true,"extensions":["wbs"]},"application/vnd.cryptii.pipe+json":{"source":"iana","compressible":true},"application/vnd.crypto-shade-file":{"source":"iana"},"application/vnd.ctc-posml":{"source":"iana","extensions":["pml"]},"application/vnd.ctct.ws+xml":{"source":"iana","compressible":true},"application/vnd.cups-pdf":{"source":"iana"},"application/vnd.cups-postscript":{"source":"iana"},"application/vnd.cups-ppd":{"source":"iana","extensions":["ppd"]},"application/vnd.cups-raster":{"source":"iana"},"application/vnd.cups-raw":{"source":"iana"},"application/vnd.curl":{"source":"iana"},"application/vnd.curl.car":{"source":"apache","extensions":["car"]},"application/vnd.curl.pcurl":{"source":"apache","extensions":["pcurl"]},"application/vnd.cyan.dean.root+xml":{"source":"iana","compressible":true},"application/vnd.cybank":{"source":"iana"},"application/vnd.d2l.coursepackage1p0+zip":{"source":"iana","compressible":false},"application/vnd.dart":{"source":"iana","compressible":true,"extensions":["dart"]},"application/vnd.data-vision.rdz":{"source":"iana","extensions":["rdz"]},"application/vnd.datapackage+json":{"source":"iana","compressible":true},"application/vnd.dataresource+json":{"source":"iana","compressible":true},"application/vnd.dbf":{"source":"iana"},"application/vnd.debian.binary-package":{"source":"iana"},"application/vnd.dece.data":{"source":"iana","extensions":["uvf","uvvf","uvd","uvvd"]},"application/vnd.dece.ttml+xml":{"source":"iana","compressible":true,"extensions":["uvt","uvvt"]},"application/vnd.dece.unspecified":{"source":"iana","extensions":["uvx","uvvx"]},"application/vnd.dece.zip":{"source":"iana","extensions":["uvz","uvvz"]},"application/vnd.denovo.fcselayout-link":{"source":"iana","extensions":["fe_launch"]},"application/vnd.desmume.movie":{"source":"iana"},"application/vnd.dir-bi.plate-dl-nosuffix":{"source":"iana"},"application/vnd.dm.delegation+xml":{"source":"iana","compressible":true},"application/vnd.dna":{"source":"iana","extensions":["dna"]},"application/vnd.document+json":{"source":"iana","compressible":true},"application/vnd.dolby.mlp":{"source":"apache","extensions":["mlp"]},"application/vnd.dolby.mobile.1":{"source":"iana"},"application/vnd.dolby.mobile.2":{"source":"iana"},"application/vnd.doremir.scorecloud-binary-document":{"source":"iana"},"application/vnd.dpgraph":{"source":"iana","extensions":["dpg"]},"application/vnd.dreamfactory":{"source":"iana","extensions":["dfac"]},"application/vnd.drive+json":{"source":"iana","compressible":true},"application/vnd.ds-keypoint":{"source":"apache","extensions":["kpxx"]},"application/vnd.dtg.local":{"source":"iana"},"application/vnd.dtg.local.flash":{"source":"iana"},"application/vnd.dtg.local.html":{"source":"iana"},"application/vnd.dvb.ait":{"source":"iana","extensions":["ait"]},"application/vnd.dvb.dvbisl+xml":{"source":"iana","compressible":true},"application/vnd.dvb.dvbj":{"source":"iana"},"application/vnd.dvb.esgcontainer":{"source":"iana"},"application/vnd.dvb.ipdcdftnotifaccess":{"source":"iana"},"application/vnd.dvb.ipdcesgaccess":{"source":"iana"},"application/vnd.dvb.ipdcesgaccess2":{"source":"iana"},"application/vnd.dvb.ipdcesgpdd":{"source":"iana"},"application/vnd.dvb.ipdcroaming":{"source":"iana"},"application/vnd.dvb.iptv.alfec-base":{"source":"iana"},"application/vnd.dvb.iptv.alfec-enhancement":{"source":"iana"},"application/vnd.dvb.notif-aggregate-root+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-container+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-generic+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-msglist+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-registration-request+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-registration-response+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-init+xml":{"source":"iana","compressible":true},"application/vnd.dvb.pfr":{"source":"iana"},"application/vnd.dvb.service":{"source":"iana","extensions":["svc"]},"application/vnd.dxr":{"source":"iana"},"application/vnd.dynageo":{"source":"iana","extensions":["geo"]},"application/vnd.dzr":{"source":"iana"},"application/vnd.easykaraoke.cdgdownload":{"source":"iana"},"application/vnd.ecdis-update":{"source":"iana"},"application/vnd.ecip.rlp":{"source":"iana"},"application/vnd.ecowin.chart":{"source":"iana","extensions":["mag"]},"application/vnd.ecowin.filerequest":{"source":"iana"},"application/vnd.ecowin.fileupdate":{"source":"iana"},"application/vnd.ecowin.series":{"source":"iana"},"application/vnd.ecowin.seriesrequest":{"source":"iana"},"application/vnd.ecowin.seriesupdate":{"source":"iana"},"application/vnd.efi.img":{"source":"iana"},"application/vnd.efi.iso":{"source":"iana"},"application/vnd.emclient.accessrequest+xml":{"source":"iana","compressible":true},"application/vnd.enliven":{"source":"iana","extensions":["nml"]},"application/vnd.enphase.envoy":{"source":"iana"},"application/vnd.eprints.data+xml":{"source":"iana","compressible":true},"application/vnd.epson.esf":{"source":"iana","extensions":["esf"]},"application/vnd.epson.msf":{"source":"iana","extensions":["msf"]},"application/vnd.epson.quickanime":{"source":"iana","extensions":["qam"]},"application/vnd.epson.salt":{"source":"iana","extensions":["slt"]},"application/vnd.epson.ssf":{"source":"iana","extensions":["ssf"]},"application/vnd.ericsson.quickcall":{"source":"iana"},"application/vnd.espass-espass+zip":{"source":"iana","compressible":false},"application/vnd.eszigno3+xml":{"source":"iana","compressible":true,"extensions":["es3","et3"]},"application/vnd.etsi.aoc+xml":{"source":"iana","compressible":true},"application/vnd.etsi.asic-e+zip":{"source":"iana","compressible":false},"application/vnd.etsi.asic-s+zip":{"source":"iana","compressible":false},"application/vnd.etsi.cug+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvcommand+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvdiscovery+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvprofile+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-bc+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-cod+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-npvr+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvservice+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsync+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvueprofile+xml":{"source":"iana","compressible":true},"application/vnd.etsi.mcid+xml":{"source":"iana","compressible":true},"application/vnd.etsi.mheg5":{"source":"iana"},"application/vnd.etsi.overload-control-policy-dataset+xml":{"source":"iana","compressible":true},"application/vnd.etsi.pstn+xml":{"source":"iana","compressible":true},"application/vnd.etsi.sci+xml":{"source":"iana","compressible":true},"application/vnd.etsi.simservs+xml":{"source":"iana","compressible":true},"application/vnd.etsi.timestamp-token":{"source":"iana"},"application/vnd.etsi.tsl+xml":{"source":"iana","compressible":true},"application/vnd.etsi.tsl.der":{"source":"iana"},"application/vnd.eudora.data":{"source":"iana"},"application/vnd.evolv.ecig.profile":{"source":"iana"},"application/vnd.evolv.ecig.settings":{"source":"iana"},"application/vnd.evolv.ecig.theme":{"source":"iana"},"application/vnd.exstream-empower+zip":{"source":"iana","compressible":false},"application/vnd.exstream-package":{"source":"iana"},"application/vnd.ezpix-album":{"source":"iana","extensions":["ez2"]},"application/vnd.ezpix-package":{"source":"iana","extensions":["ez3"]},"application/vnd.f-secure.mobile":{"source":"iana"},"application/vnd.fastcopy-disk-image":{"source":"iana"},"application/vnd.fdf":{"source":"iana","extensions":["fdf"]},"application/vnd.fdsn.mseed":{"source":"iana","extensions":["mseed"]},"application/vnd.fdsn.seed":{"source":"iana","extensions":["seed","dataless"]},"application/vnd.ffsns":{"source":"iana"},"application/vnd.ficlab.flb+zip":{"source":"iana","compressible":false},"application/vnd.filmit.zfc":{"source":"iana"},"application/vnd.fints":{"source":"iana"},"application/vnd.firemonkeys.cloudcell":{"source":"iana"},"application/vnd.flographit":{"source":"iana","extensions":["gph"]},"application/vnd.fluxtime.clip":{"source":"iana","extensions":["ftc"]},"application/vnd.font-fontforge-sfd":{"source":"iana"},"application/vnd.framemaker":{"source":"iana","extensions":["fm","frame","maker","book"]},"application/vnd.frogans.fnc":{"source":"iana","extensions":["fnc"]},"application/vnd.frogans.ltf":{"source":"iana","extensions":["ltf"]},"application/vnd.fsc.weblaunch":{"source":"iana","extensions":["fsc"]},"application/vnd.fujitsu.oasys":{"source":"iana","extensions":["oas"]},"application/vnd.fujitsu.oasys2":{"source":"iana","extensions":["oa2"]},"application/vnd.fujitsu.oasys3":{"source":"iana","extensions":["oa3"]},"application/vnd.fujitsu.oasysgp":{"source":"iana","extensions":["fg5"]},"application/vnd.fujitsu.oasysprs":{"source":"iana","extensions":["bh2"]},"application/vnd.fujixerox.art-ex":{"source":"iana"},"application/vnd.fujixerox.art4":{"source":"iana"},"application/vnd.fujixerox.ddd":{"source":"iana","extensions":["ddd"]},"application/vnd.fujixerox.docuworks":{"source":"iana","extensions":["xdw"]},"application/vnd.fujixerox.docuworks.binder":{"source":"iana","extensions":["xbd"]},"application/vnd.fujixerox.docuworks.container":{"source":"iana"},"application/vnd.fujixerox.hbpl":{"source":"iana"},"application/vnd.fut-misnet":{"source":"iana"},"application/vnd.futoin+cbor":{"source":"iana"},"application/vnd.futoin+json":{"source":"iana","compressible":true},"application/vnd.fuzzysheet":{"source":"iana","extensions":["fzs"]},"application/vnd.genomatix.tuxedo":{"source":"iana","extensions":["txd"]},"application/vnd.gentics.grd+json":{"source":"iana","compressible":true},"application/vnd.geo+json":{"source":"iana","compressible":true},"application/vnd.geocube+xml":{"source":"iana","compressible":true},"application/vnd.geogebra.file":{"source":"iana","extensions":["ggb"]},"application/vnd.geogebra.tool":{"source":"iana","extensions":["ggt"]},"application/vnd.geometry-explorer":{"source":"iana","extensions":["gex","gre"]},"application/vnd.geonext":{"source":"iana","extensions":["gxt"]},"application/vnd.geoplan":{"source":"iana","extensions":["g2w"]},"application/vnd.geospace":{"source":"iana","extensions":["g3w"]},"application/vnd.gerber":{"source":"iana"},"application/vnd.globalplatform.card-content-mgt":{"source":"iana"},"application/vnd.globalplatform.card-content-mgt-response":{"source":"iana"},"application/vnd.gmx":{"source":"iana","extensions":["gmx"]},"application/vnd.google-apps.document":{"compressible":false,"extensions":["gdoc"]},"application/vnd.google-apps.presentation":{"compressible":false,"extensions":["gslides"]},"application/vnd.google-apps.spreadsheet":{"compressible":false,"extensions":["gsheet"]},"application/vnd.google-earth.kml+xml":{"source":"iana","compressible":true,"extensions":["kml"]},"application/vnd.google-earth.kmz":{"source":"iana","compressible":false,"extensions":["kmz"]},"application/vnd.gov.sk.e-form+xml":{"source":"iana","compressible":true},"application/vnd.gov.sk.e-form+zip":{"source":"iana","compressible":false},"application/vnd.gov.sk.xmldatacontainer+xml":{"source":"iana","compressible":true},"application/vnd.grafeq":{"source":"iana","extensions":["gqf","gqs"]},"application/vnd.gridmp":{"source":"iana"},"application/vnd.groove-account":{"source":"iana","extensions":["gac"]},"application/vnd.groove-help":{"source":"iana","extensions":["ghf"]},"application/vnd.groove-identity-message":{"source":"iana","extensions":["gim"]},"application/vnd.groove-injector":{"source":"iana","extensions":["grv"]},"application/vnd.groove-tool-message":{"source":"iana","extensions":["gtm"]},"application/vnd.groove-tool-template":{"source":"iana","extensions":["tpl"]},"application/vnd.groove-vcard":{"source":"iana","extensions":["vcg"]},"application/vnd.hal+json":{"source":"iana","compressible":true},"application/vnd.hal+xml":{"source":"iana","compressible":true,"extensions":["hal"]},"application/vnd.handheld-entertainment+xml":{"source":"iana","compressible":true,"extensions":["zmm"]},"application/vnd.hbci":{"source":"iana","extensions":["hbci"]},"application/vnd.hc+json":{"source":"iana","compressible":true},"application/vnd.hcl-bireports":{"source":"iana"},"application/vnd.hdt":{"source":"iana"},"application/vnd.heroku+json":{"source":"iana","compressible":true},"application/vnd.hhe.lesson-player":{"source":"iana","extensions":["les"]},"application/vnd.hp-hpgl":{"source":"iana","extensions":["hpgl"]},"application/vnd.hp-hpid":{"source":"iana","extensions":["hpid"]},"application/vnd.hp-hps":{"source":"iana","extensions":["hps"]},"application/vnd.hp-jlyt":{"source":"iana","extensions":["jlt"]},"application/vnd.hp-pcl":{"source":"iana","extensions":["pcl"]},"application/vnd.hp-pclxl":{"source":"iana","extensions":["pclxl"]},"application/vnd.httphone":{"source":"iana"},"application/vnd.hydrostatix.sof-data":{"source":"iana","extensions":["sfd-hdstx"]},"application/vnd.hyper+json":{"source":"iana","compressible":true},"application/vnd.hyper-item+json":{"source":"iana","compressible":true},"application/vnd.hyperdrive+json":{"source":"iana","compressible":true},"application/vnd.hzn-3d-crossword":{"source":"iana"},"application/vnd.ibm.afplinedata":{"source":"iana"},"application/vnd.ibm.electronic-media":{"source":"iana"},"application/vnd.ibm.minipay":{"source":"iana","extensions":["mpy"]},"application/vnd.ibm.modcap":{"source":"iana","extensions":["afp","listafp","list3820"]},"application/vnd.ibm.rights-management":{"source":"iana","extensions":["irm"]},"application/vnd.ibm.secure-container":{"source":"iana","extensions":["sc"]},"application/vnd.iccprofile":{"source":"iana","extensions":["icc","icm"]},"application/vnd.ieee.1905":{"source":"iana"},"application/vnd.igloader":{"source":"iana","extensions":["igl"]},"application/vnd.imagemeter.folder+zip":{"source":"iana","compressible":false},"application/vnd.imagemeter.image+zip":{"source":"iana","compressible":false},"application/vnd.immervision-ivp":{"source":"iana","extensions":["ivp"]},"application/vnd.immervision-ivu":{"source":"iana","extensions":["ivu"]},"application/vnd.ims.imsccv1p1":{"source":"iana"},"application/vnd.ims.imsccv1p2":{"source":"iana"},"application/vnd.ims.imsccv1p3":{"source":"iana"},"application/vnd.ims.lis.v2.result+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolconsumerprofile+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolproxy+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolproxy.id+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolsettings+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolsettings.simple+json":{"source":"iana","compressible":true},"application/vnd.informedcontrol.rms+xml":{"source":"iana","compressible":true},"application/vnd.informix-visionary":{"source":"iana"},"application/vnd.infotech.project":{"source":"iana"},"application/vnd.infotech.project+xml":{"source":"iana","compressible":true},"application/vnd.innopath.wamp.notification":{"source":"iana"},"application/vnd.insors.igm":{"source":"iana","extensions":["igm"]},"application/vnd.intercon.formnet":{"source":"iana","extensions":["xpw","xpx"]},"application/vnd.intergeo":{"source":"iana","extensions":["i2g"]},"application/vnd.intertrust.digibox":{"source":"iana"},"application/vnd.intertrust.nncp":{"source":"iana"},"application/vnd.intu.qbo":{"source":"iana","extensions":["qbo"]},"application/vnd.intu.qfx":{"source":"iana","extensions":["qfx"]},"application/vnd.iptc.g2.catalogitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.conceptitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.knowledgeitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.newsitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.newsmessage+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.packageitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.planningitem+xml":{"source":"iana","compressible":true},"application/vnd.ipunplugged.rcprofile":{"source":"iana","extensions":["rcprofile"]},"application/vnd.irepository.package+xml":{"source":"iana","compressible":true,"extensions":["irp"]},"application/vnd.is-xpr":{"source":"iana","extensions":["xpr"]},"application/vnd.isac.fcs":{"source":"iana","extensions":["fcs"]},"application/vnd.iso11783-10+zip":{"source":"iana","compressible":false},"application/vnd.jam":{"source":"iana","extensions":["jam"]},"application/vnd.japannet-directory-service":{"source":"iana"},"application/vnd.japannet-jpnstore-wakeup":{"source":"iana"},"application/vnd.japannet-payment-wakeup":{"source":"iana"},"application/vnd.japannet-registration":{"source":"iana"},"application/vnd.japannet-registration-wakeup":{"source":"iana"},"application/vnd.japannet-setstore-wakeup":{"source":"iana"},"application/vnd.japannet-verification":{"source":"iana"},"application/vnd.japannet-verification-wakeup":{"source":"iana"},"application/vnd.jcp.javame.midlet-rms":{"source":"iana","extensions":["rms"]},"application/vnd.jisp":{"source":"iana","extensions":["jisp"]},"application/vnd.joost.joda-archive":{"source":"iana","extensions":["joda"]},"application/vnd.jsk.isdn-ngn":{"source":"iana"},"application/vnd.kahootz":{"source":"iana","extensions":["ktz","ktr"]},"application/vnd.kde.karbon":{"source":"iana","extensions":["karbon"]},"application/vnd.kde.kchart":{"source":"iana","extensions":["chrt"]},"application/vnd.kde.kformula":{"source":"iana","extensions":["kfo"]},"application/vnd.kde.kivio":{"source":"iana","extensions":["flw"]},"application/vnd.kde.kontour":{"source":"iana","extensions":["kon"]},"application/vnd.kde.kpresenter":{"source":"iana","extensions":["kpr","kpt"]},"application/vnd.kde.kspread":{"source":"iana","extensions":["ksp"]},"application/vnd.kde.kword":{"source":"iana","extensions":["kwd","kwt"]},"application/vnd.kenameaapp":{"source":"iana","extensions":["htke"]},"application/vnd.kidspiration":{"source":"iana","extensions":["kia"]},"application/vnd.kinar":{"source":"iana","extensions":["kne","knp"]},"application/vnd.koan":{"source":"iana","extensions":["skp","skd","skt","skm"]},"application/vnd.kodak-descriptor":{"source":"iana","extensions":["sse"]},"application/vnd.las":{"source":"iana"},"application/vnd.las.las+json":{"source":"iana","compressible":true},"application/vnd.las.las+xml":{"source":"iana","compressible":true,"extensions":["lasxml"]},"application/vnd.laszip":{"source":"iana"},"application/vnd.leap+json":{"source":"iana","compressible":true},"application/vnd.liberty-request+xml":{"source":"iana","compressible":true},"application/vnd.llamagraphics.life-balance.desktop":{"source":"iana","extensions":["lbd"]},"application/vnd.llamagraphics.life-balance.exchange+xml":{"source":"iana","compressible":true,"extensions":["lbe"]},"application/vnd.logipipe.circuit+zip":{"source":"iana","compressible":false},"application/vnd.loom":{"source":"iana"},"application/vnd.lotus-1-2-3":{"source":"iana","extensions":["123"]},"application/vnd.lotus-approach":{"source":"iana","extensions":["apr"]},"application/vnd.lotus-freelance":{"source":"iana","extensions":["pre"]},"application/vnd.lotus-notes":{"source":"iana","extensions":["nsf"]},"application/vnd.lotus-organizer":{"source":"iana","extensions":["org"]},"application/vnd.lotus-screencam":{"source":"iana","extensions":["scm"]},"application/vnd.lotus-wordpro":{"source":"iana","extensions":["lwp"]},"application/vnd.macports.portpkg":{"source":"iana","extensions":["portpkg"]},"application/vnd.mapbox-vector-tile":{"source":"iana"},"application/vnd.marlin.drm.actiontoken+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.conftoken+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.license+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.mdcf":{"source":"iana"},"application/vnd.mason+json":{"source":"iana","compressible":true},"application/vnd.maxmind.maxmind-db":{"source":"iana"},"application/vnd.mcd":{"source":"iana","extensions":["mcd"]},"application/vnd.medcalcdata":{"source":"iana","extensions":["mc1"]},"application/vnd.mediastation.cdkey":{"source":"iana","extensions":["cdkey"]},"application/vnd.meridian-slingshot":{"source":"iana"},"application/vnd.mfer":{"source":"iana","extensions":["mwf"]},"application/vnd.mfmp":{"source":"iana","extensions":["mfm"]},"application/vnd.micro+json":{"source":"iana","compressible":true},"application/vnd.micrografx.flo":{"source":"iana","extensions":["flo"]},"application/vnd.micrografx.igx":{"source":"iana","extensions":["igx"]},"application/vnd.microsoft.portable-executable":{"source":"iana"},"application/vnd.microsoft.windows.thumbnail-cache":{"source":"iana"},"application/vnd.miele+json":{"source":"iana","compressible":true},"application/vnd.mif":{"source":"iana","extensions":["mif"]},"application/vnd.minisoft-hp3000-save":{"source":"iana"},"application/vnd.mitsubishi.misty-guard.trustweb":{"source":"iana"},"application/vnd.mobius.daf":{"source":"iana","extensions":["daf"]},"application/vnd.mobius.dis":{"source":"iana","extensions":["dis"]},"application/vnd.mobius.mbk":{"source":"iana","extensions":["mbk"]},"application/vnd.mobius.mqy":{"source":"iana","extensions":["mqy"]},"application/vnd.mobius.msl":{"source":"iana","extensions":["msl"]},"application/vnd.mobius.plc":{"source":"iana","extensions":["plc"]},"application/vnd.mobius.txf":{"source":"iana","extensions":["txf"]},"application/vnd.mophun.application":{"source":"iana","extensions":["mpn"]},"application/vnd.mophun.certificate":{"source":"iana","extensions":["mpc"]},"application/vnd.motorola.flexsuite":{"source":"iana"},"application/vnd.motorola.flexsuite.adsi":{"source":"iana"},"application/vnd.motorola.flexsuite.fis":{"source":"iana"},"application/vnd.motorola.flexsuite.gotap":{"source":"iana"},"application/vnd.motorola.flexsuite.kmr":{"source":"iana"},"application/vnd.motorola.flexsuite.ttc":{"source":"iana"},"application/vnd.motorola.flexsuite.wem":{"source":"iana"},"application/vnd.motorola.iprm":{"source":"iana"},"application/vnd.mozilla.xul+xml":{"source":"iana","compressible":true,"extensions":["xul"]},"application/vnd.ms-3mfdocument":{"source":"iana"},"application/vnd.ms-artgalry":{"source":"iana","extensions":["cil"]},"application/vnd.ms-asf":{"source":"iana"},"application/vnd.ms-cab-compressed":{"source":"iana","extensions":["cab"]},"application/vnd.ms-color.iccprofile":{"source":"apache"},"application/vnd.ms-excel":{"source":"iana","compressible":false,"extensions":["xls","xlm","xla","xlc","xlt","xlw"]},"application/vnd.ms-excel.addin.macroenabled.12":{"source":"iana","extensions":["xlam"]},"application/vnd.ms-excel.sheet.binary.macroenabled.12":{"source":"iana","extensions":["xlsb"]},"application/vnd.ms-excel.sheet.macroenabled.12":{"source":"iana","extensions":["xlsm"]},"application/vnd.ms-excel.template.macroenabled.12":{"source":"iana","extensions":["xltm"]},"application/vnd.ms-fontobject":{"source":"iana","compressible":true,"extensions":["eot"]},"application/vnd.ms-htmlhelp":{"source":"iana","extensions":["chm"]},"application/vnd.ms-ims":{"source":"iana","extensions":["ims"]},"application/vnd.ms-lrm":{"source":"iana","extensions":["lrm"]},"application/vnd.ms-office.activex+xml":{"source":"iana","compressible":true},"application/vnd.ms-officetheme":{"source":"iana","extensions":["thmx"]},"application/vnd.ms-opentype":{"source":"apache","compressible":true},"application/vnd.ms-outlook":{"compressible":false,"extensions":["msg"]},"application/vnd.ms-package.obfuscated-opentype":{"source":"apache"},"application/vnd.ms-pki.seccat":{"source":"apache","extensions":["cat"]},"application/vnd.ms-pki.stl":{"source":"apache","extensions":["stl"]},"application/vnd.ms-playready.initiator+xml":{"source":"iana","compressible":true},"application/vnd.ms-powerpoint":{"source":"iana","compressible":false,"extensions":["ppt","pps","pot"]},"application/vnd.ms-powerpoint.addin.macroenabled.12":{"source":"iana","extensions":["ppam"]},"application/vnd.ms-powerpoint.presentation.macroenabled.12":{"source":"iana","extensions":["pptm"]},"application/vnd.ms-powerpoint.slide.macroenabled.12":{"source":"iana","extensions":["sldm"]},"application/vnd.ms-powerpoint.slideshow.macroenabled.12":{"source":"iana","extensions":["ppsm"]},"application/vnd.ms-powerpoint.template.macroenabled.12":{"source":"iana","extensions":["potm"]},"application/vnd.ms-printdevicecapabilities+xml":{"source":"iana","compressible":true},"application/vnd.ms-printing.printticket+xml":{"source":"apache","compressible":true},"application/vnd.ms-printschematicket+xml":{"source":"iana","compressible":true},"application/vnd.ms-project":{"source":"iana","extensions":["mpp","mpt"]},"application/vnd.ms-tnef":{"source":"iana"},"application/vnd.ms-windows.devicepairing":{"source":"iana"},"application/vnd.ms-windows.nwprinting.oob":{"source":"iana"},"application/vnd.ms-windows.printerpairing":{"source":"iana"},"application/vnd.ms-windows.wsd.oob":{"source":"iana"},"application/vnd.ms-wmdrm.lic-chlg-req":{"source":"iana"},"application/vnd.ms-wmdrm.lic-resp":{"source":"iana"},"application/vnd.ms-wmdrm.meter-chlg-req":{"source":"iana"},"application/vnd.ms-wmdrm.meter-resp":{"source":"iana"},"application/vnd.ms-word.document.macroenabled.12":{"source":"iana","extensions":["docm"]},"application/vnd.ms-word.template.macroenabled.12":{"source":"iana","extensions":["dotm"]},"application/vnd.ms-works":{"source":"iana","extensions":["wps","wks","wcm","wdb"]},"application/vnd.ms-wpl":{"source":"iana","extensions":["wpl"]},"application/vnd.ms-xpsdocument":{"source":"iana","compressible":false,"extensions":["xps"]},"application/vnd.msa-disk-image":{"source":"iana"},"application/vnd.mseq":{"source":"iana","extensions":["mseq"]},"application/vnd.msign":{"source":"iana"},"application/vnd.multiad.creator":{"source":"iana"},"application/vnd.multiad.creator.cif":{"source":"iana"},"application/vnd.music-niff":{"source":"iana"},"application/vnd.musician":{"source":"iana","extensions":["mus"]},"application/vnd.muvee.style":{"source":"iana","extensions":["msty"]},"application/vnd.mynfc":{"source":"iana","extensions":["taglet"]},"application/vnd.ncd.control":{"source":"iana"},"application/vnd.ncd.reference":{"source":"iana"},"application/vnd.nearst.inv+json":{"source":"iana","compressible":true},"application/vnd.nervana":{"source":"iana"},"application/vnd.netfpx":{"source":"iana"},"application/vnd.neurolanguage.nlu":{"source":"iana","extensions":["nlu"]},"application/vnd.nimn":{"source":"iana"},"application/vnd.nintendo.nitro.rom":{"source":"iana"},"application/vnd.nintendo.snes.rom":{"source":"iana"},"application/vnd.nitf":{"source":"iana","extensions":["ntf","nitf"]},"application/vnd.noblenet-directory":{"source":"iana","extensions":["nnd"]},"application/vnd.noblenet-sealer":{"source":"iana","extensions":["nns"]},"application/vnd.noblenet-web":{"source":"iana","extensions":["nnw"]},"application/vnd.nokia.catalogs":{"source":"iana"},"application/vnd.nokia.conml+wbxml":{"source":"iana"},"application/vnd.nokia.conml+xml":{"source":"iana","compressible":true},"application/vnd.nokia.iptv.config+xml":{"source":"iana","compressible":true},"application/vnd.nokia.isds-radio-presets":{"source":"iana"},"application/vnd.nokia.landmark+wbxml":{"source":"iana"},"application/vnd.nokia.landmark+xml":{"source":"iana","compressible":true},"application/vnd.nokia.landmarkcollection+xml":{"source":"iana","compressible":true},"application/vnd.nokia.n-gage.ac+xml":{"source":"iana","compressible":true,"extensions":["ac"]},"application/vnd.nokia.n-gage.data":{"source":"iana","extensions":["ngdat"]},"application/vnd.nokia.n-gage.symbian.install":{"source":"iana","extensions":["n-gage"]},"application/vnd.nokia.ncd":{"source":"iana"},"application/vnd.nokia.pcd+wbxml":{"source":"iana"},"application/vnd.nokia.pcd+xml":{"source":"iana","compressible":true},"application/vnd.nokia.radio-preset":{"source":"iana","extensions":["rpst"]},"application/vnd.nokia.radio-presets":{"source":"iana","extensions":["rpss"]},"application/vnd.novadigm.edm":{"source":"iana","extensions":["edm"]},"application/vnd.novadigm.edx":{"source":"iana","extensions":["edx"]},"application/vnd.novadigm.ext":{"source":"iana","extensions":["ext"]},"application/vnd.ntt-local.content-share":{"source":"iana"},"application/vnd.ntt-local.file-transfer":{"source":"iana"},"application/vnd.ntt-local.ogw_remote-access":{"source":"iana"},"application/vnd.ntt-local.sip-ta_remote":{"source":"iana"},"application/vnd.ntt-local.sip-ta_tcp_stream":{"source":"iana"},"application/vnd.oasis.opendocument.chart":{"source":"iana","extensions":["odc"]},"application/vnd.oasis.opendocument.chart-template":{"source":"iana","extensions":["otc"]},"application/vnd.oasis.opendocument.database":{"source":"iana","extensions":["odb"]},"application/vnd.oasis.opendocument.formula":{"source":"iana","extensions":["odf"]},"application/vnd.oasis.opendocument.formula-template":{"source":"iana","extensions":["odft"]},"application/vnd.oasis.opendocument.graphics":{"source":"iana","compressible":false,"extensions":["odg"]},"application/vnd.oasis.opendocument.graphics-template":{"source":"iana","extensions":["otg"]},"application/vnd.oasis.opendocument.image":{"source":"iana","extensions":["odi"]},"application/vnd.oasis.opendocument.image-template":{"source":"iana","extensions":["oti"]},"application/vnd.oasis.opendocument.presentation":{"source":"iana","compressible":false,"extensions":["odp"]},"application/vnd.oasis.opendocument.presentation-template":{"source":"iana","extensions":["otp"]},"application/vnd.oasis.opendocument.spreadsheet":{"source":"iana","compressible":false,"extensions":["ods"]},"application/vnd.oasis.opendocument.spreadsheet-template":{"source":"iana","extensions":["ots"]},"application/vnd.oasis.opendocument.text":{"source":"iana","compressible":false,"extensions":["odt"]},"application/vnd.oasis.opendocument.text-master":{"source":"iana","extensions":["odm"]},"application/vnd.oasis.opendocument.text-template":{"source":"iana","extensions":["ott"]},"application/vnd.oasis.opendocument.text-web":{"source":"iana","extensions":["oth"]},"application/vnd.obn":{"source":"iana"},"application/vnd.ocf+cbor":{"source":"iana"},"application/vnd.oci.image.manifest.v1+json":{"source":"iana","compressible":true},"application/vnd.oftn.l10n+json":{"source":"iana","compressible":true},"application/vnd.oipf.contentaccessdownload+xml":{"source":"iana","compressible":true},"application/vnd.oipf.contentaccessstreaming+xml":{"source":"iana","compressible":true},"application/vnd.oipf.cspg-hexbinary":{"source":"iana"},"application/vnd.oipf.dae.svg+xml":{"source":"iana","compressible":true},"application/vnd.oipf.dae.xhtml+xml":{"source":"iana","compressible":true},"application/vnd.oipf.mippvcontrolmessage+xml":{"source":"iana","compressible":true},"application/vnd.oipf.pae.gem":{"source":"iana"},"application/vnd.oipf.spdiscovery+xml":{"source":"iana","compressible":true},"application/vnd.oipf.spdlist+xml":{"source":"iana","compressible":true},"application/vnd.oipf.ueprofile+xml":{"source":"iana","compressible":true},"application/vnd.oipf.userprofile+xml":{"source":"iana","compressible":true},"application/vnd.olpc-sugar":{"source":"iana","extensions":["xo"]},"application/vnd.oma-scws-config":{"source":"iana"},"application/vnd.oma-scws-http-request":{"source":"iana"},"application/vnd.oma-scws-http-response":{"source":"iana"},"application/vnd.oma.bcast.associated-procedure-parameter+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.drm-trigger+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.imd+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.ltkm":{"source":"iana"},"application/vnd.oma.bcast.notification+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.provisioningtrigger":{"source":"iana"},"application/vnd.oma.bcast.sgboot":{"source":"iana"},"application/vnd.oma.bcast.sgdd+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.sgdu":{"source":"iana"},"application/vnd.oma.bcast.simple-symbol-container":{"source":"iana"},"application/vnd.oma.bcast.smartcard-trigger+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.sprov+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.stkm":{"source":"iana"},"application/vnd.oma.cab-address-book+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-feature-handler+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-pcc+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-subs-invite+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-user-prefs+xml":{"source":"iana","compressible":true},"application/vnd.oma.dcd":{"source":"iana"},"application/vnd.oma.dcdc":{"source":"iana"},"application/vnd.oma.dd2+xml":{"source":"iana","compressible":true,"extensions":["dd2"]},"application/vnd.oma.drm.risd+xml":{"source":"iana","compressible":true},"application/vnd.oma.group-usage-list+xml":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+json":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+tlv":{"source":"iana"},"application/vnd.oma.pal+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.detailed-progress-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.final-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.groups+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.invocation-descriptor+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.optimized-progress-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.push":{"source":"iana"},"application/vnd.oma.scidm.messages+xml":{"source":"iana","compressible":true},"application/vnd.oma.xcap-directory+xml":{"source":"iana","compressible":true},"application/vnd.omads-email+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omads-file+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omads-folder+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omaloc-supl-init":{"source":"iana"},"application/vnd.onepager":{"source":"iana"},"application/vnd.onepagertamp":{"source":"iana"},"application/vnd.onepagertamx":{"source":"iana"},"application/vnd.onepagertat":{"source":"iana"},"application/vnd.onepagertatp":{"source":"iana"},"application/vnd.onepagertatx":{"source":"iana"},"application/vnd.openblox.game+xml":{"source":"iana","compressible":true,"extensions":["obgx"]},"application/vnd.openblox.game-binary":{"source":"iana"},"application/vnd.openeye.oeb":{"source":"iana"},"application/vnd.openofficeorg.extension":{"source":"apache","extensions":["oxt"]},"application/vnd.openstreetmap.data+xml":{"source":"iana","compressible":true,"extensions":["osm"]},"application/vnd.openxmlformats-officedocument.custom-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.customxmlproperties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawing+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.chart+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.extended-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.presentation":{"source":"iana","compressible":false,"extensions":["pptx"]},"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.presprops+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slide":{"source":"iana","extensions":["sldx"]},"application/vnd.openxmlformats-officedocument.presentationml.slide+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slideshow":{"source":"iana","extensions":["ppsx"]},"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.tags+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.template":{"source":"iana","extensions":["potx"]},"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"source":"iana","compressible":false,"extensions":["xlsx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.template":{"source":"iana","extensions":["xltx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.theme+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.themeoverride+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.vmldrawing":{"source":"iana"},"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{"source":"iana","compressible":false,"extensions":["docx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.template":{"source":"iana","extensions":["dotx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.core-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.relationships+xml":{"source":"iana","compressible":true},"application/vnd.oracle.resource+json":{"source":"iana","compressible":true},"application/vnd.orange.indata":{"source":"iana"},"application/vnd.osa.netdeploy":{"source":"iana"},"application/vnd.osgeo.mapguide.package":{"source":"iana","extensions":["mgp"]},"application/vnd.osgi.bundle":{"source":"iana"},"application/vnd.osgi.dp":{"source":"iana","extensions":["dp"]},"application/vnd.osgi.subsystem":{"source":"iana","extensions":["esa"]},"application/vnd.otps.ct-kip+xml":{"source":"iana","compressible":true},"application/vnd.oxli.countgraph":{"source":"iana"},"application/vnd.pagerduty+json":{"source":"iana","compressible":true},"application/vnd.palm":{"source":"iana","extensions":["pdb","pqa","oprc"]},"application/vnd.panoply":{"source":"iana"},"application/vnd.paos.xml":{"source":"iana"},"application/vnd.patentdive":{"source":"iana"},"application/vnd.patientecommsdoc":{"source":"iana"},"application/vnd.pawaafile":{"source":"iana","extensions":["paw"]},"application/vnd.pcos":{"source":"iana"},"application/vnd.pg.format":{"source":"iana","extensions":["str"]},"application/vnd.pg.osasli":{"source":"iana","extensions":["ei6"]},"application/vnd.piaccess.application-licence":{"source":"iana"},"application/vnd.picsel":{"source":"iana","extensions":["efif"]},"application/vnd.pmi.widget":{"source":"iana","extensions":["wg"]},"application/vnd.poc.group-advertisement+xml":{"source":"iana","compressible":true},"application/vnd.pocketlearn":{"source":"iana","extensions":["plf"]},"application/vnd.powerbuilder6":{"source":"iana","extensions":["pbd"]},"application/vnd.powerbuilder6-s":{"source":"iana"},"application/vnd.powerbuilder7":{"source":"iana"},"application/vnd.powerbuilder7-s":{"source":"iana"},"application/vnd.powerbuilder75":{"source":"iana"},"application/vnd.powerbuilder75-s":{"source":"iana"},"application/vnd.preminet":{"source":"iana"},"application/vnd.previewsystems.box":{"source":"iana","extensions":["box"]},"application/vnd.proteus.magazine":{"source":"iana","extensions":["mgz"]},"application/vnd.psfs":{"source":"iana"},"application/vnd.publishare-delta-tree":{"source":"iana","extensions":["qps"]},"application/vnd.pvi.ptid1":{"source":"iana","extensions":["ptid"]},"application/vnd.pwg-multiplexed":{"source":"iana"},"application/vnd.pwg-xhtml-print+xml":{"source":"iana","compressible":true},"application/vnd.qualcomm.brew-app-res":{"source":"iana"},"application/vnd.quarantainenet":{"source":"iana"},"application/vnd.quark.quarkxpress":{"source":"iana","extensions":["qxd","qxt","qwd","qwt","qxl","qxb"]},"application/vnd.quobject-quoxdocument":{"source":"iana"},"application/vnd.radisys.moml+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-conf+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-conn+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-dialog+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-stream+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-conf+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-base+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-fax-detect+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-fax-sendrecv+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-group+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-speech+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-transform+xml":{"source":"iana","compressible":true},"application/vnd.rainstor.data":{"source":"iana"},"application/vnd.rapid":{"source":"iana"},"application/vnd.rar":{"source":"iana"},"application/vnd.realvnc.bed":{"source":"iana","extensions":["bed"]},"application/vnd.recordare.musicxml":{"source":"iana","extensions":["mxl"]},"application/vnd.recordare.musicxml+xml":{"source":"iana","compressible":true,"extensions":["musicxml"]},"application/vnd.renlearn.rlprint":{"source":"iana"},"application/vnd.restful+json":{"source":"iana","compressible":true},"application/vnd.rig.cryptonote":{"source":"iana","extensions":["cryptonote"]},"application/vnd.rim.cod":{"source":"apache","extensions":["cod"]},"application/vnd.rn-realmedia":{"source":"apache","extensions":["rm"]},"application/vnd.rn-realmedia-vbr":{"source":"apache","extensions":["rmvb"]},"application/vnd.route66.link66+xml":{"source":"iana","compressible":true,"extensions":["link66"]},"application/vnd.rs-274x":{"source":"iana"},"application/vnd.ruckus.download":{"source":"iana"},"application/vnd.s3sms":{"source":"iana"},"application/vnd.sailingtracker.track":{"source":"iana","extensions":["st"]},"application/vnd.sar":{"source":"iana"},"application/vnd.sbm.cid":{"source":"iana"},"application/vnd.sbm.mid2":{"source":"iana"},"application/vnd.scribus":{"source":"iana"},"application/vnd.sealed.3df":{"source":"iana"},"application/vnd.sealed.csf":{"source":"iana"},"application/vnd.sealed.doc":{"source":"iana"},"application/vnd.sealed.eml":{"source":"iana"},"application/vnd.sealed.mht":{"source":"iana"},"application/vnd.sealed.net":{"source":"iana"},"application/vnd.sealed.ppt":{"source":"iana"},"application/vnd.sealed.tiff":{"source":"iana"},"application/vnd.sealed.xls":{"source":"iana"},"application/vnd.sealedmedia.softseal.html":{"source":"iana"},"application/vnd.sealedmedia.softseal.pdf":{"source":"iana"},"application/vnd.seemail":{"source":"iana","extensions":["see"]},"application/vnd.sema":{"source":"iana","extensions":["sema"]},"application/vnd.semd":{"source":"iana","extensions":["semd"]},"application/vnd.semf":{"source":"iana","extensions":["semf"]},"application/vnd.shade-save-file":{"source":"iana"},"application/vnd.shana.informed.formdata":{"source":"iana","extensions":["ifm"]},"application/vnd.shana.informed.formtemplate":{"source":"iana","extensions":["itp"]},"application/vnd.shana.informed.interchange":{"source":"iana","extensions":["iif"]},"application/vnd.shana.informed.package":{"source":"iana","extensions":["ipk"]},"application/vnd.shootproof+json":{"source":"iana","compressible":true},"application/vnd.shopkick+json":{"source":"iana","compressible":true},"application/vnd.shp":{"source":"iana"},"application/vnd.shx":{"source":"iana"},"application/vnd.sigrok.session":{"source":"iana"},"application/vnd.simtech-mindmapper":{"source":"iana","extensions":["twd","twds"]},"application/vnd.siren+json":{"source":"iana","compressible":true},"application/vnd.smaf":{"source":"iana","extensions":["mmf"]},"application/vnd.smart.notebook":{"source":"iana"},"application/vnd.smart.teacher":{"source":"iana","extensions":["teacher"]},"application/vnd.snesdev-page-table":{"source":"iana"},"application/vnd.software602.filler.form+xml":{"source":"iana","compressible":true,"extensions":["fo"]},"application/vnd.software602.filler.form-xml-zip":{"source":"iana"},"application/vnd.solent.sdkm+xml":{"source":"iana","compressible":true,"extensions":["sdkm","sdkd"]},"application/vnd.spotfire.dxp":{"source":"iana","extensions":["dxp"]},"application/vnd.spotfire.sfs":{"source":"iana","extensions":["sfs"]},"application/vnd.sqlite3":{"source":"iana"},"application/vnd.sss-cod":{"source":"iana"},"application/vnd.sss-dtf":{"source":"iana"},"application/vnd.sss-ntf":{"source":"iana"},"application/vnd.stardivision.calc":{"source":"apache","extensions":["sdc"]},"application/vnd.stardivision.draw":{"source":"apache","extensions":["sda"]},"application/vnd.stardivision.impress":{"source":"apache","extensions":["sdd"]},"application/vnd.stardivision.math":{"source":"apache","extensions":["smf"]},"application/vnd.stardivision.writer":{"source":"apache","extensions":["sdw","vor"]},"application/vnd.stardivision.writer-global":{"source":"apache","extensions":["sgl"]},"application/vnd.stepmania.package":{"source":"iana","extensions":["smzip"]},"application/vnd.stepmania.stepchart":{"source":"iana","extensions":["sm"]},"application/vnd.street-stream":{"source":"iana"},"application/vnd.sun.wadl+xml":{"source":"iana","compressible":true,"extensions":["wadl"]},"application/vnd.sun.xml.calc":{"source":"apache","extensions":["sxc"]},"application/vnd.sun.xml.calc.template":{"source":"apache","extensions":["stc"]},"application/vnd.sun.xml.draw":{"source":"apache","extensions":["sxd"]},"application/vnd.sun.xml.draw.template":{"source":"apache","extensions":["std"]},"application/vnd.sun.xml.impress":{"source":"apache","extensions":["sxi"]},"application/vnd.sun.xml.impress.template":{"source":"apache","extensions":["sti"]},"application/vnd.sun.xml.math":{"source":"apache","extensions":["sxm"]},"application/vnd.sun.xml.writer":{"source":"apache","extensions":["sxw"]},"application/vnd.sun.xml.writer.global":{"source":"apache","extensions":["sxg"]},"application/vnd.sun.xml.writer.template":{"source":"apache","extensions":["stw"]},"application/vnd.sus-calendar":{"source":"iana","extensions":["sus","susp"]},"application/vnd.svd":{"source":"iana","extensions":["svd"]},"application/vnd.swiftview-ics":{"source":"iana"},"application/vnd.symbian.install":{"source":"apache","extensions":["sis","sisx"]},"application/vnd.syncml+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xsm"]},"application/vnd.syncml.dm+wbxml":{"source":"iana","charset":"UTF-8","extensions":["bdm"]},"application/vnd.syncml.dm+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xdm"]},"application/vnd.syncml.dm.notification":{"source":"iana"},"application/vnd.syncml.dmddf+wbxml":{"source":"iana"},"application/vnd.syncml.dmddf+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["ddf"]},"application/vnd.syncml.dmtnds+wbxml":{"source":"iana"},"application/vnd.syncml.dmtnds+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.syncml.ds.notification":{"source":"iana"},"application/vnd.tableschema+json":{"source":"iana","compressible":true},"application/vnd.tao.intent-module-archive":{"source":"iana","extensions":["tao"]},"application/vnd.tcpdump.pcap":{"source":"iana","extensions":["pcap","cap","dmp"]},"application/vnd.think-cell.ppttc+json":{"source":"iana","compressible":true},"application/vnd.tmd.mediaflex.api+xml":{"source":"iana","compressible":true},"application/vnd.tml":{"source":"iana"},"application/vnd.tmobile-livetv":{"source":"iana","extensions":["tmo"]},"application/vnd.tri.onesource":{"source":"iana"},"application/vnd.trid.tpt":{"source":"iana","extensions":["tpt"]},"application/vnd.triscape.mxs":{"source":"iana","extensions":["mxs"]},"application/vnd.trueapp":{"source":"iana","extensions":["tra"]},"application/vnd.truedoc":{"source":"iana"},"application/vnd.ubisoft.webplayer":{"source":"iana"},"application/vnd.ufdl":{"source":"iana","extensions":["ufd","ufdl"]},"application/vnd.uiq.theme":{"source":"iana","extensions":["utz"]},"application/vnd.umajin":{"source":"iana","extensions":["umj"]},"application/vnd.unity":{"source":"iana","extensions":["unityweb"]},"application/vnd.uoml+xml":{"source":"iana","compressible":true,"extensions":["uoml"]},"application/vnd.uplanet.alert":{"source":"iana"},"application/vnd.uplanet.alert-wbxml":{"source":"iana"},"application/vnd.uplanet.bearer-choice":{"source":"iana"},"application/vnd.uplanet.bearer-choice-wbxml":{"source":"iana"},"application/vnd.uplanet.cacheop":{"source":"iana"},"application/vnd.uplanet.cacheop-wbxml":{"source":"iana"},"application/vnd.uplanet.channel":{"source":"iana"},"application/vnd.uplanet.channel-wbxml":{"source":"iana"},"application/vnd.uplanet.list":{"source":"iana"},"application/vnd.uplanet.list-wbxml":{"source":"iana"},"application/vnd.uplanet.listcmd":{"source":"iana"},"application/vnd.uplanet.listcmd-wbxml":{"source":"iana"},"application/vnd.uplanet.signal":{"source":"iana"},"application/vnd.uri-map":{"source":"iana"},"application/vnd.valve.source.material":{"source":"iana"},"application/vnd.vcx":{"source":"iana","extensions":["vcx"]},"application/vnd.vd-study":{"source":"iana"},"application/vnd.vectorworks":{"source":"iana"},"application/vnd.vel+json":{"source":"iana","compressible":true},"application/vnd.verimatrix.vcas":{"source":"iana"},"application/vnd.veryant.thin":{"source":"iana"},"application/vnd.ves.encrypted":{"source":"iana"},"application/vnd.vidsoft.vidconference":{"source":"iana"},"application/vnd.visio":{"source":"iana","extensions":["vsd","vst","vss","vsw"]},"application/vnd.visionary":{"source":"iana","extensions":["vis"]},"application/vnd.vividence.scriptfile":{"source":"iana"},"application/vnd.vsf":{"source":"iana","extensions":["vsf"]},"application/vnd.wap.sic":{"source":"iana"},"application/vnd.wap.slc":{"source":"iana"},"application/vnd.wap.wbxml":{"source":"iana","charset":"UTF-8","extensions":["wbxml"]},"application/vnd.wap.wmlc":{"source":"iana","extensions":["wmlc"]},"application/vnd.wap.wmlscriptc":{"source":"iana","extensions":["wmlsc"]},"application/vnd.webturbo":{"source":"iana","extensions":["wtb"]},"application/vnd.wfa.p2p":{"source":"iana"},"application/vnd.wfa.wsc":{"source":"iana"},"application/vnd.windows.devicepairing":{"source":"iana"},"application/vnd.wmc":{"source":"iana"},"application/vnd.wmf.bootstrap":{"source":"iana"},"application/vnd.wolfram.mathematica":{"source":"iana"},"application/vnd.wolfram.mathematica.package":{"source":"iana"},"application/vnd.wolfram.player":{"source":"iana","extensions":["nbp"]},"application/vnd.wordperfect":{"source":"iana","extensions":["wpd"]},"application/vnd.wqd":{"source":"iana","extensions":["wqd"]},"application/vnd.wrq-hp3000-labelled":{"source":"iana"},"application/vnd.wt.stf":{"source":"iana","extensions":["stf"]},"application/vnd.wv.csp+wbxml":{"source":"iana"},"application/vnd.wv.csp+xml":{"source":"iana","compressible":true},"application/vnd.wv.ssp+xml":{"source":"iana","compressible":true},"application/vnd.xacml+json":{"source":"iana","compressible":true},"application/vnd.xara":{"source":"iana","extensions":["xar"]},"application/vnd.xfdl":{"source":"iana","extensions":["xfdl"]},"application/vnd.xfdl.webform":{"source":"iana"},"application/vnd.xmi+xml":{"source":"iana","compressible":true},"application/vnd.xmpie.cpkg":{"source":"iana"},"application/vnd.xmpie.dpkg":{"source":"iana"},"application/vnd.xmpie.plan":{"source":"iana"},"application/vnd.xmpie.ppkg":{"source":"iana"},"application/vnd.xmpie.xlim":{"source":"iana"},"application/vnd.yamaha.hv-dic":{"source":"iana","extensions":["hvd"]},"application/vnd.yamaha.hv-script":{"source":"iana","extensions":["hvs"]},"application/vnd.yamaha.hv-voice":{"source":"iana","extensions":["hvp"]},"application/vnd.yamaha.openscoreformat":{"source":"iana","extensions":["osf"]},"application/vnd.yamaha.openscoreformat.osfpvg+xml":{"source":"iana","compressible":true,"extensions":["osfpvg"]},"application/vnd.yamaha.remote-setup":{"source":"iana"},"application/vnd.yamaha.smaf-audio":{"source":"iana","extensions":["saf"]},"application/vnd.yamaha.smaf-phrase":{"source":"iana","extensions":["spf"]},"application/vnd.yamaha.through-ngn":{"source":"iana"},"application/vnd.yamaha.tunnel-udpencap":{"source":"iana"},"application/vnd.yaoweme":{"source":"iana"},"application/vnd.yellowriver-custom-menu":{"source":"iana","extensions":["cmp"]},"application/vnd.youtube.yt":{"source":"iana"},"application/vnd.zul":{"source":"iana","extensions":["zir","zirz"]},"application/vnd.zzazz.deck+xml":{"source":"iana","compressible":true,"extensions":["zaz"]},"application/voicexml+xml":{"source":"iana","compressible":true,"extensions":["vxml"]},"application/voucher-cms+json":{"source":"iana","compressible":true},"application/vq-rtcpxr":{"source":"iana"},"application/wasm":{"compressible":true,"extensions":["wasm"]},"application/watcherinfo+xml":{"source":"iana","compressible":true},"application/webpush-options+json":{"source":"iana","compressible":true},"application/whoispp-query":{"source":"iana"},"application/whoispp-response":{"source":"iana"},"application/widget":{"source":"iana","extensions":["wgt"]},"application/winhlp":{"source":"apache","extensions":["hlp"]},"application/wita":{"source":"iana"},"application/wordperfect5.1":{"source":"iana"},"application/wsdl+xml":{"source":"iana","compressible":true,"extensions":["wsdl"]},"application/wspolicy+xml":{"source":"iana","compressible":true,"extensions":["wspolicy"]},"application/x-7z-compressed":{"source":"apache","compressible":false,"extensions":["7z"]},"application/x-abiword":{"source":"apache","extensions":["abw"]},"application/x-ace-compressed":{"source":"apache","extensions":["ace"]},"application/x-amf":{"source":"apache"},"application/x-apple-diskimage":{"source":"apache","extensions":["dmg"]},"application/x-arj":{"compressible":false,"extensions":["arj"]},"application/x-authorware-bin":{"source":"apache","extensions":["aab","x32","u32","vox"]},"application/x-authorware-map":{"source":"apache","extensions":["aam"]},"application/x-authorware-seg":{"source":"apache","extensions":["aas"]},"application/x-bcpio":{"source":"apache","extensions":["bcpio"]},"application/x-bdoc":{"compressible":false,"extensions":["bdoc"]},"application/x-bittorrent":{"source":"apache","extensions":["torrent"]},"application/x-blorb":{"source":"apache","extensions":["blb","blorb"]},"application/x-bzip":{"source":"apache","compressible":false,"extensions":["bz"]},"application/x-bzip2":{"source":"apache","compressible":false,"extensions":["bz2","boz"]},"application/x-cbr":{"source":"apache","extensions":["cbr","cba","cbt","cbz","cb7"]},"application/x-cdlink":{"source":"apache","extensions":["vcd"]},"application/x-cfs-compressed":{"source":"apache","extensions":["cfs"]},"application/x-chat":{"source":"apache","extensions":["chat"]},"application/x-chess-pgn":{"source":"apache","extensions":["pgn"]},"application/x-chrome-extension":{"extensions":["crx"]},"application/x-cocoa":{"source":"nginx","extensions":["cco"]},"application/x-compress":{"source":"apache"},"application/x-conference":{"source":"apache","extensions":["nsc"]},"application/x-cpio":{"source":"apache","extensions":["cpio"]},"application/x-csh":{"source":"apache","extensions":["csh"]},"application/x-deb":{"compressible":false},"application/x-debian-package":{"source":"apache","extensions":["deb","udeb"]},"application/x-dgc-compressed":{"source":"apache","extensions":["dgc"]},"application/x-director":{"source":"apache","extensions":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]},"application/x-doom":{"source":"apache","extensions":["wad"]},"application/x-dtbncx+xml":{"source":"apache","compressible":true,"extensions":["ncx"]},"application/x-dtbook+xml":{"source":"apache","compressible":true,"extensions":["dtb"]},"application/x-dtbresource+xml":{"source":"apache","compressible":true,"extensions":["res"]},"application/x-dvi":{"source":"apache","compressible":false,"extensions":["dvi"]},"application/x-envoy":{"source":"apache","extensions":["evy"]},"application/x-eva":{"source":"apache","extensions":["eva"]},"application/x-font-bdf":{"source":"apache","extensions":["bdf"]},"application/x-font-dos":{"source":"apache"},"application/x-font-framemaker":{"source":"apache"},"application/x-font-ghostscript":{"source":"apache","extensions":["gsf"]},"application/x-font-libgrx":{"source":"apache"},"application/x-font-linux-psf":{"source":"apache","extensions":["psf"]},"application/x-font-pcf":{"source":"apache","extensions":["pcf"]},"application/x-font-snf":{"source":"apache","extensions":["snf"]},"application/x-font-speedo":{"source":"apache"},"application/x-font-sunos-news":{"source":"apache"},"application/x-font-type1":{"source":"apache","extensions":["pfa","pfb","pfm","afm"]},"application/x-font-vfont":{"source":"apache"},"application/x-freearc":{"source":"apache","extensions":["arc"]},"application/x-futuresplash":{"source":"apache","extensions":["spl"]},"application/x-gca-compressed":{"source":"apache","extensions":["gca"]},"application/x-glulx":{"source":"apache","extensions":["ulx"]},"application/x-gnumeric":{"source":"apache","extensions":["gnumeric"]},"application/x-gramps-xml":{"source":"apache","extensions":["gramps"]},"application/x-gtar":{"source":"apache","extensions":["gtar"]},"application/x-gzip":{"source":"apache"},"application/x-hdf":{"source":"apache","extensions":["hdf"]},"application/x-httpd-php":{"compressible":true,"extensions":["php"]},"application/x-install-instructions":{"source":"apache","extensions":["install"]},"application/x-iso9660-image":{"source":"apache","extensions":["iso"]},"application/x-java-archive-diff":{"source":"nginx","extensions":["jardiff"]},"application/x-java-jnlp-file":{"source":"apache","compressible":false,"extensions":["jnlp"]},"application/x-javascript":{"compressible":true},"application/x-keepass2":{"extensions":["kdbx"]},"application/x-latex":{"source":"apache","compressible":false,"extensions":["latex"]},"application/x-lua-bytecode":{"extensions":["luac"]},"application/x-lzh-compressed":{"source":"apache","extensions":["lzh","lha"]},"application/x-makeself":{"source":"nginx","extensions":["run"]},"application/x-mie":{"source":"apache","extensions":["mie"]},"application/x-mobipocket-ebook":{"source":"apache","extensions":["prc","mobi"]},"application/x-mpegurl":{"compressible":false},"application/x-ms-application":{"source":"apache","extensions":["application"]},"application/x-ms-shortcut":{"source":"apache","extensions":["lnk"]},"application/x-ms-wmd":{"source":"apache","extensions":["wmd"]},"application/x-ms-wmz":{"source":"apache","extensions":["wmz"]},"application/x-ms-xbap":{"source":"apache","extensions":["xbap"]},"application/x-msaccess":{"source":"apache","extensions":["mdb"]},"application/x-msbinder":{"source":"apache","extensions":["obd"]},"application/x-mscardfile":{"source":"apache","extensions":["crd"]},"application/x-msclip":{"source":"apache","extensions":["clp"]},"application/x-msdos-program":{"extensions":["exe"]},"application/x-msdownload":{"source":"apache","extensions":["exe","dll","com","bat","msi"]},"application/x-msmediaview":{"source":"apache","extensions":["mvb","m13","m14"]},"application/x-msmetafile":{"source":"apache","extensions":["wmf","wmz","emf","emz"]},"application/x-msmoney":{"source":"apache","extensions":["mny"]},"application/x-mspublisher":{"source":"apache","extensions":["pub"]},"application/x-msschedule":{"source":"apache","extensions":["scd"]},"application/x-msterminal":{"source":"apache","extensions":["trm"]},"application/x-mswrite":{"source":"apache","extensions":["wri"]},"application/x-netcdf":{"source":"apache","extensions":["nc","cdf"]},"application/x-ns-proxy-autoconfig":{"compressible":true,"extensions":["pac"]},"application/x-nzb":{"source":"apache","extensions":["nzb"]},"application/x-perl":{"source":"nginx","extensions":["pl","pm"]},"application/x-pilot":{"source":"nginx","extensions":["prc","pdb"]},"application/x-pkcs12":{"source":"apache","compressible":false,"extensions":["p12","pfx"]},"application/x-pkcs7-certificates":{"source":"apache","extensions":["p7b","spc"]},"application/x-pkcs7-certreqresp":{"source":"apache","extensions":["p7r"]},"application/x-pki-message":{"source":"iana"},"application/x-rar-compressed":{"source":"apache","compressible":false,"extensions":["rar"]},"application/x-redhat-package-manager":{"source":"nginx","extensions":["rpm"]},"application/x-research-info-systems":{"source":"apache","extensions":["ris"]},"application/x-sea":{"source":"nginx","extensions":["sea"]},"application/x-sh":{"source":"apache","compressible":true,"extensions":["sh"]},"application/x-shar":{"source":"apache","extensions":["shar"]},"application/x-shockwave-flash":{"source":"apache","compressible":false,"extensions":["swf"]},"application/x-silverlight-app":{"source":"apache","extensions":["xap"]},"application/x-sql":{"source":"apache","extensions":["sql"]},"application/x-stuffit":{"source":"apache","compressible":false,"extensions":["sit"]},"application/x-stuffitx":{"source":"apache","extensions":["sitx"]},"application/x-subrip":{"source":"apache","extensions":["srt"]},"application/x-sv4cpio":{"source":"apache","extensions":["sv4cpio"]},"application/x-sv4crc":{"source":"apache","extensions":["sv4crc"]},"application/x-t3vm-image":{"source":"apache","extensions":["t3"]},"application/x-tads":{"source":"apache","extensions":["gam"]},"application/x-tar":{"source":"apache","compressible":true,"extensions":["tar"]},"application/x-tcl":{"source":"apache","extensions":["tcl","tk"]},"application/x-tex":{"source":"apache","extensions":["tex"]},"application/x-tex-tfm":{"source":"apache","extensions":["tfm"]},"application/x-texinfo":{"source":"apache","extensions":["texinfo","texi"]},"application/x-tgif":{"source":"apache","extensions":["obj"]},"application/x-ustar":{"source":"apache","extensions":["ustar"]},"application/x-virtualbox-hdd":{"compressible":true,"extensions":["hdd"]},"application/x-virtualbox-ova":{"compressible":true,"extensions":["ova"]},"application/x-virtualbox-ovf":{"compressible":true,"extensions":["ovf"]},"application/x-virtualbox-vbox":{"compressible":true,"extensions":["vbox"]},"application/x-virtualbox-vbox-extpack":{"compressible":false,"extensions":["vbox-extpack"]},"application/x-virtualbox-vdi":{"compressible":true,"extensions":["vdi"]},"application/x-virtualbox-vhd":{"compressible":true,"extensions":["vhd"]},"application/x-virtualbox-vmdk":{"compressible":true,"extensions":["vmdk"]},"application/x-wais-source":{"source":"apache","extensions":["src"]},"application/x-web-app-manifest+json":{"compressible":true,"extensions":["webapp"]},"application/x-www-form-urlencoded":{"source":"iana","compressible":true},"application/x-x509-ca-cert":{"source":"iana","extensions":["der","crt","pem"]},"application/x-x509-ca-ra-cert":{"source":"iana"},"application/x-x509-next-ca-cert":{"source":"iana"},"application/x-xfig":{"source":"apache","extensions":["fig"]},"application/x-xliff+xml":{"source":"apache","compressible":true,"extensions":["xlf"]},"application/x-xpinstall":{"source":"apache","compressible":false,"extensions":["xpi"]},"application/x-xz":{"source":"apache","extensions":["xz"]},"application/x-zmachine":{"source":"apache","extensions":["z1","z2","z3","z4","z5","z6","z7","z8"]},"application/x400-bp":{"source":"iana"},"application/xacml+xml":{"source":"iana","compressible":true},"application/xaml+xml":{"source":"apache","compressible":true,"extensions":["xaml"]},"application/xcap-att+xml":{"source":"iana","compressible":true,"extensions":["xav"]},"application/xcap-caps+xml":{"source":"iana","compressible":true,"extensions":["xca"]},"application/xcap-diff+xml":{"source":"iana","compressible":true,"extensions":["xdf"]},"application/xcap-el+xml":{"source":"iana","compressible":true,"extensions":["xel"]},"application/xcap-error+xml":{"source":"iana","compressible":true,"extensions":["xer"]},"application/xcap-ns+xml":{"source":"iana","compressible":true,"extensions":["xns"]},"application/xcon-conference-info+xml":{"source":"iana","compressible":true},"application/xcon-conference-info-diff+xml":{"source":"iana","compressible":true},"application/xenc+xml":{"source":"iana","compressible":true,"extensions":["xenc"]},"application/xhtml+xml":{"source":"iana","compressible":true,"extensions":["xhtml","xht"]},"application/xhtml-voice+xml":{"source":"apache","compressible":true},"application/xliff+xml":{"source":"iana","compressible":true,"extensions":["xlf"]},"application/xml":{"source":"iana","compressible":true,"extensions":["xml","xsl","xsd","rng"]},"application/xml-dtd":{"source":"iana","compressible":true,"extensions":["dtd"]},"application/xml-external-parsed-entity":{"source":"iana"},"application/xml-patch+xml":{"source":"iana","compressible":true},"application/xmpp+xml":{"source":"iana","compressible":true},"application/xop+xml":{"source":"iana","compressible":true,"extensions":["xop"]},"application/xproc+xml":{"source":"apache","compressible":true,"extensions":["xpl"]},"application/xslt+xml":{"source":"iana","compressible":true,"extensions":["xslt"]},"application/xspf+xml":{"source":"apache","compressible":true,"extensions":["xspf"]},"application/xv+xml":{"source":"iana","compressible":true,"extensions":["mxml","xhvml","xvml","xvm"]},"application/yang":{"source":"iana","extensions":["yang"]},"application/yang-data+json":{"source":"iana","compressible":true},"application/yang-data+xml":{"source":"iana","compressible":true},"application/yang-patch+json":{"source":"iana","compressible":true},"application/yang-patch+xml":{"source":"iana","compressible":true},"application/yin+xml":{"source":"iana","compressible":true,"extensions":["yin"]},"application/zip":{"source":"iana","compressible":false,"extensions":["zip"]},"application/zlib":{"source":"iana"},"application/zstd":{"source":"iana"},"audio/1d-interleaved-parityfec":{"source":"iana"},"audio/32kadpcm":{"source":"iana"},"audio/3gpp":{"source":"iana","compressible":false,"extensions":["3gpp"]},"audio/3gpp2":{"source":"iana"},"audio/aac":{"source":"iana"},"audio/ac3":{"source":"iana"},"audio/adpcm":{"source":"apache","extensions":["adp"]},"audio/amr":{"source":"iana"},"audio/amr-wb":{"source":"iana"},"audio/amr-wb+":{"source":"iana"},"audio/aptx":{"source":"iana"},"audio/asc":{"source":"iana"},"audio/atrac-advanced-lossless":{"source":"iana"},"audio/atrac-x":{"source":"iana"},"audio/atrac3":{"source":"iana"},"audio/basic":{"source":"iana","compressible":false,"extensions":["au","snd"]},"audio/bv16":{"source":"iana"},"audio/bv32":{"source":"iana"},"audio/clearmode":{"source":"iana"},"audio/cn":{"source":"iana"},"audio/dat12":{"source":"iana"},"audio/dls":{"source":"iana"},"audio/dsr-es201108":{"source":"iana"},"audio/dsr-es202050":{"source":"iana"},"audio/dsr-es202211":{"source":"iana"},"audio/dsr-es202212":{"source":"iana"},"audio/dv":{"source":"iana"},"audio/dvi4":{"source":"iana"},"audio/eac3":{"source":"iana"},"audio/encaprtp":{"source":"iana"},"audio/evrc":{"source":"iana"},"audio/evrc-qcp":{"source":"iana"},"audio/evrc0":{"source":"iana"},"audio/evrc1":{"source":"iana"},"audio/evrcb":{"source":"iana"},"audio/evrcb0":{"source":"iana"},"audio/evrcb1":{"source":"iana"},"audio/evrcnw":{"source":"iana"},"audio/evrcnw0":{"source":"iana"},"audio/evrcnw1":{"source":"iana"},"audio/evrcwb":{"source":"iana"},"audio/evrcwb0":{"source":"iana"},"audio/evrcwb1":{"source":"iana"},"audio/evs":{"source":"iana"},"audio/flexfec":{"source":"iana"},"audio/fwdred":{"source":"iana"},"audio/g711-0":{"source":"iana"},"audio/g719":{"source":"iana"},"audio/g722":{"source":"iana"},"audio/g7221":{"source":"iana"},"audio/g723":{"source":"iana"},"audio/g726-16":{"source":"iana"},"audio/g726-24":{"source":"iana"},"audio/g726-32":{"source":"iana"},"audio/g726-40":{"source":"iana"},"audio/g728":{"source":"iana"},"audio/g729":{"source":"iana"},"audio/g7291":{"source":"iana"},"audio/g729d":{"source":"iana"},"audio/g729e":{"source":"iana"},"audio/gsm":{"source":"iana"},"audio/gsm-efr":{"source":"iana"},"audio/gsm-hr-08":{"source":"iana"},"audio/ilbc":{"source":"iana"},"audio/ip-mr_v2.5":{"source":"iana"},"audio/isac":{"source":"apache"},"audio/l16":{"source":"iana"},"audio/l20":{"source":"iana"},"audio/l24":{"source":"iana","compressible":false},"audio/l8":{"source":"iana"},"audio/lpc":{"source":"iana"},"audio/melp":{"source":"iana"},"audio/melp1200":{"source":"iana"},"audio/melp2400":{"source":"iana"},"audio/melp600":{"source":"iana"},"audio/mhas":{"source":"iana"},"audio/midi":{"source":"apache","extensions":["mid","midi","kar","rmi"]},"audio/mobile-xmf":{"source":"iana","extensions":["mxmf"]},"audio/mp3":{"compressible":false,"extensions":["mp3"]},"audio/mp4":{"source":"iana","compressible":false,"extensions":["m4a","mp4a"]},"audio/mp4a-latm":{"source":"iana"},"audio/mpa":{"source":"iana"},"audio/mpa-robust":{"source":"iana"},"audio/mpeg":{"source":"iana","compressible":false,"extensions":["mpga","mp2","mp2a","mp3","m2a","m3a"]},"audio/mpeg4-generic":{"source":"iana"},"audio/musepack":{"source":"apache"},"audio/ogg":{"source":"iana","compressible":false,"extensions":["oga","ogg","spx"]},"audio/opus":{"source":"iana"},"audio/parityfec":{"source":"iana"},"audio/pcma":{"source":"iana"},"audio/pcma-wb":{"source":"iana"},"audio/pcmu":{"source":"iana"},"audio/pcmu-wb":{"source":"iana"},"audio/prs.sid":{"source":"iana"},"audio/qcelp":{"source":"iana"},"audio/raptorfec":{"source":"iana"},"audio/red":{"source":"iana"},"audio/rtp-enc-aescm128":{"source":"iana"},"audio/rtp-midi":{"source":"iana"},"audio/rtploopback":{"source":"iana"},"audio/rtx":{"source":"iana"},"audio/s3m":{"source":"apache","extensions":["s3m"]},"audio/silk":{"source":"apache","extensions":["sil"]},"audio/smv":{"source":"iana"},"audio/smv-qcp":{"source":"iana"},"audio/smv0":{"source":"iana"},"audio/sp-midi":{"source":"iana"},"audio/speex":{"source":"iana"},"audio/t140c":{"source":"iana"},"audio/t38":{"source":"iana"},"audio/telephone-event":{"source":"iana"},"audio/tetra_acelp":{"source":"iana"},"audio/tetra_acelp_bb":{"source":"iana"},"audio/tone":{"source":"iana"},"audio/uemclip":{"source":"iana"},"audio/ulpfec":{"source":"iana"},"audio/usac":{"source":"iana"},"audio/vdvi":{"source":"iana"},"audio/vmr-wb":{"source":"iana"},"audio/vnd.3gpp.iufp":{"source":"iana"},"audio/vnd.4sb":{"source":"iana"},"audio/vnd.audiokoz":{"source":"iana"},"audio/vnd.celp":{"source":"iana"},"audio/vnd.cisco.nse":{"source":"iana"},"audio/vnd.cmles.radio-events":{"source":"iana"},"audio/vnd.cns.anp1":{"source":"iana"},"audio/vnd.cns.inf1":{"source":"iana"},"audio/vnd.dece.audio":{"source":"iana","extensions":["uva","uvva"]},"audio/vnd.digital-winds":{"source":"iana","extensions":["eol"]},"audio/vnd.dlna.adts":{"source":"iana"},"audio/vnd.dolby.heaac.1":{"source":"iana"},"audio/vnd.dolby.heaac.2":{"source":"iana"},"audio/vnd.dolby.mlp":{"source":"iana"},"audio/vnd.dolby.mps":{"source":"iana"},"audio/vnd.dolby.pl2":{"source":"iana"},"audio/vnd.dolby.pl2x":{"source":"iana"},"audio/vnd.dolby.pl2z":{"source":"iana"},"audio/vnd.dolby.pulse.1":{"source":"iana"},"audio/vnd.dra":{"source":"iana","extensions":["dra"]},"audio/vnd.dts":{"source":"iana","extensions":["dts"]},"audio/vnd.dts.hd":{"source":"iana","extensions":["dtshd"]},"audio/vnd.dts.uhd":{"source":"iana"},"audio/vnd.dvb.file":{"source":"iana"},"audio/vnd.everad.plj":{"source":"iana"},"audio/vnd.hns.audio":{"source":"iana"},"audio/vnd.lucent.voice":{"source":"iana","extensions":["lvp"]},"audio/vnd.ms-playready.media.pya":{"source":"iana","extensions":["pya"]},"audio/vnd.nokia.mobile-xmf":{"source":"iana"},"audio/vnd.nortel.vbk":{"source":"iana"},"audio/vnd.nuera.ecelp4800":{"source":"iana","extensions":["ecelp4800"]},"audio/vnd.nuera.ecelp7470":{"source":"iana","extensions":["ecelp7470"]},"audio/vnd.nuera.ecelp9600":{"source":"iana","extensions":["ecelp9600"]},"audio/vnd.octel.sbc":{"source":"iana"},"audio/vnd.presonus.multitrack":{"source":"iana"},"audio/vnd.qcelp":{"source":"iana"},"audio/vnd.rhetorex.32kadpcm":{"source":"iana"},"audio/vnd.rip":{"source":"iana","extensions":["rip"]},"audio/vnd.rn-realaudio":{"compressible":false},"audio/vnd.sealedmedia.softseal.mpeg":{"source":"iana"},"audio/vnd.vmx.cvsd":{"source":"iana"},"audio/vnd.wave":{"compressible":false},"audio/vorbis":{"source":"iana","compressible":false},"audio/vorbis-config":{"source":"iana"},"audio/wav":{"compressible":false,"extensions":["wav"]},"audio/wave":{"compressible":false,"extensions":["wav"]},"audio/webm":{"source":"apache","compressible":false,"extensions":["weba"]},"audio/x-aac":{"source":"apache","compressible":false,"extensions":["aac"]},"audio/x-aiff":{"source":"apache","extensions":["aif","aiff","aifc"]},"audio/x-caf":{"source":"apache","compressible":false,"extensions":["caf"]},"audio/x-flac":{"source":"apache","extensions":["flac"]},"audio/x-m4a":{"source":"nginx","extensions":["m4a"]},"audio/x-matroska":{"source":"apache","extensions":["mka"]},"audio/x-mpegurl":{"source":"apache","extensions":["m3u"]},"audio/x-ms-wax":{"source":"apache","extensions":["wax"]},"audio/x-ms-wma":{"source":"apache","extensions":["wma"]},"audio/x-pn-realaudio":{"source":"apache","extensions":["ram","ra"]},"audio/x-pn-realaudio-plugin":{"source":"apache","extensions":["rmp"]},"audio/x-realaudio":{"source":"nginx","extensions":["ra"]},"audio/x-tta":{"source":"apache"},"audio/x-wav":{"source":"apache","extensions":["wav"]},"audio/xm":{"source":"apache","extensions":["xm"]},"chemical/x-cdx":{"source":"apache","extensions":["cdx"]},"chemical/x-cif":{"source":"apache","extensions":["cif"]},"chemical/x-cmdf":{"source":"apache","extensions":["cmdf"]},"chemical/x-cml":{"source":"apache","extensions":["cml"]},"chemical/x-csml":{"source":"apache","extensions":["csml"]},"chemical/x-pdb":{"source":"apache"},"chemical/x-xyz":{"source":"apache","extensions":["xyz"]},"font/collection":{"source":"iana","extensions":["ttc"]},"font/otf":{"source":"iana","compressible":true,"extensions":["otf"]},"font/sfnt":{"source":"iana"},"font/ttf":{"source":"iana","compressible":true,"extensions":["ttf"]},"font/woff":{"source":"iana","extensions":["woff"]},"font/woff2":{"source":"iana","extensions":["woff2"]},"image/aces":{"source":"iana","extensions":["exr"]},"image/apng":{"compressible":false,"extensions":["apng"]},"image/avci":{"source":"iana"},"image/avcs":{"source":"iana"},"image/bmp":{"source":"iana","compressible":true,"extensions":["bmp"]},"image/cgm":{"source":"iana","extensions":["cgm"]},"image/dicom-rle":{"source":"iana","extensions":["drle"]},"image/emf":{"source":"iana","extensions":["emf"]},"image/fits":{"source":"iana","extensions":["fits"]},"image/g3fax":{"source":"iana","extensions":["g3"]},"image/gif":{"source":"iana","compressible":false,"extensions":["gif"]},"image/heic":{"source":"iana","extensions":["heic"]},"image/heic-sequence":{"source":"iana","extensions":["heics"]},"image/heif":{"source":"iana","extensions":["heif"]},"image/heif-sequence":{"source":"iana","extensions":["heifs"]},"image/hej2k":{"source":"iana","extensions":["hej2"]},"image/hsj2":{"source":"iana","extensions":["hsj2"]},"image/ief":{"source":"iana","extensions":["ief"]},"image/jls":{"source":"iana","extensions":["jls"]},"image/jp2":{"source":"iana","compressible":false,"extensions":["jp2","jpg2"]},"image/jpeg":{"source":"iana","compressible":false,"extensions":["jpeg","jpg","jpe"]},"image/jph":{"source":"iana","extensions":["jph"]},"image/jphc":{"source":"iana","extensions":["jhc"]},"image/jpm":{"source":"iana","compressible":false,"extensions":["jpm"]},"image/jpx":{"source":"iana","compressible":false,"extensions":["jpx","jpf"]},"image/jxr":{"source":"iana","extensions":["jxr"]},"image/jxra":{"source":"iana","extensions":["jxra"]},"image/jxrs":{"source":"iana","extensions":["jxrs"]},"image/jxs":{"source":"iana","extensions":["jxs"]},"image/jxsc":{"source":"iana","extensions":["jxsc"]},"image/jxsi":{"source":"iana","extensions":["jxsi"]},"image/jxss":{"source":"iana","extensions":["jxss"]},"image/ktx":{"source":"iana","extensions":["ktx"]},"image/naplps":{"source":"iana"},"image/pjpeg":{"compressible":false},"image/png":{"source":"iana","compressible":false,"extensions":["png"]},"image/prs.btif":{"source":"iana","extensions":["btif"]},"image/prs.pti":{"source":"iana","extensions":["pti"]},"image/pwg-raster":{"source":"iana"},"image/sgi":{"source":"apache","extensions":["sgi"]},"image/svg+xml":{"source":"iana","compressible":true,"extensions":["svg","svgz"]},"image/t38":{"source":"iana","extensions":["t38"]},"image/tiff":{"source":"iana","compressible":false,"extensions":["tif","tiff"]},"image/tiff-fx":{"source":"iana","extensions":["tfx"]},"image/vnd.adobe.photoshop":{"source":"iana","compressible":true,"extensions":["psd"]},"image/vnd.airzip.accelerator.azv":{"source":"iana","extensions":["azv"]},"image/vnd.cns.inf2":{"source":"iana"},"image/vnd.dece.graphic":{"source":"iana","extensions":["uvi","uvvi","uvg","uvvg"]},"image/vnd.djvu":{"source":"iana","extensions":["djvu","djv"]},"image/vnd.dvb.subtitle":{"source":"iana","extensions":["sub"]},"image/vnd.dwg":{"source":"iana","extensions":["dwg"]},"image/vnd.dxf":{"source":"iana","extensions":["dxf"]},"image/vnd.fastbidsheet":{"source":"iana","extensions":["fbs"]},"image/vnd.fpx":{"source":"iana","extensions":["fpx"]},"image/vnd.fst":{"source":"iana","extensions":["fst"]},"image/vnd.fujixerox.edmics-mmr":{"source":"iana","extensions":["mmr"]},"image/vnd.fujixerox.edmics-rlc":{"source":"iana","extensions":["rlc"]},"image/vnd.globalgraphics.pgb":{"source":"iana"},"image/vnd.microsoft.icon":{"source":"iana","extensions":["ico"]},"image/vnd.mix":{"source":"iana"},"image/vnd.mozilla.apng":{"source":"iana"},"image/vnd.ms-dds":{"extensions":["dds"]},"image/vnd.ms-modi":{"source":"iana","extensions":["mdi"]},"image/vnd.ms-photo":{"source":"apache","extensions":["wdp"]},"image/vnd.net-fpx":{"source":"iana","extensions":["npx"]},"image/vnd.radiance":{"source":"iana"},"image/vnd.sealed.png":{"source":"iana"},"image/vnd.sealedmedia.softseal.gif":{"source":"iana"},"image/vnd.sealedmedia.softseal.jpg":{"source":"iana"},"image/vnd.svf":{"source":"iana"},"image/vnd.tencent.tap":{"source":"iana","extensions":["tap"]},"image/vnd.valve.source.texture":{"source":"iana","extensions":["vtf"]},"image/vnd.wap.wbmp":{"source":"iana","extensions":["wbmp"]},"image/vnd.xiff":{"source":"iana","extensions":["xif"]},"image/vnd.zbrush.pcx":{"source":"iana","extensions":["pcx"]},"image/webp":{"source":"apache","extensions":["webp"]},"image/wmf":{"source":"iana","extensions":["wmf"]},"image/x-3ds":{"source":"apache","extensions":["3ds"]},"image/x-cmu-raster":{"source":"apache","extensions":["ras"]},"image/x-cmx":{"source":"apache","extensions":["cmx"]},"image/x-freehand":{"source":"apache","extensions":["fh","fhc","fh4","fh5","fh7"]},"image/x-icon":{"source":"apache","compressible":true,"extensions":["ico"]},"image/x-jng":{"source":"nginx","extensions":["jng"]},"image/x-mrsid-image":{"source":"apache","extensions":["sid"]},"image/x-ms-bmp":{"source":"nginx","compressible":true,"extensions":["bmp"]},"image/x-pcx":{"source":"apache","extensions":["pcx"]},"image/x-pict":{"source":"apache","extensions":["pic","pct"]},"image/x-portable-anymap":{"source":"apache","extensions":["pnm"]},"image/x-portable-bitmap":{"source":"apache","extensions":["pbm"]},"image/x-portable-graymap":{"source":"apache","extensions":["pgm"]},"image/x-portable-pixmap":{"source":"apache","extensions":["ppm"]},"image/x-rgb":{"source":"apache","extensions":["rgb"]},"image/x-tga":{"source":"apache","extensions":["tga"]},"image/x-xbitmap":{"source":"apache","extensions":["xbm"]},"image/x-xcf":{"compressible":false},"image/x-xpixmap":{"source":"apache","extensions":["xpm"]},"image/x-xwindowdump":{"source":"apache","extensions":["xwd"]},"message/cpim":{"source":"iana"},"message/delivery-status":{"source":"iana"},"message/disposition-notification":{"source":"iana","extensions":["disposition-notification"]},"message/external-body":{"source":"iana"},"message/feedback-report":{"source":"iana"},"message/global":{"source":"iana","extensions":["u8msg"]},"message/global-delivery-status":{"source":"iana","extensions":["u8dsn"]},"message/global-disposition-notification":{"source":"iana","extensions":["u8mdn"]},"message/global-headers":{"source":"iana","extensions":["u8hdr"]},"message/http":{"source":"iana","compressible":false},"message/imdn+xml":{"source":"iana","compressible":true},"message/news":{"source":"iana"},"message/partial":{"source":"iana","compressible":false},"message/rfc822":{"source":"iana","compressible":true,"extensions":["eml","mime"]},"message/s-http":{"source":"iana"},"message/sip":{"source":"iana"},"message/sipfrag":{"source":"iana"},"message/tracking-status":{"source":"iana"},"message/vnd.si.simp":{"source":"iana"},"message/vnd.wfa.wsc":{"source":"iana","extensions":["wsc"]},"model/3mf":{"source":"iana","extensions":["3mf"]},"model/gltf+json":{"source":"iana","compressible":true,"extensions":["gltf"]},"model/gltf-binary":{"source":"iana","compressible":true,"extensions":["glb"]},"model/iges":{"source":"iana","compressible":false,"extensions":["igs","iges"]},"model/mesh":{"source":"iana","compressible":false,"extensions":["msh","mesh","silo"]},"model/mtl":{"source":"iana","extensions":["mtl"]},"model/obj":{"source":"iana","extensions":["obj"]},"model/stl":{"source":"iana","extensions":["stl"]},"model/vnd.collada+xml":{"source":"iana","compressible":true,"extensions":["dae"]},"model/vnd.dwf":{"source":"iana","extensions":["dwf"]},"model/vnd.flatland.3dml":{"source":"iana"},"model/vnd.gdl":{"source":"iana","extensions":["gdl"]},"model/vnd.gs-gdl":{"source":"apache"},"model/vnd.gs.gdl":{"source":"iana"},"model/vnd.gtw":{"source":"iana","extensions":["gtw"]},"model/vnd.moml+xml":{"source":"iana","compressible":true},"model/vnd.mts":{"source":"iana","extensions":["mts"]},"model/vnd.opengex":{"source":"iana","extensions":["ogex"]},"model/vnd.parasolid.transmit.binary":{"source":"iana","extensions":["x_b"]},"model/vnd.parasolid.transmit.text":{"source":"iana","extensions":["x_t"]},"model/vnd.rosette.annotated-data-model":{"source":"iana"},"model/vnd.usdz+zip":{"source":"iana","compressible":false,"extensions":["usdz"]},"model/vnd.valve.source.compiled-map":{"source":"iana","extensions":["bsp"]},"model/vnd.vtu":{"source":"iana","extensions":["vtu"]},"model/vrml":{"source":"iana","compressible":false,"extensions":["wrl","vrml"]},"model/x3d+binary":{"source":"apache","compressible":false,"extensions":["x3db","x3dbz"]},"model/x3d+fastinfoset":{"source":"iana","extensions":["x3db"]},"model/x3d+vrml":{"source":"apache","compressible":false,"extensions":["x3dv","x3dvz"]},"model/x3d+xml":{"source":"iana","compressible":true,"extensions":["x3d","x3dz"]},"model/x3d-vrml":{"source":"iana","extensions":["x3dv"]},"multipart/alternative":{"source":"iana","compressible":false},"multipart/appledouble":{"source":"iana"},"multipart/byteranges":{"source":"iana"},"multipart/digest":{"source":"iana"},"multipart/encrypted":{"source":"iana","compressible":false},"multipart/form-data":{"source":"iana","compressible":false},"multipart/header-set":{"source":"iana"},"multipart/mixed":{"source":"iana"},"multipart/multilingual":{"source":"iana"},"multipart/parallel":{"source":"iana"},"multipart/related":{"source":"iana","compressible":false},"multipart/report":{"source":"iana"},"multipart/signed":{"source":"iana","compressible":false},"multipart/vnd.bint.med-plus":{"source":"iana"},"multipart/voice-message":{"source":"iana"},"multipart/x-mixed-replace":{"source":"iana"},"text/1d-interleaved-parityfec":{"source":"iana"},"text/cache-manifest":{"source":"iana","compressible":true,"extensions":["appcache","manifest"]},"text/calendar":{"source":"iana","extensions":["ics","ifb"]},"text/calender":{"compressible":true},"text/cmd":{"compressible":true},"text/coffeescript":{"extensions":["coffee","litcoffee"]},"text/css":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["css"]},"text/csv":{"source":"iana","compressible":true,"extensions":["csv"]},"text/csv-schema":{"source":"iana"},"text/directory":{"source":"iana"},"text/dns":{"source":"iana"},"text/ecmascript":{"source":"iana"},"text/encaprtp":{"source":"iana"},"text/enriched":{"source":"iana"},"text/flexfec":{"source":"iana"},"text/fwdred":{"source":"iana"},"text/grammar-ref-list":{"source":"iana"},"text/html":{"source":"iana","compressible":true,"extensions":["html","htm","shtml"]},"text/jade":{"extensions":["jade"]},"text/javascript":{"source":"iana","compressible":true},"text/jcr-cnd":{"source":"iana"},"text/jsx":{"compressible":true,"extensions":["jsx"]},"text/less":{"compressible":true,"extensions":["less"]},"text/markdown":{"source":"iana","compressible":true,"extensions":["markdown","md"]},"text/mathml":{"source":"nginx","extensions":["mml"]},"text/mdx":{"compressible":true,"extensions":["mdx"]},"text/mizar":{"source":"iana"},"text/n3":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["n3"]},"text/parameters":{"source":"iana","charset":"UTF-8"},"text/parityfec":{"source":"iana"},"text/plain":{"source":"iana","compressible":true,"extensions":["txt","text","conf","def","list","log","in","ini"]},"text/provenance-notation":{"source":"iana","charset":"UTF-8"},"text/prs.fallenstein.rst":{"source":"iana"},"text/prs.lines.tag":{"source":"iana","extensions":["dsc"]},"text/prs.prop.logic":{"source":"iana"},"text/raptorfec":{"source":"iana"},"text/red":{"source":"iana"},"text/rfc822-headers":{"source":"iana"},"text/richtext":{"source":"iana","compressible":true,"extensions":["rtx"]},"text/rtf":{"source":"iana","compressible":true,"extensions":["rtf"]},"text/rtp-enc-aescm128":{"source":"iana"},"text/rtploopback":{"source":"iana"},"text/rtx":{"source":"iana"},"text/sgml":{"source":"iana","extensions":["sgml","sgm"]},"text/shex":{"extensions":["shex"]},"text/slim":{"extensions":["slim","slm"]},"text/strings":{"source":"iana"},"text/stylus":{"extensions":["stylus","styl"]},"text/t140":{"source":"iana"},"text/tab-separated-values":{"source":"iana","compressible":true,"extensions":["tsv"]},"text/troff":{"source":"iana","extensions":["t","tr","roff","man","me","ms"]},"text/turtle":{"source":"iana","charset":"UTF-8","extensions":["ttl"]},"text/ulpfec":{"source":"iana"},"text/uri-list":{"source":"iana","compressible":true,"extensions":["uri","uris","urls"]},"text/vcard":{"source":"iana","compressible":true,"extensions":["vcard"]},"text/vnd.a":{"source":"iana"},"text/vnd.abc":{"source":"iana"},"text/vnd.ascii-art":{"source":"iana"},"text/vnd.curl":{"source":"iana","extensions":["curl"]},"text/vnd.curl.dcurl":{"source":"apache","extensions":["dcurl"]},"text/vnd.curl.mcurl":{"source":"apache","extensions":["mcurl"]},"text/vnd.curl.scurl":{"source":"apache","extensions":["scurl"]},"text/vnd.debian.copyright":{"source":"iana","charset":"UTF-8"},"text/vnd.dmclientscript":{"source":"iana"},"text/vnd.dvb.subtitle":{"source":"iana","extensions":["sub"]},"text/vnd.esmertec.theme-descriptor":{"source":"iana","charset":"UTF-8"},"text/vnd.ficlab.flt":{"source":"iana"},"text/vnd.fly":{"source":"iana","extensions":["fly"]},"text/vnd.fmi.flexstor":{"source":"iana","extensions":["flx"]},"text/vnd.gml":{"source":"iana"},"text/vnd.graphviz":{"source":"iana","extensions":["gv"]},"text/vnd.hgl":{"source":"iana"},"text/vnd.in3d.3dml":{"source":"iana","extensions":["3dml"]},"text/vnd.in3d.spot":{"source":"iana","extensions":["spot"]},"text/vnd.iptc.newsml":{"source":"iana"},"text/vnd.iptc.nitf":{"source":"iana"},"text/vnd.latex-z":{"source":"iana"},"text/vnd.motorola.reflex":{"source":"iana"},"text/vnd.ms-mediapackage":{"source":"iana"},"text/vnd.net2phone.commcenter.command":{"source":"iana"},"text/vnd.radisys.msml-basic-layout":{"source":"iana"},"text/vnd.senx.warpscript":{"source":"iana"},"text/vnd.si.uricatalogue":{"source":"iana"},"text/vnd.sosi":{"source":"iana"},"text/vnd.sun.j2me.app-descriptor":{"source":"iana","charset":"UTF-8","extensions":["jad"]},"text/vnd.trolltech.linguist":{"source":"iana","charset":"UTF-8"},"text/vnd.wap.si":{"source":"iana"},"text/vnd.wap.sl":{"source":"iana"},"text/vnd.wap.wml":{"source":"iana","extensions":["wml"]},"text/vnd.wap.wmlscript":{"source":"iana","extensions":["wmls"]},"text/vtt":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["vtt"]},"text/x-asm":{"source":"apache","extensions":["s","asm"]},"text/x-c":{"source":"apache","extensions":["c","cc","cxx","cpp","h","hh","dic"]},"text/x-component":{"source":"nginx","extensions":["htc"]},"text/x-fortran":{"source":"apache","extensions":["f","for","f77","f90"]},"text/x-gwt-rpc":{"compressible":true},"text/x-handlebars-template":{"extensions":["hbs"]},"text/x-java-source":{"source":"apache","extensions":["java"]},"text/x-jquery-tmpl":{"compressible":true},"text/x-lua":{"extensions":["lua"]},"text/x-markdown":{"compressible":true,"extensions":["mkd"]},"text/x-nfo":{"source":"apache","extensions":["nfo"]},"text/x-opml":{"source":"apache","extensions":["opml"]},"text/x-org":{"compressible":true,"extensions":["org"]},"text/x-pascal":{"source":"apache","extensions":["p","pas"]},"text/x-processing":{"compressible":true,"extensions":["pde"]},"text/x-sass":{"extensions":["sass"]},"text/x-scss":{"extensions":["scss"]},"text/x-setext":{"source":"apache","extensions":["etx"]},"text/x-sfv":{"source":"apache","extensions":["sfv"]},"text/x-suse-ymp":{"compressible":true,"extensions":["ymp"]},"text/x-uuencode":{"source":"apache","extensions":["uu"]},"text/x-vcalendar":{"source":"apache","extensions":["vcs"]},"text/x-vcard":{"source":"apache","extensions":["vcf"]},"text/xml":{"source":"iana","compressible":true,"extensions":["xml"]},"text/xml-external-parsed-entity":{"source":"iana"},"text/yaml":{"extensions":["yaml","yml"]},"video/1d-interleaved-parityfec":{"source":"iana"},"video/3gpp":{"source":"iana","extensions":["3gp","3gpp"]},"video/3gpp-tt":{"source":"iana"},"video/3gpp2":{"source":"iana","extensions":["3g2"]},"video/bmpeg":{"source":"iana"},"video/bt656":{"source":"iana"},"video/celb":{"source":"iana"},"video/dv":{"source":"iana"},"video/encaprtp":{"source":"iana"},"video/flexfec":{"source":"iana"},"video/h261":{"source":"iana","extensions":["h261"]},"video/h263":{"source":"iana","extensions":["h263"]},"video/h263-1998":{"source":"iana"},"video/h263-2000":{"source":"iana"},"video/h264":{"source":"iana","extensions":["h264"]},"video/h264-rcdo":{"source":"iana"},"video/h264-svc":{"source":"iana"},"video/h265":{"source":"iana"},"video/iso.segment":{"source":"iana"},"video/jpeg":{"source":"iana","extensions":["jpgv"]},"video/jpeg2000":{"source":"iana"},"video/jpm":{"source":"apache","extensions":["jpm","jpgm"]},"video/mj2":{"source":"iana","extensions":["mj2","mjp2"]},"video/mp1s":{"source":"iana"},"video/mp2p":{"source":"iana"},"video/mp2t":{"source":"iana","extensions":["ts"]},"video/mp4":{"source":"iana","compressible":false,"extensions":["mp4","mp4v","mpg4"]},"video/mp4v-es":{"source":"iana"},"video/mpeg":{"source":"iana","compressible":false,"extensions":["mpeg","mpg","mpe","m1v","m2v"]},"video/mpeg4-generic":{"source":"iana"},"video/mpv":{"source":"iana"},"video/nv":{"source":"iana"},"video/ogg":{"source":"iana","compressible":false,"extensions":["ogv"]},"video/parityfec":{"source":"iana"},"video/pointer":{"source":"iana"},"video/quicktime":{"source":"iana","compressible":false,"extensions":["qt","mov"]},"video/raptorfec":{"source":"iana"},"video/raw":{"source":"iana"},"video/rtp-enc-aescm128":{"source":"iana"},"video/rtploopback":{"source":"iana"},"video/rtx":{"source":"iana"},"video/smpte291":{"source":"iana"},"video/smpte292m":{"source":"iana"},"video/ulpfec":{"source":"iana"},"video/vc1":{"source":"iana"},"video/vc2":{"source":"iana"},"video/vnd.cctv":{"source":"iana"},"video/vnd.dece.hd":{"source":"iana","extensions":["uvh","uvvh"]},"video/vnd.dece.mobile":{"source":"iana","extensions":["uvm","uvvm"]},"video/vnd.dece.mp4":{"source":"iana"},"video/vnd.dece.pd":{"source":"iana","extensions":["uvp","uvvp"]},"video/vnd.dece.sd":{"source":"iana","extensions":["uvs","uvvs"]},"video/vnd.dece.video":{"source":"iana","extensions":["uvv","uvvv"]},"video/vnd.directv.mpeg":{"source":"iana"},"video/vnd.directv.mpeg-tts":{"source":"iana"},"video/vnd.dlna.mpeg-tts":{"source":"iana"},"video/vnd.dvb.file":{"source":"iana","extensions":["dvb"]},"video/vnd.fvt":{"source":"iana","extensions":["fvt"]},"video/vnd.hns.video":{"source":"iana"},"video/vnd.iptvforum.1dparityfec-1010":{"source":"iana"},"video/vnd.iptvforum.1dparityfec-2005":{"source":"iana"},"video/vnd.iptvforum.2dparityfec-1010":{"source":"iana"},"video/vnd.iptvforum.2dparityfec-2005":{"source":"iana"},"video/vnd.iptvforum.ttsavc":{"source":"iana"},"video/vnd.iptvforum.ttsmpeg2":{"source":"iana"},"video/vnd.motorola.video":{"source":"iana"},"video/vnd.motorola.videop":{"source":"iana"},"video/vnd.mpegurl":{"source":"iana","extensions":["mxu","m4u"]},"video/vnd.ms-playready.media.pyv":{"source":"iana","extensions":["pyv"]},"video/vnd.nokia.interleaved-multimedia":{"source":"iana"},"video/vnd.nokia.mp4vr":{"source":"iana"},"video/vnd.nokia.videovoip":{"source":"iana"},"video/vnd.objectvideo":{"source":"iana"},"video/vnd.radgamettools.bink":{"source":"iana"},"video/vnd.radgamettools.smacker":{"source":"iana"},"video/vnd.sealed.mpeg1":{"source":"iana"},"video/vnd.sealed.mpeg4":{"source":"iana"},"video/vnd.sealed.swf":{"source":"iana"},"video/vnd.sealedmedia.softseal.mov":{"source":"iana"},"video/vnd.uvvu.mp4":{"source":"iana","extensions":["uvu","uvvu"]},"video/vnd.vivo":{"source":"iana","extensions":["viv"]},"video/vnd.youtube.yt":{"source":"iana"},"video/vp8":{"source":"iana"},"video/webm":{"source":"apache","compressible":false,"extensions":["webm"]},"video/x-f4v":{"source":"apache","extensions":["f4v"]},"video/x-fli":{"source":"apache","extensions":["fli"]},"video/x-flv":{"source":"apache","compressible":false,"extensions":["flv"]},"video/x-m4v":{"source":"apache","extensions":["m4v"]},"video/x-matroska":{"source":"apache","compressible":false,"extensions":["mkv","mk3d","mks"]},"video/x-mng":{"source":"apache","extensions":["mng"]},"video/x-ms-asf":{"source":"apache","extensions":["asf","asx"]},"video/x-ms-vob":{"source":"apache","extensions":["vob"]},"video/x-ms-wm":{"source":"apache","extensions":["wm"]},"video/x-ms-wmv":{"source":"apache","compressible":false,"extensions":["wmv"]},"video/x-ms-wmx":{"source":"apache","extensions":["wmx"]},"video/x-ms-wvx":{"source":"apache","extensions":["wvx"]},"video/x-msvideo":{"source":"apache","extensions":["avi"]},"video/x-sgi-movie":{"source":"apache","extensions":["movie"]},"video/x-smv":{"source":"apache","extensions":["smv"]},"x-conference/x-cooltalk":{"source":"apache","extensions":["ice"]},"x-shader/x-fragment":{"compressible":true},"x-shader/x-vertex":{"compressible":true}}; +/***/ 5685: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -/***/ }), +var CombinedStream = __nccwpck_require__(3141); +var util = __nccwpck_require__(3837); +var path = __nccwpck_require__(1017); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var parseUrl = (__nccwpck_require__(7310).parse); +var fs = __nccwpck_require__(7147); +var mime = __nccwpck_require__(4991); +var asynckit = __nccwpck_require__(3922); +var populate = __nccwpck_require__(3061); -/***/ 125: -/***/ (function(module) { +// Public API +module.exports = FormData; -// API -module.exports = state; +// make it a Stream +util.inherits(FormData, CombinedStream); /** - * Creates initial state object - * for iteration over list + * Create readable "multipart/form-data" streams. + * Can be used to submit forms + * and file uploads to other web applications. * - * @param {array|object} list - list to iterate over - * @param {function|null} sortMethod - function to use for keys sort, - * or `null` to keep them as is - * @returns {object} - initial state object + * @constructor + * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream */ -function state(list, sortMethod) -{ - var isNamedList = !Array.isArray(list) - , initState = - { - index : 0, - keyedList: isNamedList || sortMethod ? Object.keys(list) : null, - jobs : {}, - results : isNamedList ? {} : [], - size : isNamedList ? Object.keys(list).length : list.length - } - ; - - if (sortMethod) - { - // sort array keys based on it's values - // sort object's keys just on own merit - initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) - { - return sortMethod(list[a], list[b]); - }); +function FormData(options) { + if (!(this instanceof FormData)) { + return new FormData(); } - return initState; + this._overheadLength = 0; + this._valueLength = 0; + this._valuesToMeasure = []; + + CombinedStream.call(this); + + options = options || {}; + for (var option in options) { + this[option] = options[option]; + } } +FormData.LINE_BREAK = '\r\n'; +FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; -/***/ }), +FormData.prototype.append = function(field, value, options) { -/***/ 128: -/***/ (function(module, __unusedexports, __webpack_require__) { + options = options || {}; -/*! - * mime-db - * Copyright(c) 2014 Jonathan Ong - * MIT Licensed - */ + // allow filename as single option + if (typeof options == 'string') { + options = {filename: options}; + } -/** - * Module exports. - */ + var append = CombinedStream.prototype.append.bind(this); -module.exports = __webpack_require__(118) + // all that streamy business can't handle numbers + if (typeof value == 'number') { + value = '' + value; + } + // https://github.com/felixge/node-form-data/issues/38 + if (util.isArray(value)) { + // Please convert your array into string + // the way web server expects it + this._error(new Error('Arrays are not supported.')); + return; + } -/***/ }), + var header = this._multiPartHeader(field, value, options); + var footer = this._multiPartFooter(); -/***/ 154: -/***/ (function(module) { + append(header); + append(value); + append(footer); -module.exports = defer; + // pass along options.knownLength + this._trackLength(header, value, options); +}; -/** - * Runs provided function on next iteration of the event loop - * - * @param {function} fn - function to run - */ -function defer(fn) -{ - var nextTick = typeof setImmediate == 'function' - ? setImmediate - : ( - typeof process == 'object' && typeof process.nextTick == 'function' - ? process.nextTick - : null - ); +FormData.prototype._trackLength = function(header, value, options) { + var valueLength = 0; - if (nextTick) - { - nextTick(fn); - } - else - { - setTimeout(fn, 0); + // used w/ getLengthSync(), when length is known. + // e.g. for streaming directly from a remote server, + // w/ a known file a size, and not wanting to wait for + // incoming file to finish to get its size. + if (options.knownLength != null) { + valueLength += +options.knownLength; + } else if (Buffer.isBuffer(value)) { + valueLength = value.length; + } else if (typeof value === 'string') { + valueLength = Buffer.byteLength(value); } -} + this._valueLength += valueLength; -/***/ }), + // @check why add CRLF? does this account for custom/multiple CRLFs? + this._overheadLength += + Buffer.byteLength(header) + + FormData.LINE_BREAK.length; + + // empty or either doesn't have path or not an http response + if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { + return; + } -/***/ 164: -/***/ (function(module, __unusedexports, __webpack_require__) { + // no need to bother with the length + if (!options.knownLength) { + this._valuesToMeasure.push(value); + } +}; -var Stream = __webpack_require__(413).Stream; -var util = __webpack_require__(669); +FormData.prototype._lengthRetriever = function(value, callback) { -module.exports = DelayedStream; -function DelayedStream() { - this.source = null; - this.dataSize = 0; - this.maxDataSize = 1024 * 1024; - this.pauseStream = true; + if (value.hasOwnProperty('fd')) { - this._maxDataSizeExceeded = false; - this._released = false; - this._bufferedEvents = []; -} -util.inherits(DelayedStream, Stream); + // take read range into a account + // `end` = Infinity –> read file till the end + // + // TODO: Looks like there is bug in Node fs.createReadStream + // it doesn't respect `end` options without `start` options + // Fix it when node fixes it. + // https://github.com/joyent/node/issues/7819 + if (value.end != undefined && value.end != Infinity && value.start != undefined) { + + // when end specified + // no need to calculate range + // inclusive, starts with 0 + callback(null, value.end + 1 - (value.start ? value.start : 0)); -DelayedStream.create = function(source, options) { - var delayedStream = new this(); + // not that fast snoopy + } else { + // still need to fetch file size from fs + fs.stat(value.path, function(err, stat) { - options = options || {}; - for (var option in options) { - delayedStream[option] = options[option]; - } + var fileSize; - delayedStream.source = source; + if (err) { + callback(err); + return; + } - var realEmit = source.emit; - source.emit = function() { - delayedStream._handleEmit(arguments); - return realEmit.apply(source, arguments); - }; + // update final size based on the range options + fileSize = stat.size - (value.start ? value.start : 0); + callback(null, fileSize); + }); + } - source.on('error', function() {}); - if (delayedStream.pauseStream) { - source.pause(); - } + // or http response + } else if (value.hasOwnProperty('httpVersion')) { + callback(null, +value.headers['content-length']); - return delayedStream; -}; + // or request stream http://github.com/mikeal/request + } else if (value.hasOwnProperty('httpModule')) { + // wait till response come back + value.on('response', function(response) { + value.pause(); + callback(null, +response.headers['content-length']); + }); + value.resume(); -Object.defineProperty(DelayedStream.prototype, 'readable', { - configurable: true, - enumerable: true, - get: function() { - return this.source.readable; + // something else + } else { + callback('Unknown stream'); } -}); - -DelayedStream.prototype.setEncoding = function() { - return this.source.setEncoding.apply(this.source, arguments); }; -DelayedStream.prototype.resume = function() { - if (!this._released) { - this.release(); +FormData.prototype._multiPartHeader = function(field, value, options) { + // custom header specified (as string)? + // it becomes responsible for boundary + // (e.g. to handle extra CRLFs on .NET servers) + if (typeof options.header == 'string') { + return options.header; } - this.source.resume(); -}; + var contentDisposition = this._getContentDisposition(value, options); + var contentType = this._getContentType(value, options); -DelayedStream.prototype.pause = function() { - this.source.pause(); -}; + var contents = ''; + var headers = { + // add custom disposition as third element or keep it two elements if not + 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), + // if no content type. allow it to be empty array + 'Content-Type': [].concat(contentType || []) + }; -DelayedStream.prototype.release = function() { - this._released = true; + // allow custom headers. + if (typeof options.header == 'object') { + populate(headers, options.header); + } - this._bufferedEvents.forEach(function(args) { - this.emit.apply(this, args); - }.bind(this)); - this._bufferedEvents = []; -}; + var header; + for (var prop in headers) { + if (!headers.hasOwnProperty(prop)) continue; + header = headers[prop]; -DelayedStream.prototype.pipe = function() { - var r = Stream.prototype.pipe.apply(this, arguments); - this.resume(); - return r; -}; + // skip nullish headers. + if (header == null) { + continue; + } -DelayedStream.prototype._handleEmit = function(args) { - if (this._released) { - this.emit.apply(this, args); - return; - } + // convert all headers to arrays. + if (!Array.isArray(header)) { + header = [header]; + } - if (args[0] === 'data') { - this.dataSize += args[1].length; - this._checkIfMaxDataSizeExceeded(); + // add non-empty headers. + if (header.length) { + contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; + } } - this._bufferedEvents.push(args); + return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; }; -DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { - if (this._maxDataSizeExceeded) { - return; +FormData.prototype._getContentDisposition = function(value, options) { + + var filename + , contentDisposition + ; + + if (typeof options.filepath === 'string') { + // custom filepath for relative paths + filename = path.normalize(options.filepath).replace(/\\/g, '/'); + } else if (options.filename || value.name || value.path) { + // custom filename take precedence + // formidable and the browser add a name property + // fs- and request- streams have path property + filename = path.basename(options.filename || value.name || value.path); + } else if (value.readable && value.hasOwnProperty('httpVersion')) { + // or try http response + filename = path.basename(value.client._httpMessage.path || ''); } - if (this.dataSize <= this.maxDataSize) { - return; + if (filename) { + contentDisposition = 'filename="' + filename + '"'; } - this._maxDataSizeExceeded = true; - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' - this.emit('error', new Error(message)); + return contentDisposition; }; +FormData.prototype._getContentType = function(value, options) { -/***/ }), - -/***/ 176: -/***/ (function(module, __unusedexports, __webpack_require__) { - -var serialOrdered = __webpack_require__(275); - -// Public API -module.exports = serial; + // use custom content-type above all + var contentType = options.contentType; -/** - * Runs iterator over provided array elements in series - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator - */ -function serial(list, iterator, callback) -{ - return serialOrdered(list, iterator, null, callback); -} + // or try `name` from formidable, browser + if (!contentType && value.name) { + contentType = mime.lookup(value.name); + } + // or try `path` from fs-, request- streams + if (!contentType && value.path) { + contentType = mime.lookup(value.path); + } -/***/ }), + // or if it's http-reponse + if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { + contentType = value.headers['content-type']; + } -/***/ 211: -/***/ (function(module) { + // or guess it from the filepath or filename + if (!contentType && (options.filepath || options.filename)) { + contentType = mime.lookup(options.filepath || options.filename); + } -module.exports = require("https"); + // fallback to the default content type if `value` is not simple value + if (!contentType && typeof value == 'object') { + contentType = FormData.DEFAULT_CONTENT_TYPE; + } -/***/ }), + return contentType; +}; -/***/ 213: -/***/ (function(module, __unusedexports, __webpack_require__) { +FormData.prototype._multiPartFooter = function() { + return function(next) { + var footer = FormData.LINE_BREAK; -var util = __webpack_require__(669); -var Stream = __webpack_require__(413).Stream; -var DelayedStream = __webpack_require__(164); + var lastPart = (this._streams.length === 0); + if (lastPart) { + footer += this._lastBoundary(); + } -module.exports = CombinedStream; -function CombinedStream() { - this.writable = false; - this.readable = true; - this.dataSize = 0; - this.maxDataSize = 2 * 1024 * 1024; - this.pauseStreams = true; + next(footer); + }.bind(this); +}; - this._released = false; - this._streams = []; - this._currentStream = null; - this._insideLoop = false; - this._pendingNext = false; -} -util.inherits(CombinedStream, Stream); +FormData.prototype._lastBoundary = function() { + return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; +}; -CombinedStream.create = function(options) { - var combinedStream = new this(); +FormData.prototype.getHeaders = function(userHeaders) { + var header; + var formHeaders = { + 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() + }; - options = options || {}; - for (var option in options) { - combinedStream[option] = options[option]; + for (header in userHeaders) { + if (userHeaders.hasOwnProperty(header)) { + formHeaders[header.toLowerCase()] = userHeaders[header]; + } } - return combinedStream; + return formHeaders; }; -CombinedStream.isStreamLike = function(stream) { - return (typeof stream !== 'function') - && (typeof stream !== 'string') - && (typeof stream !== 'boolean') - && (typeof stream !== 'number') - && (!Buffer.isBuffer(stream)); -}; +FormData.prototype.getBoundary = function() { + if (!this._boundary) { + this._generateBoundary(); + } -CombinedStream.prototype.append = function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); + return this._boundary; +}; - if (isStreamLike) { - if (!(stream instanceof DelayedStream)) { - var newStream = DelayedStream.create(stream, { - maxDataSize: Infinity, - pauseStream: this.pauseStreams, - }); - stream.on('data', this._checkDataSize.bind(this)); - stream = newStream; - } +FormData.prototype.getBuffer = function() { + var dataBuffer = new Buffer.alloc( 0 ); + var boundary = this.getBoundary(); - this._handleErrors(stream); + // Create the form content. Add Line breaks to the end of data. + for (var i = 0, len = this._streams.length; i < len; i++) { + if (typeof this._streams[i] !== 'function') { - if (this.pauseStreams) { - stream.pause(); + // Add content to the buffer. + if(Buffer.isBuffer(this._streams[i])) { + dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); + }else { + dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); + } + + // Add break after content. + if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { + dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); + } } } - this._streams.push(stream); - return this; + // Add the footer and return the Buffer object. + return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); }; -CombinedStream.prototype.pipe = function(dest, options) { - Stream.prototype.pipe.call(this, dest, options); - this.resume(); - return dest; +FormData.prototype._generateBoundary = function() { + // This generates a 50 character boundary similar to those used by Firefox. + // They are optimized for boyer-moore parsing. + var boundary = '--------------------------'; + for (var i = 0; i < 24; i++) { + boundary += Math.floor(Math.random() * 10).toString(16); + } + + this._boundary = boundary; }; -CombinedStream.prototype._getNext = function() { - this._currentStream = null; +// Note: getLengthSync DOESN'T calculate streams length +// As workaround one can calculate file size manually +// and add it as knownLength option +FormData.prototype.getLengthSync = function() { + var knownLength = this._overheadLength + this._valueLength; - if (this._insideLoop) { - this._pendingNext = true; - return; // defer call + // Don't get confused, there are 3 "internal" streams for each keyval pair + // so it basically checks if there is any value added to the form + if (this._streams.length) { + knownLength += this._lastBoundary().length; } - this._insideLoop = true; - try { - do { - this._pendingNext = false; - this._realGetNext(); - } while (this._pendingNext); - } finally { - this._insideLoop = false; + // https://github.com/form-data/form-data/issues/40 + if (!this.hasKnownLength()) { + // Some async length retrievers are present + // therefore synchronous length calculation is false. + // Please use getLength(callback) to get proper length + this._error(new Error('Cannot calculate proper length in synchronous way.')); } + + return knownLength; }; -CombinedStream.prototype._realGetNext = function() { - var stream = this._streams.shift(); +// Public API to check if length of added values is known +// https://github.com/form-data/form-data/issues/196 +// https://github.com/form-data/form-data/issues/262 +FormData.prototype.hasKnownLength = function() { + var hasKnownLength = true; + if (this._valuesToMeasure.length) { + hasKnownLength = false; + } - if (typeof stream == 'undefined') { - this.end(); - return; + return hasKnownLength; +}; + +FormData.prototype.getLength = function(cb) { + var knownLength = this._overheadLength + this._valueLength; + + if (this._streams.length) { + knownLength += this._lastBoundary().length; } - if (typeof stream !== 'function') { - this._pipeNext(stream); + if (!this._valuesToMeasure.length) { + process.nextTick(cb.bind(this, null, knownLength)); return; } - var getStream = stream; - getStream(function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('data', this._checkDataSize.bind(this)); - this._handleErrors(stream); + asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { + if (err) { + cb(err); + return; } - this._pipeNext(stream); - }.bind(this)); -}; + values.forEach(function(length) { + knownLength += length; + }); -CombinedStream.prototype._pipeNext = function(stream) { - this._currentStream = stream; + cb(null, knownLength); + }); +}; - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('end', this._getNext.bind(this)); - stream.pipe(this, {end: false}); - return; - } +FormData.prototype.submit = function(params, cb) { + var request + , options + , defaults = {method: 'post'} + ; - var value = stream; - this.write(value); - this._getNext(); -}; + // parse provided url if it's string + // or treat it as options object + if (typeof params == 'string') { -CombinedStream.prototype._handleErrors = function(stream) { - var self = this; - stream.on('error', function(err) { - self._emitError(err); - }); -}; + params = parseUrl(params); + options = populate({ + port: params.port, + path: params.pathname, + host: params.hostname, + protocol: params.protocol + }, defaults); -CombinedStream.prototype.write = function(data) { - this.emit('data', data); -}; + // use custom params + } else { -CombinedStream.prototype.pause = function() { - if (!this.pauseStreams) { - return; + options = populate(params, defaults); + // if no port provided use default one + if (!options.port) { + options.port = options.protocol == 'https:' ? 443 : 80; + } } - if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); - this.emit('pause'); -}; + // put that good code in getHeaders to some use + options.headers = this.getHeaders(params.headers); -CombinedStream.prototype.resume = function() { - if (!this._released) { - this._released = true; - this.writable = true; - this._getNext(); + // https if specified, fallback to http in any other case + if (options.protocol == 'https:') { + request = https.request(options); + } else { + request = http.request(options); } - if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); - this.emit('resume'); -}; + // get content length and fire away + this.getLength(function(err, length) { + if (err) { + this._error(err); + return; + } -CombinedStream.prototype.end = function() { - this._reset(); - this.emit('end'); -}; + // add content length + request.setHeader('Content-Length', length); -CombinedStream.prototype.destroy = function() { - this._reset(); - this.emit('close'); -}; + this.pipe(request); + if (cb) { + request.on('error', cb); + request.on('response', cb.bind(this, null)); + } + }.bind(this)); -CombinedStream.prototype._reset = function() { - this.writable = false; - this._streams = []; - this._currentStream = null; + return request; }; -CombinedStream.prototype._checkDataSize = function() { - this._updateDataSize(); - if (this.dataSize <= this.maxDataSize) { - return; +FormData.prototype._error = function(err) { + if (!this.error) { + this.error = err; + this.pause(); + this.emit('error', err); } +}; - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; - this._emitError(new Error(message)); +FormData.prototype.toString = function () { + return '[object FormData]'; }; -CombinedStream.prototype._updateDataSize = function() { - this.dataSize = 0; - var self = this; - this._streams.forEach(function(stream) { - if (!stream.dataSize) { - return; - } +/***/ }), - self.dataSize += stream.dataSize; +/***/ 3061: +/***/ ((module) => { + +// populates missing values +module.exports = function(dst, src) { + + Object.keys(src).forEach(function(prop) + { + dst[prop] = dst[prop] || src[prop]; }); - if (this._currentStream && this._currentStream.dataSize) { - this.dataSize += this._currentStream.dataSize; - } + return dst; }; -CombinedStream.prototype._emitError = function(err) { - this._reset(); - this.emit('error', err); -}; + +/***/ }), + +/***/ 3118: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +/*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015-2022 Douglas Christopher Wilson + * MIT Licensed + */ + +/** + * Module exports. + */ + +module.exports = __nccwpck_require__(9857) /***/ }), -/***/ 258: -/***/ (function(module, __unusedexports, __webpack_require__) { +/***/ 4991: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; +/*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ -var async = __webpack_require__(792) - , abort = __webpack_require__(762) - ; -// API -module.exports = iterate; /** - * Iterates over each job object - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {object} state - current job status - * @param {function} callback - invoked when all elements processed + * Module dependencies. + * @private */ -function iterate(list, iterator, state, callback) -{ - // store current index - var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; - state.jobs[key] = runJob(iterator, key, list[key], function(error, output) - { - // don't repeat yourself - // skip secondary callbacks - if (!(key in state.jobs)) - { - return; - } +var db = __nccwpck_require__(3118) +var extname = (__nccwpck_require__(1017).extname) - // clean up jobs - delete state.jobs[key]; +/** + * Module variables. + * @private + */ - if (error) - { - // don't process rest of the results - // stop still active jobs - // and reset the list - abort(state); - } - else - { - state.results[key] = output; - } +var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/ +var TEXT_TYPE_REGEXP = /^text\//i - // return salvaged results - callback(error, state.results); - }); -} +/** + * Module exports. + * @public + */ + +exports.charset = charset +exports.charsets = { lookup: charset } +exports.contentType = contentType +exports.extension = extension +exports.extensions = Object.create(null) +exports.lookup = lookup +exports.types = Object.create(null) + +// Populate the extensions/types maps +populateMaps(exports.extensions, exports.types) /** - * Runs iterator over provided job element + * Get the default charset for a MIME type. * - * @param {function} iterator - iterator to invoke - * @param {string|number} key - key/index of the element in the list of jobs - * @param {mixed} item - job description - * @param {function} callback - invoked after iterator is done with the job - * @returns {function|mixed} - job abort function or something else + * @param {string} type + * @return {boolean|string} */ -function runJob(iterator, key, item, callback) -{ - var aborter; - // allow shortcut if iterator expects only two arguments - if (iterator.length == 2) - { - aborter = iterator(item, async(callback)); - } - // otherwise go with full three arguments - else - { - aborter = iterator(item, key, async(callback)); +function charset (type) { + if (!type || typeof type !== 'string') { + return false } - return aborter; -} - - -/***/ }), + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type) + var mime = match && db[match[1].toLowerCase()] -/***/ 275: -/***/ (function(module, __unusedexports, __webpack_require__) { + if (mime && mime.charset) { + return mime.charset + } -var iterate = __webpack_require__(258) - , initState = __webpack_require__(125) - , terminator = __webpack_require__(2) - ; + // default text/* to utf-8 + if (match && TEXT_TYPE_REGEXP.test(match[1])) { + return 'UTF-8' + } -// Public API -module.exports = serialOrdered; -// sorting helpers -module.exports.ascending = ascending; -module.exports.descending = descending; + return false +} /** - * Runs iterator over provided sorted array elements in series + * Create a full Content-Type header given a MIME type or extension. * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} sortMethod - custom sort function - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator + * @param {string} str + * @return {boolean|string} */ -function serialOrdered(list, iterator, sortMethod, callback) -{ - var state = initState(list, sortMethod); - iterate(list, iterator, state, function iteratorHandler(error, result) - { - if (error) - { - callback(error, result); - return; - } +function contentType (str) { + // TODO: should this even be in this module? + if (!str || typeof str !== 'string') { + return false + } - state.index++; + var mime = str.indexOf('/') === -1 + ? exports.lookup(str) + : str - // are we there yet? - if (state.index < (state['keyedList'] || list).length) - { - iterate(list, iterator, state, iteratorHandler); - return; - } + if (!mime) { + return false + } - // done here - callback(null, state.results); - }); + // TODO: use content-type or other module + if (mime.indexOf('charset') === -1) { + var charset = exports.charset(mime) + if (charset) mime += '; charset=' + charset.toLowerCase() + } - return terminator.bind(state, callback); + return mime } -/* - * -- Sort methods - */ - /** - * sort helper to sort array elements in ascending order + * Get the default extension for a MIME type. * - * @param {mixed} a - an item to compare - * @param {mixed} b - an item to compare - * @returns {number} - comparison result + * @param {string} type + * @return {boolean|string} */ -function ascending(a, b) -{ - return a < b ? -1 : a > b ? 1 : 0; + +function extension (type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type) + + // get extensions + var exts = match && exports.extensions[match[1].toLowerCase()] + + if (!exts || !exts.length) { + return false + } + + return exts[0] } /** - * sort helper to sort array elements in descending order + * Lookup the MIME type for a file path/extension. * - * @param {mixed} a - an item to compare - * @param {mixed} b - an item to compare - * @returns {number} - comparison result + * @param {string} path + * @return {boolean|string} */ -function descending(a, b) -{ - return -1 * ascending(a, b); -} +function lookup (path) { + if (!path || typeof path !== 'string') { + return false + } + + // get the extension ("ext" or ".ext" or full path) + var extension = extname('x.' + path) + .toLowerCase() + .substr(1) -/***/ }), + if (!extension) { + return false + } -/***/ 294: -/***/ (function(module, __unusedexports, __webpack_require__) { + return exports.types[extension] || false +} -module.exports = -{ - parallel : __webpack_require__(89), - serial : __webpack_require__(176), - serialOrdered : __webpack_require__(275) -}; +/** + * Populate the extensions and types maps. + * @private + */ +function populateMaps (extensions, types) { + // source preference (least -> most) + var preference = ['nginx', 'apache', undefined, 'iana'] -/***/ }), + Object.keys(db).forEach(function forEachMimeType (type) { + var mime = db[type] + var exts = mime.extensions -/***/ 413: -/***/ (function(module) { + if (!exts || !exts.length) { + return + } -module.exports = require("stream"); + // mime -> extensions + extensions[type] = exts -/***/ }), + // extension -> mime + for (var i = 0; i < exts.length; i++) { + var extension = exts[i] + + if (types[extension]) { + var from = preference.indexOf(db[types[extension]].source) + var to = preference.indexOf(mime.source) -/***/ 416: -/***/ (function(module, __unusedexports, __webpack_require__) { + if (types[extension] !== 'application/octet-stream' && + (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) { + // skip the remapping + continue + } + } -var CombinedStream = __webpack_require__(213); -var util = __webpack_require__(669); -var path = __webpack_require__(622); -var http = __webpack_require__(605); -var https = __webpack_require__(211); -var parseUrl = __webpack_require__(835).parse; -var fs = __webpack_require__(747); -var mime = __webpack_require__(769); -var asynckit = __webpack_require__(294); -var populate = __webpack_require__(70); + // set the extension -> mime + types[extension] = type + } + }) +} -// Public API -module.exports = FormData; -// make it a Stream -util.inherits(FormData, CombinedStream); +/***/ }), -/** - * Create readable "multipart/form-data" streams. - * Can be used to submit forms - * and file uploads to other web applications. - * - * @constructor - * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream - */ -function FormData(options) { - if (!(this instanceof FormData)) { - return new FormData(); - } +/***/ 9491: +/***/ ((module) => { - this._overheadLength = 0; - this._valueLength = 0; - this._valuesToMeasure = []; +"use strict"; +module.exports = require("assert"); - CombinedStream.call(this); +/***/ }), - options = options || {}; - for (var option in options) { - this[option] = options[option]; - } -} +/***/ 852: +/***/ ((module) => { -FormData.LINE_BREAK = '\r\n'; -FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; +"use strict"; +module.exports = require("async_hooks"); -FormData.prototype.append = function(field, value, options) { +/***/ }), - options = options || {}; +/***/ 4300: +/***/ ((module) => { - // allow filename as single option - if (typeof options == 'string') { - options = {filename: options}; - } +"use strict"; +module.exports = require("buffer"); - var append = CombinedStream.prototype.append.bind(this); +/***/ }), - // all that streamy business can't handle numbers - if (typeof value == 'number') { - value = '' + value; - } +/***/ 6206: +/***/ ((module) => { - // https://github.com/felixge/node-form-data/issues/38 - if (util.isArray(value)) { - // Please convert your array into string - // the way web server expects it - this._error(new Error('Arrays are not supported.')); - return; - } +"use strict"; +module.exports = require("console"); - var header = this._multiPartHeader(field, value, options); - var footer = this._multiPartFooter(); +/***/ }), - append(header); - append(value); - append(footer); +/***/ 6113: +/***/ ((module) => { - // pass along options.knownLength - this._trackLength(header, value, options); -}; +"use strict"; +module.exports = require("crypto"); -FormData.prototype._trackLength = function(header, value, options) { - var valueLength = 0; +/***/ }), - // used w/ getLengthSync(), when length is known. - // e.g. for streaming directly from a remote server, - // w/ a known file a size, and not wanting to wait for - // incoming file to finish to get its size. - if (options.knownLength != null) { - valueLength += +options.knownLength; - } else if (Buffer.isBuffer(value)) { - valueLength = value.length; - } else if (typeof value === 'string') { - valueLength = Buffer.byteLength(value); - } +/***/ 7643: +/***/ ((module) => { - this._valueLength += valueLength; +"use strict"; +module.exports = require("diagnostics_channel"); - // @check why add CRLF? does this account for custom/multiple CRLFs? - this._overheadLength += - Buffer.byteLength(header) + - FormData.LINE_BREAK.length; +/***/ }), - // empty or either doesn't have path or not an http response - if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { - return; - } +/***/ 2361: +/***/ ((module) => { - // no need to bother with the length - if (!options.knownLength) { - this._valuesToMeasure.push(value); - } -}; +"use strict"; +module.exports = require("events"); -FormData.prototype._lengthRetriever = function(value, callback) { +/***/ }), - if (value.hasOwnProperty('fd')) { +/***/ 7147: +/***/ ((module) => { - // take read range into a account - // `end` = Infinity –> read file till the end - // - // TODO: Looks like there is bug in Node fs.createReadStream - // it doesn't respect `end` options without `start` options - // Fix it when node fixes it. - // https://github.com/joyent/node/issues/7819 - if (value.end != undefined && value.end != Infinity && value.start != undefined) { +"use strict"; +module.exports = require("fs"); - // when end specified - // no need to calculate range - // inclusive, starts with 0 - callback(null, value.end + 1 - (value.start ? value.start : 0)); +/***/ }), - // not that fast snoopy - } else { - // still need to fetch file size from fs - fs.stat(value.path, function(err, stat) { +/***/ 3685: +/***/ ((module) => { - var fileSize; +"use strict"; +module.exports = require("http"); - if (err) { - callback(err); - return; - } +/***/ }), - // update final size based on the range options - fileSize = stat.size - (value.start ? value.start : 0); - callback(null, fileSize); - }); - } +/***/ 5158: +/***/ ((module) => { - // or http response - } else if (value.hasOwnProperty('httpVersion')) { - callback(null, +value.headers['content-length']); +"use strict"; +module.exports = require("http2"); - // or request stream http://github.com/mikeal/request - } else if (value.hasOwnProperty('httpModule')) { - // wait till response come back - value.on('response', function(response) { - value.pause(); - callback(null, +response.headers['content-length']); - }); - value.resume(); +/***/ }), - // something else - } else { - callback('Unknown stream'); - } -}; +/***/ 5687: +/***/ ((module) => { -FormData.prototype._multiPartHeader = function(field, value, options) { - // custom header specified (as string)? - // it becomes responsible for boundary - // (e.g. to handle extra CRLFs on .NET servers) - if (typeof options.header == 'string') { - return options.header; - } +"use strict"; +module.exports = require("https"); - var contentDisposition = this._getContentDisposition(value, options); - var contentType = this._getContentType(value, options); +/***/ }), - var contents = ''; - var headers = { - // add custom disposition as third element or keep it two elements if not - 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), - // if no content type. allow it to be empty array - 'Content-Type': [].concat(contentType || []) - }; +/***/ 1808: +/***/ ((module) => { - // allow custom headers. - if (typeof options.header == 'object') { - populate(headers, options.header); - } +"use strict"; +module.exports = require("net"); - var header; - for (var prop in headers) { - if (!headers.hasOwnProperty(prop)) continue; - header = headers[prop]; +/***/ }), - // skip nullish headers. - if (header == null) { - continue; - } +/***/ 5673: +/***/ ((module) => { - // convert all headers to arrays. - if (!Array.isArray(header)) { - header = [header]; - } +"use strict"; +module.exports = require("node:events"); - // add non-empty headers. - if (header.length) { - contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; - } - } +/***/ }), - return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; -}; +/***/ 4492: +/***/ ((module) => { -FormData.prototype._getContentDisposition = function(value, options) { +"use strict"; +module.exports = require("node:stream"); - var filename - , contentDisposition - ; +/***/ }), - if (typeof options.filepath === 'string') { - // custom filepath for relative paths - filename = path.normalize(options.filepath).replace(/\\/g, '/'); - } else if (options.filename || value.name || value.path) { - // custom filename take precedence - // formidable and the browser add a name property - // fs- and request- streams have path property - filename = path.basename(options.filename || value.name || value.path); - } else if (value.readable && value.hasOwnProperty('httpVersion')) { - // or try http response - filename = path.basename(value.client._httpMessage.path || ''); - } +/***/ 7261: +/***/ ((module) => { - if (filename) { - contentDisposition = 'filename="' + filename + '"'; - } +"use strict"; +module.exports = require("node:util"); - return contentDisposition; -}; +/***/ }), -FormData.prototype._getContentType = function(value, options) { +/***/ 2037: +/***/ ((module) => { - // use custom content-type above all - var contentType = options.contentType; +"use strict"; +module.exports = require("os"); - // or try `name` from formidable, browser - if (!contentType && value.name) { - contentType = mime.lookup(value.name); - } +/***/ }), - // or try `path` from fs-, request- streams - if (!contentType && value.path) { - contentType = mime.lookup(value.path); - } +/***/ 1017: +/***/ ((module) => { - // or if it's http-reponse - if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { - contentType = value.headers['content-type']; - } +"use strict"; +module.exports = require("path"); - // or guess it from the filepath or filename - if (!contentType && (options.filepath || options.filename)) { - contentType = mime.lookup(options.filepath || options.filename); - } +/***/ }), - // fallback to the default content type if `value` is not simple value - if (!contentType && typeof value == 'object') { - contentType = FormData.DEFAULT_CONTENT_TYPE; - } +/***/ 4074: +/***/ ((module) => { - return contentType; -}; +"use strict"; +module.exports = require("perf_hooks"); -FormData.prototype._multiPartFooter = function() { - return function(next) { - var footer = FormData.LINE_BREAK; +/***/ }), - var lastPart = (this._streams.length === 0); - if (lastPart) { - footer += this._lastBoundary(); - } +/***/ 3477: +/***/ ((module) => { - next(footer); - }.bind(this); -}; +"use strict"; +module.exports = require("querystring"); -FormData.prototype._lastBoundary = function() { - return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; -}; +/***/ }), -FormData.prototype.getHeaders = function(userHeaders) { - var header; - var formHeaders = { - 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() - }; +/***/ 2781: +/***/ ((module) => { - for (header in userHeaders) { - if (userHeaders.hasOwnProperty(header)) { - formHeaders[header.toLowerCase()] = userHeaders[header]; - } - } +"use strict"; +module.exports = require("stream"); - return formHeaders; -}; +/***/ }), -FormData.prototype.getBoundary = function() { - if (!this._boundary) { - this._generateBoundary(); - } +/***/ 5356: +/***/ ((module) => { - return this._boundary; -}; +"use strict"; +module.exports = require("stream/web"); -FormData.prototype.getBuffer = function() { - var dataBuffer = new Buffer.alloc( 0 ); - var boundary = this.getBoundary(); +/***/ }), - // Create the form content. Add Line breaks to the end of data. - for (var i = 0, len = this._streams.length; i < len; i++) { - if (typeof this._streams[i] !== 'function') { +/***/ 1576: +/***/ ((module) => { - // Add content to the buffer. - if(Buffer.isBuffer(this._streams[i])) { - dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); - }else { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); - } +"use strict"; +module.exports = require("string_decoder"); - // Add break after content. - if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); - } - } - } +/***/ }), - // Add the footer and return the Buffer object. - return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); -}; +/***/ 4404: +/***/ ((module) => { -FormData.prototype._generateBoundary = function() { - // This generates a 50 character boundary similar to those used by Firefox. - // They are optimized for boyer-moore parsing. - var boundary = '--------------------------'; - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16); - } +"use strict"; +module.exports = require("tls"); - this._boundary = boundary; -}; +/***/ }), -// Note: getLengthSync DOESN'T calculate streams length -// As workaround one can calculate file size manually -// and add it as knownLength option -FormData.prototype.getLengthSync = function() { - var knownLength = this._overheadLength + this._valueLength; +/***/ 7310: +/***/ ((module) => { - // Don't get confused, there are 3 "internal" streams for each keyval pair - // so it basically checks if there is any value added to the form - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } +"use strict"; +module.exports = require("url"); - // https://github.com/form-data/form-data/issues/40 - if (!this.hasKnownLength()) { - // Some async length retrievers are present - // therefore synchronous length calculation is false. - // Please use getLength(callback) to get proper length - this._error(new Error('Cannot calculate proper length in synchronous way.')); - } +/***/ }), - return knownLength; -}; +/***/ 3837: +/***/ ((module) => { -// Public API to check if length of added values is known -// https://github.com/form-data/form-data/issues/196 -// https://github.com/form-data/form-data/issues/262 -FormData.prototype.hasKnownLength = function() { - var hasKnownLength = true; +"use strict"; +module.exports = require("util"); - if (this._valuesToMeasure.length) { - hasKnownLength = false; - } +/***/ }), - return hasKnownLength; -}; +/***/ 9830: +/***/ ((module) => { -FormData.prototype.getLength = function(cb) { - var knownLength = this._overheadLength + this._valueLength; +"use strict"; +module.exports = require("util/types"); - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } +/***/ }), - if (!this._valuesToMeasure.length) { - process.nextTick(cb.bind(this, null, knownLength)); - return; - } +/***/ 1267: +/***/ ((module) => { - asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { - if (err) { - cb(err); - return; - } +"use strict"; +module.exports = require("worker_threads"); - values.forEach(function(length) { - knownLength += length; - }); +/***/ }), - cb(null, knownLength); - }); -}; +/***/ 9796: +/***/ ((module) => { -FormData.prototype.submit = function(params, cb) { - var request - , options - , defaults = {method: 'post'} - ; +"use strict"; +module.exports = require("zlib"); - // parse provided url if it's string - // or treat it as options object - if (typeof params == 'string') { +/***/ }), - params = parseUrl(params); - options = populate({ - port: params.port, - path: params.pathname, - host: params.hostname, - protocol: params.protocol - }, defaults); +/***/ 2960: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // use custom params - } else { +"use strict"; - options = populate(params, defaults); - // if no port provided use default one - if (!options.port) { - options.port = options.protocol == 'https:' ? 443 : 80; - } - } - // put that good code in getHeaders to some use - options.headers = this.getHeaders(params.headers); +const WritableStream = (__nccwpck_require__(4492).Writable) +const inherits = (__nccwpck_require__(7261).inherits) - // https if specified, fallback to http in any other case - if (options.protocol == 'https:') { - request = https.request(options); - } else { - request = http.request(options); - } +const StreamSearch = __nccwpck_require__(1142) - // get content length and fire away - this.getLength(function(err, length) { - if (err) { - this._error(err); - return; - } +const PartStream = __nccwpck_require__(1620) +const HeaderParser = __nccwpck_require__(2032) - // add content length - request.setHeader('Content-Length', length); +const DASH = 45 +const B_ONEDASH = Buffer.from('-') +const B_CRLF = Buffer.from('\r\n') +const EMPTY_FN = function () {} - this.pipe(request); - if (cb) { - request.on('error', cb); - request.on('response', cb.bind(this, null)); - } - }.bind(this)); +function Dicer (cfg) { + if (!(this instanceof Dicer)) { return new Dicer(cfg) } + WritableStream.call(this, cfg) - return request; -}; + if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string')) { throw new TypeError('Boundary required') } -FormData.prototype._error = function(err) { - if (!this.error) { - this.error = err; - this.pause(); - this.emit('error', err); - } -}; + if (typeof cfg.boundary === 'string') { this.setBoundary(cfg.boundary) } else { this._bparser = undefined } -FormData.prototype.toString = function () { - return '[object FormData]'; -}; + this._headerFirst = cfg.headerFirst + this._dashes = 0 + this._parts = 0 + this._finished = false + this._realFinish = false + this._isPreamble = true + this._justMatched = false + this._firstWrite = true + this._inHeader = true + this._part = undefined + this._cb = undefined + this._ignoreData = false + this._partOpts = { highWaterMark: cfg.partHwm } + this._pause = false -/***/ }), + const self = this + this._hparser = new HeaderParser(cfg) + this._hparser.on('header', function (header) { + self._inHeader = false + self._part.emit('header', header) + }) +} +inherits(Dicer, WritableStream) + +Dicer.prototype.emit = function (ev) { + if (ev === 'finish' && !this._realFinish) { + if (!this._finished) { + const self = this + process.nextTick(function () { + self.emit('error', new Error('Unexpected end of multipart data')) + if (self._part && !self._ignoreData) { + const type = (self._isPreamble ? 'Preamble' : 'Part') + self._part.emit('error', new Error(type + ' terminated early due to unexpected end of multipart data')) + self._part.push(null) + process.nextTick(function () { + self._realFinish = true + self.emit('finish') + self._realFinish = false + }) + return + } + self._realFinish = true + self.emit('finish') + self._realFinish = false + }) + } + } else { WritableStream.prototype.emit.apply(this, arguments) } +} -/***/ 417: -/***/ (function(module) { +Dicer.prototype._write = function (data, encoding, cb) { + // ignore unexpected data (e.g. extra trailer data after finished) + if (!this._hparser && !this._bparser) { return cb() } -module.exports = require("crypto"); + if (this._headerFirst && this._isPreamble) { + if (!this._part) { + this._part = new PartStream(this._partOpts) + if (this._events.preamble) { this.emit('preamble', this._part) } else { this._ignore() } + } + const r = this._hparser.push(data) + if (!this._inHeader && r !== undefined && r < data.length) { data = data.slice(r) } else { return cb() } + } -/***/ }), + // allows for "easier" testing + if (this._firstWrite) { + this._bparser.push(B_CRLF) + this._firstWrite = false + } -/***/ 431: -/***/ (function(__unusedmodule, exports, __webpack_require__) { + this._bparser.push(data) -"use strict"; + if (this._pause) { this._cb = cb } else { cb() } +} -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const os = __importStar(__webpack_require__(87)); -const utils_1 = __webpack_require__(82); -/** - * Commands - * - * Command Format: - * ::name key=value,key=value::message - * - * Examples: - * ::warning::This is the message - * ::set-env name=MY_VAR::some value - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); +Dicer.prototype.reset = function () { + this._part = undefined + this._bparser = undefined + this._hparser = undefined } -exports.issueCommand = issueCommand; -function issue(name, message = '') { - issueCommand(name, {}, message); + +Dicer.prototype.setBoundary = function (boundary) { + const self = this + this._bparser = new StreamSearch('\r\n--' + boundary) + this._bparser.on('info', function (isMatch, data, start, end) { + self._oninfo(isMatch, data, start, end) + }) } -exports.issue = issue; -const CMD_STRING = '::'; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; + +Dicer.prototype._ignore = function () { + if (this._part && !this._ignoreData) { + this._ignoreData = true + this._part.on('error', EMPTY_FN) + // we must perform some kind of read on the stream even though we are + // ignoring the data, otherwise node's Readable stream will not emit 'end' + // after pushing null to the stream + this._part.resume() + } +} + +Dicer.prototype._oninfo = function (isMatch, data, start, end) { + let buf; const self = this; let i = 0; let r; let shouldWriteMore = true + + if (!this._part && this._justMatched && data) { + while (this._dashes < 2 && (start + i) < end) { + if (data[start + i] === DASH) { + ++i + ++this._dashes + } else { + if (this._dashes) { buf = B_ONEDASH } + this._dashes = 0 + break + } + } + if (this._dashes === 2) { + if ((start + i) < end && this._events.trailer) { this.emit('trailer', data.slice(start + i, end)) } + this.reset() + this._finished = true + // no more parts will be added + if (self._parts === 0) { + self._realFinish = true + self.emit('finish') + self._realFinish = false + } + } + if (this._dashes) { return } + } + if (this._justMatched) { this._justMatched = false } + if (!this._part) { + this._part = new PartStream(this._partOpts) + this._part._read = function (n) { + self._unpause() } - toString() { - let cmdStr = CMD_STRING + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - let first = true; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - if (first) { - first = false; - } - else { - cmdStr += ','; - } - cmdStr += `${key}=${escapeProperty(val)}`; - } - } + if (this._isPreamble && this._events.preamble) { this.emit('preamble', this._part) } else if (this._isPreamble !== true && this._events.part) { this.emit('part', this._part) } else { this._ignore() } + if (!this._isPreamble) { this._inHeader = true } + } + if (data && start < end && !this._ignoreData) { + if (this._isPreamble || !this._inHeader) { + if (buf) { shouldWriteMore = this._part.push(buf) } + shouldWriteMore = this._part.push(data.slice(start, end)) + if (!shouldWriteMore) { this._pause = true } + } else if (!this._isPreamble && this._inHeader) { + if (buf) { this._hparser.push(buf) } + r = this._hparser.push(data.slice(start, end)) + if (!this._inHeader && r !== undefined && r < end) { this._oninfo(false, data, start + r, end) } + } + } + if (isMatch) { + this._hparser.reset() + if (this._isPreamble) { this._isPreamble = false } else { + if (start !== end) { + ++this._parts + this._part.on('end', function () { + if (--self._parts === 0) { + if (self._finished) { + self._realFinish = true + self.emit('finish') + self._realFinish = false + } else { + self._unpause() } - } - cmdStr += `${CMD_STRING}${escapeData(this.message)}`; - return cmdStr; + } + }) + } } + this._part.push(null) + this._part = undefined + this._ignoreData = false + this._justMatched = true + this._dashes = 0 + } } -function escapeData(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A'); -} -function escapeProperty(s) { - return utils_1.toCommandValue(s) - .replace(/%/g, '%25') - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/:/g, '%3A') - .replace(/,/g, '%2C'); + +Dicer.prototype._unpause = function () { + if (!this._pause) { return } + + this._pause = false + if (this._cb) { + const cb = this._cb + this._cb = undefined + cb() + } } -//# sourceMappingURL=command.js.map + +module.exports = Dicer + /***/ }), -/***/ 470: -/***/ (function(__unusedmodule, exports, __webpack_require__) { +/***/ 2032: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const command_1 = __webpack_require__(431); -const file_command_1 = __webpack_require__(102); -const utils_1 = __webpack_require__(82); -const os = __importStar(__webpack_require__(87)); -const path = __importStar(__webpack_require__(622)); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * Sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function exportVariable(name, val) { - const convertedVal = utils_1.toCommandValue(val); - process.env[name] = convertedVal; - const filePath = process.env['GITHUB_ENV'] || ''; - if (filePath) { - const delimiter = '_GitHubActionsFileCommandDelimeter_'; - const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; - file_command_1.issueCommand('ENV', commandValue); - } - else { - command_1.issueCommand('set-env', { name }, convertedVal); + +const EventEmitter = (__nccwpck_require__(5673).EventEmitter) +const inherits = (__nccwpck_require__(7261).inherits) +const getLimit = __nccwpck_require__(1467) + +const StreamSearch = __nccwpck_require__(1142) + +const B_DCRLF = Buffer.from('\r\n\r\n') +const RE_CRLF = /\r\n/g +const RE_HDR = /^([^:]+):[ \t]?([\x00-\xFF]+)?$/ // eslint-disable-line no-control-regex + +function HeaderParser (cfg) { + EventEmitter.call(this) + + cfg = cfg || {} + const self = this + this.nread = 0 + this.maxed = false + this.npairs = 0 + this.maxHeaderPairs = getLimit(cfg, 'maxHeaderPairs', 2000) + this.maxHeaderSize = getLimit(cfg, 'maxHeaderSize', 80 * 1024) + this.buffer = '' + this.header = {} + this.finished = false + this.ss = new StreamSearch(B_DCRLF) + this.ss.on('info', function (isMatch, data, start, end) { + if (data && !self.maxed) { + if (self.nread + end - start >= self.maxHeaderSize) { + end = self.maxHeaderSize - self.nread + start + self.nread = self.maxHeaderSize + self.maxed = true + } else { self.nread += (end - start) } + + self.buffer += data.toString('binary', start, end) } + if (isMatch) { self._finish() } + }) } -exports.exportVariable = exportVariable; -/** - * Registers a secret which will get masked from logs - * @param secret value of the secret - */ -function setSecret(secret) { - command_1.issueCommand('add-mask', {}, secret); +inherits(HeaderParser, EventEmitter) + +HeaderParser.prototype.push = function (data) { + const r = this.ss.push(data) + if (this.finished) { return r } } -exports.setSecret = setSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - const filePath = process.env['GITHUB_PATH'] || ''; - if (filePath) { - file_command_1.issueCommand('PATH', inputPath); + +HeaderParser.prototype.reset = function () { + this.finished = false + this.buffer = '' + this.header = {} + this.ss.reset() +} + +HeaderParser.prototype._finish = function () { + if (this.buffer) { this._parseHeader() } + this.ss.matches = this.ss.maxMatches + const header = this.header + this.header = {} + this.buffer = '' + this.finished = true + this.nread = this.npairs = 0 + this.maxed = false + this.emit('header', header) +} + +HeaderParser.prototype._parseHeader = function () { + if (this.npairs === this.maxHeaderPairs) { return } + + const lines = this.buffer.split(RE_CRLF) + const len = lines.length + let m, h + + for (var i = 0; i < len; ++i) { // eslint-disable-line no-var + if (lines[i].length === 0) { continue } + if (lines[i][0] === '\t' || lines[i][0] === ' ') { + // folded header content + // RFC2822 says to just remove the CRLF and not the whitespace following + // it, so we follow the RFC and include the leading whitespace ... + if (h) { + this.header[h][this.header[h].length - 1] += lines[i] + continue + } } - else { - command_1.issueCommand('add-path', {}, inputPath); + + const posColon = lines[i].indexOf(':') + if ( + posColon === -1 || + posColon === 0 + ) { + return } - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; + m = RE_HDR.exec(lines[i]) + h = m[1].toLowerCase() + this.header[h] = this.header[h] || [] + this.header[h].push((m[2] || '')) + if (++this.npairs === this.maxHeaderPairs) { break } + } } -exports.addPath = addPath; -/** - * Gets the value of an input. The value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - return val.trim(); + +module.exports = HeaderParser + + +/***/ }), + +/***/ 1620: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const inherits = (__nccwpck_require__(7261).inherits) +const ReadableStream = (__nccwpck_require__(4492).Readable) + +function PartStream (opts) { + ReadableStream.call(this, opts) } -exports.getInput = getInput; +inherits(PartStream, ReadableStream) + +PartStream.prototype._read = function (n) {} + +module.exports = PartStream + + +/***/ }), + +/***/ 1142: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + /** - * Sets the value of an output. + * Copyright Brian White. All rights reserved. * - * @param name name of the output to set - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function setOutput(name, value) { - command_1.issueCommand('set-output', { name }, value); -} -exports.setOutput = setOutput; -/** - * Enables or disables the echoing of commands into stdout for the rest of the step. - * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * @see https://github.com/mscdex/streamsearch * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Based heavily on the Streaming Boyer-Moore-Horspool C++ implementation + * by Hongli Lai at: https://github.com/FooBarWidget/boyer-moore-horspool */ -function setCommandEcho(enabled) { - command_1.issue('echo', enabled ? 'on' : 'off'); -} -exports.setCommandEcho = setCommandEcho; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Gets whether Actions Step Debug is on or not - */ -function isDebug() { - return process.env['RUNNER_DEBUG'] === '1'; -} -exports.isDebug = isDebug; -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - command_1.issueCommand('debug', {}, message); +const EventEmitter = (__nccwpck_require__(5673).EventEmitter) +const inherits = (__nccwpck_require__(7261).inherits) + +function SBMH (needle) { + if (typeof needle === 'string') { + needle = Buffer.from(needle) + } + + if (!Buffer.isBuffer(needle)) { + throw new TypeError('The needle has to be a String or a Buffer.') + } + + const needleLength = needle.length + + if (needleLength === 0) { + throw new Error('The needle cannot be an empty String/Buffer.') + } + + if (needleLength > 256) { + throw new Error('The needle cannot have a length bigger than 256.') + } + + this.maxMatches = Infinity + this.matches = 0 + + this._occ = new Array(256) + .fill(needleLength) // Initialize occurrence table. + this._lookbehind_size = 0 + this._needle = needle + this._bufpos = 0 + + this._lookbehind = Buffer.alloc(needleLength) + + // Populate occurrence table with analysis of the needle, + // ignoring last letter. + for (var i = 0; i < needleLength - 1; ++i) { // eslint-disable-line no-var + this._occ[needle[i]] = needleLength - 1 - i + } } -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message. Errors will be converted to string via toString() - */ -function error(message) { - command_1.issue('error', message instanceof Error ? message.toString() : message); +inherits(SBMH, EventEmitter) + +SBMH.prototype.reset = function () { + this._lookbehind_size = 0 + this.matches = 0 + this._bufpos = 0 } -exports.error = error; -/** - * Adds an warning issue - * @param message warning issue message. Errors will be converted to string via toString() - */ -function warning(message) { - command_1.issue('warning', message instanceof Error ? message.toString() : message); + +SBMH.prototype.push = function (chunk, pos) { + if (!Buffer.isBuffer(chunk)) { + chunk = Buffer.from(chunk, 'binary') + } + const chlen = chunk.length + this._bufpos = pos || 0 + let r + while (r !== chlen && this.matches < this.maxMatches) { r = this._sbmh_feed(chunk) } + return r } -exports.warning = warning; -/** - * Writes info to log with console.log. - * @param message info message - */ -function info(message) { - process.stdout.write(message + os.EOL); + +SBMH.prototype._sbmh_feed = function (data) { + const len = data.length + const needle = this._needle + const needleLength = needle.length + const lastNeedleChar = needle[needleLength - 1] + + // Positive: points to a position in `data` + // pos == 3 points to data[3] + // Negative: points to a position in the lookbehind buffer + // pos == -2 points to lookbehind[lookbehind_size - 2] + let pos = -this._lookbehind_size + let ch + + if (pos < 0) { + // Lookbehind buffer is not empty. Perform Boyer-Moore-Horspool + // search with character lookup code that considers both the + // lookbehind buffer and the current round's haystack data. + // + // Loop until + // there is a match. + // or until + // we've moved past the position that requires the + // lookbehind buffer. In this case we switch to the + // optimized loop. + // or until + // the character to look at lies outside the haystack. + while (pos < 0 && pos <= len - needleLength) { + ch = this._sbmh_lookup_char(data, pos + needleLength - 1) + + if ( + ch === lastNeedleChar && + this._sbmh_memcmp(data, pos, needleLength - 1) + ) { + this._lookbehind_size = 0 + ++this.matches + this.emit('info', true) + + return (this._bufpos = pos + needleLength) + } + pos += this._occ[ch] + } + + // No match. + + if (pos < 0) { + // There's too few data for Boyer-Moore-Horspool to run, + // so let's use a different algorithm to skip as much as + // we can. + // Forward pos until + // the trailing part of lookbehind + data + // looks like the beginning of the needle + // or until + // pos == 0 + while (pos < 0 && !this._sbmh_memcmp(data, pos, len - pos)) { ++pos } + } + + if (pos >= 0) { + // Discard lookbehind buffer. + this.emit('info', false, this._lookbehind, 0, this._lookbehind_size) + this._lookbehind_size = 0 + } else { + // Cut off part of the lookbehind buffer that has + // been processed and append the entire haystack + // into it. + const bytesToCutOff = this._lookbehind_size + pos + if (bytesToCutOff > 0) { + // The cut off data is guaranteed not to contain the needle. + this.emit('info', false, this._lookbehind, 0, bytesToCutOff) + } + + this._lookbehind.copy(this._lookbehind, 0, bytesToCutOff, + this._lookbehind_size - bytesToCutOff) + this._lookbehind_size -= bytesToCutOff + + data.copy(this._lookbehind, this._lookbehind_size) + this._lookbehind_size += len + + this._bufpos = len + return len + } + } + + pos += (pos >= 0) * this._bufpos + + // Lookbehind buffer is now empty. We only need to check if the + // needle is in the haystack. + if (data.indexOf(needle, pos) !== -1) { + pos = data.indexOf(needle, pos) + ++this.matches + if (pos > 0) { this.emit('info', true, data, this._bufpos, pos) } else { this.emit('info', true) } + + return (this._bufpos = pos + needleLength) + } else { + pos = len - needleLength + } + + // There was no match. If there's trailing haystack data that we cannot + // match yet using the Boyer-Moore-Horspool algorithm (because the trailing + // data is less than the needle size) then match using a modified + // algorithm that starts matching from the beginning instead of the end. + // Whatever trailing data is left after running this algorithm is added to + // the lookbehind buffer. + while ( + pos < len && + ( + data[pos] !== needle[0] || + ( + (Buffer.compare( + data.subarray(pos, pos + len - pos), + needle.subarray(0, len - pos) + ) !== 0) + ) + ) + ) { + ++pos + } + if (pos < len) { + data.copy(this._lookbehind, 0, pos, pos + (len - pos)) + this._lookbehind_size = len - pos + } + + // Everything until pos is guaranteed not to contain needle data. + if (pos > 0) { this.emit('info', false, data, this._bufpos, pos < len ? pos : len) } + + this._bufpos = len + return len } -exports.info = info; -/** - * Begin an output group. - * - * Output until the next `groupEnd` will be foldable in this group - * - * @param name The name of the output group - */ -function startGroup(name) { - command_1.issue('group', name); + +SBMH.prototype._sbmh_lookup_char = function (data, pos) { + return (pos < 0) + ? this._lookbehind[this._lookbehind_size + pos] + : data[pos] } -exports.startGroup = startGroup; -/** - * End an output group. - */ -function endGroup() { - command_1.issue('endgroup'); + +SBMH.prototype._sbmh_memcmp = function (data, pos, len) { + for (var i = 0; i < len; ++i) { // eslint-disable-line no-var + if (this._sbmh_lookup_char(data, pos + i) !== this._needle[i]) { return false } + } + return true } -exports.endGroup = endGroup; -/** - * Wrap an asynchronous function call in a group. - * - * Returns the same type as the function itself. - * - * @param name The name of the group - * @param fn The function to wrap in the group - */ -function group(name, fn) { - return __awaiter(this, void 0, void 0, function* () { - startGroup(name); - let result; - try { - result = yield fn(); - } - finally { - endGroup(); - } - return result; - }); + +module.exports = SBMH + + +/***/ }), + +/***/ 727: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + + +const WritableStream = (__nccwpck_require__(4492).Writable) +const { inherits } = __nccwpck_require__(7261) +const Dicer = __nccwpck_require__(2960) + +const MultipartParser = __nccwpck_require__(2183) +const UrlencodedParser = __nccwpck_require__(8306) +const parseParams = __nccwpck_require__(1854) + +function Busboy (opts) { + if (!(this instanceof Busboy)) { return new Busboy(opts) } + + if (typeof opts !== 'object') { + throw new TypeError('Busboy expected an options-Object.') + } + if (typeof opts.headers !== 'object') { + throw new TypeError('Busboy expected an options-Object with headers-attribute.') + } + if (typeof opts.headers['content-type'] !== 'string') { + throw new TypeError('Missing Content-Type-header.') + } + + const { + headers, + ...streamOptions + } = opts + + this.opts = { + autoDestroy: false, + ...streamOptions + } + WritableStream.call(this, this.opts) + + this._done = false + this._parser = this.getParserByHeaders(headers) + this._finished = false } -exports.group = group; -//----------------------------------------------------------------------- -// Wrapper action state -//----------------------------------------------------------------------- -/** - * Saves state for current action, the state can only be retrieved by this action's post job execution. - * - * @param name name of the state to store - * @param value value to store. Non-string values will be converted to a string via JSON.stringify - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function saveState(name, value) { - command_1.issueCommand('save-state', { name }, value); +inherits(Busboy, WritableStream) + +Busboy.prototype.emit = function (ev) { + if (ev === 'finish') { + if (!this._done) { + this._parser?.end() + return + } else if (this._finished) { + return + } + this._finished = true + } + WritableStream.prototype.emit.apply(this, arguments) } -exports.saveState = saveState; -/** - * Gets the value of an state set by this action's main execution. - * - * @param name name of the state to get - * @returns string - */ -function getState(name) { - return process.env[`STATE_${name}`] || ''; + +Busboy.prototype.getParserByHeaders = function (headers) { + const parsed = parseParams(headers['content-type']) + + const cfg = { + defCharset: this.opts.defCharset, + fileHwm: this.opts.fileHwm, + headers, + highWaterMark: this.opts.highWaterMark, + isPartAFile: this.opts.isPartAFile, + limits: this.opts.limits, + parsedConType: parsed, + preservePath: this.opts.preservePath + } + + if (MultipartParser.detect.test(parsed[0])) { + return new MultipartParser(this, cfg) + } + if (UrlencodedParser.detect.test(parsed[0])) { + return new UrlencodedParser(this, cfg) + } + throw new Error('Unsupported Content-Type.') } -exports.getState = getState; -//# sourceMappingURL=core.js.map -/***/ }), +Busboy.prototype._write = function (chunk, encoding, cb) { + this._parser.write(chunk, cb) +} -/***/ 605: -/***/ (function(module) { +module.exports = Busboy +module.exports["default"] = Busboy +module.exports.Busboy = Busboy + +module.exports.Dicer = Dicer -module.exports = require("http"); /***/ }), -/***/ 618: -/***/ (function(module, __unusedexports, __webpack_require__) { +/***/ 2183: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -/*! For license information please see mailgun.js.LICENSE.txt */ -!function(e,t){ true?module.exports=t():undefined}(this,(function(){return(()=>{var e={271:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=r(185);class n extends o.EventTarget{constructor(){throw super(),new TypeError("AbortSignal cannot be constructed directly")}get aborted(){const e=s.get(this);if("boolean"!=typeof e)throw new TypeError("Expected 'this' to be an 'AbortSignal' object, but got "+(null===this?"null":typeof this));return e}}o.defineEventAttribute(n.prototype,"abort");const s=new WeakMap;Object.defineProperties(n.prototype,{aborted:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(n.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortSignal"});class i{constructor(){a.set(this,function(){const e=Object.create(n.prototype);return o.EventTarget.call(e),s.set(e,!1),e}())}get signal(){return u(this)}abort(){var e;e=u(this),!1===s.get(e)&&(s.set(e,!0),e.dispatchEvent({type:"abort"}))}}const a=new WeakMap;function u(e){const t=a.get(e);if(null==t)throw new TypeError("Expected 'this' to be an 'AbortController' object, but got "+(null===e?"null":typeof e));return t}Object.defineProperties(i.prototype,{signal:{enumerable:!0},abort:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(i.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortController"}),t.AbortController=i,t.AbortSignal=n,t.default=i,e.exports=i,e.exports.AbortController=e.exports.default=i,e.exports.AbortSignal=n},990:function(e,t,r){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var n=o(r(765)),s=function(){function e(e){this.formData=e}return e.prototype.client=function(e){return new n.default(e,this.formData)},e}();t.default=s},765:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return(o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=r(78),n=(r(955),function(){function e(e){this.request=e}return e.prototype._parsePageNumber=function(e){return e.split("/").pop()},e.prototype._parsePage=function(e,t){return{id:e,number:this._parsePageNumber(t),url:t}},e.prototype._parsePageLinks=function(e){var t=this;return Object.entries(e.body.paging).reduce((function(e,r){var o=r[0],n=r[1];return e[o]=t._parsePage(o,n),e}),{})},e.prototype._parseEventList=function(e){return{items:e.body.items,pages:this._parsePageLinks(e)}},e.prototype.get=function(e,t){var r,n=this;return t&&t.page?(r=o("/v2",e,"events",t.page),delete t.page):r=o("/v2",e,"events"),this.request.get(r,t).then((function(e){return n._parseEventList(e)}))},e}());t.default=n},853:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),r(955);var o=function(){function e(e){this.request=e}return e.prototype.list=function(e){var t=this;return this.request.get("/v1/ip_pools",e).then((function(e){return t.parseIpPoolsResponse(e)}))},e.prototype.create=function(e){return this.request.post("/v1/ip_pools",e).then((function(e){return null==e?void 0:e.body}))},e.prototype.update=function(e,t){return this.request.patch("/v1/ip_pools/"+e,t).then((function(e){return null==e?void 0:e.body}))},e.prototype.delete=function(e,t){return this.request.delete("/v1/ip_pools/"+e,t).then((function(e){return null==e?void 0:e.body}))},e.prototype.parseIpPoolsResponse=function(e){return e.body.ip_pools},e}();t.default=o},580:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),r(955);var o=function(){function e(e){this.request=e}return e.prototype.list=function(e){var t=this;return this.request.get("/v3/ips",e).then((function(e){return t.parseIpsResponse(e)}))},e.prototype.get=function(e){var t=this;return this.request.get("/v3/ips/"+e).then((function(e){return t.parseIpsResponse(e)}))},e.prototype.parseIpsResponse=function(e){return e.body},e}();t.default=o},616:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype._parseResponse=function(e){return e.body?e.body:e},e.prototype.create=function(e,t){return t.message?this.request.postMulti("/v3/"+e+"/messages.mime",t).then(this._parseResponse):this.request.postMulti("/v3/"+e+"/messages",t).then(this._parseResponse)},e}();t.default=r},726:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.get=function(e,t){var r={};return Array.isArray(e)&&(e=e.join(",")),r.addresses=e,t&&(r.syntax_only=!1),this.request.get("/v3/address/parse",r).then((function(e){return e.body}))},e}();t.default=r},955:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return(o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r0&&n[n.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!n||s[1]>n[0]&&s[1]0&&(f.searchParams=r.query,delete f.query),[4,l.default(u.default(this.url,t),o({method:e.toLocaleUpperCase(),headers:i,throwHttpErrors:!1},f))];case 1:return(null==(p=s.sent())?void 0:p.ok)?[3,6]:(null==p?void 0:p.body)&&d(p.body)?[4,(m=p.body,_=[],new Promise((function(e,t){m.on("data",(function(e){return _.push(e)})),m.on("error",t),m.on("end",(function(){return e(Buffer.concat(_).toString("utf8"))}))})))]:[3,3];case 2:return y=s.sent(),[3,5];case 3:return[4,null==p?void 0:p.json()];case 4:y=s.sent(),s.label=5;case 5:throw h=y,new c.default({status:null==p?void 0:p.status,statusText:null==p?void 0:p.statusText,body:{message:h}});case 6:return b={},[4,null==p?void 0:p.json()];case 7:return[2,(b.body=s.sent(),b.status=null==p?void 0:p.status,b)]}var m,_}))}))},e.prototype.query=function(e,t,r,n){return this.request(e,t,o({query:r},n))},e.prototype.command=function(e,t,r,n){return this.request(e,t,o({headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r},n))},e.prototype.get=function(e,t,r){return this.query("get",e,t,r)},e.prototype.head=function(e,t,r){return this.query("head",e,t,r)},e.prototype.options=function(e,t,r){return this.query("options",e,t,r)},e.prototype.post=function(e,t,r){return this.command("post",e,t,r)},e.prototype.postMulti=function(e,t){var r=new this.formData;return Object.keys(t).filter((function(e){return t[e]})).forEach((function(e){if("attachment"!==e)Array.isArray(t[e])?t[e].forEach((function(t){r.append(e,t)})):r.append(e,t[e]);else{var o=t.attachment;if(Array.isArray(o))o.forEach((function(t){var o=t.data?t.data:t,n=f(t);r.append(e,o,n)}));else{var n=d(o)?o:o.data,s=f(o);r.append(e,n,s)}}})),this.command("post",e,r,{headers:{"Content-Type":null}})},e.prototype.put=function(e,t,r){return this.command("put",e,t,r)},e.prototype.patch=function(e,t,r){return this.command("patch",e,t,r)},e.prototype.delete=function(e,t,r){return this.command("delete",e,t,r)},e}();t.default=p},893:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){return this.request.get("/v3/routes",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get("/v3/routes/"+e).then((function(e){return e.body.route}))},e.prototype.create=function(e){return this.request.post("/v3/routes",e).then((function(e){return e.body.route}))},e.prototype.update=function(e,t){return this.request.put("/v3/routes/"+e,t).then((function(e){return e.body}))},e.prototype.destroy=function(e){return this.request.delete("/v3/routes/"+e).then((function(e){return e.body}))},e}();t.default=r},154:function(e,t,r){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var n=o(r(78)),s=function(e){this.start=new Date(e.start),this.end=new Date(e.end),this.resolution=e.resolution,this.stats=e.stats.map((function(e){return e.time=new Date(e.time),e}))},i=function(){function e(e){this.request=e}return e.prototype._parseStats=function(e){return new s(e.body)},e.prototype.getDomain=function(e,t){return this.request.get(n.default("/v3",e,"stats/total"),t).then(this._parseStats)},e.prototype.getAccount=function(e){return this.request.get("/v3/stats/total",e).then(this._parseStats)},e}();t.default=i},526:function(e,t,r){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var n=o(r(835)),s=o(r(78)),i={headers:{"Content-Type":"application/json"}},a=function(e){this.type="bounces",this.address=e.address,this.code=+e.code,this.error=e.error,this.created_at=new Date(e.created_at)},u=function(e){this.type="complaints",this.address=e.address,this.created_at=new Date(e.created_at)},l=function(e){this.type="unsubscribes",this.address=e.address,this.tags=e.tags,this.created_at=new Date(e.created_at)},c=function(){function e(e){this.request=e,this.models={bounces:a,complaints:u,unsubscribes:l}}return e.prototype._parsePage=function(e,t){var r=n.default.parse(t,!0).query;return{id:e,page:r.page,address:r.address,url:t}},e.prototype._parsePageLinks=function(e){var t=this;return Object.entries(e.body.paging).reduce((function(e,r){var o=r[0],n=r[1];return e[o]=t._parsePage(o,n),e}),{})},e.prototype._parseList=function(e,t){var r={};return r.items=e.body.items.map((function(e){return new t(e)})),r.pages=this._parsePageLinks(e),r},e.prototype._parseItem=function(e,t){return new t(e.body)},e.prototype.list=function(e,t,r){var o=this,n=this.models[t];return this.request.get(s.default("v3",e,t),r).then((function(e){return o._parseList(e,n)}))},e.prototype.get=function(e,t,r){var o=this,n=this.models[t];return this.request.get(s.default("v3",e,t,encodeURIComponent(r))).then((function(e){return o._parseItem(e,n)}))},e.prototype.create=function(e,t,r){return Array.isArray(r)||(r=[r]),this.request.post(s.default("v3",e,t),r,i).then((function(e){return e.body}))},e.prototype.destroy=function(e,t,r){return this.request.delete(s.default("v3",e,t,encodeURIComponent(r))).then((function(e){return e.body}))},e}();t.default=c,e.exports=c},335:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.get=function(e){return this.request.get("/v3/address/validate",{address:e}).then((function(e){return e.body}))},e}();t.default=r},632:function(e,t,r){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var n=o(r(78)),s=function(e,t){this.id=e,this.url=t.url},i=function(){function e(e){this.request=e}return e.prototype._parseWebhookList=function(e){return e.body.webhooks},e.prototype._parseWebhookWithID=function(e){return function(t){return new s(e,t.body.webhook)}},e.prototype._parseWebhookTest=function(e){return{code:e.body.code,message:e.body.message}},e.prototype.list=function(e,t){return this.request.get(n.default("/v2/domains",e,"webhooks"),t).then(this._parseWebhookList)},e.prototype.get=function(e,t){return this.request.get(n.default("/v2/domains",e,"webhooks",t)).then(this._parseWebhookWithID(t))},e.prototype.create=function(e,t,r,o){return o?this.request.put(n.default("/v2/domains",e,"webhooks",t,"test"),{url:r}).then(this._parseWebhookTest):this.request.post(n.default("/v2/domains",e,"webhooks"),{id:t,url:r}).then(this._parseWebhookWithID(t))},e.prototype.update=function(e,t,r){return this.request.put(n.default("/v2/domains",e,"webhooks",t),{url:r}).then(this._parseWebhookWithID(t))},e.prototype.destroy=function(e,t){return this.request.delete(n.default("/v2/domains",e,"webhooks",t)).then(this._parseWebhookWithID(t))},e}();t.default=i},706:e=>{!function(){"use strict";e.exports=function(e){return(e instanceof Buffer?e:Buffer.from(e.toString(),"binary")).toString("base64")}}()},175:e=>{"use strict";e.exports=function(e){if(!/^data:/i.test(e))throw new TypeError('`uri` does not appear to be a Data URI (must begin with "data:")');const t=(e=e.replace(/\r?\n/g,"")).indexOf(",");if(-1===t||t<=4)throw new TypeError("malformed data: URI");const r=e.substring(5,t).split(";");let o="",n=!1;const s=r[0]||"text/plain";let i=s;for(let e=1;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=new WeakMap,o=new WeakMap;function n(e){const t=r.get(e);return console.assert(null!=t,"'this' is expected an Event object, but got",e),t}function s(e){null==e.passiveListener?e.event.cancelable&&(e.canceled=!0,"function"==typeof e.event.preventDefault&&e.event.preventDefault()):"undefined"!=typeof console&&"function"==typeof console.error&&console.error("Unable to preventDefault inside passive event listener invocation.",e.passiveListener)}function i(e,t){r.set(this,{eventTarget:e,event:t,eventPhase:2,currentTarget:e,canceled:!1,stopped:!1,immediateStopped:!1,passiveListener:null,timeStamp:t.timeStamp||Date.now()}),Object.defineProperty(this,"isTrusted",{value:!1,enumerable:!0});const o=Object.keys(t);for(let e=0;e0){const e=new Array(arguments.length);for(let t=0;t{const{Readable:o}=r(413),n=new WeakMap;class s{constructor(e=[],t={type:""}){let r=0;const o=e.map((e=>{let t;return t=e instanceof Buffer?e:ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):e instanceof ArrayBuffer?Buffer.from(e):e instanceof s?e:Buffer.from("string"==typeof e?e:String(e)),r+=t.length||t.size||0,t})),i=void 0===t.type?"":String(t.type).toLowerCase();n.set(this,{type:/[^\u0020-\u007E]/.test(i)?"":i,size:r,parts:o})}get size(){return n.get(this).size}get type(){return n.get(this).type}async text(){return Buffer.from(await this.arrayBuffer()).toString()}async arrayBuffer(){const e=new Uint8Array(this.size);let t=0;for await(const r of this.stream())e.set(r,t),t+=r.length;return e.buffer}stream(){return o.from(async function*(e){for(const t of e)"stream"in t?yield*t.stream():yield t}(n.get(this).parts))}slice(e=0,t=this.size,r=""){const{size:o}=this;let i=e<0?Math.max(o+e,0):Math.min(e,o),a=t<0?Math.max(o+t,0):Math.min(t,o);const u=Math.max(a-i,0),l=n.get(this).parts.values(),c=[];let d=0;for(const e of l){const t=ArrayBuffer.isView(e)?e.byteLength:e.size;if(i&&t<=i)i-=t,a-=t;else{const r=e.slice(i,Math.min(t,a));if(c.push(r),d+=ArrayBuffer.isView(r)?r.byteLength:r.size,i=0,d>=u)break}}const f=new s([],{type:r});return Object.assign(n.get(f),{size:u,parts:c}),f}get[Symbol.toStringTag](){return"Blob"}static[Symbol.hasInstance](e){return"object"==typeof e&&"function"==typeof e.stream&&0===e.stream.length&&"function"==typeof e.constructor&&/^(Blob|File)$/.test(e[Symbol.toStringTag])}}Object.defineProperties(s.prototype,{size:{enumerable:!0},type:{enumerable:!0},slice:{enumerable:!0}}),e.exports=s},556:(e,t,r)=>{"use strict";const o=r(711),n=r(271);if(global.fetch||(global.fetch=(e,t)=>o(e,{highWaterMark:1e7,...t})),global.Headers||(global.Headers=o.Headers),global.Request||(global.Request=o.Request),global.Response||(global.Response=o.Response),global.AbortController||(global.AbortController=n),!global.ReadableStream)try{global.ReadableStream=r(377)}catch(e){}e.exports=r(721)},721:function(e){var t;t=function(){"use strict";const e={},t=e=>"undefined"!=typeof self&&self&&e in self?self:"undefined"!=typeof window&&window&&e in window?window:"undefined"!=typeof global&&global&&e in global?global:"undefined"!=typeof globalThis&&globalThis?globalThis:void 0,r=["Headers","Request","Response","ReadableStream","fetch","AbortController","FormData"];for(const o of r)Object.defineProperty(e,o,{get(){const e=t(o),r=e&&e[o];return"function"==typeof r?r.bind(e):r}});const o=e=>null!==e&&"object"==typeof e,n="function"==typeof e.AbortController,s="function"==typeof e.ReadableStream,i="function"==typeof e.FormData,a=(t,r)=>{const o=new e.Headers(t||{}),n=r instanceof e.Headers,s=new e.Headers(r||{});for(const[e,t]of s)n&&"undefined"===t||void 0===t?o.delete(e):o.set(e,t);return o},u=(...e)=>{let t={},r={};for(const n of e){if(Array.isArray(n))Array.isArray(t)||(t=[]),t=[...t,...n];else if(o(n)){for(let[e,r]of Object.entries(n))o(r)&&e in t&&(r=u(t[e],r)),t={...t,[e]:r};o(n.headers)&&(r=a(r,n.headers))}t.headers=r}return t},l=["get","post","put","patch","head","delete"],c={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},d=[413,429,503],f=Symbol("stop");class p extends Error{constructor(e){super(e.statusText||String(0===e.status||e.status?e.status:"Unknown response error")),this.name="HTTPError",this.response=e}}class h extends Error{constructor(e){super("Request timed out"),this.name="TimeoutError",this.request=e}}const y=e=>new Promise((t=>setTimeout(t,e))),b=e=>l.includes(e)?e.toUpperCase():e,m={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:d},_=(e={})=>{if("number"==typeof e)return{...m,limit:e};if(e.methods&&!Array.isArray(e.methods))throw new Error("retry.methods must be an array");if(e.statusCodes&&!Array.isArray(e.statusCodes))throw new Error("retry.statusCodes must be an array");return{...m,...e,afterStatusCodes:d}},g=2147483647;class w{constructor(t,r={}){if(this._retryCount=0,this._input=t,this._options={credentials:this._input.credentials||"same-origin",...r,headers:a(this._input.headers,r.headers),hooks:u({beforeRequest:[],beforeRetry:[],afterResponse:[]},r.hooks),method:b(r.method||this._input.method),prefixUrl:String(r.prefixUrl||""),retry:_(r.retry),throwHttpErrors:!1!==r.throwHttpErrors,timeout:void 0===r.timeout?1e4:r.timeout,fetch:r.fetch||e.fetch},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof e.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(n&&(this.abortController=new e.AbortController,this._options.signal&&this._options.signal.addEventListener("abort",(()=>{this.abortController.abort()})),this._options.signal=this.abortController.signal),this.request=new e.Request(this._input,this._options),this._options.searchParams){const t="?"+new URLSearchParams(this._options.searchParams).toString(),r=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,t);!(i&&this._options.body instanceof e.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new e.Request(new e.Request(r,this.request),this._options)}void 0!==this._options.json&&(this._options.body=JSON.stringify(this._options.json),this.request.headers.set("content-type","application/json"),this.request=new e.Request(this.request,{body:this._options.body}));const o=async()=>{if(this._options.timeout>g)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await y(1);let t=await this._fetch();for(const r of this._options.hooks.afterResponse){const o=await r(this.request,this._options,this._decorateResponse(t.clone()));o instanceof e.Response&&(t=o)}if(this._decorateResponse(t),!t.ok&&this._options.throwHttpErrors)throw new p(t);if(this._options.onDownloadProgress){if("function"!=typeof this._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!s)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return this._stream(t.clone(),this._options.onDownloadProgress)}return t},l=this._options.retry.methods.includes(this.request.method.toLowerCase())?this._retry(o):o();for(const[e,t]of Object.entries(c))l[e]=async()=>{this.request.headers.set("accept",this.request.headers.get("accept")||t);const o=(await l).clone();if("json"===e){if(204===o.status)return"";if(r.parseJson)return r.parseJson(await o.text())}return o[e]()};return l}_calculateRetryDelay(e){if(this._retryCount++,this._retryCountthis._options.retry.maxRetryAfter?0:e}if(413===e.response.status)return 0}return.3*2**(this._retryCount-1)*1e3}return 0}_decorateResponse(e){return this._options.parseJson&&(e.json=async()=>this._options.parseJson(await e.text())),e}async _retry(e){try{return await e()}catch(t){const r=Math.min(this._calculateRetryDelay(t),g);if(0!==r&&this._retryCount>0){await y(r);for(const e of this._options.hooks.beforeRetry)if(await e({request:this.request,options:this._options,error:t,retryCount:this._retryCount})===f)return;return this._retry(e)}if(this._options.throwHttpErrors)throw t}}async _fetch(){for(const e of this._options.hooks.beforeRequest){const t=await e(this.request,this._options);if(t instanceof Request){this.request=t;break}if(t instanceof Response)return t}return!1===this._options.timeout?this._options.fetch(this.request.clone()):(e=this.request.clone(),t=this.abortController,r=this._options,new Promise(((o,n)=>{const s=setTimeout((()=>{t&&t.abort(),n(new h(e))}),r.timeout);r.fetch(e).then(o).catch(n).then((()=>{clearTimeout(s)}))})));var e,t,r}_stream(t,r){const o=Number(t.headers.get("content-length"))||0;let n=0;return new e.Response(new e.ReadableStream({start(e){const s=t.body.getReader();r&&r({percent:0,transferredBytes:0,totalBytes:o},new Uint8Array),async function t(){const{done:i,value:a}=await s.read();i?e.close():(r&&(n+=a.byteLength,r({percent:0===o?0:n/o,transferredBytes:n,totalBytes:o},a)),e.enqueue(a),t())}()}}))}}const v=(...e)=>{for(const t of e)if((!o(t)||Array.isArray(t))&&void 0!==t)throw new TypeError("The `options` argument must be an object");return u({},...e)},S=e=>{const t=(t,r)=>new w(t,v(e,r));for(const r of l)t[r]=(t,o)=>new w(t,v(e,o,{method:r}));return t.HTTPError=p,t.TimeoutError=h,t.create=e=>S(v(e)),t.extend=t=>S(v(e,t)),t.stop=f,t};return S()},e.exports=t()},711:(e,t,r)=>{"use strict";t=e.exports=I;const o=r(605),n=r(211),s=r(761),i=r(413),a=r(175),u=r(669),l=r(30),c=r(417),d=r(835);class f extends Error{constructor(e,t){super(e),Error.captureStackTrace(this,this.constructor),this.type=t}get name(){return this.constructor.name}get[Symbol.toStringTag](){return this.constructor.name}}class p extends f{constructor(e,t,r){super(e,t),r&&(this.code=this.errno=r.code,this.erroredSysCall=r.syscall)}}const h=Symbol.toStringTag,y=e=>"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.delete&&"function"==typeof e.get&&"function"==typeof e.getAll&&"function"==typeof e.has&&"function"==typeof e.set&&"function"==typeof e.sort&&"URLSearchParams"===e[h],b=e=>"object"==typeof e&&"function"==typeof e.arrayBuffer&&"string"==typeof e.type&&"function"==typeof e.stream&&"function"==typeof e.constructor&&/^(Blob|File)$/.test(e[h]);function m(e){return"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.set&&"function"==typeof e.get&&"function"==typeof e.getAll&&"function"==typeof e.delete&&"function"==typeof e.keys&&"function"==typeof e.values&&"function"==typeof e.entries&&"function"==typeof e.constructor&&"FormData"===e[h]}const _="\r\n",g="-".repeat(2),w=Buffer.byteLength(_),v=e=>`${g}${e}${g}${_.repeat(2)}`;function S(e,t,r){let o="";return o+=`${g}${e}\r\n`,o+=`Content-Disposition: form-data; name="${t}"`,b(r)&&(o+=`; filename="${r.name}"\r\n`,o+=`Content-Type: ${r.type||"application/octet-stream"}`),`${o}${_.repeat(2)}`}const T=Symbol("Body internals");class R{constructor(e,{size:t=0}={}){let r=null;null===e?e=null:y(e)?e=Buffer.from(e.toString()):b(e)||Buffer.isBuffer(e)||(u.types.isAnyArrayBuffer(e)?e=Buffer.from(e):ArrayBuffer.isView(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):e instanceof i||(m(e)?(r=`NodeFetchFormDataBoundary${c.randomBytes(8).toString("hex")}`,e=i.Readable.from(async function*(e,t){for(const[r,o]of e)yield S(t,r,o),b(o)?yield*o.stream():yield o,yield _;yield v(t)}(e,r))):e=Buffer.from(String(e)))),this[T]={body:e,boundary:r,disturbed:!1,error:null},this.size=t,e instanceof i&&e.on("error",(e=>{const t=e instanceof f?e:new p(`Invalid response body while trying to fetch ${this.url}: ${e.message}`,"system",e);this[T].error=t}))}get body(){return this[T].body}get bodyUsed(){return this[T].disturbed}async arrayBuffer(){const{buffer:e,byteOffset:t,byteLength:r}=await q(this);return e.slice(t,t+r)}async blob(){const e=this.headers&&this.headers.get("content-type")||this[T].body&&this[T].body.type||"",t=await this.buffer();return new l([t],{type:e})}async json(){const e=await q(this);return JSON.parse(e.toString())}async text(){return(await q(this)).toString()}buffer(){return q(this)}}async function q(e){if(e[T].disturbed)throw new TypeError(`body used already for: ${e.url}`);if(e[T].disturbed=!0,e[T].error)throw e[T].error;let{body:t}=e;if(null===t)return Buffer.alloc(0);if(b(t)&&(t=t.stream()),Buffer.isBuffer(t))return t;if(!(t instanceof i))return Buffer.alloc(0);const r=[];let o=0;try{for await(const n of t){if(e.size>0&&o+n.length>e.size){const r=new p(`content size at ${e.url} over limit: ${e.size}`,"max-size");throw t.destroy(r),r}o+=n.length,r.push(n)}}catch(t){throw t instanceof f?t:new p(`Invalid response body while trying to fetch ${e.url}: ${t.message}`,"system",t)}if(!0!==t.readableEnded&&!0!==t._readableState.ended)throw new p(`Premature close of server response while trying to fetch ${e.url}`);try{return r.every((e=>"string"==typeof e))?Buffer.from(r.join("")):Buffer.concat(r,o)}catch(t){throw new p(`Could not create Buffer from response body for ${e.url}: ${t.message}`,"system",t)}}Object.defineProperties(R.prototype,{body:{enumerable:!0},bodyUsed:{enumerable:!0},arrayBuffer:{enumerable:!0},blob:{enumerable:!0},json:{enumerable:!0},text:{enumerable:!0}});const P=(e,t)=>{let r,o,{body:n}=e;if(e.bodyUsed)throw new Error("cannot clone body after it is used");return n instanceof i&&"function"!=typeof n.getBoundary&&(r=new i.PassThrough({highWaterMark:t}),o=new i.PassThrough({highWaterMark:t}),n.pipe(r),n.pipe(o),e[T].body=r,n=o),n},E=(e,t)=>null===e?null:"string"==typeof e?"text/plain;charset=UTF-8":y(e)?"application/x-www-form-urlencoded;charset=UTF-8":b(e)?e.type||null:Buffer.isBuffer(e)||u.types.isAnyArrayBuffer(e)||ArrayBuffer.isView(e)?null:e&&"function"==typeof e.getBoundary?`multipart/form-data;boundary=${e.getBoundary()}`:m(e)?`multipart/form-data; boundary=${t[T].boundary}`:e instanceof i?null:"text/plain;charset=UTF-8",j="function"==typeof o.validateHeaderName?o.validateHeaderName:e=>{if(!/^[\^`\-\w!#$%&'*+.|~]+$/.test(e)){const t=new TypeError(`Header name must be a valid HTTP token [${e}]`);throw Object.defineProperty(t,"code",{value:"ERR_INVALID_HTTP_TOKEN"}),t}},k="function"==typeof o.validateHeaderValue?o.validateHeaderValue:(e,t)=>{if(/[^\t\u0020-\u007E\u0080-\u00FF]/.test(t)){const t=new TypeError(`Invalid character in header content ["${e}"]`);throw Object.defineProperty(t,"code",{value:"ERR_INVALID_CHAR"}),t}};class O extends URLSearchParams{constructor(e){let t=[];if(e instanceof O){const r=e.raw();for(const[e,o]of Object.entries(r))t.push(...o.map((t=>[e,t])))}else if(null==e);else{if("object"!=typeof e||u.types.isBoxedPrimitive(e))throw new TypeError("Failed to construct 'Headers': The provided value is not of type '(sequence> or record)");{const r=e[Symbol.iterator];if(null==r)t.push(...Object.entries(e));else{if("function"!=typeof r)throw new TypeError("Header pairs must be iterable");t=[...e].map((e=>{if("object"!=typeof e||u.types.isBoxedPrimitive(e))throw new TypeError("Each header pair must be an iterable object");return[...e]})).map((e=>{if(2!==e.length)throw new TypeError("Each header pair must be a name/value tuple");return[...e]}))}}}return t=t.length>0?t.map((([e,t])=>(j(e),k(e,String(t)),[String(e).toLowerCase(),String(t)]))):void 0,super(t),new Proxy(this,{get(e,t,r){switch(t){case"append":case"set":return(e,o)=>(j(e),k(e,String(o)),URLSearchParams.prototype[t].call(r,String(e).toLowerCase(),String(o)));case"delete":case"has":case"getAll":return e=>(j(e),URLSearchParams.prototype[t].call(r,String(e).toLowerCase()));case"keys":return()=>(e.sort(),new Set(URLSearchParams.prototype.keys.call(e)).keys());default:return Reflect.get(e,t,r)}}})}get[Symbol.toStringTag](){return this.constructor.name}toString(){return Object.prototype.toString.call(this)}get(e){const t=this.getAll(e);if(0===t.length)return null;let r=t.join(", ");return/^content-encoding$/i.test(e)&&(r=r.toLowerCase()),r}forEach(e){for(const t of this.keys())e(this.get(t),t)}*values(){for(const e of this.keys())yield this.get(e)}*entries(){for(const e of this.keys())yield[e,this.get(e)]}[Symbol.iterator](){return this.entries()}raw(){return[...this.keys()].reduce(((e,t)=>(e[t]=this.getAll(t),e)),{})}[Symbol.for("nodejs.util.inspect.custom")](){return[...this.keys()].reduce(((e,t)=>{const r=this.getAll(t);return e[t]="host"===t?r[0]:r.length>1?r:r[0],e}),{})}}Object.defineProperties(O.prototype,["get","entries","forEach","values"].reduce(((e,t)=>(e[t]={enumerable:!0},e)),{}));const C=new Set([301,302,303,307,308]),A=e=>C.has(e),B=Symbol("Response internals");class x extends R{constructor(e=null,t={}){super(e,t);const r=t.status||200,o=new O(t.headers);if(null!==e&&!o.has("Content-Type")){const t=E(e);t&&o.append("Content-Type",t)}this[B]={url:t.url,status:r,statusText:t.statusText||"",headers:o,counter:t.counter,highWaterMark:t.highWaterMark}}get url(){return this[B].url||""}get status(){return this[B].status}get ok(){return this[B].status>=200&&this[B].status<300}get redirected(){return this[B].counter>0}get statusText(){return this[B].statusText}get headers(){return this[B].headers}get highWaterMark(){return this[B].highWaterMark}clone(){return new x(P(this,this.highWaterMark),{url:this.url,status:this.status,statusText:this.statusText,headers:this.headers,ok:this.ok,redirected:this.redirected,size:this.size})}static redirect(e,t=302){if(!A(t))throw new RangeError('Failed to execute "redirect" on "response": Invalid status code');return new x(null,{headers:{location:new URL(e).toString()},status:t})}get[Symbol.toStringTag](){return"Response"}}Object.defineProperties(x.prototype,{url:{enumerable:!0},status:{enumerable:!0},ok:{enumerable:!0},redirected:{enumerable:!0},statusText:{enumerable:!0},headers:{enumerable:!0},clone:{enumerable:!0}});const W=Symbol("Request internals"),L=e=>"object"==typeof e&&"object"==typeof e[W];class z extends R{constructor(e,t={}){let r;L(e)?r=new URL(e.url):(r=new URL(e),e={});let o=t.method||e.method||"GET";if(o=o.toUpperCase(),(null!=t.body||L(e))&&null!==e.body&&("GET"===o||"HEAD"===o))throw new TypeError("Request with GET/HEAD method cannot have body");const n=t.body?t.body:L(e)&&null!==e.body?P(e):null;super(n,{size:t.size||e.size||0});const s=new O(t.headers||e.headers||{});if(null!==n&&!s.has("Content-Type")){const e=E(n,this);e&&s.append("Content-Type",e)}let i=L(e)?e.signal:null;if("signal"in t&&(i=t.signal),null!==i&&("object"!=typeof(a=i)||"AbortSignal"!==a[h]))throw new TypeError("Expected signal to be an instanceof AbortSignal");var a;this[W]={method:o,redirect:t.redirect||e.redirect||"follow",headers:s,parsedURL:r,signal:i},this.follow=void 0===t.follow?void 0===e.follow?20:e.follow:t.follow,this.compress=void 0===t.compress?void 0===e.compress||e.compress:t.compress,this.counter=t.counter||e.counter||0,this.agent=t.agent||e.agent,this.highWaterMark=t.highWaterMark||e.highWaterMark||16384,this.insecureHTTPParser=t.insecureHTTPParser||e.insecureHTTPParser||!1}get method(){return this[W].method}get url(){return d.format(this[W].parsedURL)}get headers(){return this[W].headers}get redirect(){return this[W].redirect}get signal(){return this[W].signal}clone(){return new z(this)}get[Symbol.toStringTag](){return"Request"}}Object.defineProperties(z.prototype,{method:{enumerable:!0},url:{enumerable:!0},headers:{enumerable:!0},redirect:{enumerable:!0},clone:{enumerable:!0},signal:{enumerable:!0}});class M extends f{constructor(e,t="aborted"){super(e,t)}}const $=new Set(["data:","http:","https:"]);async function I(e,t){return new Promise(((r,u)=>{const l=new z(e,t),c=(e=>{const{parsedURL:t}=e[W],r=new O(e[W].headers);r.has("Accept")||r.set("Accept","*/*");let o=null;if(null===e.body&&/^(post|put)$/i.test(e.method)&&(o="0"),null!==e.body){const t=(e=>{const{body:t}=e;return null===t?0:b(t)?t.size:Buffer.isBuffer(t)?t.length:t&&"function"==typeof t.getLengthSync?t.hasKnownLength&&t.hasKnownLength()?t.getLengthSync():null:m(t)?function(e,t){let r=0;for(const[o,n]of e)r+=Buffer.byteLength(S(t,o,n)),b(n)?r+=n.size:r+=Buffer.byteLength(String(n)),r+=w;return r+=Buffer.byteLength(v(t)),r}(e[T].boundary):null})(e);"number"!=typeof t||Number.isNaN(t)||(o=String(t))}o&&r.set("Content-Length",o),r.has("User-Agent")||r.set("User-Agent","node-fetch"),e.compress&&!r.has("Accept-Encoding")&&r.set("Accept-Encoding","gzip,deflate,br");let{agent:n}=e;"function"==typeof n&&(n=n(t)),r.has("Connection")||n||r.set("Connection","close");const s=(e=>{if(e.search)return e.search;const t=e.href.length-1,r=e.hash||("#"===e.href[t]?"#":"");return"?"===e.href[t-r.length]?"?":""})(t);return{path:t.pathname+s,pathname:t.pathname,hostname:t.hostname,protocol:t.protocol,port:t.port,hash:t.hash,search:t.search,query:t.query,href:t.href,method:e.method,headers:r[Symbol.for("nodejs.util.inspect.custom")](),insecureHTTPParser:e.insecureHTTPParser,agent:n}})(l);if(!$.has(c.protocol))throw new TypeError(`node-fetch cannot load ${e}. URL scheme "${c.protocol.replace(/:$/,"")}" is not supported.`);if("data:"===c.protocol){const e=a(l.url),t=new x(e,{headers:{"Content-Type":e.typeFull}});return void r(t)}const d=("https:"===c.protocol?n:o).request,{signal:f}=l;let h=null;const y=()=>{const e=new M("The operation was aborted.");u(e),l.body&&l.body instanceof i.Readable&&l.body.destroy(e),h&&h.body&&h.body.emit("error",e)};if(f&&f.aborted)return void y();const _=()=>{y(),R()},g=d(c);f&&f.addEventListener("abort",_);const R=()=>{g.abort(),f&&f.removeEventListener("abort",_)};g.on("error",(e=>{u(new p(`request to ${l.url} failed, reason: ${e.message}`,"system",e)),R()})),g.on("response",(e=>{g.setTimeout(0);const o=function(e=[]){return new O(e.reduce(((e,t,r,o)=>(r%2==0&&e.push(o.slice(r,r+2)),e)),[]).filter((([e,t])=>{try{return j(e),k(e,String(t)),!0}catch{return!1}})))}(e.rawHeaders);if(A(e.statusCode)){const n=o.get("Location"),s=null===n?null:new URL(n,l.url);switch(l.redirect){case"error":return u(new p(`uri requested responds with a redirect, redirect mode is set to error: ${l.url}`,"no-redirect")),void R();case"manual":if(null!==s)try{o.set("Location",s)}catch(e){u(e)}break;case"follow":{if(null===s)break;if(l.counter>=l.follow)return u(new p(`maximum redirect reached at: ${l.url}`,"max-redirect")),void R();const o={headers:new O(l.headers),follow:l.follow,counter:l.counter+1,agent:l.agent,compress:l.compress,method:l.method,body:l.body,signal:l.signal,size:l.size};return 303!==e.statusCode&&l.body&&t.body instanceof i.Readable?(u(new p("Cannot follow redirect with body being a readable stream","unsupported-redirect")),void R()):(303!==e.statusCode&&(301!==e.statusCode&&302!==e.statusCode||"POST"!==l.method)||(o.method="GET",o.body=void 0,o.headers.delete("content-length")),r(I(new z(s,o))),void R())}}}e.once("end",(()=>{f&&f.removeEventListener("abort",_)}));let n=i.pipeline(e,new i.PassThrough,(e=>{u(e)}));process.version<"v12.10"&&e.on("aborted",_);const a={url:l.url,status:e.statusCode,statusText:e.statusMessage,headers:o,size:l.size,counter:l.counter,highWaterMark:l.highWaterMark},c=o.get("Content-Encoding");if(!l.compress||"HEAD"===l.method||null===c||204===e.statusCode||304===e.statusCode)return h=new x(n,a),void r(h);const d={flush:s.Z_SYNC_FLUSH,finishFlush:s.Z_SYNC_FLUSH};if("gzip"===c||"x-gzip"===c)return n=i.pipeline(n,s.createGunzip(d),(e=>{u(e)})),h=new x(n,a),void r(h);if("deflate"!==c&&"x-deflate"!==c){if("br"===c)return n=i.pipeline(n,s.createBrotliDecompress(),(e=>{u(e)})),h=new x(n,a),void r(h);h=new x(n,a),r(h)}else i.pipeline(e,new i.PassThrough,(e=>{u(e)})).once("data",(e=>{n=8==(15&e[0])?i.pipeline(n,s.createInflate(),(e=>{u(e)})):i.pipeline(n,s.createInflateRaw(),(e=>{u(e)})),h=new x(n,a),r(h)}))})),((e,{body:t})=>{null===t?e.end():b(t)?t.stream().pipe(e):Buffer.isBuffer(t)?(e.write(t),e.end()):t.pipe(e)})(g,l)}))}t.AbortError=M,t.FetchError=p,t.Headers=O,t.Request=z,t.Response=x,t.default=I,t.isRedirect=A},78:e=>{function t(e){return e.replace(/[\/]+/g,"/").replace(/\/\?/g,"?").replace(/\/\#/g,"#").replace(/\:\//g,"://")}e.exports=function(){var e=[].slice.call(arguments,0).join("/");return t(e)}},377:(e,t,r)=>{"use strict";r.r(t),r.d(t,{ByteLengthQueuingStrategy:()=>pr,CountQueuingStrategy:()=>mr,ReadableByteStreamController:()=>ye,ReadableStream:()=>rr,ReadableStreamBYOBReader:()=>ze,ReadableStreamBYOBRequest:()=>he,ReadableStreamDefaultController:()=>Mt,ReadableStreamDefaultReader:()=>X,TransformStream:()=>Tr,TransformStreamDefaultController:()=>jr,WritableStream:()=>Ge,WritableStreamDefaultController:()=>yt,WritableStreamDefaultWriter:()=>ut});const o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol:e=>`Symbol(${e})`;function n(){}const s="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0;function i(e){return"object"==typeof e&&null!==e||"function"==typeof e}const a=n,u=Promise,l=Promise.prototype.then,c=Promise.resolve.bind(u),d=Promise.reject.bind(u);function f(e){return new u(e)}function p(e){return c(e)}function h(e){return d(e)}function y(e,t,r){return l.call(e,t,r)}function b(e,t,r){y(y(e,t,r),void 0,a)}function m(e,t){b(e,t)}function _(e,t){b(e,void 0,t)}function g(e,t,r){return y(e,t,r)}function w(e){y(e,void 0,a)}const v=(()=>{const e=s&&s.queueMicrotask;if("function"==typeof e)return e;const t=p(void 0);return e=>y(t,e)})();function S(e,t,r){if("function"!=typeof e)throw new TypeError("Argument is not a function");return Function.prototype.apply.call(e,t,r)}function T(e,t,r){try{return p(S(e,t,r))}catch(e){return h(e)}}class R{constructor(){this._cursor=0,this._size=0,this._front={_elements:[],_next:void 0},this._back=this._front,this._cursor=0,this._size=0}get length(){return this._size}push(e){const t=this._back;let r=t;16383===t._elements.length&&(r={_elements:[],_next:void 0}),t._elements.push(e),r!==t&&(this._back=r,t._next=r),++this._size}shift(){const e=this._front;let t=e;const r=this._cursor;let o=r+1;const n=e._elements,s=n[r];return 16384===o&&(t=e._next,o=0),--this._size,this._cursor=o,e!==t&&(this._front=t),n[r]=void 0,s}forEach(e){let t=this._cursor,r=this._front,o=r._elements;for(;!(t===o.length&&void 0===r._next||t===o.length&&(r=r._next,o=r._elements,t=0,0===o.length));)e(o[t]),++t}peek(){const e=this._front,t=this._cursor;return e._elements[t]}}function q(e,t){e._ownerReadableStream=t,t._reader=e,"readable"===t._state?k(e):"closed"===t._state?function(e){k(e),A(e)}(e):O(e,t._storedError)}function P(e,t){return ar(e._ownerReadableStream,t)}function E(e){"readable"===e._ownerReadableStream._state?C(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness")):function(e,t){O(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness"))}(e),e._ownerReadableStream._reader=void 0,e._ownerReadableStream=void 0}function j(e){return new TypeError("Cannot "+e+" a stream using a released reader")}function k(e){e._closedPromise=f(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r}))}function O(e,t){k(e),C(e,t)}function C(e,t){void 0!==e._closedPromise_reject&&(w(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}function A(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}const B=o("[[AbortSteps]]"),x=o("[[ErrorSteps]]"),W=o("[[CancelSteps]]"),L=o("[[PullSteps]]"),z=Number.isFinite||function(e){return"number"==typeof e&&isFinite(e)},M=Math.trunc||function(e){return e<0?Math.ceil(e):Math.floor(e)};function $(e,t){if(void 0!==e&&"object"!=typeof(r=e)&&"function"!=typeof r)throw new TypeError(`${t} is not an object.`);var r}function I(e,t){if("function"!=typeof e)throw new TypeError(`${t} is not a function.`)}function D(e,t){if(!function(e){return"object"==typeof e&&null!==e||"function"==typeof e}(e))throw new TypeError(`${t} is not an object.`)}function F(e,t,r){if(void 0===e)throw new TypeError(`Parameter ${t} is required in '${r}'.`)}function U(e,t,r){if(void 0===e)throw new TypeError(`${t} is required in '${r}'.`)}function H(e){return Number(e)}function N(e){return 0===e?0:e}function V(e,t){const r=Number.MAX_SAFE_INTEGER;let o=Number(e);if(o=N(o),!z(o))throw new TypeError(`${t} is not a finite number`);if(o=function(e){return N(M(e))}(o),o<0||o>r)throw new TypeError(`${t} is outside the accepted range of 0 to ${r}, inclusive`);return z(o)&&0!==o?o:0}function Q(e,t){if(!sr(e))throw new TypeError(`${t} is not a ReadableStream.`)}function Y(e){return new X(e)}function G(e,t){e._reader._readRequests.push(t)}function J(e,t,r){const o=e._reader._readRequests.shift();r?o._closeSteps():o._chunkSteps(t)}function K(e){return e._reader._readRequests.length}function Z(e){const t=e._reader;return void 0!==t&&!!ee(t)}class X{constructor(e){if(F(e,1,"ReadableStreamDefaultReader"),Q(e,"First parameter"),ir(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");q(this,e),this._readRequests=new R}get closed(){return ee(this)?this._closedPromise:h(re("closed"))}cancel(e){return ee(this)?void 0===this._ownerReadableStream?h(j("cancel")):P(this,e):h(re("cancel"))}read(){if(!ee(this))return h(re("read"));if(void 0===this._ownerReadableStream)return h(j("read from"));let e,t;const r=f(((r,o)=>{e=r,t=o}));return te(this,{_chunkSteps:t=>e({value:t,done:!1}),_closeSteps:()=>e({value:void 0,done:!0}),_errorSteps:e=>t(e)}),r}releaseLock(){if(!ee(this))throw re("releaseLock");if(void 0!==this._ownerReadableStream){if(this._readRequests.length>0)throw new TypeError("Tried to release a reader lock when that reader has pending read() calls un-settled");E(this)}}}function ee(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_readRequests")}function te(e,t){const r=e._ownerReadableStream;r._disturbed=!0,"closed"===r._state?t._closeSteps():"errored"===r._state?t._errorSteps(r._storedError):r._readableStreamController[L](t)}function re(e){return new TypeError(`ReadableStreamDefaultReader.prototype.${e} can only be used on a ReadableStreamDefaultReader`)}Object.defineProperties(X.prototype,{cancel:{enumerable:!0},read:{enumerable:!0},releaseLock:{enumerable:!0},closed:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(X.prototype,o.toStringTag,{value:"ReadableStreamDefaultReader",configurable:!0});const oe=Object.getPrototypeOf(Object.getPrototypeOf((async function*(){})).prototype);class ne{constructor(e,t){this._ongoingPromise=void 0,this._isFinished=!1,this._reader=e,this._preventCancel=t}next(){const e=()=>this._nextSteps();return this._ongoingPromise=this._ongoingPromise?g(this._ongoingPromise,e,e):e(),this._ongoingPromise}return(e){const t=()=>this._returnSteps(e);return this._ongoingPromise?g(this._ongoingPromise,t,t):t()}_nextSteps(){if(this._isFinished)return Promise.resolve({value:void 0,done:!0});const e=this._reader;if(void 0===e._ownerReadableStream)return h(j("iterate"));let t,r;const o=f(((e,o)=>{t=e,r=o}));return te(e,{_chunkSteps:e=>{this._ongoingPromise=void 0,v((()=>t({value:e,done:!1})))},_closeSteps:()=>{this._ongoingPromise=void 0,this._isFinished=!0,E(e),t({value:void 0,done:!0})},_errorSteps:t=>{this._ongoingPromise=void 0,this._isFinished=!0,E(e),r(t)}}),o}_returnSteps(e){if(this._isFinished)return Promise.resolve({value:e,done:!0});this._isFinished=!0;const t=this._reader;if(void 0===t._ownerReadableStream)return h(j("finish iterating"));if(!this._preventCancel){const r=P(t,e);return E(t),g(r,(()=>({value:e,done:!0})))}return E(t),p({value:e,done:!0})}}const se={next(){return ie(this)?this._asyncIteratorImpl.next():h(ae("next"))},return(e){return ie(this)?this._asyncIteratorImpl.return(e):h(ae("return"))}};function ie(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_asyncIteratorImpl")}function ae(e){return new TypeError(`ReadableStreamAsyncIterator.${e} can only be used on a ReadableSteamAsyncIterator`)}void 0!==oe&&Object.setPrototypeOf(se,oe);const ue=Number.isNaN||function(e){return e!=e};function le(e){return!!function(e){return"number"==typeof e&&(!ue(e)&&!(e<0))}(e)&&e!==1/0}function ce(e){const t=e._queue.shift();return e._queueTotalSize-=t.size,e._queueTotalSize<0&&(e._queueTotalSize=0),t.value}function de(e,t,r){if(!le(r=Number(r)))throw new RangeError("Size must be a finite, non-NaN, non-negative number.");e._queue.push({value:t,size:r}),e._queueTotalSize+=r}function fe(e){e._queue=new R,e._queueTotalSize=0}function pe(e){return e.slice()}class he{constructor(){throw new TypeError("Illegal constructor")}get view(){if(!me(this))throw Ae("view");return this._view}respond(e){if(!me(this))throw Ae("respond");if(F(e,1,"respond"),e=V(e,"First parameter"),void 0===this._associatedReadableByteStreamController)throw new TypeError("This BYOB request has been invalidated");this._view.buffer,function(e,t){if(!le(t=Number(t)))throw new RangeError("bytesWritten must be a finite");Ee(e,t)}(this._associatedReadableByteStreamController,e)}respondWithNewView(e){if(!me(this))throw Ae("respondWithNewView");if(F(e,1,"respondWithNewView"),!ArrayBuffer.isView(e))throw new TypeError("You can only respond with array buffer views");if(0===e.byteLength)throw new TypeError("chunk must have non-zero byteLength");if(0===e.buffer.byteLength)throw new TypeError("chunk's buffer must have non-zero byteLength");if(void 0===this._associatedReadableByteStreamController)throw new TypeError("This BYOB request has been invalidated");!function(e,t){const r=e._pendingPullIntos.peek();if(r.byteOffset+r.bytesFilled!==t.byteOffset)throw new RangeError("The region specified by view does not match byobRequest");if(r.byteLength!==t.byteLength)throw new RangeError("The buffer of view has different capacity than byobRequest");r.buffer=t.buffer,Ee(e,t.byteLength)}(this._associatedReadableByteStreamController,e)}}Object.defineProperties(he.prototype,{respond:{enumerable:!0},respondWithNewView:{enumerable:!0},view:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(he.prototype,o.toStringTag,{value:"ReadableStreamBYOBRequest",configurable:!0});class ye{constructor(){throw new TypeError("Illegal constructor")}get byobRequest(){if(!be(this))throw Be("byobRequest");if(null===this._byobRequest&&this._pendingPullIntos.length>0){const e=this._pendingPullIntos.peek(),t=new Uint8Array(e.buffer,e.byteOffset+e.bytesFilled,e.byteLength-e.bytesFilled),r=Object.create(he.prototype);!function(e,t,r){e._associatedReadableByteStreamController=t,e._view=r}(r,this,t),this._byobRequest=r}return this._byobRequest}get desiredSize(){if(!be(this))throw Be("desiredSize");return Ce(this)}close(){if(!be(this))throw Be("close");if(this._closeRequested)throw new TypeError("The stream has already been closed; do not close it again!");const e=this._controlledReadableByteStream._state;if("readable"!==e)throw new TypeError(`The stream (in ${e} state) is not in the readable state and cannot be closed`);!function(e){const t=e._controlledReadableByteStream;if(!e._closeRequested&&"readable"===t._state)if(e._queueTotalSize>0)e._closeRequested=!0;else{if(e._pendingPullIntos.length>0&&e._pendingPullIntos.peek().bytesFilled>0){const t=new TypeError("Insufficient bytes to fill elements in the given buffer");throw Oe(e,t),t}ke(e),ur(t)}}(this)}enqueue(e){if(!be(this))throw Be("enqueue");if(F(e,1,"enqueue"),!ArrayBuffer.isView(e))throw new TypeError("chunk must be an array buffer view");if(0===e.byteLength)throw new TypeError("chunk must have non-zero byteLength");if(0===e.buffer.byteLength)throw new TypeError("chunk's buffer must have non-zero byteLength");if(this._closeRequested)throw new TypeError("stream is closed or draining");const t=this._controlledReadableByteStream._state;if("readable"!==t)throw new TypeError(`The stream (in ${t} state) is not in the readable state and cannot be enqueued to`);!function(e,t){const r=e._controlledReadableByteStream;if(e._closeRequested||"readable"!==r._state)return;const o=t.buffer,n=t.byteOffset,s=t.byteLength,i=o;Z(r)?0===K(r)?ve(e,i,n,s):J(r,new Uint8Array(i,n,s),!1):Le(r)?(ve(e,i,n,s),Pe(e)):ve(e,i,n,s),_e(e)}(this,e)}error(e){if(!be(this))throw Be("error");Oe(this,e)}[W](e){this._pendingPullIntos.length>0&&(this._pendingPullIntos.peek().bytesFilled=0),fe(this);const t=this._cancelAlgorithm(e);return ke(this),t}[L](e){const t=this._controlledReadableByteStream;if(this._queueTotalSize>0){const t=this._queue.shift();this._queueTotalSize-=t.byteLength,Re(this);const r=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return void e._chunkSteps(r)}const r=this._autoAllocateChunkSize;if(void 0!==r){let t;try{t=new ArrayBuffer(r)}catch(t){return void e._errorSteps(t)}const o={buffer:t,byteOffset:0,byteLength:r,bytesFilled:0,elementSize:1,viewConstructor:Uint8Array,readerType:"default"};this._pendingPullIntos.push(o)}G(t,e),_e(this)}}function be(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_controlledReadableByteStream")}function me(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_associatedReadableByteStreamController")}function _e(e){(function(e){const t=e._controlledReadableByteStream;return"readable"===t._state&&(!e._closeRequested&&(!!e._started&&(!!(Z(t)&&K(t)>0)||(!!(Le(t)&&We(t)>0)||Ce(e)>0))))})(e)&&(e._pulling?e._pullAgain=!0:(e._pulling=!0,b(e._pullAlgorithm(),(()=>{e._pulling=!1,e._pullAgain&&(e._pullAgain=!1,_e(e))}),(t=>{Oe(e,t)}))))}function ge(e,t){let r=!1;"closed"===e._state&&(r=!0);const o=we(t);"default"===t.readerType?J(e,o,r):function(e,t,r){const o=e._reader._readIntoRequests.shift();r?o._closeSteps(t):o._chunkSteps(t)}(e,o,r)}function we(e){const t=e.bytesFilled,r=e.elementSize;return new e.viewConstructor(e.buffer,e.byteOffset,t/r)}function ve(e,t,r,o){e._queue.push({buffer:t,byteOffset:r,byteLength:o}),e._queueTotalSize+=o}function Se(e,t){const r=t.elementSize,o=t.bytesFilled-t.bytesFilled%r,n=Math.min(e._queueTotalSize,t.byteLength-t.bytesFilled),s=t.bytesFilled+n,i=s-s%r;let a=n,u=!1;i>o&&(a=i-t.bytesFilled,u=!0);const l=e._queue;for(;a>0;){const r=l.peek(),o=Math.min(a,r.byteLength),n=t.byteOffset+t.bytesFilled;c=t.buffer,d=n,f=r.buffer,p=r.byteOffset,h=o,new Uint8Array(c).set(new Uint8Array(f,p,h),d),r.byteLength===o?l.shift():(r.byteOffset+=o,r.byteLength-=o),e._queueTotalSize-=o,Te(e,o,t),a-=o}var c,d,f,p,h;return u}function Te(e,t,r){qe(e),r.bytesFilled+=t}function Re(e){0===e._queueTotalSize&&e._closeRequested?(ke(e),ur(e._controlledReadableByteStream)):_e(e)}function qe(e){null!==e._byobRequest&&(e._byobRequest._associatedReadableByteStreamController=void 0,e._byobRequest._view=null,e._byobRequest=null)}function Pe(e){for(;e._pendingPullIntos.length>0;){if(0===e._queueTotalSize)return;const t=e._pendingPullIntos.peek();Se(e,t)&&(je(e),ge(e._controlledReadableByteStream,t))}}function Ee(e,t){const r=e._pendingPullIntos.peek();if("closed"===e._controlledReadableByteStream._state){if(0!==t)throw new TypeError("bytesWritten must be 0 when calling respond() on a closed stream");!function(e,t){t.buffer=t.buffer;const r=e._controlledReadableByteStream;if(Le(r))for(;We(r)>0;)ge(r,je(e))}(e,r)}else!function(e,t,r){if(r.bytesFilled+t>r.byteLength)throw new RangeError("bytesWritten out of range");if(Te(e,t,r),r.bytesFilled0){const t=r.byteOffset+r.bytesFilled,n=r.buffer.slice(t-o,t);ve(e,n,0,n.byteLength)}r.buffer=r.buffer,r.bytesFilled-=o,ge(e._controlledReadableByteStream,r),Pe(e)}(e,t,r);_e(e)}function je(e){const t=e._pendingPullIntos.shift();return qe(e),t}function ke(e){e._pullAlgorithm=void 0,e._cancelAlgorithm=void 0}function Oe(e,t){const r=e._controlledReadableByteStream;"readable"===r._state&&(function(e){qe(e),e._pendingPullIntos=new R}(e),fe(e),ke(e),lr(r,t))}function Ce(e){const t=e._controlledReadableByteStream._state;return"errored"===t?null:"closed"===t?0:e._strategyHWM-e._queueTotalSize}function Ae(e){return new TypeError(`ReadableStreamBYOBRequest.prototype.${e} can only be used on a ReadableStreamBYOBRequest`)}function Be(e){return new TypeError(`ReadableByteStreamController.prototype.${e} can only be used on a ReadableByteStreamController`)}function xe(e,t){e._reader._readIntoRequests.push(t)}function We(e){return e._reader._readIntoRequests.length}function Le(e){const t=e._reader;return void 0!==t&&!!Me(t)}Object.defineProperties(ye.prototype,{close:{enumerable:!0},enqueue:{enumerable:!0},error:{enumerable:!0},byobRequest:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ye.prototype,o.toStringTag,{value:"ReadableByteStreamController",configurable:!0});class ze{constructor(e){if(F(e,1,"ReadableStreamBYOBReader"),Q(e,"First parameter"),ir(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");if(!be(e._readableStreamController))throw new TypeError("Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte source");q(this,e),this._readIntoRequests=new R}get closed(){return Me(this)?this._closedPromise:h($e("closed"))}cancel(e){return Me(this)?void 0===this._ownerReadableStream?h(j("cancel")):P(this,e):h($e("cancel"))}read(e){if(!Me(this))return h($e("read"));if(!ArrayBuffer.isView(e))return h(new TypeError("view must be an array buffer view"));if(0===e.byteLength)return h(new TypeError("view must have non-zero byteLength"));if(0===e.buffer.byteLength)return h(new TypeError("view's buffer must have non-zero byteLength"));if(void 0===this._ownerReadableStream)return h(j("read from"));let t,r;const o=f(((e,o)=>{t=e,r=o}));return function(e,t,r){const o=e._ownerReadableStream;o._disturbed=!0,"errored"===o._state?r._errorSteps(o._storedError):function(e,t,r){const o=e._controlledReadableByteStream;let n=1;t.constructor!==DataView&&(n=t.constructor.BYTES_PER_ELEMENT);const s=t.constructor,i={buffer:t.buffer,byteOffset:t.byteOffset,byteLength:t.byteLength,bytesFilled:0,elementSize:n,viewConstructor:s,readerType:"byob"};if(e._pendingPullIntos.length>0)return e._pendingPullIntos.push(i),void xe(o,r);if("closed"!==o._state){if(e._queueTotalSize>0){if(Se(e,i)){const t=we(i);return Re(e),void r._chunkSteps(t)}if(e._closeRequested){const t=new TypeError("Insufficient bytes to fill elements in the given buffer");return Oe(e,t),void r._errorSteps(t)}}e._pendingPullIntos.push(i),xe(o,r),_e(e)}else{const e=new s(i.buffer,i.byteOffset,0);r._closeSteps(e)}}(o._readableStreamController,t,r)}(this,e,{_chunkSteps:e=>t({value:e,done:!1}),_closeSteps:e=>t({value:e,done:!0}),_errorSteps:e=>r(e)}),o}releaseLock(){if(!Me(this))throw $e("releaseLock");if(void 0!==this._ownerReadableStream){if(this._readIntoRequests.length>0)throw new TypeError("Tried to release a reader lock when that reader has pending read() calls un-settled");E(this)}}}function Me(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_readIntoRequests")}function $e(e){return new TypeError(`ReadableStreamBYOBReader.prototype.${e} can only be used on a ReadableStreamBYOBReader`)}function Ie(e,t){const{highWaterMark:r}=e;if(void 0===r)return t;if(ue(r)||r<0)throw new RangeError("Invalid highWaterMark");return r}function De(e){const{size:t}=e;return t||(()=>1)}function Fe(e,t){$(e,t);const r=null==e?void 0:e.highWaterMark,o=null==e?void 0:e.size;return{highWaterMark:void 0===r?void 0:H(r),size:void 0===o?void 0:Ue(o,`${t} has member 'size' that`)}}function Ue(e,t){return I(e,t),t=>H(e(t))}function He(e,t,r){return I(e,r),r=>T(e,t,[r])}function Ne(e,t,r){return I(e,r),()=>T(e,t,[])}function Ve(e,t,r){return I(e,r),r=>S(e,t,[r])}function Qe(e,t,r){return I(e,r),(r,o)=>T(e,t,[r,o])}function Ye(e,t){if(!Ze(e))throw new TypeError(`${t} is not a WritableStream.`)}Object.defineProperties(ze.prototype,{cancel:{enumerable:!0},read:{enumerable:!0},releaseLock:{enumerable:!0},closed:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ze.prototype,o.toStringTag,{value:"ReadableStreamBYOBReader",configurable:!0});class Ge{constructor(e={},t={}){void 0===e?e=null:D(e,"First parameter");const r=Fe(t,"Second parameter"),o=function(e,t){$(e,t);const r=null==e?void 0:e.abort,o=null==e?void 0:e.close,n=null==e?void 0:e.start,s=null==e?void 0:e.type,i=null==e?void 0:e.write;return{abort:void 0===r?void 0:He(r,e,`${t} has member 'abort' that`),close:void 0===o?void 0:Ne(o,e,`${t} has member 'close' that`),start:void 0===n?void 0:Ve(n,e,`${t} has member 'start' that`),write:void 0===i?void 0:Qe(i,e,`${t} has member 'write' that`),type:s}}(e,"First parameter");if(Ke(this),void 0!==o.type)throw new RangeError("Invalid type is specified");const n=De(r);!function(e,t,r,o){const n=Object.create(yt.prototype);let s=()=>{},i=()=>p(void 0),a=()=>p(void 0),u=()=>p(void 0);void 0!==t.start&&(s=()=>t.start(n)),void 0!==t.write&&(i=e=>t.write(e,n)),void 0!==t.close&&(a=()=>t.close()),void 0!==t.abort&&(u=e=>t.abort(e)),bt(e,n,s,i,a,u,r,o)}(this,o,Ie(r,1),n)}get locked(){if(!Ze(this))throw Tt("locked");return Xe(this)}abort(e){return Ze(this)?Xe(this)?h(new TypeError("Cannot abort a stream that already has a writer")):et(this,e):h(Tt("abort"))}close(){return Ze(this)?Xe(this)?h(new TypeError("Cannot close a stream that already has a writer")):st(this)?h(new TypeError("Cannot close an already-closing stream")):tt(this):h(Tt("close"))}getWriter(){if(!Ze(this))throw Tt("getWriter");return Je(this)}}function Je(e){return new ut(e)}function Ke(e){e._state="writable",e._storedError=void 0,e._writer=void 0,e._writableStreamController=void 0,e._writeRequests=new R,e._inFlightWriteRequest=void 0,e._closeRequest=void 0,e._inFlightCloseRequest=void 0,e._pendingAbortRequest=void 0,e._backpressure=!1}function Ze(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_writableStreamController")}function Xe(e){return void 0!==e._writer}function et(e,t){const r=e._state;if("closed"===r||"errored"===r)return p(void 0);if(void 0!==e._pendingAbortRequest)return e._pendingAbortRequest._promise;let o=!1;"erroring"===r&&(o=!0,t=void 0);const n=f(((r,n)=>{e._pendingAbortRequest={_promise:void 0,_resolve:r,_reject:n,_reason:t,_wasAlreadyErroring:o}}));return e._pendingAbortRequest._promise=n,o||ot(e,t),n}function tt(e){const t=e._state;if("closed"===t||"errored"===t)return h(new TypeError(`The stream (in ${t} state) is not in the writable state and cannot be closed`));const r=f(((t,r)=>{const o={_resolve:t,_reject:r};e._closeRequest=o})),o=e._writer;var n;return void 0!==o&&e._backpressure&&"writable"===t&&xt(o),de(n=e._writableStreamController,ht,0),gt(n),r}function rt(e,t){"writable"!==e._state?nt(e):ot(e,t)}function ot(e,t){const r=e._writableStreamController;e._state="erroring",e._storedError=t;const o=e._writer;void 0!==o&&dt(o,t),!function(e){return void 0!==e._inFlightWriteRequest||void 0!==e._inFlightCloseRequest}(e)&&r._started&&nt(e)}function nt(e){e._state="errored",e._writableStreamController[x]();const t=e._storedError;if(e._writeRequests.forEach((e=>{e._reject(t)})),e._writeRequests=new R,void 0===e._pendingAbortRequest)return void it(e);const r=e._pendingAbortRequest;if(e._pendingAbortRequest=void 0,r._wasAlreadyErroring)return r._reject(t),void it(e);b(e._writableStreamController[B](r._reason),(()=>{r._resolve(),it(e)}),(t=>{r._reject(t),it(e)}))}function st(e){return void 0!==e._closeRequest||void 0!==e._inFlightCloseRequest}function it(e){void 0!==e._closeRequest&&(e._closeRequest._reject(e._storedError),e._closeRequest=void 0);const t=e._writer;void 0!==t&&jt(t,e._storedError)}function at(e,t){const r=e._writer;void 0!==r&&t!==e._backpressure&&(t?function(e){Ot(e)}(r):xt(r)),e._backpressure=t}Object.defineProperties(Ge.prototype,{abort:{enumerable:!0},close:{enumerable:!0},getWriter:{enumerable:!0},locked:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(Ge.prototype,o.toStringTag,{value:"WritableStream",configurable:!0});class ut{constructor(e){if(F(e,1,"WritableStreamDefaultWriter"),Ye(e,"First parameter"),Xe(e))throw new TypeError("This stream has already been locked for exclusive writing by another writer");this._ownerWritableStream=e,e._writer=this;const t=e._state;if("writable"===t)!st(e)&&e._backpressure?Ot(this):At(this),Pt(this);else if("erroring"===t)Ct(this,e._storedError),Pt(this);else if("closed"===t)At(this),Pt(this),kt(this);else{const t=e._storedError;Ct(this,t),Et(this,t)}}get closed(){return lt(this)?this._closedPromise:h(Rt("closed"))}get desiredSize(){if(!lt(this))throw Rt("desiredSize");if(void 0===this._ownerWritableStream)throw qt("desiredSize");return function(e){const t=e._ownerWritableStream,r=t._state;return"errored"===r||"erroring"===r?null:"closed"===r?0:_t(t._writableStreamController)}(this)}get ready(){return lt(this)?this._readyPromise:h(Rt("ready"))}abort(e){return lt(this)?void 0===this._ownerWritableStream?h(qt("abort")):function(e,t){return et(e._ownerWritableStream,t)}(this,e):h(Rt("abort"))}close(){if(!lt(this))return h(Rt("close"));const e=this._ownerWritableStream;return void 0===e?h(qt("close")):st(e)?h(new TypeError("Cannot close an already-closing stream")):ct(this)}releaseLock(){if(!lt(this))throw Rt("releaseLock");void 0!==this._ownerWritableStream&&ft(this)}write(e){return lt(this)?void 0===this._ownerWritableStream?h(qt("write to")):pt(this,e):h(Rt("write"))}}function lt(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_ownerWritableStream")}function ct(e){return tt(e._ownerWritableStream)}function dt(e,t){"pending"===e._readyPromiseState?Bt(e,t):function(e,t){Ct(e,t)}(e,t)}function ft(e){const t=e._ownerWritableStream,r=new TypeError("Writer was released and can no longer be used to monitor the stream's closedness");dt(e,r),function(e,t){"pending"===e._closedPromiseState?jt(e,t):function(e,t){Et(e,t)}(e,t)}(e,r),t._writer=void 0,e._ownerWritableStream=void 0}function pt(e,t){const r=e._ownerWritableStream,o=r._writableStreamController,n=function(e,t){try{return e._strategySizeAlgorithm(t)}catch(t){return wt(e,t),1}}(o,t);if(r!==e._ownerWritableStream)return h(qt("write to"));const s=r._state;if("errored"===s)return h(r._storedError);if(st(r)||"closed"===s)return h(new TypeError("The stream is closing or closed and cannot be written to"));if("erroring"===s)return h(r._storedError);const i=function(e){return f(((t,r)=>{const o={_resolve:t,_reject:r};e._writeRequests.push(o)}))}(r);return function(e,t,r){try{de(e,t,r)}catch(t){return void wt(e,t)}const o=e._controlledWritableStream;st(o)||"writable"!==o._state||at(o,vt(e)),gt(e)}(o,t,n),i}Object.defineProperties(ut.prototype,{abort:{enumerable:!0},close:{enumerable:!0},releaseLock:{enumerable:!0},write:{enumerable:!0},closed:{enumerable:!0},desiredSize:{enumerable:!0},ready:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ut.prototype,o.toStringTag,{value:"WritableStreamDefaultWriter",configurable:!0});const ht={};class yt{constructor(){throw new TypeError("Illegal constructor")}error(e){if(!i(t=this)||!Object.prototype.hasOwnProperty.call(t,"_controlledWritableStream"))throw new TypeError("WritableStreamDefaultController.prototype.error can only be used on a WritableStreamDefaultController");var t;"writable"===this._controlledWritableStream._state&&St(this,e)}[B](e){const t=this._abortAlgorithm(e);return mt(this),t}[x](){fe(this)}}function bt(e,t,r,o,n,s,i,a){t._controlledWritableStream=e,e._writableStreamController=t,t._queue=void 0,t._queueTotalSize=void 0,fe(t),t._started=!1,t._strategySizeAlgorithm=a,t._strategyHWM=i,t._writeAlgorithm=o,t._closeAlgorithm=n,t._abortAlgorithm=s;const u=vt(t);at(e,u),b(p(r()),(()=>{t._started=!0,gt(t)}),(r=>{t._started=!0,rt(e,r)}))}function mt(e){e._writeAlgorithm=void 0,e._closeAlgorithm=void 0,e._abortAlgorithm=void 0,e._strategySizeAlgorithm=void 0}function _t(e){return e._strategyHWM-e._queueTotalSize}function gt(e){const t=e._controlledWritableStream;if(!e._started)return;if(void 0!==t._inFlightWriteRequest)return;if("erroring"===t._state)return void nt(t);if(0===e._queue.length)return;const r=e._queue.peek().value;r===ht?function(e){const t=e._controlledWritableStream;(function(e){e._inFlightCloseRequest=e._closeRequest,e._closeRequest=void 0})(t),ce(e);const r=e._closeAlgorithm();mt(e),b(r,(()=>{!function(e){e._inFlightCloseRequest._resolve(void 0),e._inFlightCloseRequest=void 0,"erroring"===e._state&&(e._storedError=void 0,void 0!==e._pendingAbortRequest&&(e._pendingAbortRequest._resolve(),e._pendingAbortRequest=void 0)),e._state="closed";const t=e._writer;void 0!==t&&kt(t)}(t)}),(e=>{!function(e,t){e._inFlightCloseRequest._reject(t),e._inFlightCloseRequest=void 0,void 0!==e._pendingAbortRequest&&(e._pendingAbortRequest._reject(t),e._pendingAbortRequest=void 0),rt(e,t)}(t,e)}))}(e):function(e,t){const r=e._controlledWritableStream;!function(e){e._inFlightWriteRequest=e._writeRequests.shift()}(r),b(e._writeAlgorithm(t),(()=>{!function(e){e._inFlightWriteRequest._resolve(void 0),e._inFlightWriteRequest=void 0}(r);const t=r._state;if(ce(e),!st(r)&&"writable"===t){const t=vt(e);at(r,t)}gt(e)}),(t=>{"writable"===r._state&&mt(e),function(e,t){e._inFlightWriteRequest._reject(t),e._inFlightWriteRequest=void 0,rt(e,t)}(r,t)}))}(e,r)}function wt(e,t){"writable"===e._controlledWritableStream._state&&St(e,t)}function vt(e){return _t(e)<=0}function St(e,t){const r=e._controlledWritableStream;mt(e),ot(r,t)}function Tt(e){return new TypeError(`WritableStream.prototype.${e} can only be used on a WritableStream`)}function Rt(e){return new TypeError(`WritableStreamDefaultWriter.prototype.${e} can only be used on a WritableStreamDefaultWriter`)}function qt(e){return new TypeError("Cannot "+e+" a stream using a released writer")}function Pt(e){e._closedPromise=f(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r,e._closedPromiseState="pending"}))}function Et(e,t){Pt(e),jt(e,t)}function jt(e,t){void 0!==e._closedPromise_reject&&(w(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0,e._closedPromiseState="rejected")}function kt(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0,e._closedPromiseState="resolved")}function Ot(e){e._readyPromise=f(((t,r)=>{e._readyPromise_resolve=t,e._readyPromise_reject=r})),e._readyPromiseState="pending"}function Ct(e,t){Ot(e),Bt(e,t)}function At(e){Ot(e),xt(e)}function Bt(e,t){void 0!==e._readyPromise_reject&&(w(e._readyPromise),e._readyPromise_reject(t),e._readyPromise_resolve=void 0,e._readyPromise_reject=void 0,e._readyPromiseState="rejected")}function xt(e){void 0!==e._readyPromise_resolve&&(e._readyPromise_resolve(void 0),e._readyPromise_resolve=void 0,e._readyPromise_reject=void 0,e._readyPromiseState="fulfilled")}Object.defineProperties(yt.prototype,{error:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(yt.prototype,o.toStringTag,{value:"WritableStreamDefaultController",configurable:!0});const Wt="undefined"!=typeof DOMException?DOMException:void 0,Lt=function(e){if("function"!=typeof e&&"object"!=typeof e)return!1;try{return new e,!0}catch(e){return!1}}(Wt)?Wt:function(){const e=function(e,t){this.message=e||"",this.name=t||"Error",Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)};return e.prototype=Object.create(Error.prototype),Object.defineProperty(e.prototype,"constructor",{value:e,writable:!0,configurable:!0}),e}();function zt(e,t,r,o,s,i){const a=Y(e),u=Je(t);e._disturbed=!0;let l=!1,c=p(void 0);return f(((d,g)=>{let v;if(void 0!==i){if(v=()=>{const r=new Lt("Aborted","AbortError"),n=[];o||n.push((()=>"writable"===t._state?et(t,r):p(void 0))),s||n.push((()=>"readable"===e._state?ar(e,r):p(void 0))),j((()=>Promise.all(n.map((e=>e())))),!0,r)},i.aborted)return void v();i.addEventListener("abort",v)}var S,T,R;if(P(e,a._closedPromise,(e=>{o?k(!0,e):j((()=>et(t,e)),!0,e)})),P(t,u._closedPromise,(t=>{s?k(!0,t):j((()=>ar(e,t)),!0,t)})),S=e,T=a._closedPromise,R=()=>{r?k():j((()=>function(e){const t=e._ownerWritableStream,r=t._state;return st(t)||"closed"===r?p(void 0):"errored"===r?h(t._storedError):ct(e)}(u)))},"closed"===S._state?R():m(T,R),st(t)||"closed"===t._state){const t=new TypeError("the destination writable stream closed before all data could be piped to it");s?k(!0,t):j((()=>ar(e,t)),!0,t)}function q(){const e=c;return y(c,(()=>e!==c?q():void 0))}function P(e,t,r){"errored"===e._state?r(e._storedError):_(t,r)}function j(e,r,o){function n(){b(e(),(()=>O(r,o)),(e=>O(!0,e)))}l||(l=!0,"writable"!==t._state||st(t)?n():m(q(),n))}function k(e,r){l||(l=!0,"writable"!==t._state||st(t)?O(e,r):m(q(),(()=>O(e,r))))}function O(e,t){ft(u),E(a),void 0!==i&&i.removeEventListener("abort",v),e?g(t):d(void 0)}w(f(((e,t)=>{!function r(o){o?e():y(l?p(!0):y(u._readyPromise,(()=>f(((e,t)=>{te(a,{_chunkSteps:t=>{c=y(pt(u,t),void 0,n),e(!1)},_closeSteps:()=>e(!0),_errorSteps:t})})))),r,t)}(!1)})))}))}class Mt{constructor(){throw new TypeError("Illegal constructor")}get desiredSize(){if(!$t(this))throw Gt("desiredSize");return Vt(this)}close(){if(!$t(this))throw Gt("close");if(!Qt(this))throw new TypeError("The stream is not in a state that permits close");Ut(this)}enqueue(e){if(!$t(this))throw Gt("enqueue");if(!Qt(this))throw new TypeError("The stream is not in a state that permits enqueue");return Ht(this,e)}error(e){if(!$t(this))throw Gt("error");Nt(this,e)}[W](e){fe(this);const t=this._cancelAlgorithm(e);return Ft(this),t}[L](e){const t=this._controlledReadableStream;if(this._queue.length>0){const r=ce(this);this._closeRequested&&0===this._queue.length?(Ft(this),ur(t)):It(this),e._chunkSteps(r)}else G(t,e),It(this)}}function $t(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_controlledReadableStream")}function It(e){Dt(e)&&(e._pulling?e._pullAgain=!0:(e._pulling=!0,b(e._pullAlgorithm(),(()=>{e._pulling=!1,e._pullAgain&&(e._pullAgain=!1,It(e))}),(t=>{Nt(e,t)}))))}function Dt(e){const t=e._controlledReadableStream;return!!Qt(e)&&(!!e._started&&(!!(ir(t)&&K(t)>0)||Vt(e)>0))}function Ft(e){e._pullAlgorithm=void 0,e._cancelAlgorithm=void 0,e._strategySizeAlgorithm=void 0}function Ut(e){if(!Qt(e))return;const t=e._controlledReadableStream;e._closeRequested=!0,0===e._queue.length&&(Ft(e),ur(t))}function Ht(e,t){if(!Qt(e))return;const r=e._controlledReadableStream;if(ir(r)&&K(r)>0)J(r,t,!1);else{let r;try{r=e._strategySizeAlgorithm(t)}catch(t){throw Nt(e,t),t}try{de(e,t,r)}catch(t){throw Nt(e,t),t}}It(e)}function Nt(e,t){const r=e._controlledReadableStream;"readable"===r._state&&(fe(e),Ft(e),lr(r,t))}function Vt(e){const t=e._controlledReadableStream._state;return"errored"===t?null:"closed"===t?0:e._strategyHWM-e._queueTotalSize}function Qt(e){const t=e._controlledReadableStream._state;return!e._closeRequested&&"readable"===t}function Yt(e,t,r,o,n,s,i){t._controlledReadableStream=e,t._queue=void 0,t._queueTotalSize=void 0,fe(t),t._started=!1,t._closeRequested=!1,t._pullAgain=!1,t._pulling=!1,t._strategySizeAlgorithm=i,t._strategyHWM=s,t._pullAlgorithm=o,t._cancelAlgorithm=n,e._readableStreamController=t,b(p(r()),(()=>{t._started=!0,It(t)}),(e=>{Nt(t,e)}))}function Gt(e){return new TypeError(`ReadableStreamDefaultController.prototype.${e} can only be used on a ReadableStreamDefaultController`)}function Jt(e,t,r){return I(e,r),r=>T(e,t,[r])}function Kt(e,t,r){return I(e,r),r=>T(e,t,[r])}function Zt(e,t,r){return I(e,r),r=>S(e,t,[r])}function Xt(e,t){if("bytes"!=(e=`${e}`))throw new TypeError(`${t} '${e}' is not a valid enumeration value for ReadableStreamType`);return e}function er(e,t){if("byob"!=(e=`${e}`))throw new TypeError(`${t} '${e}' is not a valid enumeration value for ReadableStreamReaderMode`);return e}function tr(e,t){$(e,t);const r=null==e?void 0:e.preventAbort,o=null==e?void 0:e.preventCancel,n=null==e?void 0:e.preventClose,s=null==e?void 0:e.signal;return void 0!==s&&function(e,t){if(!function(e){if("object"!=typeof e||null===e)return!1;try{return"boolean"==typeof e.aborted}catch(e){return!1}}(e))throw new TypeError(`${t} is not an AbortSignal.`)}(s,`${t} has member 'signal' that`),{preventAbort:Boolean(r),preventCancel:Boolean(o),preventClose:Boolean(n),signal:s}}Object.defineProperties(Mt.prototype,{close:{enumerable:!0},enqueue:{enumerable:!0},error:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(Mt.prototype,o.toStringTag,{value:"ReadableStreamDefaultController",configurable:!0});class rr{constructor(e={},t={}){void 0===e?e=null:D(e,"First parameter");const r=Fe(t,"Second parameter"),o=function(e,t){$(e,t);const r=e,o=null==r?void 0:r.autoAllocateChunkSize,n=null==r?void 0:r.cancel,s=null==r?void 0:r.pull,i=null==r?void 0:r.start,a=null==r?void 0:r.type;return{autoAllocateChunkSize:void 0===o?void 0:V(o,`${t} has member 'autoAllocateChunkSize' that`),cancel:void 0===n?void 0:Jt(n,r,`${t} has member 'cancel' that`),pull:void 0===s?void 0:Kt(s,r,`${t} has member 'pull' that`),start:void 0===i?void 0:Zt(i,r,`${t} has member 'start' that`),type:void 0===a?void 0:Xt(a,`${t} has member 'type' that`)}}(e,"First parameter");if(nr(this),"bytes"===o.type){if(void 0!==r.size)throw new RangeError("The strategy for a byte stream cannot have a size function");!function(e,t,r){const o=Object.create(ye.prototype);let n=()=>{},s=()=>p(void 0),i=()=>p(void 0);void 0!==t.start&&(n=()=>t.start(o)),void 0!==t.pull&&(s=()=>t.pull(o)),void 0!==t.cancel&&(i=e=>t.cancel(e));const a=t.autoAllocateChunkSize;!function(e,t,r,o,n,s,i){t._controlledReadableByteStream=e,t._pullAgain=!1,t._pulling=!1,t._byobRequest=null,t._queue=t._queueTotalSize=void 0,fe(t),t._closeRequested=!1,t._started=!1,t._strategyHWM=s,t._pullAlgorithm=o,t._cancelAlgorithm=n,t._autoAllocateChunkSize=i,t._pendingPullIntos=new R,e._readableStreamController=t,b(p(r()),(()=>{t._started=!0,_e(t)}),(e=>{Oe(t,e)}))}(e,o,n,s,i,r,a)}(this,o,Ie(r,0))}else{const e=De(r);!function(e,t,r,o){const n=Object.create(Mt.prototype);let s=()=>{},i=()=>p(void 0),a=()=>p(void 0);void 0!==t.start&&(s=()=>t.start(n)),void 0!==t.pull&&(i=()=>t.pull(n)),void 0!==t.cancel&&(a=e=>t.cancel(e)),Yt(e,n,s,i,a,r,o)}(this,o,Ie(r,1),e)}}get locked(){if(!sr(this))throw cr("locked");return ir(this)}cancel(e){return sr(this)?ir(this)?h(new TypeError("Cannot cancel a stream that already has a reader")):ar(this,e):h(cr("cancel"))}getReader(e){if(!sr(this))throw cr("getReader");return void 0===function(e,t){$(e,t);const r=null==e?void 0:e.mode;return{mode:void 0===r?void 0:er(r,`${t} has member 'mode' that`)}}(e,"First parameter").mode?Y(this):new ze(this)}pipeThrough(e,t={}){if(!sr(this))throw cr("pipeThrough");F(e,1,"pipeThrough");const r=function(e,t){$(e,t);const r=null==e?void 0:e.readable;U(r,"readable","ReadableWritablePair"),Q(r,`${t} has member 'readable' that`);const o=null==e?void 0:e.writable;return U(o,"writable","ReadableWritablePair"),Ye(o,`${t} has member 'writable' that`),{readable:r,writable:o}}(e,"First parameter"),o=tr(t,"Second parameter");if(ir(this))throw new TypeError("ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream");if(Xe(r.writable))throw new TypeError("ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream");return w(zt(this,r.writable,o.preventClose,o.preventAbort,o.preventCancel,o.signal)),r.readable}pipeTo(e,t={}){if(!sr(this))return h(cr("pipeTo"));if(void 0===e)return h("Parameter 1 is required in 'pipeTo'.");if(!Ze(e))return h(new TypeError("ReadableStream.prototype.pipeTo's first argument must be a WritableStream"));let r;try{r=tr(t,"Second parameter")}catch(e){return h(e)}return ir(this)?h(new TypeError("ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream")):Xe(e)?h(new TypeError("ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream")):zt(this,e,r.preventClose,r.preventAbort,r.preventCancel,r.signal)}tee(){if(!sr(this))throw cr("tee");const e=function(e,t){const r=Y(e);let o,n,s,i,a,u=!1,l=!1,c=!1;const d=f((e=>{a=e}));function h(){return u||(u=!0,te(r,{_chunkSteps:e=>{v((()=>{u=!1;const t=e,r=e;l||Ht(s._readableStreamController,t),c||Ht(i._readableStreamController,r),a(void 0)}))},_closeSteps:()=>{u=!1,l||Ut(s._readableStreamController),c||Ut(i._readableStreamController)},_errorSteps:()=>{u=!1}})),p(void 0)}function y(){}return s=or(y,h,(function(t){if(l=!0,o=t,c){const t=pe([o,n]),r=ar(e,t);a(r)}return d})),i=or(y,h,(function(t){if(c=!0,n=t,l){const t=pe([o,n]),r=ar(e,t);a(r)}return d})),_(r._closedPromise,(e=>{Nt(s._readableStreamController,e),Nt(i._readableStreamController,e),a(void 0)})),[s,i]}(this);return pe(e)}values(e){if(!sr(this))throw cr("values");return function(e,t){const r=Y(e),o=new ne(r,t),n=Object.create(se);return n._asyncIteratorImpl=o,n}(this,function(e,t){$(e,"First parameter");const r=null==e?void 0:e.preventCancel;return{preventCancel:Boolean(r)}}(e).preventCancel)}}function or(e,t,r,o=1,n=(()=>1)){const s=Object.create(rr.prototype);return nr(s),Yt(s,Object.create(Mt.prototype),e,t,r,o,n),s}function nr(e){e._state="readable",e._reader=void 0,e._storedError=void 0,e._disturbed=!1}function sr(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_readableStreamController")}function ir(e){return void 0!==e._reader}function ar(e,t){return e._disturbed=!0,"closed"===e._state?p(void 0):"errored"===e._state?h(e._storedError):(ur(e),g(e._readableStreamController[W](t),n))}function ur(e){e._state="closed";const t=e._reader;void 0!==t&&(ee(t)&&(t._readRequests.forEach((e=>{e._closeSteps()})),t._readRequests=new R),A(t))}function lr(e,t){e._state="errored",e._storedError=t;const r=e._reader;void 0!==r&&(ee(r)?(r._readRequests.forEach((e=>{e._errorSteps(t)})),r._readRequests=new R):(r._readIntoRequests.forEach((e=>{e._errorSteps(t)})),r._readIntoRequests=new R),C(r,t))}function cr(e){return new TypeError(`ReadableStream.prototype.${e} can only be used on a ReadableStream`)}function dr(e,t){$(e,t);const r=null==e?void 0:e.highWaterMark;return U(r,"highWaterMark","QueuingStrategyInit"),{highWaterMark:H(r)}}Object.defineProperties(rr.prototype,{cancel:{enumerable:!0},getReader:{enumerable:!0},pipeThrough:{enumerable:!0},pipeTo:{enumerable:!0},tee:{enumerable:!0},values:{enumerable:!0},locked:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(rr.prototype,o.toStringTag,{value:"ReadableStream",configurable:!0}),"symbol"==typeof o.asyncIterator&&Object.defineProperty(rr.prototype,o.asyncIterator,{value:rr.prototype.values,writable:!0,configurable:!0});const fr=function(e){return e.byteLength};class pr{constructor(e){F(e,1,"ByteLengthQueuingStrategy"),e=dr(e,"First parameter"),this._byteLengthQueuingStrategyHighWaterMark=e.highWaterMark}get highWaterMark(){if(!yr(this))throw hr("highWaterMark");return this._byteLengthQueuingStrategyHighWaterMark}get size(){if(!yr(this))throw hr("size");return fr}}function hr(e){return new TypeError(`ByteLengthQueuingStrategy.prototype.${e} can only be used on a ByteLengthQueuingStrategy`)}function yr(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_byteLengthQueuingStrategyHighWaterMark")}Object.defineProperties(pr.prototype,{highWaterMark:{enumerable:!0},size:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(pr.prototype,o.toStringTag,{value:"ByteLengthQueuingStrategy",configurable:!0});const br=function(){return 1};class mr{constructor(e){F(e,1,"CountQueuingStrategy"),e=dr(e,"First parameter"),this._countQueuingStrategyHighWaterMark=e.highWaterMark}get highWaterMark(){if(!gr(this))throw _r("highWaterMark");return this._countQueuingStrategyHighWaterMark}get size(){if(!gr(this))throw _r("size");return br}}function _r(e){return new TypeError(`CountQueuingStrategy.prototype.${e} can only be used on a CountQueuingStrategy`)}function gr(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_countQueuingStrategyHighWaterMark")}function wr(e,t,r){return I(e,r),r=>T(e,t,[r])}function vr(e,t,r){return I(e,r),r=>S(e,t,[r])}function Sr(e,t,r){return I(e,r),(r,o)=>T(e,t,[r,o])}Object.defineProperties(mr.prototype,{highWaterMark:{enumerable:!0},size:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(mr.prototype,o.toStringTag,{value:"CountQueuingStrategy",configurable:!0});class Tr{constructor(e={},t={},r={}){void 0===e&&(e=null);const o=Fe(t,"Second parameter"),n=Fe(r,"Third parameter"),s=function(e,t){$(e,t);const r=null==e?void 0:e.flush,o=null==e?void 0:e.readableType,n=null==e?void 0:e.start,s=null==e?void 0:e.transform,i=null==e?void 0:e.writableType;return{flush:void 0===r?void 0:wr(r,e,`${t} has member 'flush' that`),readableType:o,start:void 0===n?void 0:vr(n,e,`${t} has member 'start' that`),transform:void 0===s?void 0:Sr(s,e,`${t} has member 'transform' that`),writableType:i}}(e,"First parameter");if(void 0!==s.readableType)throw new RangeError("Invalid readableType specified");if(void 0!==s.writableType)throw new RangeError("Invalid writableType specified");const i=Ie(n,0),a=De(n),u=Ie(o,1),l=De(o);let c;!function(e,t,r,o,n,s){function i(){return t}e._writable=function(e,t,r,o,n=1,s=(()=>1)){const i=Object.create(Ge.prototype);return Ke(i),bt(i,Object.create(yt.prototype),e,t,r,o,n,s),i}(i,(function(t){return function(e,t){const r=e._transformStreamController;return e._backpressure?g(e._backpressureChangePromise,(()=>{const o=e._writable;if("erroring"===o._state)throw o._storedError;return Ar(r,t)})):Ar(r,t)}(e,t)}),(function(){return function(e){const t=e._readable,r=e._transformStreamController,o=r._flushAlgorithm();return Or(r),g(o,(()=>{if("errored"===t._state)throw t._storedError;Ut(t._readableStreamController)}),(r=>{throw qr(e,r),t._storedError}))}(e)}),(function(t){return function(e,t){return qr(e,t),p(void 0)}(e,t)}),r,o),e._readable=or(i,(function(){return function(e){return Er(e,!1),e._backpressureChangePromise}(e)}),(function(t){return Pr(e,t),p(void 0)}),n,s),e._backpressure=void 0,e._backpressureChangePromise=void 0,e._backpressureChangePromise_resolve=void 0,Er(e,!0),e._transformStreamController=void 0}(this,f((e=>{c=e})),u,l,i,a),function(e,t){const r=Object.create(jr.prototype);let o=e=>{try{return Cr(r,e),p(void 0)}catch(e){return h(e)}},n=()=>p(void 0);void 0!==t.transform&&(o=e=>t.transform(e,r)),void 0!==t.flush&&(n=()=>t.flush(r)),function(e,t,r,o){t._controlledTransformStream=e,e._transformStreamController=t,t._transformAlgorithm=r,t._flushAlgorithm=o}(e,r,o,n)}(this,s),void 0!==s.start?c(s.start(this._transformStreamController)):c(void 0)}get readable(){if(!Rr(this))throw xr("readable");return this._readable}get writable(){if(!Rr(this))throw xr("writable");return this._writable}}function Rr(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_transformStreamController")}function qr(e,t){Nt(e._readable._readableStreamController,t),Pr(e,t)}function Pr(e,t){Or(e._transformStreamController),wt(e._writable._writableStreamController,t),e._backpressure&&Er(e,!1)}function Er(e,t){void 0!==e._backpressureChangePromise&&e._backpressureChangePromise_resolve(),e._backpressureChangePromise=f((t=>{e._backpressureChangePromise_resolve=t})),e._backpressure=t}Object.defineProperties(Tr.prototype,{readable:{enumerable:!0},writable:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(Tr.prototype,o.toStringTag,{value:"TransformStream",configurable:!0});class jr{constructor(){throw new TypeError("Illegal constructor")}get desiredSize(){if(!kr(this))throw Br("desiredSize");return Vt(this._controlledTransformStream._readable._readableStreamController)}enqueue(e){if(!kr(this))throw Br("enqueue");Cr(this,e)}error(e){if(!kr(this))throw Br("error");var t;t=e,qr(this._controlledTransformStream,t)}terminate(){if(!kr(this))throw Br("terminate");!function(e){const t=e._controlledTransformStream;Ut(t._readable._readableStreamController);Pr(t,new TypeError("TransformStream terminated"))}(this)}}function kr(e){return!!i(e)&&!!Object.prototype.hasOwnProperty.call(e,"_controlledTransformStream")}function Or(e){e._transformAlgorithm=void 0,e._flushAlgorithm=void 0}function Cr(e,t){const r=e._controlledTransformStream,o=r._readable._readableStreamController;if(!Qt(o))throw new TypeError("Readable side is not in a state that permits enqueue");try{Ht(o,t)}catch(e){throw Pr(r,e),r._readable._storedError}(function(e){return!Dt(e)})(o)!==r._backpressure&&Er(r,!0)}function Ar(e,t){return g(e._transformAlgorithm(t),void 0,(t=>{throw qr(e._controlledTransformStream,t),t}))}function Br(e){return new TypeError(`TransformStreamDefaultController.prototype.${e} can only be used on a TransformStreamDefaultController`)}function xr(e){return new TypeError(`TransformStream.prototype.${e} can only be used on a TransformStream`)}Object.defineProperties(jr.prototype,{enqueue:{enumerable:!0},error:{enumerable:!0},terminate:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(jr.prototype,o.toStringTag,{value:"TransformStreamDefaultController",configurable:!0})},417:e=>{"use strict";e.exports=__webpack_require__(417)},605:e=>{"use strict";e.exports=__webpack_require__(605)},211:e=>{"use strict";e.exports=__webpack_require__(211)},413:e=>{"use strict";e.exports=__webpack_require__(413)},835:e=>{"use strict";e.exports=__webpack_require__(835)},669:e=>{"use strict";e.exports=__webpack_require__(669)},761:e=>{"use strict";e.exports=__webpack_require__(761)}},t={};function r(o){if(t[o])return t[o].exports;var n=t[o]={exports:{}};return e[o].call(n.exports,n,n.exports,r),n.exports}return r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r(990)})().default})); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9tYWlsZ3VuL3dlYnBhY2svdW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbiIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2Fib3J0LWNvbnRyb2xsZXIvZGlzdC9hYm9ydC1jb250cm9sbGVyLmpzIiwid2VicGFjazovL21haWxndW4vLi9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2NsaWVudC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2RvbWFpbnMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9lcnJvci50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2V2ZW50cy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2lwLXBvb2xzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvaXBzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvbWVzc2FnZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9wYXJzZS50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3JlcXVlc3QudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9yb3V0ZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9zdGF0cy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3N1cHByZXNzaW9ucy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3ZhbGlkYXRlLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvd2ViaG9va3MudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvZGF0YS11cmktdG8tYnVmZmVyL2Rpc3Qvc3JjL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvZXZlbnQtdGFyZ2V0LXNoaW0vZGlzdC9ldmVudC10YXJnZXQtc2hpbS5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2ZldGNoLWJsb2IvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9reS11bml2ZXJzYWwvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9reS91bWQuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9ub2RlLWZldGNoL2Rpc3QvaW5kZXguY2pzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvdXJsLWpvaW4vbGliL3VybC1qb2luLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvd2ViLXN0cmVhbXMtcG9seWZpbGwvZGlzdC9wb255ZmlsbC5lczIwMTgubWpzIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgXCJjcnlwdG9cIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIFwiaHR0cFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgXCJodHRwc1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgXCJzdHJlYW1cIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIFwidXJsXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBcInV0aWxcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIFwiemxpYlwiIiwid2VicGFjazovL21haWxndW4vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3N0YXJ0dXAiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL21haWxndW4vd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCJdLCJuYW1lcyI6WyJyb290IiwiZmFjdG9yeSIsImV4cG9ydHMiLCJtb2R1bGUiLCJkZWZpbmUiLCJhbWQiLCJ0aGlzIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJ2YWx1ZSIsImV2ZW50VGFyZ2V0U2hpbSIsIkFib3J0U2lnbmFsIiwiRXZlbnRUYXJnZXQiLCJzdXBlciIsIlR5cGVFcnJvciIsImFib3J0ZWQiLCJhYm9ydGVkRmxhZ3MiLCJnZXQiLCJkZWZpbmVFdmVudEF0dHJpYnV0ZSIsInByb3RvdHlwZSIsIldlYWtNYXAiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZW51bWVyYWJsZSIsIlN5bWJvbCIsInRvU3RyaW5nVGFnIiwiY29uZmlndXJhYmxlIiwiQWJvcnRDb250cm9sbGVyIiwic2lnbmFscyIsInNldCIsInNpZ25hbCIsImNyZWF0ZSIsImNhbGwiLCJjcmVhdGVBYm9ydFNpZ25hbCIsImdldFNpZ25hbCIsImRpc3BhdGNoRXZlbnQiLCJ0eXBlIiwiY29udHJvbGxlciIsImFib3J0IiwiZGVmYXVsdCIsIkZvcm1EYXRhIiwiZm9ybURhdGEiLCJjbGllbnQiLCJvcHRpb25zIiwiY29uZmlnIiwidXJsIiwidXNlcm5hbWUiLCJFcnJvciIsImtleSIsInJlcXVlc3QiLCJkb21haW5zIiwid2ViaG9va3MiLCJldmVudHMiLCJzdGF0cyIsInN1cHByZXNzaW9ucyIsIm1lc3NhZ2VzIiwicm91dGVzIiwiaXBzIiwiaXBfcG9vbHMiLCJwdWJsaWNfa2V5IiwicHVibGljX3JlcXVlc3QiLCJ2YWxpZGF0ZSIsInBhcnNlIiwiZGF0YSIsInJlY2VpdmluZyIsInNlbmRpbmciLCJuYW1lIiwicmVxdWlyZV90bHMiLCJza2lwX3ZlcmlmaWNhdGlvbiIsInN0YXRlIiwid2lsZGNhcmQiLCJzcGFtX2FjdGlvbiIsImNyZWF0ZWRfYXQiLCJzbXRwX3Bhc3N3b3JkIiwic210cF9sb2dpbiIsInJlY2VpdmluZ19kbnNfcmVjb3JkcyIsInNlbmRpbmdfZG5zX3JlY29yZHMiLCJfcGFyc2VNZXNzYWdlIiwicmVzcG9uc2UiLCJib2R5IiwiX3BhcnNlRG9tYWluTGlzdCIsIml0ZW1zIiwibWFwIiwiaXRlbSIsIkRvbWFpbiIsIl9wYXJzZURvbWFpbiIsImRvbWFpbiIsIl9wYXJzZVRyYWNraW5nU2V0dGluZ3MiLCJ0cmFja2luZyIsIl9wYXJzZVRyYWNraW5nVXBkYXRlIiwibGlzdCIsInF1ZXJ5IiwidGhlbiIsInBvc3QiLCJkZXN0cm95IiwiZGVsZXRlIiwiZ2V0VHJhY2tpbmciLCJ1cGRhdGVUcmFja2luZyIsInB1dCIsImdldElwcyIsImFzc2lnbklwIiwiaXAiLCJkZWxldGVJcCIsImxpbmtJcFBvb2wiLCJwb29sX2lkIiwidW5saW5rSXBQb2xsIiwic3RhdHVzIiwic3RhdHVzVGV4dCIsIm1lc3NhZ2UiLCJib2R5TWVzc2FnZSIsImVycm9yIiwic3RhY2siLCJkZXRhaWxzIiwidXJsam9pbiIsIl9wYXJzZVBhZ2VOdW1iZXIiLCJzcGxpdCIsInBvcCIsIl9wYXJzZVBhZ2UiLCJpZCIsIm51bWJlciIsIl9wYXJzZVBhZ2VMaW5rcyIsImVudHJpZXMiLCJwYWdpbmciLCJyZWR1Y2UiLCJhY2MiLCJfcGFyc2VFdmVudExpc3QiLCJwYWdlcyIsInBhZ2UiLCJwYXJzZUlwUG9vbHNSZXNwb25zZSIsInVwZGF0ZSIsInBvb2xJZCIsInBhdGNoIiwicGFyc2VJcHNSZXNwb25zZSIsIl9wYXJzZVJlc3BvbnNlIiwicG9zdE11bHRpIiwiYWRkcmVzc2VzIiwiZW5hYmxlRG5zRXNwQ2hlY2tzIiwiQXJyYXkiLCJpc0FycmF5Iiwiam9pbiIsInN5bnRheF9vbmx5IiwiaXNTdHJlYW0iLCJhdHRhY2htZW50IiwicGlwZSIsImdldEF0dGFjaG1lbnRPcHRpb25zIiwiZmlsZW5hbWUiLCJjb250ZW50VHlwZSIsImtub3duTGVuZ3RoIiwiaGVhZGVycyIsIm1ldGhvZCIsImJhc2ljIiwiQXV0aG9yaXphdGlvbiIsInBhcmFtcyIsImdldE93blByb3BlcnR5TmFtZXMiLCJsZW5ndGgiLCJzZWFyY2hQYXJhbXMiLCJ0b0xvY2FsZVVwcGVyQ2FzZSIsInRocm93SHR0cEVycm9ycyIsIm9rIiwic3RyZWFtIiwiY2h1bmtzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJvbiIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsInRvU3RyaW5nIiwianNvbiIsImNvbW1hbmQiLCJoZWFkIiwia2V5cyIsImZpbHRlciIsImZvckVhY2giLCJhcHBlbmQiLCJvYmoiLCJSZXF1ZXN0Iiwic3RhcnQiLCJEYXRlIiwiZW5kIiwicmVzb2x1dGlvbiIsInN0YXQiLCJ0aW1lIiwiX3BhcnNlU3RhdHMiLCJTdGF0cyIsImdldERvbWFpbiIsImdldEFjY291bnQiLCJjcmVhdGVPcHRpb25zIiwiYWRkcmVzcyIsImNvZGUiLCJ0YWdzIiwibW9kZWxzIiwiYm91bmNlcyIsIkJvdW5jZSIsImNvbXBsYWludHMiLCJDb21wbGFpbnQiLCJ1bnN1YnNjcmliZXMiLCJVbnN1YnNjcmliZSIsInBhZ2VVcmwiLCJfcGFyc2VMaXN0IiwiTW9kZWwiLCJkIiwiX3BhcnNlSXRlbSIsIm1vZGVsIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwiU3VwcHJlc3Npb25DbGllbnQiLCJfcGFyc2VXZWJob29rTGlzdCIsIl9wYXJzZVdlYmhvb2tXaXRoSUQiLCJXZWJob29rIiwid2ViaG9vayIsIl9wYXJzZVdlYmhvb2tUZXN0IiwidGVzdCIsInN0ciIsImZyb20iLCJ1cmkiLCJmaXJzdENvbW1hIiwicmVwbGFjZSIsImluZGV4T2YiLCJtZXRhIiwic3Vic3RyaW5nIiwiY2hhcnNldCIsImJhc2U2NCIsInR5cGVGdWxsIiwiaSIsImVuY29kaW5nIiwidW5lc2NhcGUiLCJidWZmZXIiLCJwcml2YXRlRGF0YSIsIndyYXBwZXJzIiwicGQiLCJldmVudCIsInJldHYiLCJjb25zb2xlIiwiYXNzZXJ0Iiwic2V0Q2FuY2VsRmxhZyIsInBhc3NpdmVMaXN0ZW5lciIsImNhbmNlbGFibGUiLCJjYW5jZWxlZCIsInByZXZlbnREZWZhdWx0IiwiRXZlbnQiLCJldmVudFRhcmdldCIsImV2ZW50UGhhc2UiLCJjdXJyZW50VGFyZ2V0Iiwic3RvcHBlZCIsImltbWVkaWF0ZVN0b3BwZWQiLCJ0aW1lU3RhbXAiLCJub3ciLCJkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3IiLCJkZWZpbmVDYWxsRGVzY3JpcHRvciIsImFwcGx5IiwiYXJndW1lbnRzIiwiZ2V0V3JhcHBlciIsInByb3RvIiwid3JhcHBlciIsIkJhc2VFdmVudCIsIkN1c3RvbUV2ZW50IiwiY29uc3RydWN0b3IiLCJ3cml0YWJsZSIsImlzRnVuYyIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImRlZmluZVdyYXBwZXIiLCJnZXRQcm90b3R5cGVPZiIsImlzU3RvcHBlZCIsInNldFBhc3NpdmVMaXN0ZW5lciIsInN0b3BQcm9wYWdhdGlvbiIsInN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiIsIkJvb2xlYW4iLCJidWJibGVzIiwiY29tcG9zZWQiLCJjYW5jZWxCdWJibGUiLCJ3aW5kb3ciLCJzZXRQcm90b3R5cGVPZiIsImxpc3RlbmVyc01hcCIsImlzT2JqZWN0IiwieCIsImdldExpc3RlbmVycyIsImxpc3RlbmVycyIsImV2ZW50VGFyZ2V0UHJvdG90eXBlIiwiZXZlbnROYW1lIiwibm9kZSIsImxpc3RlbmVyVHlwZSIsImxpc3RlbmVyIiwibmV4dCIsInByZXYiLCJuZXdOb2RlIiwicGFzc2l2ZSIsIm9uY2UiLCJkZWZpbmVFdmVudEF0dHJpYnV0ZURlc2NyaXB0b3IiLCJkZWZpbmVDdXN0b21FdmVudFRhcmdldCIsImV2ZW50TmFtZXMiLCJDdXN0b21FdmVudFRhcmdldCIsInR5cGVzIiwiTWFwIiwib3B0aW9uc0lzT2JqIiwiY2FwdHVyZSIsInVuZGVmaW5lZCIsIndyYXBwZWRFdmVudCIsIndyYXBFdmVudCIsImVyciIsImhhbmRsZUV2ZW50Iiwic2V0RXZlbnRQaGFzZSIsInNldEN1cnJlbnRUYXJnZXQiLCJkZWZhdWx0UHJldmVudGVkIiwiUmVhZGFibGUiLCJ3bSIsIkJsb2IiLCJibG9iUGFydHMiLCJzaXplIiwicGFydHMiLCJlbGVtZW50IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJieXRlT2Zmc2V0IiwiYnl0ZUxlbmd0aCIsIlN0cmluZyIsInRvTG93ZXJDYXNlIiwiYXJyYXlCdWZmZXIiLCJVaW50OEFycmF5Iiwib2Zmc2V0IiwiYXN5bmMiLCJwYXJ0IiwicmVhZCIsInJlbGF0aXZlU3RhcnQiLCJNYXRoIiwibWF4IiwibWluIiwicmVsYXRpdmVFbmQiLCJzcGFuIiwidmFsdWVzIiwiYWRkZWQiLCJzbGljZSIsImJsb2IiLCJhc3NpZ24iLCJoYXNJbnN0YW5jZSIsIm9iamVjdCIsImZldGNoIiwiZ2xvYmFsIiwiaGlnaFdhdGVyTWFyayIsIkhlYWRlcnMiLCJSZXNwb25zZSIsIlJlYWRhYmxlU3RyZWFtIiwiXyIsImdsb2JhbHMiLCJnZXRHbG9iYWwiLCJwcm9wZXJ0eSIsInNlbGYiLCJnbG9iYWxUaGlzIiwiZ2xvYmFsUHJvcGVydGllcyIsImdsb2JhbE9iamVjdCIsImJpbmQiLCJzdXBwb3J0c0Fib3J0Q29udHJvbGxlciIsInN1cHBvcnRzU3RyZWFtcyIsInN1cHBvcnRzRm9ybURhdGEiLCJtZXJnZUhlYWRlcnMiLCJzb3VyY2UxIiwic291cmNlMiIsInJlc3VsdCIsImlzSGVhZGVyc0luc3RhbmNlIiwic291cmNlIiwiZGVlcE1lcmdlIiwic291cmNlcyIsInJldHVyblZhbHVlIiwicmVxdWVzdE1ldGhvZHMiLCJyZXNwb25zZVR5cGVzIiwidGV4dCIsInJldHJ5QWZ0ZXJTdGF0dXNDb2RlcyIsInN0b3AiLCJIVFRQRXJyb3IiLCJUaW1lb3V0RXJyb3IiLCJkZWxheSIsIm1zIiwic2V0VGltZW91dCIsIm5vcm1hbGl6ZVJlcXVlc3RNZXRob2QiLCJpbnB1dCIsImluY2x1ZGVzIiwidG9VcHBlckNhc2UiLCJkZWZhdWx0UmV0cnlPcHRpb25zIiwibGltaXQiLCJtZXRob2RzIiwic3RhdHVzQ29kZXMiLCJhZnRlclN0YXR1c0NvZGVzIiwibm9ybWFsaXplUmV0cnlPcHRpb25zIiwicmV0cnkiLCJtYXhTYWZlVGltZW91dCIsIkt5IiwiX3JldHJ5Q291bnQiLCJfaW5wdXQiLCJfb3B0aW9ucyIsImNyZWRlbnRpYWxzIiwiaG9va3MiLCJiZWZvcmVSZXF1ZXN0IiwiYmVmb3JlUmV0cnkiLCJhZnRlclJlc3BvbnNlIiwicHJlZml4VXJsIiwidGltZW91dCIsIlVSTCIsInN0YXJ0c1dpdGgiLCJlbmRzV2l0aCIsImFib3J0Q29udHJvbGxlciIsImFkZEV2ZW50TGlzdGVuZXIiLCJVUkxTZWFyY2hQYXJhbXMiLCJKU09OIiwic3RyaW5naWZ5IiwiZm4iLCJSYW5nZUVycm9yIiwiX2ZldGNoIiwiaG9vayIsIm1vZGlmaWVkUmVzcG9uc2UiLCJfZGVjb3JhdGVSZXNwb25zZSIsImNsb25lIiwib25Eb3dubG9hZFByb2dyZXNzIiwiX3N0cmVhbSIsIl9yZXRyeSIsIm1pbWVUeXBlIiwicGFyc2VKc29uIiwicmV0cnlBZnRlciIsImFmdGVyIiwiTnVtYmVyIiwiaXNOYU4iLCJtYXhSZXRyeUFmdGVyIiwiX2NhbGN1bGF0ZVJldHJ5RGVsYXkiLCJyZXRyeUNvdW50IiwidGltZW91dElEIiwiY2F0Y2giLCJjbGVhclRpbWVvdXQiLCJ0b3RhbEJ5dGVzIiwidHJhbnNmZXJyZWRCeXRlcyIsInJlYWRlciIsImdldFJlYWRlciIsInBlcmNlbnQiLCJkb25lIiwiY2xvc2UiLCJlbnF1ZXVlIiwidmFsaWRhdGVBbmRNZXJnZSIsImNyZWF0ZUluc3RhbmNlIiwiZGVmYXVsdHMiLCJreSIsIm5ld0RlZmF1bHRzIiwiZXh0ZW5kIiwiaHR0cCIsImh0dHBzIiwiemxpYiIsIlN0cmVhbSIsImRhdGFVcmlUb0J1ZmZlciIsInV0aWwiLCJjcnlwdG8iLCJGZXRjaEJhc2VFcnJvciIsImNhcHR1cmVTdGFja1RyYWNlIiwiRmV0Y2hFcnJvciIsInN5c3RlbUVycm9yIiwiZXJybm8iLCJlcnJvcmVkU3lzQ2FsbCIsInN5c2NhbGwiLCJOQU1FIiwiaXNVUkxTZWFyY2hQYXJhbWV0ZXJzIiwiZ2V0QWxsIiwiaGFzIiwic29ydCIsImlzQmxvYiIsImlzRm9ybURhdGEiLCJjYXJyaWFnZSIsImRhc2hlcyIsInJlcGVhdCIsImNhcnJpYWdlTGVuZ3RoIiwiZ2V0Rm9vdGVyIiwiYm91bmRhcnkiLCJnZXRIZWFkZXIiLCJmaWVsZCIsImhlYWRlciIsIklOVEVSTkFMUyIsIkJvZHkiLCJpc0J1ZmZlciIsImlzQW55QXJyYXlCdWZmZXIiLCJyYW5kb21CeXRlcyIsImZvcm0iLCJmb3JtRGF0YUl0ZXJhdG9yIiwiZGlzdHVyYmVkIiwiY29uc3VtZUJvZHkiLCJjdCIsImJ1ZiIsImFsbG9jIiwiYWNjdW0iLCJhY2N1bUJ5dGVzIiwicmVhZGFibGVFbmRlZCIsIl9yZWFkYWJsZVN0YXRlIiwiZW5kZWQiLCJldmVyeSIsImMiLCJib2R5VXNlZCIsImluc3RhbmNlIiwicDEiLCJwMiIsImdldEJvdW5kYXJ5IiwiUGFzc1Rocm91Z2giLCJleHRyYWN0Q29udGVudFR5cGUiLCJ2YWxpZGF0ZUhlYWRlck5hbWUiLCJ2YWxpZGF0ZUhlYWRlclZhbHVlIiwiaW5pdCIsInJhdyIsImlzQm94ZWRQcmltaXRpdmUiLCJpdGVyYXRvciIsInBhaXIiLCJQcm94eSIsInRhcmdldCIsInAiLCJyZWNlaXZlciIsIlNldCIsIlJlZmxlY3QiLCJjYWxsYmFjayIsImZvciIsInJlZGlyZWN0U3RhdHVzIiwiaXNSZWRpcmVjdCIsIklOVEVSTkFMUyQxIiwiY291bnRlciIsInJlZGlyZWN0ZWQiLCJsb2NhdGlvbiIsIklOVEVSTkFMUyQyIiwiaXNSZXF1ZXN0IiwicGFyc2VkVVJMIiwiaW5wdXRCb2R5IiwicmVkaXJlY3QiLCJmb2xsb3ciLCJjb21wcmVzcyIsImFnZW50IiwiaW5zZWN1cmVIVFRQUGFyc2VyIiwiZm9ybWF0IiwiQWJvcnRFcnJvciIsInN1cHBvcnRlZFNjaGVtYXMiLCJvcHRpb25zXyIsImNvbnRlbnRMZW5ndGhWYWx1ZSIsImdldExlbmd0aFN5bmMiLCJoYXNLbm93bkxlbmd0aCIsImdldEZvcm1EYXRhTGVuZ3RoIiwiZ2V0VG90YWxCeXRlcyIsInNlYXJjaCIsImxhc3RPZmZzZXQiLCJocmVmIiwiaGFzaCIsImdldFNlYXJjaCIsInBhdGgiLCJwYXRobmFtZSIsImhvc3RuYW1lIiwicHJvdG9jb2wiLCJwb3J0IiwiZ2V0Tm9kZVJlcXVlc3RPcHRpb25zIiwic2VuZCIsImVtaXQiLCJhYm9ydEFuZEZpbmFsaXplIiwiZmluYWxpemUiLCJyZXF1ZXN0XyIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJyZXNwb25zZV8iLCJpbmRleCIsImFycmF5IiwiZnJvbVJhd0hlYWRlcnMiLCJyYXdIZWFkZXJzIiwic3RhdHVzQ29kZSIsImxvY2F0aW9uVVJMIiwicmVxdWVzdE9wdGlvbnMiLCJwaXBlbGluZSIsInByb2Nlc3MiLCJ2ZXJzaW9uIiwicmVzcG9uc2VPcHRpb25zIiwic3RhdHVzTWVzc2FnZSIsImNvZGluZ3MiLCJ6bGliT3B0aW9ucyIsImZsdXNoIiwiWl9TWU5DX0ZMVVNIIiwiZmluaXNoRmx1c2giLCJjcmVhdGVHdW56aXAiLCJjcmVhdGVCcm90bGlEZWNvbXByZXNzIiwiY3JlYXRlSW5mbGF0ZSIsImNyZWF0ZUluZmxhdGVSYXciLCJkZXN0Iiwid3JpdGUiLCJ3cml0ZVRvU3RyZWFtIiwibm9ybWFsaXplIiwiam9pbmVkIiwiU3ltYm9sUG9seWZpbGwiLCJkZXNjcmlwdGlvbiIsIm5vb3AiLCJ0eXBlSXNPYmplY3QiLCJyZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24iLCJvcmlnaW5hbFByb21pc2UiLCJvcmlnaW5hbFByb21pc2VUaGVuIiwib3JpZ2luYWxQcm9taXNlUmVzb2x2ZSIsIm9yaWdpbmFsUHJvbWlzZVJlamVjdCIsIm5ld1Byb21pc2UiLCJleGVjdXRvciIsInByb21pc2VSZXNvbHZlZFdpdGgiLCJwcm9taXNlUmVqZWN0ZWRXaXRoIiwicmVhc29uIiwiUGVyZm9ybVByb21pc2VUaGVuIiwicHJvbWlzZSIsIm9uRnVsZmlsbGVkIiwib25SZWplY3RlZCIsInVwb25Qcm9taXNlIiwidXBvbkZ1bGZpbGxtZW50IiwidXBvblJlamVjdGlvbiIsInRyYW5zZm9ybVByb21pc2VXaXRoIiwiZnVsZmlsbG1lbnRIYW5kbGVyIiwicmVqZWN0aW9uSGFuZGxlciIsInNldFByb21pc2VJc0hhbmRsZWRUb1RydWUiLCJxdWV1ZU1pY3JvdGFzayIsImdsb2JhbFF1ZXVlTWljcm90YXNrIiwicmVzb2x2ZWRQcm9taXNlIiwicmVmbGVjdENhbGwiLCJGIiwiViIsImFyZ3MiLCJGdW5jdGlvbiIsInByb21pc2VDYWxsIiwiU2ltcGxlUXVldWUiLCJfY3Vyc29yIiwiX3NpemUiLCJfZnJvbnQiLCJfZWxlbWVudHMiLCJfbmV4dCIsIl9iYWNrIiwib2xkQmFjayIsIm5ld0JhY2siLCJRVUVVRV9NQVhfQVJSQVlfU0laRSIsIm9sZEZyb250IiwibmV3RnJvbnQiLCJvbGRDdXJzb3IiLCJuZXdDdXJzb3IiLCJlbGVtZW50cyIsImZyb250IiwiY3Vyc29yIiwiUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZSIsIl9vd25lclJlYWRhYmxlU3RyZWFtIiwiX3JlYWRlciIsIl9zdGF0ZSIsImRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSIsImRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzb2x2ZSIsImRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkIiwiX3N0b3JlZEVycm9yIiwiUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljQ2FuY2VsIiwiUmVhZGFibGVTdHJlYW1DYW5jZWwiLCJSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlIiwiZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlc2V0VG9SZWplY3RlZCIsInJlYWRlckxvY2tFeGNlcHRpb24iLCJfY2xvc2VkUHJvbWlzZSIsIl9jbG9zZWRQcm9taXNlX3Jlc29sdmUiLCJfY2xvc2VkUHJvbWlzZV9yZWplY3QiLCJBYm9ydFN0ZXBzIiwiRXJyb3JTdGVwcyIsIkNhbmNlbFN0ZXBzIiwiUHVsbFN0ZXBzIiwiTnVtYmVySXNGaW5pdGUiLCJpc0Zpbml0ZSIsIk1hdGhUcnVuYyIsInRydW5jIiwidiIsImNlaWwiLCJmbG9vciIsImFzc2VydERpY3Rpb25hcnkiLCJjb250ZXh0IiwiYXNzZXJ0RnVuY3Rpb24iLCJhc3NlcnRPYmplY3QiLCJhc3NlcnRSZXF1aXJlZEFyZ3VtZW50IiwicG9zaXRpb24iLCJhc3NlcnRSZXF1aXJlZEZpZWxkIiwiY29udmVydFVucmVzdHJpY3RlZERvdWJsZSIsImNlbnNvck5lZ2F0aXZlWmVybyIsImNvbnZlcnRVbnNpZ25lZExvbmdMb25nV2l0aEVuZm9yY2VSYW5nZSIsInVwcGVyQm91bmQiLCJNQVhfU0FGRV9JTlRFR0VSIiwiaW50ZWdlclBhcnQiLCJhc3NlcnRSZWFkYWJsZVN0cmVhbSIsIklzUmVhZGFibGVTdHJlYW0iLCJBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyIiwiUmVhZGFibGVTdHJlYW1BZGRSZWFkUmVxdWVzdCIsInJlYWRSZXF1ZXN0IiwiX3JlYWRSZXF1ZXN0cyIsIlJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRSZXF1ZXN0Iiwic2hpZnQiLCJfY2xvc2VTdGVwcyIsIl9jaHVua1N0ZXBzIiwiUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMiLCJSZWFkYWJsZVN0cmVhbUhhc0RlZmF1bHRSZWFkZXIiLCJJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciIsIklzUmVhZGFibGVTdHJlYW1Mb2NrZWQiLCJkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsInJlc29sdmVQcm9taXNlIiwicmVqZWN0UHJvbWlzZSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQiLCJfZXJyb3JTdGVwcyIsImUiLCJoYXNPd25Qcm9wZXJ0eSIsIl9kaXN0dXJiZWQiLCJfcmVhZGFibGVTdHJlYW1Db250cm9sbGVyIiwiY2FuY2VsIiwicmVsZWFzZUxvY2siLCJjbG9zZWQiLCJBc3luY0l0ZXJhdG9yUHJvdG90eXBlIiwiUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9ySW1wbCIsInByZXZlbnRDYW5jZWwiLCJfb25nb2luZ1Byb21pc2UiLCJfaXNGaW5pc2hlZCIsIl9wcmV2ZW50Q2FuY2VsIiwibmV4dFN0ZXBzIiwiX25leHRTdGVwcyIsInJldHVyblN0ZXBzIiwiX3JldHVyblN0ZXBzIiwiUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlIiwiSXNSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IiLCJfYXN5bmNJdGVyYXRvckltcGwiLCJzdHJlYW1Bc3luY0l0ZXJhdG9yQnJhbmRDaGVja0V4Y2VwdGlvbiIsInJldHVybiIsIk51bWJlcklzTmFOIiwiSXNGaW5pdGVOb25OZWdhdGl2ZU51bWJlciIsIklzTm9uTmVnYXRpdmVOdW1iZXIiLCJJbmZpbml0eSIsIkRlcXVldWVWYWx1ZSIsImNvbnRhaW5lciIsIl9xdWV1ZSIsIl9xdWV1ZVRvdGFsU2l6ZSIsIkVucXVldWVWYWx1ZVdpdGhTaXplIiwiUmVzZXRRdWV1ZSIsIkNyZWF0ZUFycmF5RnJvbUxpc3QiLCJSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IiwiSXNSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IiwiYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uIiwiX3ZpZXciLCJieXRlc1dyaXR0ZW4iLCJfYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEludGVybmFsIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmQiLCJ2aWV3IiwiZmlyc3REZXNjcmlwdG9yIiwiX3BlbmRpbmdQdWxsSW50b3MiLCJwZWVrIiwiYnl0ZXNGaWxsZWQiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZFdpdGhOZXdWaWV3IiwicmVzcG9uZCIsInJlc3BvbmRXaXRoTmV3VmlldyIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIiLCJJc1JlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIiLCJieXRlU3RyZWFtQ29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24iLCJfYnlvYlJlcXVlc3QiLCJieW9iUmVxdWVzdCIsIlNldFVwUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZSIsIl9jbG9zZVJlcXVlc3RlZCIsIl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyIsIlJlYWRhYmxlU3RyZWFtQ2xvc2UiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2UiLCJ0cmFuc2ZlcnJlZEJ1ZmZlciIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlQ2h1bmtUb1F1ZXVlIiwiUmVhZGFibGVTdHJlYW1IYXNCWU9CUmVhZGVyIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclByb2Nlc3NQdWxsSW50b0Rlc2NyaXB0b3JzVXNpbmdRdWV1ZSIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWUiLCJfY2FuY2VsQWxnb3JpdGhtIiwiZW50cnkiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbiIsImF1dG9BbGxvY2F0ZUNodW5rU2l6ZSIsIl9hdXRvQWxsb2NhdGVDaHVua1NpemUiLCJidWZmZXJFIiwicHVsbEludG9EZXNjcmlwdG9yIiwiZWxlbWVudFNpemUiLCJ2aWV3Q29uc3RydWN0b3IiLCJyZWFkZXJUeXBlIiwiX3N0YXJ0ZWQiLCJSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRJbnRvUmVxdWVzdHMiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hvdWxkQ2FsbFB1bGwiLCJfcHVsbGluZyIsIl9wdWxsQWdhaW4iLCJfcHVsbEFsZ29yaXRobSIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb21taXRQdWxsSW50b0Rlc2NyaXB0b3IiLCJmaWxsZWRWaWV3IiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbnZlcnRQdWxsSW50b0Rlc2NyaXB0b3IiLCJyZWFkSW50b1JlcXVlc3QiLCJfcmVhZEludG9SZXF1ZXN0cyIsIlJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsUHVsbEludG9EZXNjcmlwdG9yRnJvbVF1ZXVlIiwiY3VycmVudEFsaWduZWRCeXRlcyIsIm1heEJ5dGVzVG9Db3B5IiwibWF4Qnl0ZXNGaWxsZWQiLCJtYXhBbGlnbmVkQnl0ZXMiLCJ0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nIiwicmVhZHkiLCJxdWV1ZSIsImhlYWRPZlF1ZXVlIiwiYnl0ZXNUb0NvcHkiLCJkZXN0U3RhcnQiLCJkZXN0T2Zmc2V0Iiwic3JjIiwic3JjT2Zmc2V0IiwibiIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsSGVhZFB1bGxJbnRvRGVzY3JpcHRvciIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJJbnZhbGlkYXRlQllPQlJlcXVlc3QiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8iLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluQ2xvc2VkU3RhdGUiLCJyZW1haW5kZXJTaXplIiwicmVtYWluZGVyIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRJblJlYWRhYmxlU3RhdGUiLCJkZXNjcmlwdG9yIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyUGVuZGluZ1B1bGxJbnRvcyIsIlJlYWRhYmxlU3RyZWFtRXJyb3IiLCJfc3RyYXRlZ3lIV00iLCJSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdCIsIklzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyIiwiZGVzaXJlZFNpemUiLCJSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIiLCJieW9iUmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsIkRhdGFWaWV3IiwiQllURVNfUEVSX0VMRU1FTlQiLCJjdG9yIiwiZW1wdHlWaWV3IiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclB1bGxJbnRvIiwiUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyUmVhZCIsIkV4dHJhY3RIaWdoV2F0ZXJNYXJrIiwic3RyYXRlZ3kiLCJkZWZhdWx0SFdNIiwiRXh0cmFjdFNpemVBbGdvcml0aG0iLCJjb252ZXJ0UXVldWluZ1N0cmF0ZWd5IiwiY29udmVydFF1ZXVpbmdTdHJhdGVneVNpemUiLCJjb252ZXJ0VW5kZXJseWluZ1NpbmtBYm9ydENhbGxiYWNrIiwib3JpZ2luYWwiLCJjb252ZXJ0VW5kZXJseWluZ1NpbmtDbG9zZUNhbGxiYWNrIiwiY29udmVydFVuZGVybHlpbmdTaW5rU3RhcnRDYWxsYmFjayIsImNvbnZlcnRVbmRlcmx5aW5nU2lua1dyaXRlQ2FsbGJhY2siLCJhc3NlcnRXcml0YWJsZVN0cmVhbSIsIklzV3JpdGFibGVTdHJlYW0iLCJXcml0YWJsZVN0cmVhbSIsInJhd1VuZGVybHlpbmdTaW5rIiwicmF3U3RyYXRlZ3kiLCJ1bmRlcmx5aW5nU2luayIsImNvbnZlcnRVbmRlcmx5aW5nU2luayIsIkluaXRpYWxpemVXcml0YWJsZVN0cmVhbSIsInNpemVBbGdvcml0aG0iLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIiwic3RhcnRBbGdvcml0aG0iLCJ3cml0ZUFsZ29yaXRobSIsImNsb3NlQWxnb3JpdGhtIiwiYWJvcnRBbGdvcml0aG0iLCJTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIiLCJTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJGcm9tVW5kZXJseWluZ1NpbmsiLCJzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uIiwiSXNXcml0YWJsZVN0cmVhbUxvY2tlZCIsIldyaXRhYmxlU3RyZWFtQWJvcnQiLCJXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodCIsIldyaXRhYmxlU3RyZWFtQ2xvc2UiLCJBY3F1aXJlV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyIiwiX3dyaXRlciIsIl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIiLCJfd3JpdGVSZXF1ZXN0cyIsIl9pbkZsaWdodFdyaXRlUmVxdWVzdCIsIl9jbG9zZVJlcXVlc3QiLCJfaW5GbGlnaHRDbG9zZVJlcXVlc3QiLCJfcGVuZGluZ0Fib3J0UmVxdWVzdCIsIl9iYWNrcHJlc3N1cmUiLCJfcHJvbWlzZSIsIndhc0FscmVhZHlFcnJvcmluZyIsIl9yZXNvbHZlIiwiX3JlamVjdCIsIl9yZWFzb24iLCJfd2FzQWxyZWFkeUVycm9yaW5nIiwiV3JpdGFibGVTdHJlYW1TdGFydEVycm9yaW5nIiwiY2xvc2VSZXF1ZXN0Iiwid3JpdGVyIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc29sdmUiLCJjbG9zZVNlbnRpbmVsIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckFkdmFuY2VRdWV1ZUlmTmVlZGVkIiwiV3JpdGFibGVTdHJlYW1EZWFsV2l0aFJlamVjdGlvbiIsIldyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3JpbmciLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVSZWFkeVByb21pc2VSZWplY3RlZCIsIldyaXRhYmxlU3RyZWFtSGFzT3BlcmF0aW9uTWFya2VkSW5GbGlnaHQiLCJzdG9yZWRFcnJvciIsIndyaXRlUmVxdWVzdCIsIldyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQiLCJhYm9ydFJlcXVlc3QiLCJkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCIsIldyaXRhYmxlU3RyZWFtVXBkYXRlQmFja3ByZXNzdXJlIiwiYmFja3ByZXNzdXJlIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemUiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzZXQiLCJnZXRXcml0ZXIiLCJsb2NrZWQiLCJfb3duZXJXcml0YWJsZVN0cmVhbSIsImRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZCIsImRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSIsImRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCIsImRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVzb2x2ZSIsImRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQiLCJJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciIsImRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uIiwiZGVmYXVsdFdyaXRlckxvY2tFeGNlcHRpb24iLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJHZXREZXNpcmVkU2l6ZSIsIl9yZWFkeVByb21pc2UiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJBYm9ydCIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckNsb3NlIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyUmVsZWFzZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcldyaXRlIiwiX3JlYWR5UHJvbWlzZVN0YXRlIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlamVjdCIsImRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNldFRvUmVqZWN0ZWQiLCJyZWxlYXNlZEVycm9yIiwiX2Nsb3NlZFByb21pc2VTdGF0ZSIsImRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVzZXRUb1JlamVjdGVkIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyRW5zdXJlQ2xvc2VkUHJvbWlzZVJlamVjdGVkIiwiY2h1bmtTaXplIiwiX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSIsImNodW5rU2l6ZUUiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3JJZk5lZWRlZCIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRDaHVua1NpemUiLCJXcml0YWJsZVN0cmVhbUFkZFdyaXRlUmVxdWVzdCIsImVucXVldWVFIiwiX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRCYWNrcHJlc3N1cmUiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyV3JpdGUiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IiLCJfYWJvcnRBbGdvcml0aG0iLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiX3dyaXRlQWxnb3JpdGhtIiwiX2Nsb3NlQWxnb3JpdGhtIiwiciIsIldyaXRhYmxlU3RyZWFtTWFya0Nsb3NlUmVxdWVzdEluRmxpZ2h0Iiwic2lua0Nsb3NlUHJvbWlzZSIsIldyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZSIsIldyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZVdpdGhFcnJvciIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQcm9jZXNzQ2xvc2UiLCJXcml0YWJsZVN0cmVhbU1hcmtGaXJzdFdyaXRlUmVxdWVzdEluRmxpZ2h0IiwiV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodFdyaXRlIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodFdyaXRlV2l0aEVycm9yIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NXcml0ZSIsIl9yZWFkeVByb21pc2VfcmVzb2x2ZSIsIl9yZWFkeVByb21pc2VfcmVqZWN0IiwiTmF0aXZlRE9NRXhjZXB0aW9uIiwiRE9NRXhjZXB0aW9uIiwiRE9NRXhjZXB0aW9uJDEiLCJfYSIsImlzRE9NRXhjZXB0aW9uQ29uc3RydWN0b3IiLCJjcmVhdGVET01FeGNlcHRpb25Qb2x5ZmlsbCIsIlJlYWRhYmxlU3RyZWFtUGlwZVRvIiwicHJldmVudENsb3NlIiwicHJldmVudEFib3J0Iiwic2h1dHRpbmdEb3duIiwiY3VycmVudFdyaXRlIiwiYWN0aW9ucyIsInNodXRkb3duV2l0aEFjdGlvbiIsImFsbCIsImFjdGlvbiIsImlzT3JCZWNvbWVzRXJyb3JlZCIsInNodXRkb3duIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2VXaXRoRXJyb3JQcm9wYWdhdGlvbiIsImRlc3RDbG9zZWQiLCJ3YWl0Rm9yV3JpdGVzVG9GaW5pc2giLCJvbGRDdXJyZW50V3JpdGUiLCJvcmlnaW5hbElzRXJyb3IiLCJvcmlnaW5hbEVycm9yIiwiZG9UaGVSZXN0IiwibmV3RXJyb3IiLCJpc0Vycm9yIiwicmVzb2x2ZUxvb3AiLCJyZWplY3RMb29wIiwicmVzb2x2ZVJlYWQiLCJyZWplY3RSZWFkIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIklzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsImRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYW5DbG9zZU9yRW5xdWV1ZSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyIsIl9jb250cm9sbGVkUmVhZGFibGVTdHJlYW0iLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJTaG91bGRDYWxsUHVsbCIsIlNldFVwUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsInB1bGxBbGdvcml0aG0iLCJjYW5jZWxBbGdvcml0aG0iLCJjb252ZXJ0VW5kZXJseWluZ1NvdXJjZUNhbmNlbENhbGxiYWNrIiwiY29udmVydFVuZGVybHlpbmdTb3VyY2VQdWxsQ2FsbGJhY2siLCJjb252ZXJ0VW5kZXJseWluZ1NvdXJjZVN0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0UmVhZGFibGVTdHJlYW1UeXBlIiwiY29udmVydFJlYWRhYmxlU3RyZWFtUmVhZGVyTW9kZSIsIm1vZGUiLCJjb252ZXJ0UGlwZU9wdGlvbnMiLCJpc0Fib3J0U2lnbmFsIiwiYXNzZXJ0QWJvcnRTaWduYWwiLCJyYXdVbmRlcmx5aW5nU291cmNlIiwidW5kZXJseWluZ1NvdXJjZSIsInB1bGwiLCJjb252ZXJ0VW5kZXJseWluZ0RlZmF1bHRPckJ5dGVTb3VyY2UiLCJJbml0aWFsaXplUmVhZGFibGVTdHJlYW0iLCJ1bmRlcmx5aW5nQnl0ZVNvdXJjZSIsIlNldFVwUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciIsIlNldFVwUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZyb21VbmRlcmx5aW5nU291cmNlIiwiU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2UiLCJzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEiLCJyYXdPcHRpb25zIiwiY29udmVydFJlYWRlck9wdGlvbnMiLCJyYXdUcmFuc2Zvcm0iLCJ0cmFuc2Zvcm0iLCJyZWFkYWJsZSIsImNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpciIsImRlc3RpbmF0aW9uIiwiYnJhbmNoZXMiLCJjbG9uZUZvckJyYW5jaDIiLCJyZWFzb24xIiwicmVhc29uMiIsImJyYW5jaDEiLCJicmFuY2gyIiwicmVzb2x2ZUNhbmNlbFByb21pc2UiLCJyZWFkaW5nIiwiY2FuY2VsZWQxIiwiY2FuY2VsZWQyIiwiY2FuY2VsUHJvbWlzZSIsInZhbHVlMSIsInZhbHVlMiIsIkNyZWF0ZVJlYWRhYmxlU3RyZWFtIiwiY29tcG9zaXRlUmVhc29uIiwiY2FuY2VsUmVzdWx0IiwiUmVhZGFibGVTdHJlYW1UZWUiLCJpbXBsIiwiQWNxdWlyZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciIsImNvbnZlcnRJdGVyYXRvck9wdGlvbnMiLCJjb252ZXJ0UXVldWluZ1N0cmF0ZWd5SW5pdCIsInBpcGVUaHJvdWdoIiwicGlwZVRvIiwidGVlIiwiYXN5bmNJdGVyYXRvciIsImJ5dGVMZW5ndGhTaXplRnVuY3Rpb24iLCJCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5IiwiX2J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrIiwiSXNCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5IiwiYnl0ZUxlbmd0aEJyYW5kQ2hlY2tFeGNlcHRpb24iLCJjb3VudFNpemVGdW5jdGlvbiIsIkNvdW50UXVldWluZ1N0cmF0ZWd5IiwiX2NvdW50UXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayIsIklzQ291bnRRdWV1aW5nU3RyYXRlZ3kiLCJjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24iLCJjb252ZXJ0VHJhbnNmb3JtZXJGbHVzaENhbGxiYWNrIiwiY29udmVydFRyYW5zZm9ybWVyU3RhcnRDYWxsYmFjayIsImNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrIiwiVHJhbnNmb3JtU3RyZWFtIiwicmF3VHJhbnNmb3JtZXIiLCJyYXdXcml0YWJsZVN0cmF0ZWd5IiwicmF3UmVhZGFibGVTdHJhdGVneSIsIndyaXRhYmxlU3RyYXRlZ3kiLCJyZWFkYWJsZVN0cmF0ZWd5IiwidHJhbnNmb3JtZXIiLCJyZWFkYWJsZVR5cGUiLCJ3cml0YWJsZVR5cGUiLCJjb252ZXJ0VHJhbnNmb3JtZXIiLCJyZWFkYWJsZUhpZ2hXYXRlck1hcmsiLCJyZWFkYWJsZVNpemVBbGdvcml0aG0iLCJ3cml0YWJsZUhpZ2hXYXRlck1hcmsiLCJ3cml0YWJsZVNpemVBbGdvcml0aG0iLCJzdGFydFByb21pc2VfcmVzb2x2ZSIsInN0YXJ0UHJvbWlzZSIsIl93cml0YWJsZSIsIkNyZWF0ZVdyaXRhYmxlU3RyZWFtIiwiX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXIiLCJfYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyUGVyZm9ybVRyYW5zZm9ybSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRTaW5rV3JpdGVBbGdvcml0aG0iLCJfcmVhZGFibGUiLCJmbHVzaFByb21pc2UiLCJfZmx1c2hBbGdvcml0aG0iLCJUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyIsIlRyYW5zZm9ybVN0cmVhbUVycm9yIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtDbG9zZUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRTaW5rQWJvcnRBbGdvcml0aG0iLCJUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUiLCJUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U291cmNlUHVsbEFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUiLCJfYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZV9yZXNvbHZlIiwiSW5pdGlhbGl6ZVRyYW5zZm9ybVN0cmVhbSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyIiwidHJhbnNmb3JtQWxnb3JpdGhtIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlIiwidHJhbnNmb3JtUmVzdWx0RSIsImZsdXNoQWxnb3JpdGhtIiwiX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW0iLCJfdHJhbnNmb3JtQWxnb3JpdGhtIiwiU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIlNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJGcm9tVHJhbnNmb3JtZXIiLCJJc1RyYW5zZm9ybVN0cmVhbSIsInN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMiIsIklzVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIiLCJkZWZhdWx0Q29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24kMSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyVGVybWluYXRlIiwicmVhZGFibGVDb250cm9sbGVyIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckhhc0JhY2twcmVzc3VyZSIsInRlcm1pbmF0ZSIsInJlcXVpcmUiLCJfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18iLCJfX3dlYnBhY2tfcmVxdWlyZV9fIiwibW9kdWxlSWQiLCJfX3dlYnBhY2tfbW9kdWxlc19fIiwiZGVmaW5pdGlvbiIsIm8iLCJwcm9wIl0sIm1hcHBpbmdzIjoiO0NBQUEsU0FBMkNBLEVBQU1DLEdBQzFCLGlCQUFaQyxTQUEwQyxpQkFBWEMsT0FDeENBLE9BQU9ELFFBQVVELElBQ1EsbUJBQVhHLFFBQXlCQSxPQUFPQyxJQUM5Q0QsT0FBTyxHQUFJSCxHQUNlLGlCQUFaQyxRQUNkQSxRQUFpQixRQUFJRCxJQUVyQkQsRUFBYyxRQUFJQyxJQVJwQixDQVNHSyxNQUFNLFdBQ1QsTSx3Q0NKQUMsT0FBT0MsZUFBZU4sRUFBUyxhQUEvQixDQUErQ08sT0FBTyxJQUV0RCxJQUFJQyxFQUFrQixFQUFRLEtBTTlCLE1BQU1DLFVBQW9CRCxFQUFnQkUsWUFJdEMs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T0FBT1ksVUFBVWtxQixlQUFldHBCLEtBQUtpSixFQUFLaTZCLEdDQ2pGTCxFQUFvQjlLLEVBQUs1NUIsSUFDSCxvQkFBWHFCLFFBQTBCQSxPQUFPQyxhQUMxQ2pCLE9BQU9DLGVBQWVOLEVBQVNxQixPQUFPQyxZQUFhLENBQUVmLE1BQU8sV0FFN0RGLE9BQU9DLGVBQWVOLEVBQVMsYUFBYyxDQUFFTyxPQUFPLEtIRmhEbWtDLEVBQW9CLE0iLCJmaWxlIjoibWFpbGd1bi5qcyIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcIm1haWxndW5cIl0gPSBmYWN0b3J5KCk7XG5cdGVsc2Vcblx0XHRyb290W1wibWFpbGd1blwiXSA9IGZhY3RvcnkoKTtcbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xucmV0dXJuICIsIi8qKlxuICogQGF1dGhvciBUb3J1IE5hZ2FzaGltYSA8aHR0cHM6Ly9naXRodWIuY29tL215c3RpY2F0ZWE+XG4gKiBTZWUgTElDRU5TRSBmaWxlIGluIHJvb3QgZGlyZWN0b3J5IGZvciBmdWxsIGxpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIGV2ZW50VGFyZ2V0U2hpbSA9IHJlcXVpcmUoJ2V2ZW50LXRhcmdldC1zaGltJyk7XG5cbi8qKlxuICogVGhlIHNpZ25hbCBjbGFzcy5cbiAqIEBzZWUgaHR0cHM6Ly9kb20uc3BlYy53aGF0d2cub3JnLyNhYm9ydHNpZ25hbFxuICovXG5jbGFzcyBBYm9ydFNpZ25hbCBleHRlbmRzIGV2ZW50VGFyZ2V0U2hpbS5FdmVudFRhcmdldCB7XG4gICAgLyoqXG4gICAgICogQWJvcnRTaWduYWwgY2Fubm90IGJlIGNvbnN0cnVjdGVkIGRpcmVjdGx5LlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQWJvcnRTaWduYWwgY2Fubm90IGJlIGNvbnN0cnVjdGVkIGRpcmVjdGx5XCIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGlzIGBBYm9ydFNpZ25hbGAncyBgQWJvcnRDb250cm9sbGVyYCBoYXMgc2lnbmFsZWQgdG8gYWJvcnQsIGFuZCBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBnZXQgYWJvcnRlZCgpIHtcbiAgICAgICAgY29uc3QgYWJvcnRlZCA9IGFib3J0ZWRGbGFncy5nZXQodGhpcyk7XG4gICAgICAgIGlmICh0eXBlb2YgYWJvcnRlZCAhPT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEV4cGVjdGVkICd0aGlzJyB0byBiZSBhbiAnQWJvcnRTaWduYWwnIG9iamVjdCwgYnV0IGdvdCAke3RoaXMgPT09IG51bGwgPyBcIm51bGxcIiA6IHR5cGVvZiB0aGlzfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhYm9ydGVkO1xuICAgIH1cbn1cbmV2ZW50VGFyZ2V0U2hpbS5kZWZpbmVFdmVudEF0dHJpYnV0ZShBYm9ydFNpZ25hbC5wcm90b3R5cGUsIFwiYWJvcnRcIik7XG4vKipcbiAqIENyZWF0ZSBhbiBBYm9ydFNpZ25hbCBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUFib3J0U2lnbmFsKCkge1xuICAgIGNvbnN0IHNpZ25hbCA9IE9iamVjdC5jcmVhdGUoQWJvcnRTaWduYWwucHJvdG90eXBlKTtcbiAgICBldmVudFRhcmdldFNoaW0uRXZlbnRUYXJnZXQuY2FsbChzaWduYWwpO1xuICAgIGFib3J0ZWRGbGFncy5zZXQoc2lnbmFsLCBmYWxzZSk7XG4gICAgcmV0dXJuIHNpZ25hbDtcbn1cbi8qKlxuICogQWJvcnQgYSBnaXZlbiBzaWduYWwuXG4gKi9cbmZ1bmN0aW9uIGFib3J0U2lnbmFsKHNpZ25hbCkge1xuICAgIGlmIChhYm9ydGVkRmxhZ3MuZ2V0KHNpZ25hbCkgIT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYWJvcnRlZEZsYWdzLnNldChzaWduYWwsIHRydWUpO1xuICAgIHNpZ25hbC5kaXNwYXRjaEV2ZW50KHsgdHlwZTogXCJhYm9ydFwiIH0pO1xufVxuLyoqXG4gKiBBYm9ydGVkIGZsYWcgZm9yIGVhY2ggaW5zdGFuY2VzLlxuICovXG5jb25zdCBhYm9ydGVkRmxhZ3MgPSBuZXcgV2Vha01hcCgpO1xuLy8gUHJvcGVydGllcyBzaG91bGQgYmUgZW51bWVyYWJsZS5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEFib3J0U2lnbmFsLnByb3RvdHlwZSwge1xuICAgIGFib3J0ZWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxufSk7XG4vLyBgdG9TdHJpbmcoKWAgc2hvdWxkIHJldHVybiBgXCJbb2JqZWN0IEFib3J0U2lnbmFsXVwiYFxuaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLnRvU3RyaW5nVGFnID09PSBcInN5bWJvbFwiKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFib3J0U2lnbmFsLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IFwiQWJvcnRTaWduYWxcIixcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBUaGUgQWJvcnRDb250cm9sbGVyLlxuICogQHNlZSBodHRwczovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2Fib3J0Y29udHJvbGxlclxuICovXG5jbGFzcyBBYm9ydENvbnRyb2xsZXIge1xuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgdGhpcyBjb250cm9sbGVyLlxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzaWduYWxzLnNldCh0aGlzLCBjcmVhdGVBYm9ydFNpZ25hbCgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgYEFib3J0U2lnbmFsYCBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIGdldCBzaWduYWwoKSB7XG4gICAgICAgIHJldHVybiBnZXRTaWduYWwodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFib3J0IGFuZCBzaWduYWwgdG8gYW55IG9ic2VydmVycyB0aGF0IHRoZSBhc3NvY2lhdGVkIGFjdGl2aXR5IGlzIHRvIGJlIGFib3J0ZWQuXG4gICAgICovXG4gICAgYWJvcnQoKSB7XG4gICAgICAgIGFib3J0U2lnbmFsKGdldFNpZ25hbCh0aGlzKSk7XG4gICAgfVxufVxuLyoqXG4gKiBBc3NvY2lhdGVkIHNpZ25hbHMuXG4gKi9cbmNvbnN0IHNpZ25hbHMgPSBuZXcgV2Vha01hcCgpO1xuLyoqXG4gKiBHZXQgdGhlIGFzc29jaWF0ZWQgc2lnbmFsIG9mIGEgZ2l2ZW4gY29udHJvbGxlci5cbiAqL1xuZnVuY3Rpb24gZ2V0U2lnbmFsKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzaWduYWwgPSBzaWduYWxzLmdldChjb250cm9sbGVyKTtcbiAgICBpZiAoc2lnbmFsID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgRXhwZWN0ZWQgJ3RoaXMnIHRvIGJlIGFuICdBYm9ydENvbnRyb2xsZXInIG9iamVjdCwgYnV0IGdvdCAke2NvbnRyb2xsZXIgPT09IG51bGwgPyBcIm51bGxcIiA6IHR5cGVvZiBjb250cm9sbGVyfWApO1xuICAgIH1cbiAgICByZXR1cm4gc2lnbmFsO1xufVxuLy8gUHJvcGVydGllcyBzaG91bGQgYmUgZW51bWVyYWJsZS5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEFib3J0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBzaWduYWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGFib3J0OiB7IGVudW1lcmFibGU6IHRydWUgfSxcbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLnRvU3RyaW5nVGFnID09PSBcInN5bWJvbFwiKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFib3J0Q29udHJvbGxlci5wcm90b3R5cGUsIFN5bWJvbC50b1N0cmluZ1RhZywge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIHZhbHVlOiBcIkFib3J0Q29udHJvbGxlclwiLFxuICAgIH0pO1xufVxuXG5leHBvcnRzLkFib3J0Q29udHJvbGxlciA9IEFib3J0Q29udHJvbGxlcjtcbmV4cG9ydHMuQWJvcnRTaWduYWwgPSBBYm9ydFNpZ25hbDtcbmV4cG9ydHMuZGVmYXVsdCA9IEFib3J0Q29udHJvbGxlcjtcblxubW9kdWxlLmV4cG9ydHMgPSBBYm9ydENvbnRyb2xsZXJcbm1vZHVsZS5leHBvcnRzLkFib3J0Q29udHJvbGxlciA9IG1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IEFib3J0Q29udHJvbGxlclxubW9kdWxlLmV4cG9ydHMuQWJvcnRTaWduYWwgPSBBYm9ydFNpZ25hbFxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWJvcnQtY29udHJvbGxlci5qcy5tYXBcbiIsImltcG9ydCBDbGllbnQgZnJvbSAnLi9saWIvY2xpZW50J1xuaW1wb3J0IE9wdGlvbnMgZnJvbSAnLi9saWIvaW50ZXJmYWNlcy9PcHRpb25zJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFpbGd1biB7XG4gIHByaXZhdGUgZm9ybURhdGE6IG5ldyAoKSA9PiBGb3JtRGF0YVxuXG4gIGNvbnN0cnVjdG9yKEZvcm1EYXRhOiBuZXcgKCkgPT4gRm9ybURhdGEpIHtcbiAgICB0aGlzLmZvcm1EYXRhID0gRm9ybURhdGE7XG4gIH1cblxuICBjbGllbnQob3B0aW9uczogT3B0aW9ucykge1xuICAgIHJldHVybiBuZXcgQ2xpZW50KG9wdGlvbnMsIHRoaXMuZm9ybURhdGEpXG4gIH1cbn07IiwiaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcbmltcG9ydCBPcHRpb25zIGZyb20gJy4vaW50ZXJmYWNlcy9PcHRpb25zJztcbmltcG9ydCBSZXF1ZXN0T3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvUmVxdWVzdE9wdGlvbnMnO1xuXG5pbXBvcnQgRG9tYWluQ2xpZW50IGZyb20gJy4vZG9tYWlucyc7XG5pbXBvcnQgRXZlbnRDbGllbnQgZnJvbSAnLi9ldmVudHMnO1xuaW1wb3J0IFN0YXRzQ2xpZW50IGZyb20gJy4vc3RhdHMnO1xuaW1wb3J0IFN1cHByZXNzaW9uQ2xpZW50IGZyb20gJy4vc3VwcHJlc3Npb25zJztcbmltcG9ydCBXZWJob29rQ2xpZW50IGZyb20gJy4vd2ViaG9va3MnO1xuaW1wb3J0IE1lc3NhZ2VzQ2xpZW50IGZyb20gJy4vbWVzc2FnZXMnO1xuaW1wb3J0IFJvdXRlc0NsaWVudCBmcm9tICcuL3JvdXRlcyc7XG5pbXBvcnQgVmFsaWRhdGVDbGllbnQgZnJvbSAnLi92YWxpZGF0ZSc7XG5pbXBvcnQgUGFyc2VDbGllbnQgZnJvbSAnLi9wYXJzZSc7XG5pbXBvcnQgSXBzQ2xpZW50IGZyb20gJy4vaXBzJztcbmltcG9ydCBJcFBvb2xzQ2xpZW50IGZyb20gJy4vaXAtcG9vbHMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDbGllbnQge1xuICBwcml2YXRlIHJlcXVlc3Q7XG5cbiAgcHVibGljIGRvbWFpbnM7XG4gIHB1YmxpYyB3ZWJob29rcztcbiAgcHVibGljIGV2ZW50cztcbiAgcHVibGljIHN0YXRzO1xuICBwdWJsaWMgc3VwcHJlc3Npb25zO1xuICBwdWJsaWMgbWVzc2FnZXM7XG4gIHB1YmxpYyByb3V0ZXM7XG4gIHB1YmxpYyBwdWJsaWNfcmVxdWVzdDtcbiAgcHVibGljIHZhbGlkYXRlO1xuICBwdWJsaWMgcGFyc2U7XG4gIHB1YmxpYyBpcHM7XG4gIHB1YmxpYyBpcF9wb29scztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zLCBmb3JtRGF0YTogbmV3ICgpID0+IEZvcm1EYXRhKSB7XG4gICAgY29uc3QgY29uZmlnOiBSZXF1ZXN0T3B0aW9ucyA9IHsgLi4ub3B0aW9ucyB9IGFzIFJlcXVlc3RPcHRpb25zO1xuXG4gICAgaWYgKCFjb25maWcudXJsKSB7XG4gICAgICBjb25maWcudXJsID0gJ2h0dHBzOi8vYXBpLm1haWxndW4ubmV0J1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLnVzZXJuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmFtZXRlciBcInVzZXJuYW1lXCIgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIWNvbmZpZy5rZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFwia2V5XCIgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgdGhpcy5yZXF1ZXN0ID0gbmV3IFJlcXVlc3QoY29uZmlnLCBmb3JtRGF0YSk7XG5cbiAgICB0aGlzLmRvbWFpbnMgPSBuZXcgRG9tYWluQ2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy53ZWJob29rcyA9IG5ldyBXZWJob29rQ2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5ldmVudHMgPSBuZXcgRXZlbnRDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLnN0YXRzID0gbmV3IFN0YXRzQ2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5zdXBwcmVzc2lvbnMgPSBuZXcgU3VwcHJlc3Npb25DbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLm1lc3NhZ2VzID0gbmV3IE1lc3NhZ2VzQ2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5yb3V0ZXMgPSBuZXcgUm91dGVzQ2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5pcHMgPSBuZXcgSXBzQ2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5pcF9wb29scyA9IG5ldyBJcFBvb2xzQ2xpZW50KHRoaXMucmVxdWVzdCk7XG5cbiAgICBpZiAoY29uZmlnLnB1YmxpY19rZXkpIHtcbiAgICAgIGNvbmZpZy5rZXkgPSBjb25maWcucHVibGljX2tleTtcblxuICAgICAgdGhpcy5wdWJsaWNfcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KGNvbmZpZywgZm9ybURhdGEpO1xuICAgICAgdGhpcy52YWxpZGF0ZSA9IG5ldyBWYWxpZGF0ZUNsaWVudCh0aGlzLnB1YmxpY19yZXF1ZXN0KTtcbiAgICAgIHRoaXMucGFyc2UgPSBuZXcgUGFyc2VDbGllbnQodGhpcy5wdWJsaWNfcmVxdWVzdCk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgdXJsam9pbiBmcm9tICd1cmwtam9pbic7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5pbnRlcmZhY2UgRG9tYWluRGF0YSB7XG4gIG5hbWU6IHN0cmluZztcbiAgcmVxdWlyZV90bHM6IGFueTtcbiAgc2tpcF92ZXJpZmljYXRpb246IGFueTtcbiAgc3RhdGU6IGFueTtcbiAgd2lsZGNhcmQ6IGFueTtcbiAgc3BhbV9hY3Rpb246IGFueTtcbiAgY3JlYXRlZF9hdDogc3RyaW5nIHwgRGF0ZTtcbiAgc210cF9wYXNzd29yZDogc3RyaW5nO1xuICBzbXRwX2xvZ2luOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbn1cblxuY2xhc3MgRG9tYWluIHtcbiAgbmFtZTogYW55O1xuICByZXF1aXJlX3RsczogYW55O1xuICBza2lwX3ZlcmlmaWNhdGlvbjogYW55O1xuICBzdGF0ZTogYW55O1xuICB3aWxkY2FyZDogYW55O1xuICBzcGFtX2FjdGlvbjogYW55O1xuICBjcmVhdGVkX2F0OiBhbnk7XG4gIHNtdHBfcGFzc3dvcmQ6IGFueTtcbiAgc210cF9sb2dpbjogYW55O1xuICB0eXBlOiBhbnk7XG4gIHJlY2VpdmluZ19kbnNfcmVjb3JkczogYW55O1xuICBzZW5kaW5nX2Ruc19yZWNvcmRzOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogRG9tYWluRGF0YSwgcmVjZWl2aW5nPzogYW55LCBzZW5kaW5nPzogYW55KSB7XG4gICAgdGhpcy5uYW1lID0gZGF0YS5uYW1lO1xuICAgIHRoaXMucmVxdWlyZV90bHMgPSBkYXRhLnJlcXVpcmVfdGxzO1xuICAgIHRoaXMuc2tpcF92ZXJpZmljYXRpb24gPSBkYXRhLnNraXBfdmVyaWZpY2F0aW9uO1xuICAgIHRoaXMuc3RhdGUgPSBkYXRhLnN0YXRlO1xuICAgIHRoaXMud2lsZGNhcmQgPSBkYXRhLndpbGRjYXJkO1xuICAgIHRoaXMuc3BhbV9hY3Rpb24gPSBkYXRhLnNwYW1fYWN0aW9uO1xuICAgIHRoaXMuY3JlYXRlZF9hdCA9IGRhdGEuY3JlYXRlZF9hdDtcbiAgICB0aGlzLnNtdHBfcGFzc3dvcmQgPSBkYXRhLnNtdHBfcGFzc3dvcmQ7XG4gICAgdGhpcy5zbXRwX2xvZ2luID0gZGF0YS5zbXRwX2xvZ2luO1xuICAgIHRoaXMudHlwZSA9IGRhdGEudHlwZTtcblxuICAgIHRoaXMucmVjZWl2aW5nX2Ruc19yZWNvcmRzID0gcmVjZWl2aW5nIHx8IG51bGw7XG4gICAgdGhpcy5zZW5kaW5nX2Ruc19yZWNvcmRzID0gc2VuZGluZyB8fCBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvbWFpbkNsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VNZXNzYWdlKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gIH1cblxuICBfcGFyc2VEb21haW5MaXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgaXRlbXM6IERvbWFpbkRhdGFbXSB9IH0pIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBuZXcgRG9tYWluKGl0ZW0pO1xuICAgIH0pO1xuICB9XG5cbiAgX3BhcnNlRG9tYWluKHJlc3BvbnNlOiB7XG4gICAgYm9keToge1xuICAgICAgZG9tYWluOiBhbnksXG4gICAgICByZWNlaXZpbmdfZG5zX3JlY29yZHM6IGFueSxcbiAgICAgIHNlbmRpbmdfZG5zX3JlY29yZHM6IGFueVxuICAgIH1cbiAgfSkge1xuICAgIHJldHVybiBuZXcgRG9tYWluKFxuICAgICAgcmVzcG9uc2UuYm9keS5kb21haW4sXG4gICAgICByZXNwb25zZS5ib2R5LnJlY2VpdmluZ19kbnNfcmVjb3JkcyxcbiAgICAgIHJlc3BvbnNlLmJvZHkuc2VuZGluZ19kbnNfcmVjb3Jkc1xuICAgICk7XG4gIH1cblxuICBfcGFyc2VUcmFja2luZ1NldHRpbmdzKHJlc3BvbnNlOiB7IGJvZHk6IHsgdHJhY2tpbmc6IGFueSB9IH0pIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS50cmFja2luZztcbiAgfVxuXG4gIF9wYXJzZVRyYWNraW5nVXBkYXRlKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gIH1cblxuICBsaXN0KHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCgnL3YyL2RvbWFpbnMnLCBxdWVyeSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlRG9tYWluTGlzdCk7XG4gIH1cblxuICBnZXQoZG9tYWluOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YyL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlRG9tYWluKTtcbiAgfVxuXG4gIGNyZWF0ZShkYXRhOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3QoJy92Mi9kb21haW5zJywgZGF0YSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlRG9tYWluKTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YyL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlTWVzc2FnZSk7XG4gIH1cblxuICAvLyBUcmFja2luZ1xuXG4gIGdldFRyYWNraW5nKGRvbWFpbjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd0cmFja2luZycpKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VUcmFja2luZ1NldHRpbmdzKTtcbiAgfVxuXG4gIHVwZGF0ZVRyYWNraW5nKGRvbWFpbjogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIGRhdGE6IGFueSkge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucHV0KHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAndHJhY2tpbmcnLCB0eXBlKSwgZGF0YSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlVHJhY2tpbmdVcGRhdGUpO1xuICB9XG5cbiAgLy8gSVBzXG5cbiAgZ2V0SXBzKGRvbWFpbjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICdpcHMnKSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiB7IGl0ZW1zOiBzdHJpbmdbXSB9IH0pID0+IHJlc3BvbnNlPy5ib2R5Py5pdGVtcyk7XG4gIH1cblxuICBhc3NpZ25JcChkb21haW46IHN0cmluZywgaXA6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IGlwIH0pO1xuICB9XG5cbiAgZGVsZXRlSXAoZG9tYWluOiBzdHJpbmcsIGlwOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZSh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycsIGlwKSk7XG4gIH1cblxuICBsaW5rSXBQb29sKGRvbWFpbjogc3RyaW5nLCBwb29sX2lkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3QodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICdpcHMnKSwgeyBwb29sX2lkIH0pO1xuICB9XG5cbiAgdW5saW5rSXBQb2xsKGRvbWFpbjogc3RyaW5nLCBwb29sX2lkOiBzdHJpbmcsIGlwOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZSh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycsICdpcF9wb29sJyksIHsgcG9vbF9pZCwgaXAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCBBUElFcnJvck9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL0FQSUVycm9yT3B0aW9ucyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFQSUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBzdGF0dXM6IG51bWJlciB8IHN0cmluZztcbiAgc3RhY2s6IHN0cmluZztcbiAgZGV0YWlsczogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBzdGF0dXMsXG4gICAgc3RhdHVzVGV4dCxcbiAgICBtZXNzYWdlLFxuICAgIGJvZHkgPSB7fVxuICB9OiBBUElFcnJvck9wdGlvbnMpIHtcbiAgICBjb25zdCB7IG1lc3NhZ2U6IGJvZHlNZXNzYWdlLCBlcnJvciB9ID0gYm9keTtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5zdGFjayA9IG51bGw7XG4gICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7XG4gICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZSB8fCBlcnJvciB8fCBzdGF0dXNUZXh0O1xuICAgIHRoaXMuZGV0YWlscyA9IGJvZHlNZXNzYWdlO1xuICB9XG59XG4iLCJjb25zdCB1cmxqb2luID0gcmVxdWlyZSgndXJsLWpvaW4nKTtcblxuY29uc3QgTWdSZXF1ZXN0ID0gcmVxdWlyZSgnLi9yZXF1ZXN0Jyk7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV2ZW50Q2xpZW50IHtcbiAgcmVxdWVzdDogdHlwZW9mIE1nUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiB0eXBlb2YgTWdSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIF9wYXJzZVBhZ2VOdW1iZXIodXJsOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdXJsLnNwbGl0KCcvJykucG9wKCk7XG4gIH1cblxuICBfcGFyc2VQYWdlKGlkOiBzdHJpbmcsIHVybDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHsgaWQsIG51bWJlcjogdGhpcy5fcGFyc2VQYWdlTnVtYmVyKHVybCksIHVybCB9O1xuICB9XG5cbiAgX3BhcnNlUGFnZUxpbmtzKHJlc3BvbnNlOiB7IGJvZHk6IHsgcGFnaW5nOiBhbnkgfSB9KSB7XG4gICAgY29uc3QgcGFnZXMgPSBPYmplY3QuZW50cmllcyhyZXNwb25zZS5ib2R5LnBhZ2luZyk7XG4gICAgcmV0dXJuIHBhZ2VzLnJlZHVjZShcbiAgICAgIChhY2M6IGFueSwgW2lkLCB1cmxdOiBbdXJsOiBzdHJpbmcsIGlkOiBzdHJpbmddKSA9PiB7XG4gICAgICAgIGFjY1tpZF0gPSB0aGlzLl9wYXJzZVBhZ2UoaWQsIHVybClcbiAgICAgICAgcmV0dXJuIGFjY1xuICAgICAgfSwge30pO1xuICB9XG5cbiAgX3BhcnNlRXZlbnRMaXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgaXRlbXM6IGFueSwgcGFnaW5nOiBhbnkgfSAgfSkge1xuICAgIHJldHVybiB7XG4gICAgICBpdGVtczogcmVzcG9uc2UuYm9keS5pdGVtcyxcbiAgICAgIHBhZ2VzOiB0aGlzLl9wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZSlcbiAgICB9O1xuICB9XG5cbiAgZ2V0KGRvbWFpbjogc3RyaW5nLCBxdWVyeTogeyBwYWdlOiBhbnkgfSkge1xuICAgIGxldCB1cmw7XG5cbiAgICBpZiAocXVlcnkgJiYgcXVlcnkucGFnZSkge1xuICAgICAgdXJsID0gdXJsam9pbignL3YyJywgZG9tYWluLCAnZXZlbnRzJywgcXVlcnkucGFnZSk7XG4gICAgICBkZWxldGUgcXVlcnkucGFnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXJsID0gdXJsam9pbignL3YyJywgZG9tYWluLCAnZXZlbnRzJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiB7IGl0ZW1zOiBhbnksIHBhZ2luZzogYW55IH0gfSkgPT4gdGhpcy5fcGFyc2VFdmVudExpc3QocmVzcG9uc2UpKTtcbiAgfVxufVxuIiwiY29uc3QgTWdSZXF1ZXN0ID0gcmVxdWlyZSgnLi9yZXF1ZXN0Jyk7XG5cbmltcG9ydCB7IElwUG9vbCB9IGZyb20gXCIuL2ludGVyZmFjZXMvSXBQb29sc1wiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJcFBvb2xzQ2xpZW50IHtcbiAgcmVxdWVzdDogdHlwZW9mIE1nUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiB0eXBlb2YgTWdSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIGxpc3QocXVlcnk6IGFueSk6IElwUG9vbFtdIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCgnL3YxL2lwX3Bvb2xzJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogeyBpcF9wb29sczogSXBQb29sLCBtZXNzYWdlOiBzdHJpbmcgfSB9KSA9PiB0aGlzLnBhcnNlSXBQb29sc1Jlc3BvbnNlKHJlc3BvbnNlKSk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogeyBuYW1lOiBzdHJpbmcsIGRlc2NyaXB0aW9uPzogc3RyaW5nLCBpcHM/OiBzdHJpbmdbXSB9KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0KCcvdjEvaXBfcG9vbHMnLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IHsgbWVzc2FnZTogc3RyaW5nLCBwb29sX2lkOiBzdHJpbmcgfSB9KSA9PiByZXNwb25zZT8uYm9keSk7XG4gIH1cblxuICB1cGRhdGUocG9vbElkOiBzdHJpbmcsIGRhdGE6IHsgbmFtZTogc3RyaW5nLCBkZXNjcmlwdGlvbjogc3RyaW5nLCBhZGRfaXA6IHN0cmluZywgcmVtb3ZlX2lwOiBzdHJpbmcgfSkge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucGF0Y2goYC92MS9pcF9wb29scy8ke3Bvb2xJZH1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZT8uYm9keSk7XG4gIH1cblxuICBkZWxldGUocG9vbElkOiBzdHJpbmcsIGRhdGE6IHsgaWQ6IHN0cmluZywgcG9vbF9pZDogc3RyaW5nIH0pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YxL2lwX3Bvb2xzLyR7cG9vbElkfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogYW55IH0pID0+IHJlc3BvbnNlPy5ib2R5KTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2U6IHsgYm9keTogYW55IHwgYW55IH0pIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5pcF9wb29scztcbiAgfVxufVxuIiwiY29uc3QgTWdSZXF1ZXN0ID0gcmVxdWlyZSgnLi9yZXF1ZXN0Jyk7XG5pbXBvcnQgeyBJcERhdGEsIElwc0xpc3RSZXNwb25zZUJvZHkgfSBmcm9tICcuL2ludGVyZmFjZXMvSXBzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSXBzQ2xpZW50IHtcbiAgcmVxdWVzdDogdHlwZW9mIE1nUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiB0eXBlb2YgTWdSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIGxpc3QocXVlcnk6IGFueSkge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvaXBzJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogSXBzTGlzdFJlc3BvbnNlQm9keSB9KSA9PiB0aGlzLnBhcnNlSXBzUmVzcG9uc2UocmVzcG9uc2UpKTtcbiAgfVxuXG4gIGdldChpcDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYC92My9pcHMvJHtpcH1gKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IElwRGF0YSB9KSA9PiB0aGlzLnBhcnNlSXBzUmVzcG9uc2UocmVzcG9uc2UpKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJcHNSZXNwb25zZShyZXNwb25zZTogeyBib2R5OiBJcHNMaXN0UmVzcG9uc2VCb2R5IHwgSXBEYXRhIH0pIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keTtcbiAgfVxufVxuIiwiaW1wb3J0IFJlcXVlc3QgZnJvbSBcIi4vcmVxdWVzdFwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXNzYWdlc0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VSZXNwb25zZShyZXNwb25zZTogeyBib2R5OiBhbnkgfSkge1xuICAgIGlmIChyZXNwb25zZS5ib2R5KSB7XG4gICAgICByZXR1cm4gcmVzcG9uc2UuYm9keTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cblxuICBjcmVhdGUoZG9tYWluOiBzdHJpbmcsIGRhdGE6IGFueSkge1xuICAgIGlmIChkYXRhLm1lc3NhZ2UpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdE11bHRpKGAvdjMvJHtkb21haW59L21lc3NhZ2VzLm1pbWVgLCBkYXRhKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VSZXNwb25zZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0TXVsdGkoYC92My8ke2RvbWFpbn0vbWVzc2FnZXNgLCBkYXRhKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VSZXNwb25zZSk7XG4gIH1cbn1cbiIsImltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhcnNlQ2xpZW50IHtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIGdldChhZGRyZXNzZXM6IHN0cmluZ1tdIHwgc3RyaW5nLCBlbmFibGVEbnNFc3BDaGVja3M6IGJvb2xlYW4pIHtcbiAgICBjb25zdCBxdWVyeSA9IHt9IGFzIHsgYWRkcmVzc2VzOiBzdHJpbmcsIHN5bnRheF9vbmx5OiBib29sZWFuIH07XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhZGRyZXNzZXMpKSB7XG4gICAgICBhZGRyZXNzZXMgPSBhZGRyZXNzZXMuam9pbignLCcpO1xuICAgIH1cblxuICAgIHF1ZXJ5LmFkZHJlc3NlcyA9IGFkZHJlc3NlcztcblxuICAgIGlmIChlbmFibGVEbnNFc3BDaGVja3MpIHtcbiAgICAgIHF1ZXJ5LnN5bnRheF9vbmx5ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9hZGRyZXNzL3BhcnNlJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG59XG4iLCJcbmltcG9ydCBCdG9hIGZyb20gJ2J0b2EnO1xuaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IGt5IGZyb20gJ2t5LXVuaXZlcnNhbCc7XG5cbmltcG9ydCBBUElFcnJvciBmcm9tICcuL2Vycm9yJztcbmltcG9ydCBSZXF1ZXN0T3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvUmVxdWVzdE9wdGlvbnMnO1xuaW1wb3J0IEFQSUVycm9yT3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvQVBJRXJyb3JPcHRpb25zJztcblxuY29uc3QgaXNTdHJlYW0gPSAoYXR0YWNobWVudDogYW55KSA9PiB0eXBlb2YgYXR0YWNobWVudCA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGF0dGFjaG1lbnQucGlwZSA9PT0gJ2Z1bmN0aW9uJztcblxuY29uc3QgZ2V0QXR0YWNobWVudE9wdGlvbnMgPSAoaXRlbTogYW55KTogeyBmaWxlbmFtZT86IHN0cmluZywgY29udGVudFR5cGU/OiBzdHJpbmcsIGtub3duTGVuZ3RoPzogbnVtYmVyIH0gPT4ge1xuICBpZiAodHlwZW9mIGl0ZW0gIT09ICdvYmplY3QnIHx8IGlzU3RyZWFtKGl0ZW0pKSByZXR1cm4ge307XG5cbiAgY29uc3Qge1xuICAgIGZpbGVuYW1lLFxuICAgIGNvbnRlbnRUeXBlLFxuICAgIGtub3duTGVuZ3RoXG4gIH0gPSBpdGVtO1xuXG4gIHJldHVybiB7XG4gICAgLi4uKGZpbGVuYW1lID8geyBmaWxlbmFtZSB9IDogeyBmaWxlbmFtZTogJ2ZpbGUnIH0pLFxuICAgIC4uLihjb250ZW50VHlwZSAmJiB7IGNvbnRlbnRUeXBlIH0pLFxuICAgIC4uLihrbm93bkxlbmd0aCAmJiB7IGtub3duTGVuZ3RoIH0pXG4gIH07XG59XG5cbmNvbnN0IHN0cmVhbVRvU3RyaW5nID0gKHN0cmVhbTogYW55KSA9PiB7XG4gIGNvbnN0IGNodW5rczogYW55ID0gW11cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzdHJlYW0ub24oJ2RhdGEnLCAoY2h1bms6IGFueSkgPT4gY2h1bmtzLnB1c2goY2h1bmspKVxuICAgIHN0cmVhbS5vbignZXJyb3InLCByZWplY3QpXG4gICAgc3RyZWFtLm9uKCdlbmQnLCAoKSA9PiByZXNvbHZlKEJ1ZmZlci5jb25jYXQoY2h1bmtzKS50b1N0cmluZygndXRmOCcpKSlcbiAgfSlcbn1cblxuY2xhc3MgUmVxdWVzdCB7XG4gIHByaXZhdGUgdXNlcm5hbWU7XG4gIHByaXZhdGUga2V5O1xuICBwcml2YXRlIHVybDtcbiAgcHJpdmF0ZSBoZWFkZXJzOiBhbnk7XG4gIHByaXZhdGUgZm9ybURhdGE6IG5ldyAoKSA9PiBGb3JtRGF0YTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucywgZm9ybURhdGE6IG5ldyAoKSA9PiBGb3JtRGF0YSkge1xuICAgIHRoaXMudXNlcm5hbWUgPSBvcHRpb25zLnVzZXJuYW1lO1xuICAgIHRoaXMua2V5ID0gb3B0aW9ucy5rZXk7XG4gICAgdGhpcy51cmwgPSBvcHRpb25zLnVybDtcbiAgICB0aGlzLmhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnMgfHwge307XG4gICAgdGhpcy5mb3JtRGF0YSA9IGZvcm1EYXRhO1xuICB9XG5cbiAgYXN5bmMgcmVxdWVzdChtZXRob2Q6IHN0cmluZywgdXJsOiBzdHJpbmcsIG9wdGlvbnM/OiBhbnkpIHtcbiAgICBjb25zdCBiYXNpYyA9IEJ0b2EoYCR7dGhpcy51c2VybmFtZX06JHt0aGlzLmtleX1gKTtcbiAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgQXV0aG9yaXphdGlvbjogYEJhc2ljICR7YmFzaWN9YCxcbiAgICAgIC4uLnRoaXMuaGVhZGVycyxcbiAgICAgIC4uLm9wdGlvbnM/LmhlYWRlcnNcbiAgICB9O1xuXG4gICAgZGVsZXRlIG9wdGlvbnM/LmhlYWRlcnM7XG5cbiAgICBpZiAoIWhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddKSB7XG4gICAgICAvLyBmb3IgZm9ybS1kYXRhIGl0IHdpbGwgYmUgTnVsbCBzbyB3ZSBuZWVkIHRvIHJlbW92ZSBpdFxuICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmFtcyA9IHsgLi4ub3B0aW9ucyB9O1xuXG4gICAgaWYgKG9wdGlvbnM/LnF1ZXJ5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9wdGlvbnM/LnF1ZXJ5KS5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJhbXMuc2VhcmNoUGFyYW1zID0gb3B0aW9ucy5xdWVyeTtcbiAgICAgIGRlbGV0ZSBwYXJhbXMucXVlcnlcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGt5KFxuICAgICAgdXJsam9pbih0aGlzLnVybCwgdXJsKSxcbiAgICAgIHtcbiAgICAgICAgbWV0aG9kOiBtZXRob2QudG9Mb2NhbGVVcHBlckNhc2UoKSxcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgdGhyb3dIdHRwRXJyb3JzOiBmYWxzZSxcbiAgICAgICAgLi4ucGFyYW1zXG4gICAgICB9XG4gICAgKTtcblxuICAgIGlmICghcmVzcG9uc2U/Lm9rKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gcmVzcG9uc2U/LmJvZHkgJiYgaXNTdHJlYW0ocmVzcG9uc2UuYm9keSlcbiAgICAgICAgPyBhd2FpdCBzdHJlYW1Ub1N0cmluZyhyZXNwb25zZS5ib2R5KVxuICAgICAgICA6IGF3YWl0IHJlc3BvbnNlPy5qc29uKCk7XG5cbiAgICAgIHRocm93IG5ldyBBUElFcnJvcih7XG4gICAgICAgIHN0YXR1czogcmVzcG9uc2U/LnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogcmVzcG9uc2U/LnN0YXR1c1RleHQsXG4gICAgICAgIGJvZHk6IHsgbWVzc2FnZSB9XG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJvZHk6IGF3YWl0IHJlc3BvbnNlPy5qc29uKCksXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlPy5zdGF0dXNcbiAgICB9O1xuICB9XG5cbiAgcXVlcnkobWV0aG9kOiBzdHJpbmcsIHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zPzogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChtZXRob2QsIHVybCwgeyBxdWVyeSwgLi4ub3B0aW9ucyB9KTtcbiAgfVxuXG4gIGNvbW1hbmQobWV0aG9kOiBzdHJpbmcsIHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7XG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyB9LFxuICAgICAgYm9keTogZGF0YSxcbiAgICAgIC4uLm9wdGlvbnNcbiAgICB9KTtcbiAgfVxuXG4gIGdldCh1cmw6IHN0cmluZywgcXVlcnk/OiBhbnksIG9wdGlvbnM/OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeSgnZ2V0JywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBoZWFkKHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeSgnaGVhZCcsIHVybCwgcXVlcnksIG9wdGlvbnMpO1xuICB9XG5cbiAgb3B0aW9ucyh1cmw6IHN0cmluZywgcXVlcnk6IGFueSwgb3B0aW9uczogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnkoJ29wdGlvbnMnLCB1cmwsIHF1ZXJ5LCBvcHRpb25zKTtcbiAgfVxuXG4gIHBvc3QodXJsOiBzdHJpbmcsIGRhdGE6IGFueSwgb3B0aW9ucz86IGFueSkge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ3Bvc3QnLCB1cmwsIGRhdGEsIG9wdGlvbnMpO1xuICB9XG5cbiAgcG9zdE11bHRpKHVybDogc3RyaW5nLCBkYXRhOiBhbnkpIHtcblxuICAgIGNvbnN0IGZvcm1EYXRhOiBGb3JtRGF0YSA9IG5ldyB0aGlzLmZvcm1EYXRhKCk7XG4gICAgY29uc3QgcGFyYW1zOiBhbnkgPSB7XG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiBudWxsIH1cbiAgICB9O1xuXG4gICAgT2JqZWN0LmtleXMoZGF0YSlcbiAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gZGF0YVtrZXldOyB9KVxuICAgICAgLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoa2V5ID09PSAnYXR0YWNobWVudCcpIHtcbiAgICAgICAgICBjb25zdCBvYmogPSBkYXRhLmF0dGFjaG1lbnQ7XG5cbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgICAgICBvYmouZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICBjb25zdCBkYXRhID0gaXRlbS5kYXRhID8gaXRlbS5kYXRhIDogaXRlbTtcbiAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGdldEF0dGFjaG1lbnRPcHRpb25zKGl0ZW0pO1xuICAgICAgICAgICAgICAoZm9ybURhdGEgYXMgYW55KS5hcHBlbmQoa2V5LCBkYXRhLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhID0gaXNTdHJlYW0ob2JqKSA/IG9iaiA6IG9iai5kYXRhO1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGdldEF0dGFjaG1lbnRPcHRpb25zKG9iaik7XG4gICAgICAgICAgICAoZm9ybURhdGEgYXMgYW55KS5hcHBlbmQoa2V5LCBkYXRhLCBvcHRpb25zKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhW2tleV0pKSB7XG4gICAgICAgICAgZGF0YVtrZXldLmZvckVhY2goZnVuY3Rpb24gKGl0ZW06IGFueSkge1xuICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKGtleSwgaXRlbSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9ybURhdGEuYXBwZW5kKGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5jb21tYW5kKCdwb3N0JywgdXJsLCBmb3JtRGF0YSwgcGFyYW1zKTtcbiAgfVxuXG4gIHB1dCh1cmw6IHN0cmluZywgZGF0YTogYW55LCBvcHRpb25zPzogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncHV0JywgdXJsLCBkYXRhLCBvcHRpb25zKTtcbiAgfVxuXG4gIHBhdGNoKHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kKCdwYXRjaCcsIHVybCwgZGF0YSwgb3B0aW9ucyk7XG4gIH1cblxuICBkZWxldGUodXJsOiBzdHJpbmcsIGRhdGE/OiBhbnksIG9wdGlvbnM/OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kKCdkZWxldGUnLCB1cmwsIGRhdGEsIG9wdGlvbnMpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFJlcXVlc3QiLCJpbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSb3V0ZXNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgbGlzdChxdWVyeTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9yb3V0ZXMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5pdGVtcyk7XG4gIH1cblxuICBnZXQoaWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KGAvdjMvcm91dGVzLyR7aWR9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5yb3V0ZSk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0KCcvdjMvcm91dGVzJywgZGF0YSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5yb3V0ZSk7XG4gIH1cblxuICB1cGRhdGUoaWQ6IHN0cmluZywgZGF0YTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9yb3V0ZXMvJHtpZH1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIGRlc3Ryb3koaWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKGAvdjMvcm91dGVzLyR7aWR9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keSk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQgU3RhdHNPcHRpb25zIGZyb20gJy4vaW50ZXJmYWNlcy9TdGF0c09wdGlvbnMnO1xuXG5jbGFzcyBTdGF0cyB7XG4gIHN0YXJ0OiBEYXRlO1xuICBlbmQ6IERhdGU7XG4gIHJlc29sdXRpb246IHN0cmluZztcbiAgc3RhdHM6IGFueTtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBTdGF0c09wdGlvbnMpIHtcbiAgICB0aGlzLnN0YXJ0ID0gbmV3IERhdGUoZGF0YS5zdGFydCk7XG4gICAgdGhpcy5lbmQgPSBuZXcgRGF0ZShkYXRhLmVuZCk7XG4gICAgdGhpcy5yZXNvbHV0aW9uID0gZGF0YS5yZXNvbHV0aW9uO1xuICAgIHRoaXMuc3RhdHMgPSBkYXRhLnN0YXRzLm1hcChmdW5jdGlvbiAoc3RhdDogeyB0aW1lOiBzdHJpbmcgfCBEYXRlIH0pIHtcbiAgICAgIHN0YXQudGltZSA9IG5ldyBEYXRlKHN0YXQudGltZSk7XG4gICAgICByZXR1cm4gc3RhdDtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGF0c0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VTdGF0cyhyZXNwb25zZTogeyBib2R5OiBTdGF0c09wdGlvbnMgfSkge1xuICAgIHJldHVybiBuZXcgU3RhdHMocmVzcG9uc2UuYm9keSk7XG4gIH1cblxuICBnZXREb21haW4oZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjMnLCBkb21haW4sICdzdGF0cy90b3RhbCcpLCBxdWVyeSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlU3RhdHMpO1xuICB9XG5cbiAgZ2V0QWNjb3VudChxdWVyeTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9zdGF0cy90b3RhbCcsIHF1ZXJ5KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VTdGF0cyk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmwgZnJvbSAndXJsJztcbmltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcblxuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcbmltcG9ydCB7IEJvdW5jZURhdGEsIENvbXBsYWludERhdGEsIFVuc3Vic2NyaWJlRGF0YSB9IGZyb20gJy4vaW50ZXJmYWNlcy9TdXByZXNzaW9ucyc7XG5cbnR5cGUgVE1vZGVsID0gdHlwZW9mIEJvdW5jZSB8IHR5cGVvZiBDb21wbGFpbnQgfCB0eXBlb2YgVW5zdWJzY3JpYmU7XG5cbmNvbnN0IGNyZWF0ZU9wdGlvbnMgPSB7XG4gIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9XG59O1xuXG5jbGFzcyBCb3VuY2Uge1xuICB0eXBlOiBzdHJpbmc7XG4gIGFkZHJlc3M6IHN0cmluZztcbiAgY29kZTogbnVtYmVyO1xuICBlcnJvcjogc3RyaW5nO1xuICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IEJvdW5jZURhdGEpIHtcbiAgICB0aGlzLnR5cGUgPSAnYm91bmNlcyc7XG4gICAgdGhpcy5hZGRyZXNzID0gZGF0YS5hZGRyZXNzO1xuICAgIHRoaXMuY29kZSA9ICtkYXRhLmNvZGU7XG4gICAgdGhpcy5lcnJvciA9IGRhdGEuZXJyb3I7XG4gICAgdGhpcy5jcmVhdGVkX2F0ID0gbmV3IERhdGUoZGF0YS5jcmVhdGVkX2F0KTtcbiAgfVxufVxuXG5jbGFzcyBDb21wbGFpbnQge1xuICB0eXBlOiBzdHJpbmc7XG4gIGFkZHJlc3M6IGFueTtcbiAgY3JlYXRlZF9hdDogRGF0ZTtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBDb21wbGFpbnREYXRhKSB7XG4gICAgdGhpcy50eXBlID0gJ2NvbXBsYWludHMnO1xuICAgIHRoaXMuYWRkcmVzcyA9IGRhdGEuYWRkcmVzcztcbiAgICB0aGlzLmNyZWF0ZWRfYXQgPSBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRfYXQpO1xuICB9XG59XG5cbmNsYXNzIFVuc3Vic2NyaWJlIHtcbiAgdHlwZTogc3RyaW5nO1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIHRhZ3M6IGFueTtcbiAgY3JlYXRlZF9hdDogRGF0ZTtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBVbnN1YnNjcmliZURhdGEpIHtcbiAgICB0aGlzLnR5cGUgPSAndW5zdWJzY3JpYmVzJztcbiAgICB0aGlzLmFkZHJlc3MgPSBkYXRhLmFkZHJlc3M7XG4gICAgdGhpcy50YWdzID0gZGF0YS50YWdzO1xuICAgIHRoaXMuY3JlYXRlZF9hdCA9IG5ldyBEYXRlKGRhdGEuY3JlYXRlZF9hdCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3VwcHJlc3Npb25DbGllbnQge1xuICByZXF1ZXN0OiBhbnk7XG4gIG1vZGVsczoge1xuICAgIGJvdW5jZXM6IHR5cGVvZiBCb3VuY2U7XG4gICAgY29tcGxhaW50czogdHlwZW9mIENvbXBsYWludDtcbiAgICB1bnN1YnNjcmliZXM6IHR5cGVvZiBVbnN1YnNjcmliZTtcbiAgfTtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLm1vZGVscyA9IHtcbiAgICAgIGJvdW5jZXM6IEJvdW5jZSxcbiAgICAgIGNvbXBsYWludHM6IENvbXBsYWludCxcbiAgICAgIHVuc3Vic2NyaWJlczogVW5zdWJzY3JpYmVcbiAgICB9O1xuICB9XG5cbiAgX3BhcnNlUGFnZShpZDogc3RyaW5nLCBwYWdlVXJsOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwYXJzZWRVcmwgPSB1cmwucGFyc2UocGFnZVVybCwgdHJ1ZSk7XG4gICAgY29uc3QgeyBxdWVyeSB9ID0gcGFyc2VkVXJsO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkLFxuICAgICAgcGFnZTogcXVlcnkucGFnZSxcbiAgICAgIGFkZHJlc3M6IHF1ZXJ5LmFkZHJlc3MsXG4gICAgICB1cmw6IHBhZ2VVcmxcbiAgICB9O1xuICB9XG5cbiAgX3BhcnNlUGFnZUxpbmtzKHJlc3BvbnNlOiB7IGJvZHk6IHsgcGFnaW5nOiBhbnkgfSB9KSB7XG4gICAgY29uc3QgcGFnZXMgPSBPYmplY3QuZW50cmllcyhyZXNwb25zZS5ib2R5LnBhZ2luZyk7XG4gICAgcmV0dXJuIHBhZ2VzLnJlZHVjZShcbiAgICAgIChhY2M6IGFueSwgW2lkLCB1cmxdOiBbdXJsOiBzdHJpbmcsIGlkOiBzdHJpbmddKSA9PiB7XG4gICAgICAgIGFjY1tpZF0gPSB0aGlzLl9wYXJzZVBhZ2UoaWQsIHVybClcbiAgICAgICAgcmV0dXJuIGFjY1xuICAgICAgfSwge30pO1xuICB9XG5cbiAgX3BhcnNlTGlzdChyZXNwb25zZTogeyBib2R5OiB7IGl0ZW1zOiBhbnksIHBhZ2luZzogYW55IH0gfSwgTW9kZWw6IFRNb2RlbCkge1xuICAgIGNvbnN0IGRhdGEgPSB7fSBhcyBhbnk7XG5cbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoKGQ6IGFueSkgPT4gbmV3IE1vZGVsKGQpKTtcblxuICAgIGRhdGEucGFnZXMgPSB0aGlzLl9wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZSk7XG5cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIF9wYXJzZUl0ZW0ocmVzcG9uc2U6IHsgYm9keTogYW55IH0sIE1vZGVsOiBUTW9kZWwpIHtcbiAgICByZXR1cm4gbmV3IE1vZGVsKHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgbGlzdChkb21haW46IHN0cmluZywgdHlwZTogc3RyaW5nLCBxdWVyeTogYW55KSB7XG4gICAgY29uc3QgbW9kZWwgPSAodGhpcy5tb2RlbHMgYXMgYW55KVt0eXBlXTtcblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAgIC5nZXQodXJsam9pbigndjMnLCBkb21haW4sIHR5cGUpLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiB7IGl0ZW1zOiBhbnksIHBhZ2luZzogYW55IH0gfSkgPT4gdGhpcy5fcGFyc2VMaXN0KHJlc3BvbnNlLCBtb2RlbCkpO1xuICB9XG5cbiAgZ2V0KGRvbWFpbjogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIGFkZHJlc3M6IHN0cmluZykge1xuICAgIGNvbnN0IG1vZGVsID0gKHRoaXMubW9kZWxzIGFzIGFueSlbdHlwZV07XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAuZ2V0KHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlLCBlbmNvZGVVUklDb21wb25lbnQoYWRkcmVzcykpKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiB0aGlzLl9wYXJzZUl0ZW0ocmVzcG9uc2UsIG1vZGVsKSk7XG4gIH1cblxuICBjcmVhdGUoZG9tYWluOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgZGF0YTogYW55KSB7XG4gICAgLy8gc3VwcG9ydHMgYWRkaW5nIG11bHRpcGxlIHN1cHByZXNzaW9ucyBieSBkZWZhdWx0XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICBkYXRhID0gW2RhdGFdO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAucG9zdCh1cmxqb2luKCd2MycsIGRvbWFpbiwgdHlwZSksIGRhdGEsIGNyZWF0ZU9wdGlvbnMpXG4gICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgYWRkcmVzczogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFxuICAgIC5kZWxldGUodXJsam9pbigndjMnLCBkb21haW4sIHR5cGUsIGVuY29kZVVSSUNvbXBvbmVudChhZGRyZXNzKSkpXG4gICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN1cHByZXNzaW9uQ2xpZW50O1xuIiwiXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWYWxpZGF0ZUNsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBnZXQoYWRkcmVzczogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9hZGRyZXNzL3ZhbGlkYXRlJywgeyBhZGRyZXNzIH0pXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG59XG4iLCJpbXBvcnQgdXJsam9pbiBmcm9tICd1cmwtam9pbic7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5jbGFzcyBXZWJob29rIHtcbiAgaWQ6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgZGF0YTogeyB1cmw6IHN0cmluZyB9KSB7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMudXJsID0gZGF0YS51cmw7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2ViaG9va0NsaWVudCB7XG4gIHJlcXVlc3Q6IGFueTtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tMaXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgd2ViaG9va3M6IGFueSB9IH0pIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS53ZWJob29rcztcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tXaXRoSUQoaWQ6IHN0cmluZykge1xuICAgIHJldHVybiBmdW5jdGlvbiAocmVzcG9uc2U6IHsgYm9keTogeyB3ZWJob29rOiBhbnkgfSB9KSB7XG4gICAgICByZXR1cm4gbmV3IFdlYmhvb2soaWQsIHJlc3BvbnNlLmJvZHkud2ViaG9vayk7XG4gICAgfTtcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tUZXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgY29kZTogbnVtYmVyLCBtZXNzYWdlOiBzdHJpbmcgfSB9KSB7XG4gICAgcmV0dXJuIHsgY29kZTogcmVzcG9uc2UuYm9keS5jb2RlLCBtZXNzYWdlOiByZXNwb25zZS5ib2R5Lm1lc3NhZ2UgfTtcbiAgfVxuXG4gIGxpc3QoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJyksIHF1ZXJ5KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rTGlzdCk7XG4gIH1cblxuICBnZXQoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJywgaWQpKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rV2l0aElEKGlkKSk7XG4gIH1cblxuICBjcmVhdGUoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcsIHVybDogc3RyaW5nLCB0ZXN0OiBib29sZWFuKSB7XG4gICAgaWYgKHRlc3QpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QucHV0KHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAnd2ViaG9va3MnLCBpZCwgJ3Rlc3QnKSwgeyB1cmwgfSlcbiAgICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rVGVzdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0KHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAnd2ViaG9va3MnKSwgeyBpZCwgdXJsIH0pXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tXaXRoSUQoaWQpKTtcbiAgfVxuXG4gIHVwZGF0ZShkb21haW46IHN0cmluZywgaWQ6IHN0cmluZywgdXJsOiBzdHJpbmcsKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkKSwgeyB1cmwgfSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG5cbiAgZGVzdHJveShkb21haW46IHN0cmluZywgaWQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAnd2ViaG9va3MnLCBpZCkpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tXaXRoSUQoaWQpKTtcbiAgfVxufVxuIiwiKGZ1bmN0aW9uICgpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgZnVuY3Rpb24gYnRvYShzdHIpIHtcbiAgICB2YXIgYnVmZmVyO1xuXG4gICAgaWYgKHN0ciBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgYnVmZmVyID0gc3RyO1xuICAgIH0gZWxzZSB7XG4gICAgICBidWZmZXIgPSBCdWZmZXIuZnJvbShzdHIudG9TdHJpbmcoKSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB9XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBidG9hO1xufSgpKTtcbiIsIlwidXNlIHN0cmljdFwiO1xuLyoqXG4gKiBSZXR1cm5zIGEgYEJ1ZmZlcmAgaW5zdGFuY2UgZnJvbSB0aGUgZ2l2ZW4gZGF0YSBVUkkgYHVyaWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVyaSBEYXRhIFVSSSB0byB0dXJuIGludG8gYSBCdWZmZXIgaW5zdGFuY2VcbiAqIEByZXR1cm4ge0J1ZmZlcn0gQnVmZmVyIGluc3RhbmNlIGZyb20gRGF0YSBVUklcbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIGRhdGFVcmlUb0J1ZmZlcih1cmkpIHtcbiAgICBpZiAoIS9eZGF0YTovaS50ZXN0KHVyaSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYHVyaWAgZG9lcyBub3QgYXBwZWFyIHRvIGJlIGEgRGF0YSBVUkkgKG11c3QgYmVnaW4gd2l0aCBcImRhdGE6XCIpJyk7XG4gICAgfVxuICAgIC8vIHN0cmlwIG5ld2xpbmVzXG4gICAgdXJpID0gdXJpLnJlcGxhY2UoL1xccj9cXG4vZywgJycpO1xuICAgIC8vIHNwbGl0IHRoZSBVUkkgdXAgaW50byB0aGUgXCJtZXRhZGF0YVwiIGFuZCB0aGUgXCJkYXRhXCIgcG9ydGlvbnNcbiAgICBjb25zdCBmaXJzdENvbW1hID0gdXJpLmluZGV4T2YoJywnKTtcbiAgICBpZiAoZmlyc3RDb21tYSA9PT0gLTEgfHwgZmlyc3RDb21tYSA8PSA0KSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ21hbGZvcm1lZCBkYXRhOiBVUkknKTtcbiAgICB9XG4gICAgLy8gcmVtb3ZlIHRoZSBcImRhdGE6XCIgc2NoZW1lIGFuZCBwYXJzZSB0aGUgbWV0YWRhdGFcbiAgICBjb25zdCBtZXRhID0gdXJpLnN1YnN0cmluZyg1LCBmaXJzdENvbW1hKS5zcGxpdCgnOycpO1xuICAgIGxldCBjaGFyc2V0ID0gJyc7XG4gICAgbGV0IGJhc2U2NCA9IGZhbHNlO1xuICAgIGNvbnN0IHR5cGUgPSBtZXRhWzBdIHx8ICd0ZXh0L3BsYWluJztcbiAgICBsZXQgdHlwZUZ1bGwgPSB0eXBlO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbWV0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAobWV0YVtpXSA9PT0gJ2Jhc2U2NCcpIHtcbiAgICAgICAgICAgIGJhc2U2NCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0eXBlRnVsbCArPSBgOyR7bWV0YVtpXX1gO1xuICAgICAgICAgICAgaWYgKG1ldGFbaV0uaW5kZXhPZignY2hhcnNldD0nKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGNoYXJzZXQgPSBtZXRhW2ldLnN1YnN0cmluZyg4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBkZWZhdWx0cyB0byBVUy1BU0NJSSBvbmx5IGlmIHR5cGUgaXMgbm90IHByb3ZpZGVkXG4gICAgaWYgKCFtZXRhWzBdICYmICFjaGFyc2V0Lmxlbmd0aCkge1xuICAgICAgICB0eXBlRnVsbCArPSAnO2NoYXJzZXQ9VVMtQVNDSUknO1xuICAgICAgICBjaGFyc2V0ID0gJ1VTLUFTQ0lJJztcbiAgICB9XG4gICAgLy8gZ2V0IHRoZSBlbmNvZGVkIGRhdGEgcG9ydGlvbiBhbmQgZGVjb2RlIFVSSS1lbmNvZGVkIGNoYXJzXG4gICAgY29uc3QgZW5jb2RpbmcgPSBiYXNlNjQgPyAnYmFzZTY0JyA6ICdhc2NpaSc7XG4gICAgY29uc3QgZGF0YSA9IHVuZXNjYXBlKHVyaS5zdWJzdHJpbmcoZmlyc3RDb21tYSArIDEpKTtcbiAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShkYXRhLCBlbmNvZGluZyk7XG4gICAgLy8gc2V0IGAudHlwZWAgYW5kIGAudHlwZUZ1bGxgIHByb3BlcnRpZXMgdG8gTUlNRSB0eXBlXG4gICAgYnVmZmVyLnR5cGUgPSB0eXBlO1xuICAgIGJ1ZmZlci50eXBlRnVsbCA9IHR5cGVGdWxsO1xuICAgIC8vIHNldCB0aGUgYC5jaGFyc2V0YCBwcm9wZXJ0eVxuICAgIGJ1ZmZlci5jaGFyc2V0ID0gY2hhcnNldDtcbiAgICByZXR1cm4gYnVmZmVyO1xufVxubW9kdWxlLmV4cG9ydHMgPSBkYXRhVXJpVG9CdWZmZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCIvKipcbiAqIEBhdXRob3IgVG9ydSBOYWdhc2hpbWEgPGh0dHBzOi8vZ2l0aHViLmNvbS9teXN0aWNhdGVhPlxuICogQGNvcHlyaWdodCAyMDE1IFRvcnUgTmFnYXNoaW1hLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogU2VlIExJQ0VOU0UgZmlsZSBpbiByb290IGRpcmVjdG9yeSBmb3IgZnVsbCBsaWNlbnNlLlxuICovXG4ndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gUHJpdmF0ZURhdGFcbiAqIEBwcm9wZXJ0eSB7RXZlbnRUYXJnZXR9IGV2ZW50VGFyZ2V0IFRoZSBldmVudCB0YXJnZXQuXG4gKiBAcHJvcGVydHkge3t0eXBlOnN0cmluZ319IGV2ZW50IFRoZSBvcmlnaW5hbCBldmVudCBvYmplY3QuXG4gKiBAcHJvcGVydHkge251bWJlcn0gZXZlbnRQaGFzZSBUaGUgY3VycmVudCBldmVudCBwaGFzZS5cbiAqIEBwcm9wZXJ0eSB7RXZlbnRUYXJnZXR8bnVsbH0gY3VycmVudFRhcmdldCBUaGUgY3VycmVudCBldmVudCB0YXJnZXQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGNhbmNlbGVkIFRoZSBmbGFnIHRvIHByZXZlbnQgZGVmYXVsdC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gc3RvcHBlZCBUaGUgZmxhZyB0byBzdG9wIHByb3BhZ2F0aW9uLlxuICogQHByb3BlcnR5IHtib29sZWFufSBpbW1lZGlhdGVTdG9wcGVkIFRoZSBmbGFnIHRvIHN0b3AgcHJvcGFnYXRpb24gaW1tZWRpYXRlbHkuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufG51bGx9IHBhc3NpdmVMaXN0ZW5lciBUaGUgbGlzdGVuZXIgaWYgdGhlIGN1cnJlbnQgbGlzdGVuZXIgaXMgcGFzc2l2ZS4gT3RoZXJ3aXNlIHRoaXMgaXMgbnVsbC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0aW1lU3RhbXAgVGhlIHVuaXggdGltZS5cbiAqIEBwcml2YXRlXG4gKi9cblxuLyoqXG4gKiBQcml2YXRlIGRhdGEgZm9yIGV2ZW50IHdyYXBwZXJzLlxuICogQHR5cGUge1dlYWtNYXA8RXZlbnQsIFByaXZhdGVEYXRhPn1cbiAqIEBwcml2YXRlXG4gKi9cbmNvbnN0IHByaXZhdGVEYXRhID0gbmV3IFdlYWtNYXAoKTtcblxuLyoqXG4gKiBDYWNoZSBmb3Igd3JhcHBlciBjbGFzc2VzLlxuICogQHR5cGUge1dlYWtNYXA8T2JqZWN0LCBGdW5jdGlvbj59XG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCB3cmFwcGVycyA9IG5ldyBXZWFrTWFwKCk7XG5cbi8qKlxuICogR2V0IHByaXZhdGUgZGF0YS5cbiAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IFRoZSBldmVudCBvYmplY3QgdG8gZ2V0IHByaXZhdGUgZGF0YS5cbiAqIEByZXR1cm5zIHtQcml2YXRlRGF0YX0gVGhlIHByaXZhdGUgZGF0YSBvZiB0aGUgZXZlbnQuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBwZChldmVudCkge1xuICAgIGNvbnN0IHJldHYgPSBwcml2YXRlRGF0YS5nZXQoZXZlbnQpO1xuICAgIGNvbnNvbGUuYXNzZXJ0KFxuICAgICAgICByZXR2ICE9IG51bGwsXG4gICAgICAgIFwiJ3RoaXMnIGlzIGV4cGVjdGVkIGFuIEV2ZW50IG9iamVjdCwgYnV0IGdvdFwiLFxuICAgICAgICBldmVudFxuICAgICk7XG4gICAgcmV0dXJuIHJldHZcbn1cblxuLyoqXG4gKiBodHRwczovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI3NldC10aGUtY2FuY2VsZWQtZmxhZ1xuICogQHBhcmFtIGRhdGEge1ByaXZhdGVEYXRhfSBwcml2YXRlIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIHNldENhbmNlbEZsYWcoZGF0YSkge1xuICAgIGlmIChkYXRhLnBhc3NpdmVMaXN0ZW5lciAhPSBudWxsKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS5lcnJvciA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICAgICBcIlVuYWJsZSB0byBwcmV2ZW50RGVmYXVsdCBpbnNpZGUgcGFzc2l2ZSBldmVudCBsaXN0ZW5lciBpbnZvY2F0aW9uLlwiLFxuICAgICAgICAgICAgICAgIGRhdGEucGFzc2l2ZUxpc3RlbmVyXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoIWRhdGEuZXZlbnQuY2FuY2VsYWJsZSkge1xuICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBkYXRhLmNhbmNlbGVkID0gdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGRhdGEuZXZlbnQucHJldmVudERlZmF1bHQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBkYXRhLmV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9kb20uc3BlYy53aGF0d2cub3JnLyNpbnRlcmZhY2UtZXZlbnRcbiAqIEBwcml2YXRlXG4gKi9cbi8qKlxuICogVGhlIGV2ZW50IHdyYXBwZXIuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7RXZlbnRUYXJnZXR9IGV2ZW50VGFyZ2V0IFRoZSBldmVudCB0YXJnZXQgb2YgdGhpcyBkaXNwYXRjaGluZy5cbiAqIEBwYXJhbSB7RXZlbnR8e3R5cGU6c3RyaW5nfX0gZXZlbnQgVGhlIG9yaWdpbmFsIGV2ZW50IHRvIHdyYXAuXG4gKi9cbmZ1bmN0aW9uIEV2ZW50KGV2ZW50VGFyZ2V0LCBldmVudCkge1xuICAgIHByaXZhdGVEYXRhLnNldCh0aGlzLCB7XG4gICAgICAgIGV2ZW50VGFyZ2V0LFxuICAgICAgICBldmVudCxcbiAgICAgICAgZXZlbnRQaGFzZTogMixcbiAgICAgICAgY3VycmVudFRhcmdldDogZXZlbnRUYXJnZXQsXG4gICAgICAgIGNhbmNlbGVkOiBmYWxzZSxcbiAgICAgICAgc3RvcHBlZDogZmFsc2UsXG4gICAgICAgIGltbWVkaWF0ZVN0b3BwZWQ6IGZhbHNlLFxuICAgICAgICBwYXNzaXZlTGlzdGVuZXI6IG51bGwsXG4gICAgICAgIHRpbWVTdGFtcDogZXZlbnQudGltZVN0YW1wIHx8IERhdGUubm93KCksXG4gICAgfSk7XG5cbiAgICAvLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNVbmZvcmdlYWJsZVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcImlzVHJ1c3RlZFwiLCB7IHZhbHVlOiBmYWxzZSwgZW51bWVyYWJsZTogdHJ1ZSB9KTtcblxuICAgIC8vIERlZmluZSBhY2Nlc3NvcnNcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZXZlbnQpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICBjb25zdCBrZXkgPSBrZXlzW2ldO1xuICAgICAgICBpZiAoIShrZXkgaW4gdGhpcykpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrZXksIGRlZmluZVJlZGlyZWN0RGVzY3JpcHRvcihrZXkpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gU2hvdWxkIGJlIGVudW1lcmFibGUsIGJ1dCBjbGFzcyBtZXRob2RzIGFyZSBub3QgZW51bWVyYWJsZS5cbkV2ZW50LnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGlzIGV2ZW50LlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5ldmVudC50eXBlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7RXZlbnRUYXJnZXR9XG4gICAgICovXG4gICAgZ2V0IHRhcmdldCgpIHtcbiAgICAgICAgcmV0dXJuIHBkKHRoaXMpLmV2ZW50VGFyZ2V0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7RXZlbnRUYXJnZXR9XG4gICAgICovXG4gICAgZ2V0IGN1cnJlbnRUYXJnZXQoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5jdXJyZW50VGFyZ2V0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHtFdmVudFRhcmdldFtdfSBUaGUgY29tcG9zZWQgcGF0aCBvZiB0aGlzIGV2ZW50LlxuICAgICAqL1xuICAgIGNvbXBvc2VkUGF0aCgpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFRhcmdldCA9IHBkKHRoaXMpLmN1cnJlbnRUYXJnZXQ7XG4gICAgICAgIGlmIChjdXJyZW50VGFyZ2V0ID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBbXVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbY3VycmVudFRhcmdldF1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgTk9ORS5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldCBOT05FKCkge1xuICAgICAgICByZXR1cm4gMFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDb25zdGFudCBvZiBDQVBUVVJJTkdfUEhBU0UuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgQ0FQVFVSSU5HX1BIQVNFKCkge1xuICAgICAgICByZXR1cm4gMVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDb25zdGFudCBvZiBBVF9UQVJHRVQuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgQVRfVEFSR0VUKCkge1xuICAgICAgICByZXR1cm4gMlxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDb25zdGFudCBvZiBCVUJCTElOR19QSEFTRS5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldCBCVUJCTElOR19QSEFTRSgpIHtcbiAgICAgICAgcmV0dXJuIDNcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIHRhcmdldCBvZiB0aGlzIGV2ZW50LlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0IGV2ZW50UGhhc2UoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5ldmVudFBoYXNlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFN0b3AgZXZlbnQgYnViYmxpbmcuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgc3RvcFByb3BhZ2F0aW9uKCkge1xuICAgICAgICBjb25zdCBkYXRhID0gcGQodGhpcyk7XG5cbiAgICAgICAgZGF0YS5zdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhLmV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBkYXRhLmV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFN0b3AgZXZlbnQgYnViYmxpbmcuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkge1xuICAgICAgICBjb25zdCBkYXRhID0gcGQodGhpcyk7XG5cbiAgICAgICAgZGF0YS5zdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgZGF0YS5pbW1lZGlhdGVTdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhLmV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBkYXRhLmV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBmbGFnIHRvIGJlIGJ1YmJsaW5nLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIGdldCBidWJibGVzKCkge1xuICAgICAgICByZXR1cm4gQm9vbGVhbihwZCh0aGlzKS5ldmVudC5idWJibGVzKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBiZSBjYW5jZWxhYmxlLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIGdldCBjYW5jZWxhYmxlKCkge1xuICAgICAgICByZXR1cm4gQm9vbGVhbihwZCh0aGlzKS5ldmVudC5jYW5jZWxhYmxlKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgdGhpcyBldmVudC5cbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICAgKi9cbiAgICBwcmV2ZW50RGVmYXVsdCgpIHtcbiAgICAgICAgc2V0Q2FuY2VsRmxhZyhwZCh0aGlzKSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBmbGFnIHRvIGluZGljYXRlIGNhbmNlbGxhdGlvbiBzdGF0ZS5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgZGVmYXVsdFByZXZlbnRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHBkKHRoaXMpLmNhbmNlbGVkXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBmbGFnIHRvIGJlIGNvbXBvc2VkLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIGdldCBjb21wb3NlZCgpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4ocGQodGhpcykuZXZlbnQuY29tcG9zZWQpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1bml4IHRpbWUgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldCB0aW1lU3RhbXAoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS50aW1lU3RhbXBcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIHRhcmdldCBvZiB0aGlzIGV2ZW50LlxuICAgICAqIEB0eXBlIHtFdmVudFRhcmdldH1cbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqL1xuICAgIGdldCBzcmNFbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuZXZlbnRUYXJnZXRcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIGZsYWcgdG8gc3RvcCBldmVudCBidWJibGluZy5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqL1xuICAgIGdldCBjYW5jZWxCdWJibGUoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5zdG9wcGVkXG4gICAgfSxcbiAgICBzZXQgY2FuY2VsQnViYmxlKHZhbHVlKSB7XG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRhdGEgPSBwZCh0aGlzKTtcblxuICAgICAgICBkYXRhLnN0b3BwZWQgPSB0cnVlO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGEuZXZlbnQuY2FuY2VsQnViYmxlID09PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgZGF0YS5ldmVudC5jYW5jZWxCdWJibGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBmbGFnIHRvIGluZGljYXRlIGNhbmNlbGxhdGlvbiBzdGF0ZS5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqL1xuICAgIGdldCByZXR1cm5WYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuICFwZCh0aGlzKS5jYW5jZWxlZFxuICAgIH0sXG4gICAgc2V0IHJldHVyblZhbHVlKHZhbHVlKSB7XG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHNldENhbmNlbEZsYWcocGQodGhpcykpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgdGhpcyBldmVudCBvYmplY3QuIEJ1dCBkbyBub3RoaW5nIHVuZGVyIGV2ZW50IGRpc3BhdGNoaW5nLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFRoZSBldmVudCB0eXBlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2J1YmJsZXM9ZmFsc2VdIFRoZSBmbGFnIHRvIGJlIHBvc3NpYmxlIHRvIGJ1YmJsZSB1cC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtjYW5jZWxhYmxlPWZhbHNlXSBUaGUgZmxhZyB0byBiZSBwb3NzaWJsZSB0byBjYW5jZWwuXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBpbml0RXZlbnQoKSB7XG4gICAgICAgIC8vIERvIG5vdGhpbmcuXG4gICAgfSxcbn07XG5cbi8vIGBjb25zdHJ1Y3RvcmAgaXMgbm90IGVudW1lcmFibGUuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnQucHJvdG90eXBlLCBcImNvbnN0cnVjdG9yXCIsIHtcbiAgICB2YWx1ZTogRXZlbnQsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxufSk7XG5cbi8vIEVuc3VyZSBgZXZlbnQgaW5zdGFuY2VvZiB3aW5kb3cuRXZlbnRgIGlzIGB0cnVlYC5cbmlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHR5cGVvZiB3aW5kb3cuRXZlbnQgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoRXZlbnQucHJvdG90eXBlLCB3aW5kb3cuRXZlbnQucHJvdG90eXBlKTtcblxuICAgIC8vIE1ha2UgYXNzb2NpYXRpb24gZm9yIHdyYXBwZXJzLlxuICAgIHdyYXBwZXJzLnNldCh3aW5kb3cuRXZlbnQucHJvdG90eXBlLCBFdmVudCk7XG59XG5cbi8qKlxuICogR2V0IHRoZSBwcm9wZXJ0eSBkZXNjcmlwdG9yIHRvIHJlZGlyZWN0IGEgZ2l2ZW4gcHJvcGVydHkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFByb3BlcnR5IG5hbWUgdG8gZGVmaW5lIHByb3BlcnR5IGRlc2NyaXB0b3IuXG4gKiBAcmV0dXJucyB7UHJvcGVydHlEZXNjcmlwdG9yfSBUaGUgcHJvcGVydHkgZGVzY3JpcHRvciB0byByZWRpcmVjdCB0aGUgcHJvcGVydHkuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3Ioa2V5KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHBkKHRoaXMpLmV2ZW50W2tleV1cbiAgICAgICAgfSxcbiAgICAgICAgc2V0KHZhbHVlKSB7XG4gICAgICAgICAgICBwZCh0aGlzKS5ldmVudFtrZXldID0gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBwcm9wZXJ0eSBkZXNjcmlwdG9yIHRvIGNhbGwgYSBnaXZlbiBtZXRob2QgcHJvcGVydHkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFByb3BlcnR5IG5hbWUgdG8gZGVmaW5lIHByb3BlcnR5IGRlc2NyaXB0b3IuXG4gKiBAcmV0dXJucyB7UHJvcGVydHlEZXNjcmlwdG9yfSBUaGUgcHJvcGVydHkgZGVzY3JpcHRvciB0byBjYWxsIHRoZSBtZXRob2QgcHJvcGVydHkuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBkZWZpbmVDYWxsRGVzY3JpcHRvcihrZXkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZSgpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gcGQodGhpcykuZXZlbnQ7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRba2V5XS5hcHBseShldmVudCwgYXJndW1lbnRzKVxuICAgICAgICB9LFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgfVxufVxuXG4vKipcbiAqIERlZmluZSBuZXcgd3JhcHBlciBjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IEJhc2VFdmVudCBUaGUgYmFzZSB3cmFwcGVyIGNsYXNzLlxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvIFRoZSBwcm90b3R5cGUgb2YgdGhlIG9yaWdpbmFsIGV2ZW50LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBUaGUgZGVmaW5lZCB3cmFwcGVyIGNsYXNzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lV3JhcHBlcihCYXNlRXZlbnQsIHByb3RvKSB7XG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHByb3RvKTtcbiAgICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIEJhc2VFdmVudFxuICAgIH1cblxuICAgIC8qKiBDdXN0b21FdmVudCAqL1xuICAgIGZ1bmN0aW9uIEN1c3RvbUV2ZW50KGV2ZW50VGFyZ2V0LCBldmVudCkge1xuICAgICAgICBCYXNlRXZlbnQuY2FsbCh0aGlzLCBldmVudFRhcmdldCwgZXZlbnQpO1xuICAgIH1cblxuICAgIEN1c3RvbUV2ZW50LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQmFzZUV2ZW50LnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogQ3VzdG9tRXZlbnQsIGNvbmZpZ3VyYWJsZTogdHJ1ZSwgd3JpdGFibGU6IHRydWUgfSxcbiAgICB9KTtcblxuICAgIC8vIERlZmluZSBhY2Nlc3NvcnMuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07XG4gICAgICAgIGlmICghKGtleSBpbiBCYXNlRXZlbnQucHJvdG90eXBlKSkge1xuICAgICAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocHJvdG8sIGtleSk7XG4gICAgICAgICAgICBjb25zdCBpc0Z1bmMgPSB0eXBlb2YgZGVzY3JpcHRvci52YWx1ZSA9PT0gXCJmdW5jdGlvblwiO1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFxuICAgICAgICAgICAgICAgIEN1c3RvbUV2ZW50LnByb3RvdHlwZSxcbiAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgaXNGdW5jXG4gICAgICAgICAgICAgICAgICAgID8gZGVmaW5lQ2FsbERlc2NyaXB0b3Ioa2V5KVxuICAgICAgICAgICAgICAgICAgICA6IGRlZmluZVJlZGlyZWN0RGVzY3JpcHRvcihrZXkpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIEN1c3RvbUV2ZW50XG59XG5cbi8qKlxuICogR2V0IHRoZSB3cmFwcGVyIGNsYXNzIG9mIGEgZ2l2ZW4gcHJvdG90eXBlLlxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvIFRoZSBwcm90b3R5cGUgb2YgdGhlIG9yaWdpbmFsIGV2ZW50IHRvIGdldCBpdHMgd3JhcHBlci5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gVGhlIHdyYXBwZXIgY2xhc3MuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBnZXRXcmFwcGVyKHByb3RvKSB7XG4gICAgaWYgKHByb3RvID09IG51bGwgfHwgcHJvdG8gPT09IE9iamVjdC5wcm90b3R5cGUpIHtcbiAgICAgICAgcmV0dXJuIEV2ZW50XG4gICAgfVxuXG4gICAgbGV0IHdyYXBwZXIgPSB3cmFwcGVycy5nZXQocHJvdG8pO1xuICAgIGlmICh3cmFwcGVyID09IG51bGwpIHtcbiAgICAgICAgd3JhcHBlciA9IGRlZmluZVdyYXBwZXIoZ2V0V3JhcHBlcihPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pKSwgcHJvdG8pO1xuICAgICAgICB3cmFwcGVycy5zZXQocHJvdG8sIHdyYXBwZXIpO1xuICAgIH1cbiAgICByZXR1cm4gd3JhcHBlclxufVxuXG4vKipcbiAqIFdyYXAgYSBnaXZlbiBldmVudCB0byBtYW5hZ2VtZW50IGEgZGlzcGF0Y2hpbmcuXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0IG9mIHRoaXMgZGlzcGF0Y2hpbmcuXG4gKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgVGhlIGV2ZW50IHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RXZlbnR9IFRoZSB3cmFwcGVyIGluc3RhbmNlLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gd3JhcEV2ZW50KGV2ZW50VGFyZ2V0LCBldmVudCkge1xuICAgIGNvbnN0IFdyYXBwZXIgPSBnZXRXcmFwcGVyKE9iamVjdC5nZXRQcm90b3R5cGVPZihldmVudCkpO1xuICAgIHJldHVybiBuZXcgV3JhcHBlcihldmVudFRhcmdldCwgZXZlbnQpXG59XG5cbi8qKlxuICogR2V0IHRoZSBpbW1lZGlhdGVTdG9wcGVkIGZsYWcgb2YgYSBnaXZlbiBldmVudC5cbiAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IFRoZSBldmVudCB0byBnZXQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVGhlIGZsYWcgdG8gc3RvcCBwcm9wYWdhdGlvbiBpbW1lZGlhdGVseS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGlzU3RvcHBlZChldmVudCkge1xuICAgIHJldHVybiBwZChldmVudCkuaW1tZWRpYXRlU3RvcHBlZFxufVxuXG4vKipcbiAqIFNldCB0aGUgY3VycmVudCBldmVudCBwaGFzZSBvZiBhIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIHNldCBjdXJyZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBldmVudFBoYXNlIE5ldyBldmVudCBwaGFzZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc2V0RXZlbnRQaGFzZShldmVudCwgZXZlbnRQaGFzZSkge1xuICAgIHBkKGV2ZW50KS5ldmVudFBoYXNlID0gZXZlbnRQaGFzZTtcbn1cblxuLyoqXG4gKiBTZXQgdGhlIGN1cnJlbnQgdGFyZ2V0IG9mIGEgZ2l2ZW4gZXZlbnQuXG4gKiBAcGFyYW0ge0V2ZW50fSBldmVudCBUaGUgZXZlbnQgdG8gc2V0IGN1cnJlbnQgdGFyZ2V0LlxuICogQHBhcmFtIHtFdmVudFRhcmdldHxudWxsfSBjdXJyZW50VGFyZ2V0IE5ldyBjdXJyZW50IHRhcmdldC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc2V0Q3VycmVudFRhcmdldChldmVudCwgY3VycmVudFRhcmdldCkge1xuICAgIHBkKGV2ZW50KS5jdXJyZW50VGFyZ2V0ID0gY3VycmVudFRhcmdldDtcbn1cblxuLyoqXG4gKiBTZXQgYSBwYXNzaXZlIGxpc3RlbmVyIG9mIGEgZ2l2ZW4gZXZlbnQuXG4gKiBAcGFyYW0ge0V2ZW50fSBldmVudCBUaGUgZXZlbnQgdG8gc2V0IGN1cnJlbnQgdGFyZ2V0LlxuICogQHBhcmFtIHtGdW5jdGlvbnxudWxsfSBwYXNzaXZlTGlzdGVuZXIgTmV3IHBhc3NpdmUgbGlzdGVuZXIuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNldFBhc3NpdmVMaXN0ZW5lcihldmVudCwgcGFzc2l2ZUxpc3RlbmVyKSB7XG4gICAgcGQoZXZlbnQpLnBhc3NpdmVMaXN0ZW5lciA9IHBhc3NpdmVMaXN0ZW5lcjtcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBMaXN0ZW5lck5vZGVcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGxpc3RlbmVyXG4gKiBAcHJvcGVydHkgezF8MnwzfSBsaXN0ZW5lclR5cGVcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gcGFzc2l2ZVxuICogQHByb3BlcnR5IHtib29sZWFufSBvbmNlXG4gKiBAcHJvcGVydHkge0xpc3RlbmVyTm9kZXxudWxsfSBuZXh0XG4gKiBAcHJpdmF0ZVxuICovXG5cbi8qKlxuICogQHR5cGUge1dlYWtNYXA8b2JqZWN0LCBNYXA8c3RyaW5nLCBMaXN0ZW5lck5vZGU+Pn1cbiAqIEBwcml2YXRlXG4gKi9cbmNvbnN0IGxpc3RlbmVyc01hcCA9IG5ldyBXZWFrTWFwKCk7XG5cbi8vIExpc3RlbmVyIHR5cGVzXG5jb25zdCBDQVBUVVJFID0gMTtcbmNvbnN0IEJVQkJMRSA9IDI7XG5jb25zdCBBVFRSSUJVVEUgPSAzO1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgYSBnaXZlbiB2YWx1ZSBpcyBhbiBvYmplY3Qgb3Igbm90LlxuICogQHBhcmFtIHthbnl9IHggVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBpc09iamVjdCh4KSB7XG4gICAgcmV0dXJuIHggIT09IG51bGwgJiYgdHlwZW9mIHggPT09IFwib2JqZWN0XCIgLy9lc2xpbnQtZGlzYWJsZS1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG59XG5cbi8qKlxuICogR2V0IGxpc3RlbmVycy5cbiAqIEBwYXJhbSB7RXZlbnRUYXJnZXR9IGV2ZW50VGFyZ2V0IFRoZSBldmVudCB0YXJnZXQgdG8gZ2V0LlxuICogQHJldHVybnMge01hcDxzdHJpbmcsIExpc3RlbmVyTm9kZT59IFRoZSBsaXN0ZW5lcnMuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBnZXRMaXN0ZW5lcnMoZXZlbnRUYXJnZXQpIHtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnNNYXAuZ2V0KGV2ZW50VGFyZ2V0KTtcbiAgICBpZiAobGlzdGVuZXJzID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgIFwiJ3RoaXMnIGlzIGV4cGVjdGVkIGFuIEV2ZW50VGFyZ2V0IG9iamVjdCwgYnV0IGdvdCBhbm90aGVyIHZhbHVlLlwiXG4gICAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGxpc3RlbmVyc1xufVxuXG4vKipcbiAqIEdldCB0aGUgcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgdGhlIGV2ZW50IGF0dHJpYnV0ZSBvZiBhIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byBnZXQgcHJvcGVydHkgZGVzY3JpcHRvci5cbiAqIEByZXR1cm5zIHtQcm9wZXJ0eURlc2NyaXB0b3J9IFRoZSBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lRXZlbnRBdHRyaWJ1dGVEZXNjcmlwdG9yKGV2ZW50TmFtZSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IGdldExpc3RlbmVycyh0aGlzKTtcbiAgICAgICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmxpc3RlbmVyVHlwZSA9PT0gQVRUUklCVVRFKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlLmxpc3RlbmVyXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9LFxuXG4gICAgICAgIHNldChsaXN0ZW5lcikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gXCJmdW5jdGlvblwiICYmICFpc09iamVjdChsaXN0ZW5lcikpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lciA9IG51bGw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IGdldExpc3RlbmVycyh0aGlzKTtcblxuICAgICAgICAgICAgLy8gVHJhdmVyc2UgdG8gdGhlIHRhaWwgd2hpbGUgcmVtb3Zpbmcgb2xkIHZhbHVlLlxuICAgICAgICAgICAgbGV0IHByZXYgPSBudWxsO1xuICAgICAgICAgICAgbGV0IG5vZGUgPSBsaXN0ZW5lcnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUubGlzdGVuZXJUeXBlID09PSBBVFRSSUJVVEUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIG9sZCB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHByZXYgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IG5vZGUubmV4dDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlLm5leHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zZXQoZXZlbnROYW1lLCBub2RlLm5leHQpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLmRlbGV0ZShldmVudE5hbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcHJldiA9IG5vZGU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUubmV4dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWRkIG5ldyB2YWx1ZS5cbiAgICAgICAgICAgIGlmIChsaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld05vZGUgPSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLFxuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lclR5cGU6IEFUVFJJQlVURSxcbiAgICAgICAgICAgICAgICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBuZXh0OiBudWxsLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHByZXYgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNldChldmVudE5hbWUsIG5ld05vZGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IG5ld05vZGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgfVxufVxuXG4vKipcbiAqIERlZmluZSBhbiBldmVudCBhdHRyaWJ1dGUgKGUuZy4gYGV2ZW50VGFyZ2V0Lm9uY2xpY2tgKS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFRhcmdldFByb3RvdHlwZSBUaGUgZXZlbnQgdGFyZ2V0IHByb3RvdHlwZSB0byBkZWZpbmUgYW4gZXZlbnQgYXR0cmJpdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBldmVudCBuYW1lIHRvIGRlZmluZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiBkZWZpbmVFdmVudEF0dHJpYnV0ZShldmVudFRhcmdldFByb3RvdHlwZSwgZXZlbnROYW1lKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFxuICAgICAgICBldmVudFRhcmdldFByb3RvdHlwZSxcbiAgICAgICAgYG9uJHtldmVudE5hbWV9YCxcbiAgICAgICAgZGVmaW5lRXZlbnRBdHRyaWJ1dGVEZXNjcmlwdG9yKGV2ZW50TmFtZSlcbiAgICApO1xufVxuXG4vKipcbiAqIERlZmluZSBhIGN1c3RvbSBFdmVudFRhcmdldCB3aXRoIGV2ZW50IGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBldmVudE5hbWVzIEV2ZW50IG5hbWVzIGZvciBldmVudCBhdHRyaWJ1dGVzLlxuICogQHJldHVybnMge0V2ZW50VGFyZ2V0fSBUaGUgY3VzdG9tIEV2ZW50VGFyZ2V0LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lQ3VzdG9tRXZlbnRUYXJnZXQoZXZlbnROYW1lcykge1xuICAgIC8qKiBDdXN0b21FdmVudFRhcmdldCAqL1xuICAgIGZ1bmN0aW9uIEN1c3RvbUV2ZW50VGFyZ2V0KCkge1xuICAgICAgICBFdmVudFRhcmdldC5jYWxsKHRoaXMpO1xuICAgIH1cblxuICAgIEN1c3RvbUV2ZW50VGFyZ2V0LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXZlbnRUYXJnZXQucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgICB2YWx1ZTogQ3VzdG9tRXZlbnRUYXJnZXQsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICB9KTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXZlbnROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICBkZWZpbmVFdmVudEF0dHJpYnV0ZShDdXN0b21FdmVudFRhcmdldC5wcm90b3R5cGUsIGV2ZW50TmFtZXNbaV0pO1xuICAgIH1cblxuICAgIHJldHVybiBDdXN0b21FdmVudFRhcmdldFxufVxuXG4vKipcbiAqIEV2ZW50VGFyZ2V0LlxuICpcbiAqIC0gVGhpcyBpcyBjb25zdHJ1Y3RvciBpZiBubyBhcmd1bWVudHMuXG4gKiAtIFRoaXMgaXMgYSBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGEgQ3VzdG9tRXZlbnRUYXJnZXQgY29uc3RydWN0b3IgaWYgdGhlcmUgYXJlIGFyZ3VtZW50cy5cbiAqXG4gKiBGb3IgZXhhbXBsZTpcbiAqXG4gKiAgICAgY2xhc3MgQSBleHRlbmRzIEV2ZW50VGFyZ2V0IHt9XG4gKiAgICAgY2xhc3MgQiBleHRlbmRzIEV2ZW50VGFyZ2V0KFwibWVzc2FnZVwiKSB7fVxuICogICAgIGNsYXNzIEMgZXh0ZW5kcyBFdmVudFRhcmdldChcIm1lc3NhZ2VcIiwgXCJlcnJvclwiKSB7fVxuICogICAgIGNsYXNzIEQgZXh0ZW5kcyBFdmVudFRhcmdldChbXCJtZXNzYWdlXCIsIFwiZXJyb3JcIl0pIHt9XG4gKi9cbmZ1bmN0aW9uIEV2ZW50VGFyZ2V0KCkge1xuICAgIC8qZXNsaW50LWRpc2FibGUgY29uc2lzdGVudC1yZXR1cm4gKi9cbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mIEV2ZW50VGFyZ2V0KSB7XG4gICAgICAgIGxpc3RlbmVyc01hcC5zZXQodGhpcywgbmV3IE1hcCgpKTtcbiAgICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxICYmIEFycmF5LmlzQXJyYXkoYXJndW1lbnRzWzBdKSkge1xuICAgICAgICByZXR1cm4gZGVmaW5lQ3VzdG9tRXZlbnRUYXJnZXQoYXJndW1lbnRzWzBdKVxuICAgIH1cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgdHlwZXMgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICB0eXBlc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmaW5lQ3VzdG9tRXZlbnRUYXJnZXQodHlwZXMpXG4gICAgfVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIilcbiAgICAvKmVzbGludC1lbmFibGUgY29uc2lzdGVudC1yZXR1cm4gKi9cbn1cblxuLy8gU2hvdWxkIGJlIGVudW1lcmFibGUsIGJ1dCBjbGFzcyBtZXRob2RzIGFyZSBub3QgZW51bWVyYWJsZS5cbkV2ZW50VGFyZ2V0LnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBBZGQgYSBnaXZlbiBsaXN0ZW5lciB0byB0aGlzIGV2ZW50IHRhcmdldC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIFRoZSBldmVudCBuYW1lIHRvIGFkZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgdG8gYWRkLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbnx7Y2FwdHVyZT86Ym9vbGVhbixwYXNzaXZlPzpib29sZWFuLG9uY2U/OmJvb2xlYW59fSBbb3B0aW9uc10gVGhlIG9wdGlvbnMgZm9yIHRoaXMgbGlzdGVuZXIuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChsaXN0ZW5lciA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSBcImZ1bmN0aW9uXCIgJiYgIWlzT2JqZWN0KGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIidsaXN0ZW5lcicgc2hvdWxkIGJlIGEgZnVuY3Rpb24gb3IgYW4gb2JqZWN0LlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGlzdGVuZXJzID0gZ2V0TGlzdGVuZXJzKHRoaXMpO1xuICAgICAgICBjb25zdCBvcHRpb25zSXNPYmogPSBpc09iamVjdChvcHRpb25zKTtcbiAgICAgICAgY29uc3QgY2FwdHVyZSA9IG9wdGlvbnNJc09ialxuICAgICAgICAgICAgPyBCb29sZWFuKG9wdGlvbnMuY2FwdHVyZSlcbiAgICAgICAgICAgIDogQm9vbGVhbihvcHRpb25zKTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXJUeXBlID0gY2FwdHVyZSA/IENBUFRVUkUgOiBCVUJCTEU7XG4gICAgICAgIGNvbnN0IG5ld05vZGUgPSB7XG4gICAgICAgICAgICBsaXN0ZW5lcixcbiAgICAgICAgICAgIGxpc3RlbmVyVHlwZSxcbiAgICAgICAgICAgIHBhc3NpdmU6IG9wdGlvbnNJc09iaiAmJiBCb29sZWFuKG9wdGlvbnMucGFzc2l2ZSksXG4gICAgICAgICAgICBvbmNlOiBvcHRpb25zSXNPYmogJiYgQm9vbGVhbihvcHRpb25zLm9uY2UpLFxuICAgICAgICAgICAgbmV4dDogbnVsbCxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTZXQgaXQgYXMgdGhlIGZpcnN0IG5vZGUgaWYgdGhlIGZpcnN0IG5vZGUgaXMgbnVsbC5cbiAgICAgICAgbGV0IG5vZGUgPSBsaXN0ZW5lcnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgICAgIGlmIChub2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycy5zZXQoZXZlbnROYW1lLCBuZXdOb2RlKTtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJhdmVyc2UgdG8gdGhlIHRhaWwgd2hpbGUgY2hlY2tpbmcgZHVwbGljYXRpb24uLlxuICAgICAgICBsZXQgcHJldiA9IG51bGw7XG4gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyID09PSBsaXN0ZW5lciAmJlxuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXJUeXBlID09PSBsaXN0ZW5lclR5cGVcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIC8vIFNob3VsZCBpZ25vcmUgZHVwbGljYXRpb24uXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwcmV2ID0gbm9kZTtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgaXQuXG4gICAgICAgIHByZXYubmV4dCA9IG5ld05vZGU7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGdpdmVuIGxpc3RlbmVyIGZyb20gdGhpcyBldmVudCB0YXJnZXQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHRvIHJlbW92ZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW58e2NhcHR1cmU/OmJvb2xlYW4scGFzc2l2ZT86Ym9vbGVhbixvbmNlPzpib29sZWFufX0gW29wdGlvbnNdIFRoZSBvcHRpb25zIGZvciB0aGlzIGxpc3RlbmVyLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgICAgICBpZiAobGlzdGVuZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG4gICAgICAgIGNvbnN0IGNhcHR1cmUgPSBpc09iamVjdChvcHRpb25zKVxuICAgICAgICAgICAgPyBCb29sZWFuKG9wdGlvbnMuY2FwdHVyZSlcbiAgICAgICAgICAgIDogQm9vbGVhbihvcHRpb25zKTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXJUeXBlID0gY2FwdHVyZSA/IENBUFRVUkUgOiBCVUJCTEU7XG5cbiAgICAgICAgbGV0IHByZXYgPSBudWxsO1xuICAgICAgICBsZXQgbm9kZSA9IGxpc3RlbmVycy5nZXQoZXZlbnROYW1lKTtcbiAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXIgPT09IGxpc3RlbmVyICYmXG4gICAgICAgICAgICAgICAgbm9kZS5saXN0ZW5lclR5cGUgPT09IGxpc3RlbmVyVHlwZVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByZXYgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJldi5uZXh0ID0gbm9kZS5uZXh0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobm9kZS5uZXh0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zZXQoZXZlbnROYW1lLCBub2RlLm5leHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5kZWxldGUoZXZlbnROYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHByZXYgPSBub2RlO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUubmV4dDtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBEaXNwYXRjaCBhIGdpdmVuIGV2ZW50LlxuICAgICAqIEBwYXJhbSB7RXZlbnR8e3R5cGU6c3RyaW5nfX0gZXZlbnQgVGhlIGV2ZW50IHRvIGRpc3BhdGNoLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBgZmFsc2VgIGlmIGNhbmNlbGVkLlxuICAgICAqL1xuICAgIGRpc3BhdGNoRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50ID09IG51bGwgfHwgdHlwZW9mIGV2ZW50LnR5cGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZXZlbnQudHlwZVwiIHNob3VsZCBiZSBhIHN0cmluZy4nKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgbGlzdGVuZXJzIGFyZW4ndCByZWdpc3RlcmVkLCB0ZXJtaW5hdGUuXG4gICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IGdldExpc3RlbmVycyh0aGlzKTtcbiAgICAgICAgY29uc3QgZXZlbnROYW1lID0gZXZlbnQudHlwZTtcbiAgICAgICAgbGV0IG5vZGUgPSBsaXN0ZW5lcnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgICAgIGlmIChub2RlID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaW5jZSB3ZSBjYW5ub3QgcmV3cml0ZSBzZXZlcmFsIHByb3BlcnRpZXMsIHNvIHdyYXAgb2JqZWN0LlxuICAgICAgICBjb25zdCB3cmFwcGVkRXZlbnQgPSB3cmFwRXZlbnQodGhpcywgZXZlbnQpO1xuXG4gICAgICAgIC8vIFRoaXMgZG9lc24ndCBwcm9jZXNzIGNhcHR1cmluZyBwaGFzZSBhbmQgYnViYmxpbmcgcGhhc2UuXG4gICAgICAgIC8vIFRoaXMgaXNuJ3QgcGFydGljaXBhdGluZyBpbiBhIHRyZWUuXG4gICAgICAgIGxldCBwcmV2ID0gbnVsbDtcbiAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoaXMgbGlzdGVuZXIgaWYgaXQncyBvbmNlXG4gICAgICAgICAgICBpZiAobm9kZS5vbmNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByZXYgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJldi5uZXh0ID0gbm9kZS5uZXh0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobm9kZS5uZXh0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zZXQoZXZlbnROYW1lLCBub2RlLm5leHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5kZWxldGUoZXZlbnROYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHByZXYgPSBub2RlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDYWxsIHRoaXMgbGlzdGVuZXJcbiAgICAgICAgICAgIHNldFBhc3NpdmVMaXN0ZW5lcihcbiAgICAgICAgICAgICAgICB3cmFwcGVkRXZlbnQsXG4gICAgICAgICAgICAgICAgbm9kZS5wYXNzaXZlID8gbm9kZS5saXN0ZW5lciA6IG51bGxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG5vZGUubGlzdGVuZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXIuY2FsbCh0aGlzLCB3cmFwcGVkRXZlbnQpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUuZXJyb3IgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgbm9kZS5saXN0ZW5lclR5cGUgIT09IEFUVFJJQlVURSAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBub2RlLmxpc3RlbmVyLmhhbmRsZUV2ZW50ID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXIuaGFuZGxlRXZlbnQod3JhcHBlZEV2ZW50KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQnJlYWsgaWYgYGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbmAgd2FzIGNhbGxlZC5cbiAgICAgICAgICAgIGlmIChpc1N0b3BwZWQod3JhcHBlZEV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0UGFzc2l2ZUxpc3RlbmVyKHdyYXBwZWRFdmVudCwgbnVsbCk7XG4gICAgICAgIHNldEV2ZW50UGhhc2Uod3JhcHBlZEV2ZW50LCAwKTtcbiAgICAgICAgc2V0Q3VycmVudFRhcmdldCh3cmFwcGVkRXZlbnQsIG51bGwpO1xuXG4gICAgICAgIHJldHVybiAhd3JhcHBlZEV2ZW50LmRlZmF1bHRQcmV2ZW50ZWRcbiAgICB9LFxufTtcblxuLy8gYGNvbnN0cnVjdG9yYCBpcyBub3QgZW51bWVyYWJsZS5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudFRhcmdldC5wcm90b3R5cGUsIFwiY29uc3RydWN0b3JcIiwge1xuICAgIHZhbHVlOiBFdmVudFRhcmdldCxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgd3JpdGFibGU6IHRydWUsXG59KTtcblxuLy8gRW5zdXJlIGBldmVudFRhcmdldCBpbnN0YW5jZW9mIHdpbmRvdy5FdmVudFRhcmdldGAgaXMgYHRydWVgLlxuaWYgKFxuICAgIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICB0eXBlb2Ygd2luZG93LkV2ZW50VGFyZ2V0ICE9PSBcInVuZGVmaW5lZFwiXG4pIHtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoRXZlbnRUYXJnZXQucHJvdG90eXBlLCB3aW5kb3cuRXZlbnRUYXJnZXQucHJvdG90eXBlKTtcbn1cblxuZXhwb3J0cy5kZWZpbmVFdmVudEF0dHJpYnV0ZSA9IGRlZmluZUV2ZW50QXR0cmlidXRlO1xuZXhwb3J0cy5FdmVudFRhcmdldCA9IEV2ZW50VGFyZ2V0O1xuZXhwb3J0cy5kZWZhdWx0ID0gRXZlbnRUYXJnZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRUYXJnZXRcbm1vZHVsZS5leHBvcnRzLkV2ZW50VGFyZ2V0ID0gbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gRXZlbnRUYXJnZXRcbm1vZHVsZS5leHBvcnRzLmRlZmluZUV2ZW50QXR0cmlidXRlID0gZGVmaW5lRXZlbnRBdHRyaWJ1dGVcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LXRhcmdldC1zaGltLmpzLm1hcFxuIiwiY29uc3Qge1JlYWRhYmxlfSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xuXG4vKipcbiAqIEB0eXBlIHtXZWFrTWFwPEJsb2IsIHt0eXBlOiBzdHJpbmcsIHNpemU6IG51bWJlciwgcGFydHM6IChCbG9iIHwgQnVmZmVyKVtdIH0+fVxuICovXG5jb25zdCB3bSA9IG5ldyBXZWFrTWFwKCk7XG5cbmFzeW5jIGZ1bmN0aW9uICogcmVhZChwYXJ0cykge1xuXHRmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcblx0XHRpZiAoJ3N0cmVhbScgaW4gcGFydCkge1xuXHRcdFx0eWllbGQgKiBwYXJ0LnN0cmVhbSgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR5aWVsZCBwYXJ0O1xuXHRcdH1cblx0fVxufVxuXG5jbGFzcyBCbG9iIHtcblx0LyoqXG5cdCAqIFRoZSBCbG9iKCkgY29uc3RydWN0b3IgcmV0dXJucyBhIG5ldyBCbG9iIG9iamVjdC4gVGhlIGNvbnRlbnRcblx0ICogb2YgdGhlIGJsb2IgY29uc2lzdHMgb2YgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhlIHZhbHVlcyBnaXZlblxuXHQgKiBpbiB0aGUgcGFyYW1ldGVyIGFycmF5LlxuXHQgKlxuXHQgKiBAcGFyYW0geyhBcnJheUJ1ZmZlckxpa2UgfCBBcnJheUJ1ZmZlclZpZXcgfCBCbG9iIHwgQnVmZmVyIHwgc3RyaW5nKVtdfSBibG9iUGFydHNcblx0ICogQHBhcmFtIHt7IHR5cGU/OiBzdHJpbmcgfX0gW29wdGlvbnNdXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcihibG9iUGFydHMgPSBbXSwgb3B0aW9ucyA9IHt0eXBlOiAnJ30pIHtcblx0XHRsZXQgc2l6ZSA9IDA7XG5cblx0XHRjb25zdCBwYXJ0cyA9IGJsb2JQYXJ0cy5tYXAoZWxlbWVudCA9PiB7XG5cdFx0XHRsZXQgYnVmZmVyO1xuXHRcdFx0aWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBCdWZmZXIpIHtcblx0XHRcdFx0YnVmZmVyID0gZWxlbWVudDtcblx0XHRcdH0gZWxzZSBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KGVsZW1lbnQpKSB7XG5cdFx0XHRcdGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGVsZW1lbnQuYnVmZmVyLCBlbGVtZW50LmJ5dGVPZmZzZXQsIGVsZW1lbnQuYnl0ZUxlbmd0aCk7XG5cdFx0XHR9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuXHRcdFx0XHRidWZmZXIgPSBCdWZmZXIuZnJvbShlbGVtZW50KTtcblx0XHRcdH0gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEJsb2IpIHtcblx0XHRcdFx0YnVmZmVyID0gZWxlbWVudDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHR5cGVvZiBlbGVtZW50ID09PSAnc3RyaW5nJyA/IGVsZW1lbnQgOiBTdHJpbmcoZWxlbWVudCkpO1xuXHRcdFx0fVxuXG5cdFx0XHRzaXplICs9IGJ1ZmZlci5sZW5ndGggfHwgYnVmZmVyLnNpemUgfHwgMDtcblx0XHRcdHJldHVybiBidWZmZXI7XG5cdFx0fSk7XG5cblx0XHRjb25zdCB0eXBlID0gb3B0aW9ucy50eXBlID09PSB1bmRlZmluZWQgPyAnJyA6IFN0cmluZyhvcHRpb25zLnR5cGUpLnRvTG93ZXJDYXNlKCk7XG5cblx0XHR3bS5zZXQodGhpcywge1xuXHRcdFx0dHlwZTogL1teXFx1MDAyMC1cXHUwMDdFXS8udGVzdCh0eXBlKSA/ICcnIDogdHlwZSxcblx0XHRcdHNpemUsXG5cdFx0XHRwYXJ0c1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBCbG9iIGludGVyZmFjZSdzIHNpemUgcHJvcGVydHkgcmV0dXJucyB0aGVcblx0ICogc2l6ZSBvZiB0aGUgQmxvYiBpbiBieXRlcy5cblx0ICovXG5cdGdldCBzaXplKCkge1xuXHRcdHJldHVybiB3bS5nZXQodGhpcykuc2l6ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgdHlwZSBwcm9wZXJ0eSBvZiBhIEJsb2Igb2JqZWN0IHJldHVybnMgdGhlIE1JTUUgdHlwZSBvZiB0aGUgZmlsZS5cblx0ICovXG5cdGdldCB0eXBlKCkge1xuXHRcdHJldHVybiB3bS5nZXQodGhpcykudHlwZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgdGV4dCgpIG1ldGhvZCBpbiB0aGUgQmxvYiBpbnRlcmZhY2UgcmV0dXJucyBhIFByb21pc2Vcblx0ICogdGhhdCByZXNvbHZlcyB3aXRoIGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGNvbnRlbnRzIG9mXG5cdCAqIHRoZSBibG9iLCBpbnRlcnByZXRlZCBhcyBVVEYtOC5cblx0ICpcblx0ICogQHJldHVybiB7UHJvbWlzZTxzdHJpbmc+fVxuXHQgKi9cblx0YXN5bmMgdGV4dCgpIHtcblx0XHRyZXR1cm4gQnVmZmVyLmZyb20oYXdhaXQgdGhpcy5hcnJheUJ1ZmZlcigpKS50b1N0cmluZygpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBhcnJheUJ1ZmZlcigpIG1ldGhvZCBpbiB0aGUgQmxvYiBpbnRlcmZhY2UgcmV0dXJucyBhXG5cdCAqIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBjb250ZW50cyBvZiB0aGUgYmxvYiBhc1xuXHQgKiBiaW5hcnkgZGF0YSBjb250YWluZWQgaW4gYW4gQXJyYXlCdWZmZXIuXG5cdCAqXG5cdCAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXlCdWZmZXI+fVxuXHQgKi9cblx0YXN5bmMgYXJyYXlCdWZmZXIoKSB7XG5cdFx0Y29uc3QgZGF0YSA9IG5ldyBVaW50OEFycmF5KHRoaXMuc2l6ZSk7XG5cdFx0bGV0IG9mZnNldCA9IDA7XG5cdFx0Zm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiB0aGlzLnN0cmVhbSgpKSB7XG5cdFx0XHRkYXRhLnNldChjaHVuaywgb2Zmc2V0KTtcblx0XHRcdG9mZnNldCArPSBjaHVuay5sZW5ndGg7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGRhdGEuYnVmZmVyO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRoZSBCbG9iIGludGVyZmFjZSdzIHN0cmVhbSgpIG1ldGhvZCBpcyBkaWZmZXJlbmNlIGZyb20gbmF0aXZlXG5cdCAqIGFuZCB1c2VzIG5vZGUgc3RyZWFtcyBpbnN0ZWFkIG9mIHdoYXR3ZyBzdHJlYW1zLlxuXHQgKlxuXHQgKiBAcmV0dXJucyB7UmVhZGFibGV9IE5vZGUgcmVhZGFibGUgc3RyZWFtXG5cdCAqL1xuXHRzdHJlYW0oKSB7XG5cdFx0cmV0dXJuIFJlYWRhYmxlLmZyb20ocmVhZCh3bS5nZXQodGhpcykucGFydHMpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgQmxvYiBpbnRlcmZhY2UncyBzbGljZSgpIG1ldGhvZCBjcmVhdGVzIGFuZCByZXR1cm5zIGFcblx0ICogbmV3IEJsb2Igb2JqZWN0IHdoaWNoIGNvbnRhaW5zIGRhdGEgZnJvbSBhIHN1YnNldCBvZiB0aGVcblx0ICogYmxvYiBvbiB3aGljaCBpdCdzIGNhbGxlZC5cblx0ICpcblx0ICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydF1cblx0ICogQHBhcmFtIHtudW1iZXJ9IFtlbmRdXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZV1cblx0ICovXG5cdHNsaWNlKHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5zaXplLCB0eXBlID0gJycpIHtcblx0XHRjb25zdCB7c2l6ZX0gPSB0aGlzO1xuXG5cdFx0bGV0IHJlbGF0aXZlU3RhcnQgPSBzdGFydCA8IDAgPyBNYXRoLm1heChzaXplICsgc3RhcnQsIDApIDogTWF0aC5taW4oc3RhcnQsIHNpemUpO1xuXHRcdGxldCByZWxhdGl2ZUVuZCA9IGVuZCA8IDAgPyBNYXRoLm1heChzaXplICsgZW5kLCAwKSA6IE1hdGgubWluKGVuZCwgc2l6ZSk7XG5cblx0XHRjb25zdCBzcGFuID0gTWF0aC5tYXgocmVsYXRpdmVFbmQgLSByZWxhdGl2ZVN0YXJ0LCAwKTtcblx0XHRjb25zdCBwYXJ0cyA9IHdtLmdldCh0aGlzKS5wYXJ0cy52YWx1ZXMoKTtcblx0XHRjb25zdCBibG9iUGFydHMgPSBbXTtcblx0XHRsZXQgYWRkZWQgPSAwO1xuXG5cdFx0Zm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG5cdFx0XHRjb25zdCBzaXplID0gQXJyYXlCdWZmZXIuaXNWaWV3KHBhcnQpID8gcGFydC5ieXRlTGVuZ3RoIDogcGFydC5zaXplO1xuXHRcdFx0aWYgKHJlbGF0aXZlU3RhcnQgJiYgc2l6ZSA8PSByZWxhdGl2ZVN0YXJ0KSB7XG5cdFx0XHRcdC8vIFNraXAgdGhlIGJlZ2lubmluZyBhbmQgY2hhbmdlIHRoZSByZWxhdGl2ZVxuXHRcdFx0XHQvLyBzdGFydCAmIGVuZCBwb3NpdGlvbiBhcyB3ZSBza2lwIHRoZSB1bndhbnRlZCBwYXJ0c1xuXHRcdFx0XHRyZWxhdGl2ZVN0YXJ0IC09IHNpemU7XG5cdFx0XHRcdHJlbGF0aXZlRW5kIC09IHNpemU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCBjaHVuayA9IHBhcnQuc2xpY2UocmVsYXRpdmVTdGFydCwgTWF0aC5taW4oc2l6ZSwgcmVsYXRpdmVFbmQpKTtcblx0XHRcdFx0YmxvYlBhcnRzLnB1c2goY2h1bmspO1xuXHRcdFx0XHRhZGRlZCArPSBBcnJheUJ1ZmZlci5pc1ZpZXcoY2h1bmspID8gY2h1bmsuYnl0ZUxlbmd0aCA6IGNodW5rLnNpemU7XG5cdFx0XHRcdHJlbGF0aXZlU3RhcnQgPSAwOyAvLyBBbGwgbmV4dCBzZXF1ZW50YWwgcGFydHMgc2hvdWxkIHN0YXJ0IGF0IDBcblxuXHRcdFx0XHQvLyBkb24ndCBhZGQgdGhlIG92ZXJmbG93IHRvIG5ldyBibG9iUGFydHNcblx0XHRcdFx0aWYgKGFkZGVkID49IHNwYW4pIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbXSwge3R5cGV9KTtcblx0XHRPYmplY3QuYXNzaWduKHdtLmdldChibG9iKSwge3NpemU6IHNwYW4sIHBhcnRzOiBibG9iUGFydHN9KTtcblxuXHRcdHJldHVybiBibG9iO1xuXHR9XG5cblx0Z2V0IFtTeW1ib2wudG9TdHJpbmdUYWddKCkge1xuXHRcdHJldHVybiAnQmxvYic7XG5cdH1cblxuXHRzdGF0aWMgW1N5bWJvbC5oYXNJbnN0YW5jZV0ob2JqZWN0KSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnICYmXG5cdFx0XHR0eXBlb2Ygb2JqZWN0LnN0cmVhbSA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdFx0b2JqZWN0LnN0cmVhbS5sZW5ndGggPT09IDAgJiZcblx0XHRcdHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgPT09ICdmdW5jdGlvbicgJiZcblx0XHRcdC9eKEJsb2J8RmlsZSkkLy50ZXN0KG9iamVjdFtTeW1ib2wudG9TdHJpbmdUYWddKVxuXHRcdCk7XG5cdH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQmxvYi5wcm90b3R5cGUsIHtcblx0c2l6ZToge2VudW1lcmFibGU6IHRydWV9LFxuXHR0eXBlOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHNsaWNlOiB7ZW51bWVyYWJsZTogdHJ1ZX1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEJsb2I7XG4iLCIndXNlIHN0cmljdCc7XG5jb25zdCBmZXRjaCA9IHJlcXVpcmUoJ25vZGUtZmV0Y2gnKTtcbmNvbnN0IEFib3J0Q29udHJvbGxlciA9IHJlcXVpcmUoJ2Fib3J0LWNvbnRyb2xsZXInKTtcblxuY29uc3QgVEVOX01FR0FCWVRFUyA9IDEwMDAgKiAxMDAwICogMTA7XG5cbmlmICghZ2xvYmFsLmZldGNoKSB7XG5cdGdsb2JhbC5mZXRjaCA9ICh1cmwsIG9wdGlvbnMpID0+IGZldGNoKHVybCwge2hpZ2hXYXRlck1hcms6IFRFTl9NRUdBQllURVMsIC4uLm9wdGlvbnN9KTtcbn1cblxuaWYgKCFnbG9iYWwuSGVhZGVycykge1xuXHRnbG9iYWwuSGVhZGVycyA9IGZldGNoLkhlYWRlcnM7XG59XG5cbmlmICghZ2xvYmFsLlJlcXVlc3QpIHtcblx0Z2xvYmFsLlJlcXVlc3QgPSBmZXRjaC5SZXF1ZXN0O1xufVxuXG5pZiAoIWdsb2JhbC5SZXNwb25zZSkge1xuXHRnbG9iYWwuUmVzcG9uc2UgPSBmZXRjaC5SZXNwb25zZTtcbn1cblxuaWYgKCFnbG9iYWwuQWJvcnRDb250cm9sbGVyKSB7XG5cdGdsb2JhbC5BYm9ydENvbnRyb2xsZXIgPSBBYm9ydENvbnRyb2xsZXI7XG59XG5cbmlmICghZ2xvYmFsLlJlYWRhYmxlU3RyZWFtKSB7XG5cdHRyeSB7XG5cdFx0Z2xvYmFsLlJlYWRhYmxlU3RyZWFtID0gcmVxdWlyZSgnd2ViLXN0cmVhbXMtcG9seWZpbGwvcG9ueWZpbGwvZXMyMDE4Jyk7XG5cdH0gY2F0Y2ggKF8pIHt9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgna3kvdW1kJyk7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuXHR0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG5cdHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShmYWN0b3J5KSA6XG5cdChnbG9iYWwgPSB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWxUaGlzIDogZ2xvYmFsIHx8IHNlbGYsIGdsb2JhbC5reSA9IGZhY3RvcnkoKSk7XG59KHRoaXMsIChmdW5jdGlvbiAoKSB7ICd1c2Ugc3RyaWN0JztcblxuXHQvKiEgTUlUIExpY2Vuc2UgwqkgU2luZHJlIFNvcmh1cyAqL1xuXG5cdGNvbnN0IGdsb2JhbHMgPSB7fTtcblxuXHRjb25zdCBnZXRHbG9iYWwgPSBwcm9wZXJ0eSA9PiB7XG5cdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRpZiAodHlwZW9mIHNlbGYgIT09ICd1bmRlZmluZWQnICYmIHNlbGYgJiYgcHJvcGVydHkgaW4gc2VsZikge1xuXHRcdFx0cmV0dXJuIHNlbGY7XG5cdFx0fVxuXG5cdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93ICYmIHByb3BlcnR5IGluIHdpbmRvdykge1xuXHRcdFx0cmV0dXJuIHdpbmRvdztcblx0XHR9XG5cblx0XHRpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgZ2xvYmFsICYmIHByb3BlcnR5IGluIGdsb2JhbCkge1xuXHRcdFx0cmV0dXJuIGdsb2JhbDtcblx0XHR9XG5cblx0XHQvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuXHRcdGlmICh0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgJiYgZ2xvYmFsVGhpcykge1xuXHRcdFx0cmV0dXJuIGdsb2JhbFRoaXM7XG5cdFx0fVxuXHR9O1xuXG5cdGNvbnN0IGdsb2JhbFByb3BlcnRpZXMgPSBbXG5cdFx0J0hlYWRlcnMnLFxuXHRcdCdSZXF1ZXN0Jyxcblx0XHQnUmVzcG9uc2UnLFxuXHRcdCdSZWFkYWJsZVN0cmVhbScsXG5cdFx0J2ZldGNoJyxcblx0XHQnQWJvcnRDb250cm9sbGVyJyxcblx0XHQnRm9ybURhdGEnXG5cdF07XG5cblx0Zm9yIChjb25zdCBwcm9wZXJ0eSBvZiBnbG9iYWxQcm9wZXJ0aWVzKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbHMsIHByb3BlcnR5LCB7XG5cdFx0XHRnZXQoKSB7XG5cdFx0XHRcdGNvbnN0IGdsb2JhbE9iamVjdCA9IGdldEdsb2JhbChwcm9wZXJ0eSk7XG5cdFx0XHRcdGNvbnN0IHZhbHVlID0gZ2xvYmFsT2JqZWN0ICYmIGdsb2JhbE9iamVjdFtwcm9wZXJ0eV07XG5cdFx0XHRcdHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZS5iaW5kKGdsb2JhbE9iamVjdCkgOiB2YWx1ZTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdGNvbnN0IGlzT2JqZWN0ID0gdmFsdWUgPT4gdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jztcblx0Y29uc3Qgc3VwcG9ydHNBYm9ydENvbnRyb2xsZXIgPSB0eXBlb2YgZ2xvYmFscy5BYm9ydENvbnRyb2xsZXIgPT09ICdmdW5jdGlvbic7XG5cdGNvbnN0IHN1cHBvcnRzU3RyZWFtcyA9IHR5cGVvZiBnbG9iYWxzLlJlYWRhYmxlU3RyZWFtID09PSAnZnVuY3Rpb24nO1xuXHRjb25zdCBzdXBwb3J0c0Zvcm1EYXRhID0gdHlwZW9mIGdsb2JhbHMuRm9ybURhdGEgPT09ICdmdW5jdGlvbic7XG5cblx0Y29uc3QgbWVyZ2VIZWFkZXJzID0gKHNvdXJjZTEsIHNvdXJjZTIpID0+IHtcblx0XHRjb25zdCByZXN1bHQgPSBuZXcgZ2xvYmFscy5IZWFkZXJzKHNvdXJjZTEgfHwge30pO1xuXHRcdGNvbnN0IGlzSGVhZGVyc0luc3RhbmNlID0gc291cmNlMiBpbnN0YW5jZW9mIGdsb2JhbHMuSGVhZGVycztcblx0XHRjb25zdCBzb3VyY2UgPSBuZXcgZ2xvYmFscy5IZWFkZXJzKHNvdXJjZTIgfHwge30pO1xuXG5cdFx0Zm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2Ygc291cmNlKSB7XG5cdFx0XHRpZiAoKGlzSGVhZGVyc0luc3RhbmNlICYmIHZhbHVlID09PSAndW5kZWZpbmVkJykgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRyZXN1bHQuZGVsZXRlKGtleSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXN1bHQuc2V0KGtleSwgdmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH07XG5cblx0Y29uc3QgZGVlcE1lcmdlID0gKC4uLnNvdXJjZXMpID0+IHtcblx0XHRsZXQgcmV0dXJuVmFsdWUgPSB7fTtcblx0XHRsZXQgaGVhZGVycyA9IHt9O1xuXG5cdFx0Zm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykge1xuXHRcdFx0aWYgKEFycmF5LmlzQXJyYXkoc291cmNlKSkge1xuXHRcdFx0XHRpZiAoIShBcnJheS5pc0FycmF5KHJldHVyblZhbHVlKSkpIHtcblx0XHRcdFx0XHRyZXR1cm5WYWx1ZSA9IFtdO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuVmFsdWUgPSBbLi4ucmV0dXJuVmFsdWUsIC4uLnNvdXJjZV07XG5cdFx0XHR9IGVsc2UgaWYgKGlzT2JqZWN0KHNvdXJjZSkpIHtcblx0XHRcdFx0Zm9yIChsZXQgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHNvdXJjZSkpIHtcblx0XHRcdFx0XHRpZiAoaXNPYmplY3QodmFsdWUpICYmIChrZXkgaW4gcmV0dXJuVmFsdWUpKSB7XG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGRlZXBNZXJnZShyZXR1cm5WYWx1ZVtrZXldLCB2YWx1ZSk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuVmFsdWUgPSB7Li4ucmV0dXJuVmFsdWUsIFtrZXldOiB2YWx1ZX07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoaXNPYmplY3Qoc291cmNlLmhlYWRlcnMpKSB7XG5cdFx0XHRcdFx0aGVhZGVycyA9IG1lcmdlSGVhZGVycyhoZWFkZXJzLCBzb3VyY2UuaGVhZGVycyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuVmFsdWUuaGVhZGVycyA9IGhlYWRlcnM7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldHVyblZhbHVlO1xuXHR9O1xuXG5cdGNvbnN0IHJlcXVlc3RNZXRob2RzID0gW1xuXHRcdCdnZXQnLFxuXHRcdCdwb3N0Jyxcblx0XHQncHV0Jyxcblx0XHQncGF0Y2gnLFxuXHRcdCdoZWFkJyxcblx0XHQnZGVsZXRlJ1xuXHRdO1xuXG5cdGNvbnN0IHJlc3BvbnNlVHlwZXMgPSB7XG5cdFx0anNvbjogJ2FwcGxpY2F0aW9uL2pzb24nLFxuXHRcdHRleHQ6ICd0ZXh0LyonLFxuXHRcdGZvcm1EYXRhOiAnbXVsdGlwYXJ0L2Zvcm0tZGF0YScsXG5cdFx0YXJyYXlCdWZmZXI6ICcqLyonLFxuXHRcdGJsb2I6ICcqLyonXG5cdH07XG5cblx0Y29uc3QgcmV0cnlNZXRob2RzID0gW1xuXHRcdCdnZXQnLFxuXHRcdCdwdXQnLFxuXHRcdCdoZWFkJyxcblx0XHQnZGVsZXRlJyxcblx0XHQnb3B0aW9ucycsXG5cdFx0J3RyYWNlJ1xuXHRdO1xuXG5cdGNvbnN0IHJldHJ5U3RhdHVzQ29kZXMgPSBbXG5cdFx0NDA4LFxuXHRcdDQxMyxcblx0XHQ0MjksXG5cdFx0NTAwLFxuXHRcdDUwMixcblx0XHQ1MDMsXG5cdFx0NTA0XG5cdF07XG5cblx0Y29uc3QgcmV0cnlBZnRlclN0YXR1c0NvZGVzID0gW1xuXHRcdDQxMyxcblx0XHQ0MjksXG5cdFx0NTAzXG5cdF07XG5cblx0Y29uc3Qgc3RvcCA9IFN5bWJvbCgnc3RvcCcpO1xuXG5cdGNsYXNzIEhUVFBFcnJvciBleHRlbmRzIEVycm9yIHtcblx0XHRjb25zdHJ1Y3RvcihyZXNwb25zZSkge1xuXHRcdFx0Ly8gU2V0IHRoZSBtZXNzYWdlIHRvIHRoZSBzdGF0dXMgdGV4dCwgc3VjaCBhcyBVbmF1dGhvcml6ZWQsXG5cdFx0XHQvLyB3aXRoIHNvbWUgZmFsbGJhY2tzLiBUaGlzIG1lc3NhZ2Ugc2hvdWxkIG5ldmVyIGJlIHVuZGVmaW5lZC5cblx0XHRcdHN1cGVyKFxuXHRcdFx0XHRyZXNwb25zZS5zdGF0dXNUZXh0IHx8XG5cdFx0XHRcdFN0cmluZyhcblx0XHRcdFx0XHQocmVzcG9uc2Uuc3RhdHVzID09PSAwIHx8IHJlc3BvbnNlLnN0YXR1cykgP1xuXHRcdFx0XHRcdFx0cmVzcG9uc2Uuc3RhdHVzIDogJ1Vua25vd24gcmVzcG9uc2UgZXJyb3InXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0XHR0aGlzLm5hbWUgPSAnSFRUUEVycm9yJztcblx0XHRcdHRoaXMucmVzcG9uc2UgPSByZXNwb25zZTtcblx0XHR9XG5cdH1cblxuXHRjbGFzcyBUaW1lb3V0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdFx0Y29uc3RydWN0b3IocmVxdWVzdCkge1xuXHRcdFx0c3VwZXIoJ1JlcXVlc3QgdGltZWQgb3V0Jyk7XG5cdFx0XHR0aGlzLm5hbWUgPSAnVGltZW91dEVycm9yJztcblx0XHRcdHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG5cdFx0fVxuXHR9XG5cblx0Y29uc3QgZGVsYXkgPSBtcyA9PiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcblxuXHQvLyBgUHJvbWlzZS5yYWNlKClgIHdvcmthcm91bmQgKCM5MSlcblx0Y29uc3QgdGltZW91dCA9IChyZXF1ZXN0LCBhYm9ydENvbnRyb2xsZXIsIG9wdGlvbnMpID0+XG5cdFx0bmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0Y29uc3QgdGltZW91dElEID0gc2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdGlmIChhYm9ydENvbnRyb2xsZXIpIHtcblx0XHRcdFx0XHRhYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJlamVjdChuZXcgVGltZW91dEVycm9yKHJlcXVlc3QpKTtcblx0XHRcdH0sIG9wdGlvbnMudGltZW91dCk7XG5cblx0XHRcdC8qIGVzbGludC1kaXNhYmxlIHByb21pc2UvcHJlZmVyLWF3YWl0LXRvLXRoZW4gKi9cblx0XHRcdG9wdGlvbnMuZmV0Y2gocmVxdWVzdClcblx0XHRcdFx0LnRoZW4ocmVzb2x2ZSlcblx0XHRcdFx0LmNhdGNoKHJlamVjdClcblx0XHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRcdGNsZWFyVGltZW91dCh0aW1lb3V0SUQpO1xuXHRcdFx0XHR9KTtcblx0XHRcdC8qIGVzbGludC1lbmFibGUgcHJvbWlzZS9wcmVmZXItYXdhaXQtdG8tdGhlbiAqL1xuXHRcdH0pO1xuXG5cdGNvbnN0IG5vcm1hbGl6ZVJlcXVlc3RNZXRob2QgPSBpbnB1dCA9PiByZXF1ZXN0TWV0aG9kcy5pbmNsdWRlcyhpbnB1dCkgPyBpbnB1dC50b1VwcGVyQ2FzZSgpIDogaW5wdXQ7XG5cblx0Y29uc3QgZGVmYXVsdFJldHJ5T3B0aW9ucyA9IHtcblx0XHRsaW1pdDogMixcblx0XHRtZXRob2RzOiByZXRyeU1ldGhvZHMsXG5cdFx0c3RhdHVzQ29kZXM6IHJldHJ5U3RhdHVzQ29kZXMsXG5cdFx0YWZ0ZXJTdGF0dXNDb2RlczogcmV0cnlBZnRlclN0YXR1c0NvZGVzXG5cdH07XG5cblx0Y29uc3Qgbm9ybWFsaXplUmV0cnlPcHRpb25zID0gKHJldHJ5ID0ge30pID0+IHtcblx0XHRpZiAodHlwZW9mIHJldHJ5ID09PSAnbnVtYmVyJykge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0Li4uZGVmYXVsdFJldHJ5T3B0aW9ucyxcblx0XHRcdFx0bGltaXQ6IHJldHJ5XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGlmIChyZXRyeS5tZXRob2RzICYmICFBcnJheS5pc0FycmF5KHJldHJ5Lm1ldGhvZHMpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ3JldHJ5Lm1ldGhvZHMgbXVzdCBiZSBhbiBhcnJheScpO1xuXHRcdH1cblxuXHRcdGlmIChyZXRyeS5zdGF0dXNDb2RlcyAmJiAhQXJyYXkuaXNBcnJheShyZXRyeS5zdGF0dXNDb2RlcykpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcigncmV0cnkuc3RhdHVzQ29kZXMgbXVzdCBiZSBhbiBhcnJheScpO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHQuLi5kZWZhdWx0UmV0cnlPcHRpb25zLFxuXHRcdFx0Li4ucmV0cnksXG5cdFx0XHRhZnRlclN0YXR1c0NvZGVzOiByZXRyeUFmdGVyU3RhdHVzQ29kZXNcblx0XHR9O1xuXHR9O1xuXG5cdC8vIFRoZSBtYXhpbXVtIHZhbHVlIG9mIGEgMzJiaXQgaW50IChzZWUgaXNzdWUgIzExNylcblx0Y29uc3QgbWF4U2FmZVRpbWVvdXQgPSAyMTQ3NDgzNjQ3O1xuXG5cdGNsYXNzIEt5IHtcblx0XHRjb25zdHJ1Y3RvcihpbnB1dCwgb3B0aW9ucyA9IHt9KSB7XG5cdFx0XHR0aGlzLl9yZXRyeUNvdW50ID0gMDtcblx0XHRcdHRoaXMuX2lucHV0ID0gaW5wdXQ7XG5cdFx0XHR0aGlzLl9vcHRpb25zID0ge1xuXHRcdFx0XHQvLyBUT0RPOiBjcmVkZW50aWFscyBjYW4gYmUgcmVtb3ZlZCB3aGVuIHRoZSBzcGVjIGNoYW5nZSBpcyBpbXBsZW1lbnRlZCBpbiBhbGwgYnJvd3NlcnMuIENvbnRleHQ6IGh0dHBzOi8vd3d3LmNocm9tZXN0YXR1cy5jb20vZmVhdHVyZS80NTM5NDczMzEyMzUwMjA4XG5cdFx0XHRcdGNyZWRlbnRpYWxzOiB0aGlzLl9pbnB1dC5jcmVkZW50aWFscyB8fCAnc2FtZS1vcmlnaW4nLFxuXHRcdFx0XHQuLi5vcHRpb25zLFxuXHRcdFx0XHRoZWFkZXJzOiBtZXJnZUhlYWRlcnModGhpcy5faW5wdXQuaGVhZGVycywgb3B0aW9ucy5oZWFkZXJzKSxcblx0XHRcdFx0aG9va3M6IGRlZXBNZXJnZSh7XG5cdFx0XHRcdFx0YmVmb3JlUmVxdWVzdDogW10sXG5cdFx0XHRcdFx0YmVmb3JlUmV0cnk6IFtdLFxuXHRcdFx0XHRcdGFmdGVyUmVzcG9uc2U6IFtdXG5cdFx0XHRcdH0sIG9wdGlvbnMuaG9va3MpLFxuXHRcdFx0XHRtZXRob2Q6IG5vcm1hbGl6ZVJlcXVlc3RNZXRob2Qob3B0aW9ucy5tZXRob2QgfHwgdGhpcy5faW5wdXQubWV0aG9kKSxcblx0XHRcdFx0cHJlZml4VXJsOiBTdHJpbmcob3B0aW9ucy5wcmVmaXhVcmwgfHwgJycpLFxuXHRcdFx0XHRyZXRyeTogbm9ybWFsaXplUmV0cnlPcHRpb25zKG9wdGlvbnMucmV0cnkpLFxuXHRcdFx0XHR0aHJvd0h0dHBFcnJvcnM6IG9wdGlvbnMudGhyb3dIdHRwRXJyb3JzICE9PSBmYWxzZSxcblx0XHRcdFx0dGltZW91dDogdHlwZW9mIG9wdGlvbnMudGltZW91dCA9PT0gJ3VuZGVmaW5lZCcgPyAxMDAwMCA6IG9wdGlvbnMudGltZW91dCxcblx0XHRcdFx0ZmV0Y2g6IG9wdGlvbnMuZmV0Y2ggfHwgZ2xvYmFscy5mZXRjaFxuXHRcdFx0fTtcblxuXHRcdFx0aWYgKHR5cGVvZiB0aGlzLl9pbnB1dCAhPT0gJ3N0cmluZycgJiYgISh0aGlzLl9pbnB1dCBpbnN0YW5jZW9mIFVSTCB8fCB0aGlzLl9pbnB1dCBpbnN0YW5jZW9mIGdsb2JhbHMuUmVxdWVzdCkpIHtcblx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignYGlucHV0YCBtdXN0IGJlIGEgc3RyaW5nLCBVUkwsIG9yIFJlcXVlc3QnKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHRoaXMuX29wdGlvbnMucHJlZml4VXJsICYmIHR5cGVvZiB0aGlzLl9pbnB1dCA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0aWYgKHRoaXMuX2lucHV0LnN0YXJ0c1dpdGgoJy8nKSkge1xuXHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcignYGlucHV0YCBtdXN0IG5vdCBiZWdpbiB3aXRoIGEgc2xhc2ggd2hlbiB1c2luZyBgcHJlZml4VXJsYCcpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCF0aGlzLl9vcHRpb25zLnByZWZpeFVybC5lbmRzV2l0aCgnLycpKSB7XG5cdFx0XHRcdFx0dGhpcy5fb3B0aW9ucy5wcmVmaXhVcmwgKz0gJy8nO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5faW5wdXQgPSB0aGlzLl9vcHRpb25zLnByZWZpeFVybCArIHRoaXMuX2lucHV0O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoc3VwcG9ydHNBYm9ydENvbnRyb2xsZXIpIHtcblx0XHRcdFx0dGhpcy5hYm9ydENvbnRyb2xsZXIgPSBuZXcgZ2xvYmFscy5BYm9ydENvbnRyb2xsZXIoKTtcblx0XHRcdFx0aWYgKHRoaXMuX29wdGlvbnMuc2lnbmFsKSB7XG5cdFx0XHRcdFx0dGhpcy5fb3B0aW9ucy5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCAoKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmFib3J0Q29udHJvbGxlci5hYm9ydCgpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5fb3B0aW9ucy5zaWduYWwgPSB0aGlzLmFib3J0Q29udHJvbGxlci5zaWduYWw7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMucmVxdWVzdCA9IG5ldyBnbG9iYWxzLlJlcXVlc3QodGhpcy5faW5wdXQsIHRoaXMuX29wdGlvbnMpO1xuXG5cdFx0XHRpZiAodGhpcy5fb3B0aW9ucy5zZWFyY2hQYXJhbXMpIHtcblx0XHRcdFx0Y29uc3Qgc2VhcmNoUGFyYW1zID0gJz8nICsgbmV3IFVSTFNlYXJjaFBhcmFtcyh0aGlzLl9vcHRpb25zLnNlYXJjaFBhcmFtcykudG9TdHJpbmcoKTtcblx0XHRcdFx0Y29uc3QgdXJsID0gdGhpcy5yZXF1ZXN0LnVybC5yZXBsYWNlKC8oPzpcXD8uKj8pPyg/PSN8JCkvLCBzZWFyY2hQYXJhbXMpO1xuXG5cdFx0XHRcdC8vIFRvIHByb3ZpZGUgY29ycmVjdCBmb3JtIGJvdW5kYXJ5LCBDb250ZW50LVR5cGUgaGVhZGVyIHNob3VsZCBiZSBkZWxldGVkIGVhY2ggdGltZSB3aGVuIG5ldyBSZXF1ZXN0IGluc3RhbnRpYXRlZCBmcm9tIGFub3RoZXIgb25lXG5cdFx0XHRcdGlmICgoKHN1cHBvcnRzRm9ybURhdGEgJiYgdGhpcy5fb3B0aW9ucy5ib2R5IGluc3RhbmNlb2YgZ2xvYmFscy5Gb3JtRGF0YSkgfHwgdGhpcy5fb3B0aW9ucy5ib2R5IGluc3RhbmNlb2YgVVJMU2VhcmNoUGFyYW1zKSAmJiAhKHRoaXMuX29wdGlvbnMuaGVhZGVycyAmJiB0aGlzLl9vcHRpb25zLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddKSkge1xuXHRcdFx0XHRcdHRoaXMucmVxdWVzdC5oZWFkZXJzLmRlbGV0ZSgnY29udGVudC10eXBlJyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLnJlcXVlc3QgPSBuZXcgZ2xvYmFscy5SZXF1ZXN0KG5ldyBnbG9iYWxzLlJlcXVlc3QodXJsLCB0aGlzLnJlcXVlc3QpLCB0aGlzLl9vcHRpb25zKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHRoaXMuX29wdGlvbnMuanNvbiAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHRoaXMuX29wdGlvbnMuYm9keSA9IEpTT04uc3RyaW5naWZ5KHRoaXMuX29wdGlvbnMuanNvbik7XG5cdFx0XHRcdHRoaXMucmVxdWVzdC5oZWFkZXJzLnNldCgnY29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcblx0XHRcdFx0dGhpcy5yZXF1ZXN0ID0gbmV3IGdsb2JhbHMuUmVxdWVzdCh0aGlzLnJlcXVlc3QsIHtib2R5OiB0aGlzLl9vcHRpb25zLmJvZHl9KTtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgZm4gPSBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnRpbWVvdXQgPiBtYXhTYWZlVGltZW91dCkge1xuXHRcdFx0XHRcdHRocm93IG5ldyBSYW5nZUVycm9yKGBUaGUgXFxgdGltZW91dFxcYCBvcHRpb24gY2Fubm90IGJlIGdyZWF0ZXIgdGhhbiAke21heFNhZmVUaW1lb3V0fWApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0YXdhaXQgZGVsYXkoMSk7XG5cdFx0XHRcdGxldCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX2ZldGNoKCk7XG5cblx0XHRcdFx0Zm9yIChjb25zdCBob29rIG9mIHRoaXMuX29wdGlvbnMuaG9va3MuYWZ0ZXJSZXNwb25zZSkge1xuXHRcdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG5cdFx0XHRcdFx0Y29uc3QgbW9kaWZpZWRSZXNwb25zZSA9IGF3YWl0IGhvb2soXG5cdFx0XHRcdFx0XHR0aGlzLnJlcXVlc3QsXG5cdFx0XHRcdFx0XHR0aGlzLl9vcHRpb25zLFxuXHRcdFx0XHRcdFx0dGhpcy5fZGVjb3JhdGVSZXNwb25zZShyZXNwb25zZS5jbG9uZSgpKVxuXHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRpZiAobW9kaWZpZWRSZXNwb25zZSBpbnN0YW5jZW9mIGdsb2JhbHMuUmVzcG9uc2UpIHtcblx0XHRcdFx0XHRcdHJlc3BvbnNlID0gbW9kaWZpZWRSZXNwb25zZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLl9kZWNvcmF0ZVJlc3BvbnNlKHJlc3BvbnNlKTtcblxuXHRcdFx0XHRpZiAoIXJlc3BvbnNlLm9rICYmIHRoaXMuX29wdGlvbnMudGhyb3dIdHRwRXJyb3JzKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3IEhUVFBFcnJvcihyZXNwb25zZSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBJZiBgb25Eb3dubG9hZFByb2dyZXNzYCBpcyBwYXNzZWQsIGl0IHVzZXMgdGhlIHN0cmVhbSBBUEkgaW50ZXJuYWxseVxuXHRcdFx0XHQvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuXHRcdFx0XHRpZiAodGhpcy5fb3B0aW9ucy5vbkRvd25sb2FkUHJvZ3Jlc3MpIHtcblx0XHRcdFx0XHRpZiAodHlwZW9mIHRoaXMuX29wdGlvbnMub25Eb3dubG9hZFByb2dyZXNzICE9PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgYG9uRG93bmxvYWRQcm9ncmVzc2Agb3B0aW9uIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICghc3VwcG9ydHNTdHJlYW1zKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1N0cmVhbXMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4geW91ciBlbnZpcm9ubWVudC4gYFJlYWRhYmxlU3RyZWFtYCBpcyBtaXNzaW5nLicpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9zdHJlYW0ocmVzcG9uc2UuY2xvbmUoKSwgdGhpcy5fb3B0aW9ucy5vbkRvd25sb2FkUHJvZ3Jlc3MpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHJlc3BvbnNlO1xuXHRcdFx0fTtcblxuXHRcdFx0Y29uc3QgaXNSZXRyaWFibGVNZXRob2QgPSB0aGlzLl9vcHRpb25zLnJldHJ5Lm1ldGhvZHMuaW5jbHVkZXModGhpcy5yZXF1ZXN0Lm1ldGhvZC50b0xvd2VyQ2FzZSgpKTtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IGlzUmV0cmlhYmxlTWV0aG9kID8gdGhpcy5fcmV0cnkoZm4pIDogZm4oKTtcblxuXHRcdFx0Zm9yIChjb25zdCBbdHlwZSwgbWltZVR5cGVdIG9mIE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlVHlwZXMpKSB7XG5cdFx0XHRcdHJlc3VsdFt0eXBlXSA9IGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0aGlzLnJlcXVlc3QuaGVhZGVycy5zZXQoJ2FjY2VwdCcsIHRoaXMucmVxdWVzdC5oZWFkZXJzLmdldCgnYWNjZXB0JykgfHwgbWltZVR5cGUpO1xuXG5cdFx0XHRcdFx0Y29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgcmVzdWx0KS5jbG9uZSgpO1xuXG5cdFx0XHRcdFx0aWYgKHR5cGUgPT09ICdqc29uJykge1xuXHRcdFx0XHRcdFx0aWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA0KSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiAnJztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKG9wdGlvbnMucGFyc2VKc29uKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBvcHRpb25zLnBhcnNlSnNvbihhd2FpdCByZXNwb25zZS50ZXh0KCkpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiByZXNwb25zZVt0eXBlXSgpO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH1cblxuXHRcdF9jYWxjdWxhdGVSZXRyeURlbGF5KGVycm9yKSB7XG5cdFx0XHR0aGlzLl9yZXRyeUNvdW50Kys7XG5cblx0XHRcdGlmICh0aGlzLl9yZXRyeUNvdW50IDwgdGhpcy5fb3B0aW9ucy5yZXRyeS5saW1pdCAmJiAhKGVycm9yIGluc3RhbmNlb2YgVGltZW91dEVycm9yKSkge1xuXHRcdFx0XHRpZiAoZXJyb3IgaW5zdGFuY2VvZiBIVFRQRXJyb3IpIHtcblx0XHRcdFx0XHRpZiAoIXRoaXMuX29wdGlvbnMucmV0cnkuc3RhdHVzQ29kZXMuaW5jbHVkZXMoZXJyb3IucmVzcG9uc2Uuc3RhdHVzKSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIDA7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Y29uc3QgcmV0cnlBZnRlciA9IGVycm9yLnJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdSZXRyeS1BZnRlcicpO1xuXHRcdFx0XHRcdGlmIChyZXRyeUFmdGVyICYmIHRoaXMuX29wdGlvbnMucmV0cnkuYWZ0ZXJTdGF0dXNDb2Rlcy5pbmNsdWRlcyhlcnJvci5yZXNwb25zZS5zdGF0dXMpKSB7XG5cdFx0XHRcdFx0XHRsZXQgYWZ0ZXIgPSBOdW1iZXIocmV0cnlBZnRlcik7XG5cdFx0XHRcdFx0XHRpZiAoTnVtYmVyLmlzTmFOKGFmdGVyKSkge1xuXHRcdFx0XHRcdFx0XHRhZnRlciA9IERhdGUucGFyc2UocmV0cnlBZnRlcikgLSBEYXRlLm5vdygpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0YWZ0ZXIgKj0gMTAwMDtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLl9vcHRpb25zLnJldHJ5Lm1heFJldHJ5QWZ0ZXIgIT09ICd1bmRlZmluZWQnICYmIGFmdGVyID4gdGhpcy5fb3B0aW9ucy5yZXRyeS5tYXhSZXRyeUFmdGVyKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXR1cm4gYWZ0ZXI7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKGVycm9yLnJlc3BvbnNlLnN0YXR1cyA9PT0gNDEzKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjb25zdCBCQUNLT0ZGX0ZBQ1RPUiA9IDAuMztcblx0XHRcdFx0cmV0dXJuIEJBQ0tPRkZfRkFDVE9SICogKDIgKiogKHRoaXMuX3JldHJ5Q291bnQgLSAxKSkgKiAxMDAwO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHRfZGVjb3JhdGVSZXNwb25zZShyZXNwb25zZSkge1xuXHRcdFx0aWYgKHRoaXMuX29wdGlvbnMucGFyc2VKc29uKSB7XG5cdFx0XHRcdHJlc3BvbnNlLmpzb24gPSBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuX29wdGlvbnMucGFyc2VKc29uKGF3YWl0IHJlc3BvbnNlLnRleHQoKSk7XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiByZXNwb25zZTtcblx0XHR9XG5cblx0XHRhc3luYyBfcmV0cnkoZm4pIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdHJldHVybiBhd2FpdCBmbigpO1xuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0Y29uc3QgbXMgPSBNYXRoLm1pbih0aGlzLl9jYWxjdWxhdGVSZXRyeURlbGF5KGVycm9yKSwgbWF4U2FmZVRpbWVvdXQpO1xuXHRcdFx0XHRpZiAobXMgIT09IDAgJiYgdGhpcy5fcmV0cnlDb3VudCA+IDApIHtcblx0XHRcdFx0XHRhd2FpdCBkZWxheShtcyk7XG5cblx0XHRcdFx0XHRmb3IgKGNvbnN0IGhvb2sgb2YgdGhpcy5fb3B0aW9ucy5ob29rcy5iZWZvcmVSZXRyeSkge1xuXHRcdFx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3Bcblx0XHRcdFx0XHRcdGNvbnN0IGhvb2tSZXN1bHQgPSBhd2FpdCBob29rKHtcblx0XHRcdFx0XHRcdFx0cmVxdWVzdDogdGhpcy5yZXF1ZXN0LFxuXHRcdFx0XHRcdFx0XHRvcHRpb25zOiB0aGlzLl9vcHRpb25zLFxuXHRcdFx0XHRcdFx0XHRlcnJvcixcblx0XHRcdFx0XHRcdFx0cmV0cnlDb3VudDogdGhpcy5fcmV0cnlDb3VudFxuXHRcdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHRcdC8vIElmIGBzdG9wYCBpcyByZXR1cm5lZCBmcm9tIHRoZSBob29rLCB0aGUgcmV0cnkgcHJvY2VzcyBpcyBzdG9wcGVkXG5cdFx0XHRcdFx0XHRpZiAoaG9va1Jlc3VsdCA9PT0gc3RvcCkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXMuX3JldHJ5KGZuKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnRocm93SHR0cEVycm9ycykge1xuXHRcdFx0XHRcdHRocm93IGVycm9yO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0YXN5bmMgX2ZldGNoKCkge1xuXHRcdFx0Zm9yIChjb25zdCBob29rIG9mIHRoaXMuX29wdGlvbnMuaG9va3MuYmVmb3JlUmVxdWVzdCkge1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCBob29rKHRoaXMucmVxdWVzdCwgdGhpcy5fb3B0aW9ucyk7XG5cblx0XHRcdFx0aWYgKHJlc3VsdCBpbnN0YW5jZW9mIFJlcXVlc3QpIHtcblx0XHRcdFx0XHR0aGlzLnJlcXVlc3QgPSByZXN1bHQ7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAocmVzdWx0IGluc3RhbmNlb2YgUmVzcG9uc2UpIHtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnRpbWVvdXQgPT09IGZhbHNlKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLl9vcHRpb25zLmZldGNoKHRoaXMucmVxdWVzdC5jbG9uZSgpKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRpbWVvdXQodGhpcy5yZXF1ZXN0LmNsb25lKCksIHRoaXMuYWJvcnRDb250cm9sbGVyLCB0aGlzLl9vcHRpb25zKTtcblx0XHR9XG5cblx0XHQvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuXHRcdF9zdHJlYW0ocmVzcG9uc2UsIG9uRG93bmxvYWRQcm9ncmVzcykge1xuXHRcdFx0Y29uc3QgdG90YWxCeXRlcyA9IE51bWJlcihyZXNwb25zZS5oZWFkZXJzLmdldCgnY29udGVudC1sZW5ndGgnKSkgfHwgMDtcblx0XHRcdGxldCB0cmFuc2ZlcnJlZEJ5dGVzID0gMDtcblxuXHRcdFx0cmV0dXJuIG5ldyBnbG9iYWxzLlJlc3BvbnNlKFxuXHRcdFx0XHRuZXcgZ2xvYmFscy5SZWFkYWJsZVN0cmVhbSh7XG5cdFx0XHRcdFx0c3RhcnQoY29udHJvbGxlcikge1xuXHRcdFx0XHRcdFx0Y29uc3QgcmVhZGVyID0gcmVzcG9uc2UuYm9keS5nZXRSZWFkZXIoKTtcblxuXHRcdFx0XHRcdFx0aWYgKG9uRG93bmxvYWRQcm9ncmVzcykge1xuXHRcdFx0XHRcdFx0XHRvbkRvd25sb2FkUHJvZ3Jlc3Moe3BlcmNlbnQ6IDAsIHRyYW5zZmVycmVkQnl0ZXM6IDAsIHRvdGFsQnl0ZXN9LCBuZXcgVWludDhBcnJheSgpKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0YXN5bmMgZnVuY3Rpb24gcmVhZCgpIHtcblx0XHRcdFx0XHRcdFx0Y29uc3Qge2RvbmUsIHZhbHVlfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG5cdFx0XHRcdFx0XHRcdGlmIChkb25lKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29udHJvbGxlci5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGlmIChvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcblx0XHRcdFx0XHRcdFx0XHR0cmFuc2ZlcnJlZEJ5dGVzICs9IHZhbHVlLmJ5dGVMZW5ndGg7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgcGVyY2VudCA9IHRvdGFsQnl0ZXMgPT09IDAgPyAwIDogdHJhbnNmZXJyZWRCeXRlcyAvIHRvdGFsQnl0ZXM7XG5cdFx0XHRcdFx0XHRcdFx0b25Eb3dubG9hZFByb2dyZXNzKHtwZXJjZW50LCB0cmFuc2ZlcnJlZEJ5dGVzLCB0b3RhbEJ5dGVzfSwgdmFsdWUpO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0Y29udHJvbGxlci5lbnF1ZXVlKHZhbHVlKTtcblx0XHRcdFx0XHRcdFx0cmVhZCgpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZWFkKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblxuXHRjb25zdCB2YWxpZGF0ZUFuZE1lcmdlID0gKC4uLnNvdXJjZXMpID0+IHtcblx0XHRmb3IgKGNvbnN0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG5cdFx0XHRpZiAoKCFpc09iamVjdChzb3VyY2UpIHx8IEFycmF5LmlzQXJyYXkoc291cmNlKSkgJiYgdHlwZW9mIHNvdXJjZSAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGBvcHRpb25zYCBhcmd1bWVudCBtdXN0IGJlIGFuIG9iamVjdCcpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBkZWVwTWVyZ2Uoe30sIC4uLnNvdXJjZXMpO1xuXHR9O1xuXG5cdGNvbnN0IGNyZWF0ZUluc3RhbmNlID0gZGVmYXVsdHMgPT4ge1xuXHRcdGNvbnN0IGt5ID0gKGlucHV0LCBvcHRpb25zKSA9PiBuZXcgS3koaW5wdXQsIHZhbGlkYXRlQW5kTWVyZ2UoZGVmYXVsdHMsIG9wdGlvbnMpKTtcblxuXHRcdGZvciAoY29uc3QgbWV0aG9kIG9mIHJlcXVlc3RNZXRob2RzKSB7XG5cdFx0XHRreVttZXRob2RdID0gKGlucHV0LCBvcHRpb25zKSA9PiBuZXcgS3koaW5wdXQsIHZhbGlkYXRlQW5kTWVyZ2UoZGVmYXVsdHMsIG9wdGlvbnMsIHttZXRob2R9KSk7XG5cdFx0fVxuXG5cdFx0a3kuSFRUUEVycm9yID0gSFRUUEVycm9yO1xuXHRcdGt5LlRpbWVvdXRFcnJvciA9IFRpbWVvdXRFcnJvcjtcblx0XHRreS5jcmVhdGUgPSBuZXdEZWZhdWx0cyA9PiBjcmVhdGVJbnN0YW5jZSh2YWxpZGF0ZUFuZE1lcmdlKG5ld0RlZmF1bHRzKSk7XG5cdFx0a3kuZXh0ZW5kID0gbmV3RGVmYXVsdHMgPT4gY3JlYXRlSW5zdGFuY2UodmFsaWRhdGVBbmRNZXJnZShkZWZhdWx0cywgbmV3RGVmYXVsdHMpKTtcblx0XHRreS5zdG9wID0gc3RvcDtcblxuXHRcdHJldHVybiBreTtcblx0fTtcblxuXHR2YXIgaW5kZXggPSBjcmVhdGVJbnN0YW5jZSgpO1xuXG5cdHJldHVybiBpbmRleDtcblxufSkpKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZmV0Y2g7XG5cbmNvbnN0IGh0dHAgPSByZXF1aXJlKCdodHRwJyk7XG5jb25zdCBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyk7XG5jb25zdCB6bGliID0gcmVxdWlyZSgnemxpYicpO1xuY29uc3QgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG5jb25zdCBkYXRhVXJpVG9CdWZmZXIgPSByZXF1aXJlKCdkYXRhLXVyaS10by1idWZmZXInKTtcbmNvbnN0IHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5jb25zdCBCbG9iID0gcmVxdWlyZSgnZmV0Y2gtYmxvYicpO1xuY29uc3QgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5jb25zdCB1cmwgPSByZXF1aXJlKCd1cmwnKTtcblxuY2xhc3MgRmV0Y2hCYXNlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHR5cGUpIHtcblx0XHRzdXBlcihtZXNzYWdlKTtcblx0XHQvLyBIaWRlIGN1c3RvbSBlcnJvciBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIGZyb20gZW5kLXVzZXJzXG5cdFx0RXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG5cblx0XHR0aGlzLnR5cGUgPSB0eXBlO1xuXHR9XG5cblx0Z2V0IG5hbWUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IubmFtZTtcblx0fVxuXG5cdGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcblx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lO1xuXHR9XG59XG5cbi8qKlxuICogQHR5cGVkZWYge3sgYWRkcmVzcz86IHN0cmluZywgY29kZTogc3RyaW5nLCBkZXN0Pzogc3RyaW5nLCBlcnJubzogbnVtYmVyLCBpbmZvPzogb2JqZWN0LCBtZXNzYWdlOiBzdHJpbmcsIHBhdGg/OiBzdHJpbmcsIHBvcnQ/OiBudW1iZXIsIHN5c2NhbGw6IHN0cmluZ319IFN5c3RlbUVycm9yXG4qL1xuXG4vKipcbiAqIEZldGNoRXJyb3IgaW50ZXJmYWNlIGZvciBvcGVyYXRpb25hbCBlcnJvcnNcbiAqL1xuY2xhc3MgRmV0Y2hFcnJvciBleHRlbmRzIEZldGNoQmFzZUVycm9yIHtcblx0LyoqXG5cdCAqIEBwYXJhbSAge3N0cmluZ30gbWVzc2FnZSAtICAgICAgRXJyb3IgbWVzc2FnZSBmb3IgaHVtYW5cblx0ICogQHBhcmFtICB7c3RyaW5nfSBbdHlwZV0gLSAgICAgICAgRXJyb3IgdHlwZSBmb3IgbWFjaGluZVxuXHQgKiBAcGFyYW0gIHtTeXN0ZW1FcnJvcn0gW3N5c3RlbUVycm9yXSAtIEZvciBOb2RlLmpzIHN5c3RlbSBlcnJvclxuXHQgKi9cblx0Y29uc3RydWN0b3IobWVzc2FnZSwgdHlwZSwgc3lzdGVtRXJyb3IpIHtcblx0XHRzdXBlcihtZXNzYWdlLCB0eXBlKTtcblx0XHQvLyBXaGVuIGVyci50eXBlIGlzIGBzeXN0ZW1gLCBlcnIuZXJyb3JlZFN5c0NhbGwgY29udGFpbnMgc3lzdGVtIGVycm9yIGFuZCBlcnIuY29kZSBjb250YWlucyBzeXN0ZW0gZXJyb3IgY29kZVxuXHRcdGlmIChzeXN0ZW1FcnJvcikge1xuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW11bHRpLWFzc2lnblxuXHRcdFx0dGhpcy5jb2RlID0gdGhpcy5lcnJubyA9IHN5c3RlbUVycm9yLmNvZGU7XG5cdFx0XHR0aGlzLmVycm9yZWRTeXNDYWxsID0gc3lzdGVtRXJyb3Iuc3lzY2FsbDtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBJcy5qc1xuICpcbiAqIE9iamVjdCB0eXBlIGNoZWNrcy5cbiAqL1xuXG5jb25zdCBOQU1FID0gU3ltYm9sLnRvU3RyaW5nVGFnO1xuXG4vKipcbiAqIENoZWNrIGlmIGBvYmpgIGlzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdFxuICogcmVmOiBodHRwczovL2dpdGh1Yi5jb20vbm9kZS1mZXRjaC9ub2RlLWZldGNoL2lzc3Vlcy8yOTYjaXNzdWVjb21tZW50LTMwNzU5ODE0M1xuICpcbiAqIEBwYXJhbSAgeyp9IG9ialxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuY29uc3QgaXNVUkxTZWFyY2hQYXJhbWV0ZXJzID0gb2JqZWN0ID0+IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuYXBwZW5kID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5kZWxldGUgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmdldCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZ2V0QWxsID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5oYXMgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnNldCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3Quc29ydCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdG9iamVjdFtOQU1FXSA9PT0gJ1VSTFNlYXJjaFBhcmFtcydcblx0KTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamVjdGAgaXMgYSBXM0MgYEJsb2JgIG9iamVjdCAod2hpY2ggYEZpbGVgIGluaGVyaXRzIGZyb20pXG4gKlxuICogQHBhcmFtICB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBpc0Jsb2IgPSBvYmplY3QgPT4ge1xuXHRyZXR1cm4gKFxuXHRcdHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnICYmXG5cdFx0dHlwZW9mIG9iamVjdC5hcnJheUJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QudHlwZSA9PT0gJ3N0cmluZycgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnN0cmVhbSA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgPT09ICdmdW5jdGlvbicgJiZcblx0XHQvXihCbG9ifEZpbGUpJC8udGVzdChvYmplY3RbTkFNRV0pXG5cdCk7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGBvYmpgIGlzIGEgc3BlYy1jb21wbGlhbnQgYEZvcm1EYXRhYCBvYmplY3RcbiAqXG4gKiBAcGFyYW0geyp9IG9iamVjdFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNGb3JtRGF0YShvYmplY3QpIHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuYXBwZW5kID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5zZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmdldCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZ2V0QWxsID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5kZWxldGUgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnZhbHVlcyA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZW50cmllcyA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgPT09ICdmdW5jdGlvbicgJiZcblx0XHRvYmplY3RbTkFNRV0gPT09ICdGb3JtRGF0YSdcblx0KTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhbiBpbnN0YW5jZSBvZiBBYm9ydFNpZ25hbC5cbiAqXG4gKiBAcGFyYW0gIHsqfSBvYmpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGlzQWJvcnRTaWduYWwgPSBvYmplY3QgPT4ge1xuXHRyZXR1cm4gKFxuXHRcdHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnICYmXG5cdFx0b2JqZWN0W05BTUVdID09PSAnQWJvcnRTaWduYWwnXG5cdCk7XG59O1xuXG5jb25zdCBjYXJyaWFnZSA9ICdcXHJcXG4nO1xuY29uc3QgZGFzaGVzID0gJy0nLnJlcGVhdCgyKTtcbmNvbnN0IGNhcnJpYWdlTGVuZ3RoID0gQnVmZmVyLmJ5dGVMZW5ndGgoY2FycmlhZ2UpO1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZGFyeVxuICovXG5jb25zdCBnZXRGb290ZXIgPSBib3VuZGFyeSA9PiBgJHtkYXNoZXN9JHtib3VuZGFyeX0ke2Rhc2hlc30ke2NhcnJpYWdlLnJlcGVhdCgyKX1gO1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZGFyeVxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7Kn0gZmllbGRcbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGdldEhlYWRlcihib3VuZGFyeSwgbmFtZSwgZmllbGQpIHtcblx0bGV0IGhlYWRlciA9ICcnO1xuXG5cdGhlYWRlciArPSBgJHtkYXNoZXN9JHtib3VuZGFyeX0ke2NhcnJpYWdlfWA7XG5cdGhlYWRlciArPSBgQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPVwiJHtuYW1lfVwiYDtcblxuXHRpZiAoaXNCbG9iKGZpZWxkKSkge1xuXHRcdGhlYWRlciArPSBgOyBmaWxlbmFtZT1cIiR7ZmllbGQubmFtZX1cIiR7Y2FycmlhZ2V9YDtcblx0XHRoZWFkZXIgKz0gYENvbnRlbnQtVHlwZTogJHtmaWVsZC50eXBlIHx8ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nfWA7XG5cdH1cblxuXHRyZXR1cm4gYCR7aGVhZGVyfSR7Y2FycmlhZ2UucmVwZWF0KDIpfWA7XG59XG5cbi8qKlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5jb25zdCBnZXRCb3VuZGFyeSA9ICgpID0+IGNyeXB0by5yYW5kb21CeXRlcyg4KS50b1N0cmluZygnaGV4Jyk7XG5cbi8qKlxuICogQHBhcmFtIHtGb3JtRGF0YX0gZm9ybVxuICogQHBhcmFtIHtzdHJpbmd9IGJvdW5kYXJ5XG4gKi9cbmFzeW5jIGZ1bmN0aW9uICogZm9ybURhdGFJdGVyYXRvcihmb3JtLCBib3VuZGFyeSkge1xuXHRmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZV0gb2YgZm9ybSkge1xuXHRcdHlpZWxkIGdldEhlYWRlcihib3VuZGFyeSwgbmFtZSwgdmFsdWUpO1xuXG5cdFx0aWYgKGlzQmxvYih2YWx1ZSkpIHtcblx0XHRcdHlpZWxkICogdmFsdWUuc3RyZWFtKCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHlpZWxkIHZhbHVlO1xuXHRcdH1cblxuXHRcdHlpZWxkIGNhcnJpYWdlO1xuXHR9XG5cblx0eWllbGQgZ2V0Rm9vdGVyKGJvdW5kYXJ5KTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0Zvcm1EYXRhfSBmb3JtXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRhcnlcbiAqL1xuZnVuY3Rpb24gZ2V0Rm9ybURhdGFMZW5ndGgoZm9ybSwgYm91bmRhcnkpIHtcblx0bGV0IGxlbmd0aCA9IDA7XG5cblx0Zm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIGZvcm0pIHtcblx0XHRsZW5ndGggKz0gQnVmZmVyLmJ5dGVMZW5ndGgoZ2V0SGVhZGVyKGJvdW5kYXJ5LCBuYW1lLCB2YWx1ZSkpO1xuXG5cdFx0aWYgKGlzQmxvYih2YWx1ZSkpIHtcblx0XHRcdGxlbmd0aCArPSB2YWx1ZS5zaXplO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRsZW5ndGggKz0gQnVmZmVyLmJ5dGVMZW5ndGgoU3RyaW5nKHZhbHVlKSk7XG5cdFx0fVxuXG5cdFx0bGVuZ3RoICs9IGNhcnJpYWdlTGVuZ3RoO1xuXHR9XG5cblx0bGVuZ3RoICs9IEJ1ZmZlci5ieXRlTGVuZ3RoKGdldEZvb3Rlcihib3VuZGFyeSkpO1xuXG5cdHJldHVybiBsZW5ndGg7XG59XG5cbmNvbnN0IElOVEVSTkFMUyA9IFN5bWJvbCgnQm9keSBpbnRlcm5hbHMnKTtcblxuLyoqXG4gKiBCb2R5IG1peGluXG4gKlxuICogUmVmOiBodHRwczovL2ZldGNoLnNwZWMud2hhdHdnLm9yZy8jYm9keVxuICpcbiAqIEBwYXJhbSAgIFN0cmVhbSAgYm9keSAgUmVhZGFibGUgc3RyZWFtXG4gKiBAcGFyYW0gICBPYmplY3QgIG9wdHMgIFJlc3BvbnNlIG9wdGlvbnNcbiAqIEByZXR1cm4gIFZvaWRcbiAqL1xuY2xhc3MgQm9keSB7XG5cdGNvbnN0cnVjdG9yKGJvZHksIHtcblx0XHRzaXplID0gMFxuXHR9ID0ge30pIHtcblx0XHRsZXQgYm91bmRhcnkgPSBudWxsO1xuXG5cdFx0aWYgKGJvZHkgPT09IG51bGwpIHtcblx0XHRcdC8vIEJvZHkgaXMgdW5kZWZpbmVkIG9yIG51bGxcblx0XHRcdGJvZHkgPSBudWxsO1xuXHRcdH0gZWxzZSBpZiAoaXNVUkxTZWFyY2hQYXJhbWV0ZXJzKGJvZHkpKSB7XG5cdFx0Ly8gQm9keSBpcyBhIFVSTFNlYXJjaFBhcmFtc1xuXHRcdFx0Ym9keSA9IEJ1ZmZlci5mcm9tKGJvZHkudG9TdHJpbmcoKSk7XG5cdFx0fSBlbHNlIGlmIChpc0Jsb2IoYm9keSkpIDsgZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSA7IGVsc2UgaWYgKHV0aWwudHlwZXMuaXNBbnlBcnJheUJ1ZmZlcihib2R5KSkge1xuXHRcdFx0Ly8gQm9keSBpcyBBcnJheUJ1ZmZlclxuXHRcdFx0Ym9keSA9IEJ1ZmZlci5mcm9tKGJvZHkpO1xuXHRcdH0gZWxzZSBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KGJvZHkpKSB7XG5cdFx0XHQvLyBCb2R5IGlzIEFycmF5QnVmZmVyVmlld1xuXHRcdFx0Ym9keSA9IEJ1ZmZlci5mcm9tKGJvZHkuYnVmZmVyLCBib2R5LmJ5dGVPZmZzZXQsIGJvZHkuYnl0ZUxlbmd0aCk7XG5cdFx0fSBlbHNlIGlmIChib2R5IGluc3RhbmNlb2YgU3RyZWFtKSA7IGVsc2UgaWYgKGlzRm9ybURhdGEoYm9keSkpIHtcblx0XHRcdC8vIEJvZHkgaXMgYW4gaW5zdGFuY2Ugb2YgZm9ybWRhdGEtbm9kZVxuXHRcdFx0Ym91bmRhcnkgPSBgTm9kZUZldGNoRm9ybURhdGFCb3VuZGFyeSR7Z2V0Qm91bmRhcnkoKX1gO1xuXHRcdFx0Ym9keSA9IFN0cmVhbS5SZWFkYWJsZS5mcm9tKGZvcm1EYXRhSXRlcmF0b3IoYm9keSwgYm91bmRhcnkpKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gTm9uZSBvZiB0aGUgYWJvdmVcblx0XHRcdC8vIGNvZXJjZSB0byBzdHJpbmcgdGhlbiBidWZmZXJcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShTdHJpbmcoYm9keSkpO1xuXHRcdH1cblxuXHRcdHRoaXNbSU5URVJOQUxTXSA9IHtcblx0XHRcdGJvZHksXG5cdFx0XHRib3VuZGFyeSxcblx0XHRcdGRpc3R1cmJlZDogZmFsc2UsXG5cdFx0XHRlcnJvcjogbnVsbFxuXHRcdH07XG5cdFx0dGhpcy5zaXplID0gc2l6ZTtcblxuXHRcdGlmIChib2R5IGluc3RhbmNlb2YgU3RyZWFtKSB7XG5cdFx0XHRib2R5Lm9uKCdlcnJvcicsIGVyciA9PiB7XG5cdFx0XHRcdGNvbnN0IGVycm9yID0gZXJyIGluc3RhbmNlb2YgRmV0Y2hCYXNlRXJyb3IgP1xuXHRcdFx0XHRcdGVyciA6XG5cdFx0XHRcdFx0bmV3IEZldGNoRXJyb3IoYEludmFsaWQgcmVzcG9uc2UgYm9keSB3aGlsZSB0cnlpbmcgdG8gZmV0Y2ggJHt0aGlzLnVybH06ICR7ZXJyLm1lc3NhZ2V9YCwgJ3N5c3RlbScsIGVycik7XG5cdFx0XHRcdHRoaXNbSU5URVJOQUxTXS5lcnJvciA9IGVycm9yO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0Z2V0IGJvZHkoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTXS5ib2R5O1xuXHR9XG5cblx0Z2V0IGJvZHlVc2VkKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMU10uZGlzdHVyYmVkO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlY29kZSByZXNwb25zZSBhcyBBcnJheUJ1ZmZlclxuXHQgKlxuXHQgKiBAcmV0dXJuICBQcm9taXNlXG5cdCAqL1xuXHRhc3luYyBhcnJheUJ1ZmZlcigpIHtcblx0XHRjb25zdCB7YnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RofSA9IGF3YWl0IGNvbnN1bWVCb2R5KHRoaXMpO1xuXHRcdHJldHVybiBidWZmZXIuc2xpY2UoYnl0ZU9mZnNldCwgYnl0ZU9mZnNldCArIGJ5dGVMZW5ndGgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybiByYXcgcmVzcG9uc2UgYXMgQmxvYlxuXHQgKlxuXHQgKiBAcmV0dXJuIFByb21pc2Vcblx0ICovXG5cdGFzeW5jIGJsb2IoKSB7XG5cdFx0Y29uc3QgY3QgPSAodGhpcy5oZWFkZXJzICYmIHRoaXMuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpKSB8fCAodGhpc1tJTlRFUk5BTFNdLmJvZHkgJiYgdGhpc1tJTlRFUk5BTFNdLmJvZHkudHlwZSkgfHwgJyc7XG5cdFx0Y29uc3QgYnVmID0gYXdhaXQgdGhpcy5idWZmZXIoKTtcblxuXHRcdHJldHVybiBuZXcgQmxvYihbYnVmXSwge1xuXHRcdFx0dHlwZTogY3Rcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWNvZGUgcmVzcG9uc2UgYXMganNvblxuXHQgKlxuXHQgKiBAcmV0dXJuICBQcm9taXNlXG5cdCAqL1xuXHRhc3luYyBqc29uKCkge1xuXHRcdGNvbnN0IGJ1ZmZlciA9IGF3YWl0IGNvbnN1bWVCb2R5KHRoaXMpO1xuXHRcdHJldHVybiBKU09OLnBhcnNlKGJ1ZmZlci50b1N0cmluZygpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWNvZGUgcmVzcG9uc2UgYXMgdGV4dFxuXHQgKlxuXHQgKiBAcmV0dXJuICBQcm9taXNlXG5cdCAqL1xuXHRhc3luYyB0ZXh0KCkge1xuXHRcdGNvbnN0IGJ1ZmZlciA9IGF3YWl0IGNvbnN1bWVCb2R5KHRoaXMpO1xuXHRcdHJldHVybiBidWZmZXIudG9TdHJpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWNvZGUgcmVzcG9uc2UgYXMgYnVmZmVyIChub24tc3BlYyBhcGkpXG5cdCAqXG5cdCAqIEByZXR1cm4gIFByb21pc2Vcblx0ICovXG5cdGJ1ZmZlcigpIHtcblx0XHRyZXR1cm4gY29uc3VtZUJvZHkodGhpcyk7XG5cdH1cbn1cblxuLy8gSW4gYnJvd3NlcnMsIGFsbCBwcm9wZXJ0aWVzIGFyZSBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQm9keS5wcm90b3R5cGUsIHtcblx0Ym9keToge2VudW1lcmFibGU6IHRydWV9LFxuXHRib2R5VXNlZDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRhcnJheUJ1ZmZlcjoge2VudW1lcmFibGU6IHRydWV9LFxuXHRibG9iOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdGpzb246IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0dGV4dDoge2VudW1lcmFibGU6IHRydWV9XG59KTtcblxuLyoqXG4gKiBDb25zdW1lIGFuZCBjb252ZXJ0IGFuIGVudGlyZSBCb2R5IHRvIGEgQnVmZmVyLlxuICpcbiAqIFJlZjogaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2NvbmNlcHQtYm9keS1jb25zdW1lLWJvZHlcbiAqXG4gKiBAcmV0dXJuIFByb21pc2VcbiAqL1xuYXN5bmMgZnVuY3Rpb24gY29uc3VtZUJvZHkoZGF0YSkge1xuXHRpZiAoZGF0YVtJTlRFUk5BTFNdLmRpc3R1cmJlZCkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYGJvZHkgdXNlZCBhbHJlYWR5IGZvcjogJHtkYXRhLnVybH1gKTtcblx0fVxuXG5cdGRhdGFbSU5URVJOQUxTXS5kaXN0dXJiZWQgPSB0cnVlO1xuXG5cdGlmIChkYXRhW0lOVEVSTkFMU10uZXJyb3IpIHtcblx0XHR0aHJvdyBkYXRhW0lOVEVSTkFMU10uZXJyb3I7XG5cdH1cblxuXHRsZXQge2JvZHl9ID0gZGF0YTtcblxuXHQvLyBCb2R5IGlzIG51bGxcblx0aWYgKGJvZHkgPT09IG51bGwpIHtcblx0XHRyZXR1cm4gQnVmZmVyLmFsbG9jKDApO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBibG9iXG5cdGlmIChpc0Jsb2IoYm9keSkpIHtcblx0XHRib2R5ID0gYm9keS5zdHJlYW0oKTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgYnVmZmVyXG5cdGlmIChCdWZmZXIuaXNCdWZmZXIoYm9keSkpIHtcblx0XHRyZXR1cm4gYm9keTtcblx0fVxuXG5cdC8qIGM4IGlnbm9yZSBuZXh0IDMgKi9cblx0aWYgKCEoYm9keSBpbnN0YW5jZW9mIFN0cmVhbSkpIHtcblx0XHRyZXR1cm4gQnVmZmVyLmFsbG9jKDApO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBzdHJlYW1cblx0Ly8gZ2V0IHJlYWR5IHRvIGFjdHVhbGx5IGNvbnN1bWUgdGhlIGJvZHlcblx0Y29uc3QgYWNjdW0gPSBbXTtcblx0bGV0IGFjY3VtQnl0ZXMgPSAwO1xuXG5cdHRyeSB7XG5cdFx0Zm9yIGF3YWl0IChjb25zdCBjaHVuayBvZiBib2R5KSB7XG5cdFx0XHRpZiAoZGF0YS5zaXplID4gMCAmJiBhY2N1bUJ5dGVzICsgY2h1bmsubGVuZ3RoID4gZGF0YS5zaXplKSB7XG5cdFx0XHRcdGNvbnN0IGVyciA9IG5ldyBGZXRjaEVycm9yKGBjb250ZW50IHNpemUgYXQgJHtkYXRhLnVybH0gb3ZlciBsaW1pdDogJHtkYXRhLnNpemV9YCwgJ21heC1zaXplJyk7XG5cdFx0XHRcdGJvZHkuZGVzdHJveShlcnIpO1xuXHRcdFx0XHR0aHJvdyBlcnI7XG5cdFx0XHR9XG5cblx0XHRcdGFjY3VtQnl0ZXMgKz0gY2h1bmsubGVuZ3RoO1xuXHRcdFx0YWNjdW0ucHVzaChjaHVuayk7XG5cdFx0fVxuXHR9IGNhdGNoIChlcnJvcikge1xuXHRcdGlmIChlcnJvciBpbnN0YW5jZW9mIEZldGNoQmFzZUVycm9yKSB7XG5cdFx0XHR0aHJvdyBlcnJvcjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gT3RoZXIgZXJyb3JzLCBzdWNoIGFzIGluY29ycmVjdCBjb250ZW50LWVuY29kaW5nXG5cdFx0XHR0aHJvdyBuZXcgRmV0Y2hFcnJvcihgSW52YWxpZCByZXNwb25zZSBib2R5IHdoaWxlIHRyeWluZyB0byBmZXRjaCAke2RhdGEudXJsfTogJHtlcnJvci5tZXNzYWdlfWAsICdzeXN0ZW0nLCBlcnJvcik7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGJvZHkucmVhZGFibGVFbmRlZCA9PT0gdHJ1ZSB8fCBib2R5Ll9yZWFkYWJsZVN0YXRlLmVuZGVkID09PSB0cnVlKSB7XG5cdFx0dHJ5IHtcblx0XHRcdGlmIChhY2N1bS5ldmVyeShjID0+IHR5cGVvZiBjID09PSAnc3RyaW5nJykpIHtcblx0XHRcdFx0cmV0dXJuIEJ1ZmZlci5mcm9tKGFjY3VtLmpvaW4oJycpKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIEJ1ZmZlci5jb25jYXQoYWNjdW0sIGFjY3VtQnl0ZXMpO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHR0aHJvdyBuZXcgRmV0Y2hFcnJvcihgQ291bGQgbm90IGNyZWF0ZSBCdWZmZXIgZnJvbSByZXNwb25zZSBib2R5IGZvciAke2RhdGEudXJsfTogJHtlcnJvci5tZXNzYWdlfWAsICdzeXN0ZW0nLCBlcnJvcik7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHRocm93IG5ldyBGZXRjaEVycm9yKGBQcmVtYXR1cmUgY2xvc2Ugb2Ygc2VydmVyIHJlc3BvbnNlIHdoaWxlIHRyeWluZyB0byBmZXRjaCAke2RhdGEudXJsfWApO1xuXHR9XG59XG5cbi8qKlxuICogQ2xvbmUgYm9keSBnaXZlbiBSZXMvUmVxIGluc3RhbmNlXG4gKlxuICogQHBhcmFtICAgTWl4ZWQgICBpbnN0YW5jZSAgICAgICBSZXNwb25zZSBvciBSZXF1ZXN0IGluc3RhbmNlXG4gKiBAcGFyYW0gICBTdHJpbmcgIGhpZ2hXYXRlck1hcmsgIGhpZ2hXYXRlck1hcmsgZm9yIGJvdGggUGFzc1Rocm91Z2ggYm9keSBzdHJlYW1zXG4gKiBAcmV0dXJuICBNaXhlZFxuICovXG5jb25zdCBjbG9uZSA9IChpbnN0YW5jZSwgaGlnaFdhdGVyTWFyaykgPT4ge1xuXHRsZXQgcDE7XG5cdGxldCBwMjtcblx0bGV0IHtib2R5fSA9IGluc3RhbmNlO1xuXG5cdC8vIERvbid0IGFsbG93IGNsb25pbmcgYSB1c2VkIGJvZHlcblx0aWYgKGluc3RhbmNlLmJvZHlVc2VkKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgY2xvbmUgYm9keSBhZnRlciBpdCBpcyB1c2VkJyk7XG5cdH1cblxuXHQvLyBDaGVjayB0aGF0IGJvZHkgaXMgYSBzdHJlYW0gYW5kIG5vdCBmb3JtLWRhdGEgb2JqZWN0XG5cdC8vIG5vdGU6IHdlIGNhbid0IGNsb25lIHRoZSBmb3JtLWRhdGEgb2JqZWN0IHdpdGhvdXQgaGF2aW5nIGl0IGFzIGEgZGVwZW5kZW5jeVxuXHRpZiAoKGJvZHkgaW5zdGFuY2VvZiBTdHJlYW0pICYmICh0eXBlb2YgYm9keS5nZXRCb3VuZGFyeSAhPT0gJ2Z1bmN0aW9uJykpIHtcblx0XHQvLyBUZWUgaW5zdGFuY2UgYm9keVxuXHRcdHAxID0gbmV3IFN0cmVhbS5QYXNzVGhyb3VnaCh7aGlnaFdhdGVyTWFya30pO1xuXHRcdHAyID0gbmV3IFN0cmVhbS5QYXNzVGhyb3VnaCh7aGlnaFdhdGVyTWFya30pO1xuXHRcdGJvZHkucGlwZShwMSk7XG5cdFx0Ym9keS5waXBlKHAyKTtcblx0XHQvLyBTZXQgaW5zdGFuY2UgYm9keSB0byB0ZWVkIGJvZHkgYW5kIHJldHVybiB0aGUgb3RoZXIgdGVlZCBib2R5XG5cdFx0aW5zdGFuY2VbSU5URVJOQUxTXS5ib2R5ID0gcDE7XG5cdFx0Ym9keSA9IHAyO1xuXHR9XG5cblx0cmV0dXJuIGJvZHk7XG59O1xuXG4vKipcbiAqIFBlcmZvcm1zIHRoZSBvcGVyYXRpb24gXCJleHRyYWN0IGEgYENvbnRlbnQtVHlwZWAgdmFsdWUgZnJvbSB8b2JqZWN0fFwiIGFzXG4gKiBzcGVjaWZpZWQgaW4gdGhlIHNwZWNpZmljYXRpb246XG4gKiBodHRwczovL2ZldGNoLnNwZWMud2hhdHdnLm9yZy8jY29uY2VwdC1ib2R5aW5pdC1leHRyYWN0XG4gKlxuICogVGhpcyBmdW5jdGlvbiBhc3N1bWVzIHRoYXQgaW5zdGFuY2UuYm9keSBpcyBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSB7YW55fSBib2R5IEFueSBvcHRpb25zLmJvZHkgaW5wdXRcbiAqIEByZXR1cm5zIHtzdHJpbmcgfCBudWxsfVxuICovXG5jb25zdCBleHRyYWN0Q29udGVudFR5cGUgPSAoYm9keSwgcmVxdWVzdCkgPT4ge1xuXHQvLyBCb2R5IGlzIG51bGwgb3IgdW5kZWZpbmVkXG5cdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvLyBCb2R5IGlzIHN0cmluZ1xuXHRpZiAodHlwZW9mIGJvZHkgPT09ICdzdHJpbmcnKSB7XG5cdFx0cmV0dXJuICd0ZXh0L3BsYWluO2NoYXJzZXQ9VVRGLTgnO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBhIFVSTFNlYXJjaFBhcmFtc1xuXHRpZiAoaXNVUkxTZWFyY2hQYXJhbWV0ZXJzKGJvZHkpKSB7XG5cdFx0cmV0dXJuICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7Y2hhcnNldD1VVEYtOCc7XG5cdH1cblxuXHQvLyBCb2R5IGlzIGJsb2Jcblx0aWYgKGlzQmxvYihib2R5KSkge1xuXHRcdHJldHVybiBib2R5LnR5cGUgfHwgbnVsbDtcblx0fVxuXG5cdC8vIEJvZHkgaXMgYSBCdWZmZXIgKEJ1ZmZlciwgQXJyYXlCdWZmZXIgb3IgQXJyYXlCdWZmZXJWaWV3KVxuXHRpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpIHx8IHV0aWwudHlwZXMuaXNBbnlBcnJheUJ1ZmZlcihib2R5KSB8fCBBcnJheUJ1ZmZlci5pc1ZpZXcoYm9keSkpIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIERldGVjdCBmb3JtIGRhdGEgaW5wdXQgZnJvbSBmb3JtLWRhdGEgbW9kdWxlXG5cdGlmIChib2R5ICYmIHR5cGVvZiBib2R5LmdldEJvdW5kYXJ5ID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0cmV0dXJuIGBtdWx0aXBhcnQvZm9ybS1kYXRhO2JvdW5kYXJ5PSR7Ym9keS5nZXRCb3VuZGFyeSgpfWA7XG5cdH1cblxuXHRpZiAoaXNGb3JtRGF0YShib2R5KSkge1xuXHRcdHJldHVybiBgbXVsdGlwYXJ0L2Zvcm0tZGF0YTsgYm91bmRhcnk9JHtyZXF1ZXN0W0lOVEVSTkFMU10uYm91bmRhcnl9YDtcblx0fVxuXG5cdC8vIEJvZHkgaXMgc3RyZWFtIC0gY2FuJ3QgcmVhbGx5IGRvIG11Y2ggYWJvdXQgdGhpc1xuXHRpZiAoYm9keSBpbnN0YW5jZW9mIFN0cmVhbSkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gQm9keSBjb25zdHJ1Y3RvciBkZWZhdWx0cyBvdGhlciB0aGluZ3MgdG8gc3RyaW5nXG5cdHJldHVybiAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jztcbn07XG5cbi8qKlxuICogVGhlIEZldGNoIFN0YW5kYXJkIHRyZWF0cyB0aGlzIGFzIGlmIFwidG90YWwgYnl0ZXNcIiBpcyBhIHByb3BlcnR5IG9uIHRoZSBib2R5LlxuICogRm9yIHVzLCB3ZSBoYXZlIHRvIGV4cGxpY2l0bHkgZ2V0IGl0IHdpdGggYSBmdW5jdGlvbi5cbiAqXG4gKiByZWY6IGh0dHBzOi8vZmV0Y2guc3BlYy53aGF0d2cub3JnLyNjb25jZXB0LWJvZHktdG90YWwtYnl0ZXNcbiAqXG4gKiBAcGFyYW0ge2FueX0gb2JqLmJvZHkgQm9keSBvYmplY3QgZnJvbSB0aGUgQm9keSBpbnN0YW5jZS5cbiAqIEByZXR1cm5zIHtudW1iZXIgfCBudWxsfVxuICovXG5jb25zdCBnZXRUb3RhbEJ5dGVzID0gcmVxdWVzdCA9PiB7XG5cdGNvbnN0IHtib2R5fSA9IHJlcXVlc3Q7XG5cblx0Ly8gQm9keSBpcyBudWxsIG9yIHVuZGVmaW5lZFxuXHRpZiAoYm9keSA9PT0gbnVsbCkge1xuXHRcdHJldHVybiAwO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBCbG9iXG5cdGlmIChpc0Jsb2IoYm9keSkpIHtcblx0XHRyZXR1cm4gYm9keS5zaXplO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBCdWZmZXJcblx0aWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSkge1xuXHRcdHJldHVybiBib2R5Lmxlbmd0aDtcblx0fVxuXG5cdC8vIERldGVjdCBmb3JtIGRhdGEgaW5wdXQgZnJvbSBmb3JtLWRhdGEgbW9kdWxlXG5cdGlmIChib2R5ICYmIHR5cGVvZiBib2R5LmdldExlbmd0aFN5bmMgPT09ICdmdW5jdGlvbicpIHtcblx0XHRyZXR1cm4gYm9keS5oYXNLbm93bkxlbmd0aCAmJiBib2R5Lmhhc0tub3duTGVuZ3RoKCkgPyBib2R5LmdldExlbmd0aFN5bmMoKSA6IG51bGw7XG5cdH1cblxuXHQvLyBCb2R5IGlzIGEgc3BlYy1jb21wbGlhbnQgZm9ybS1kYXRhXG5cdGlmIChpc0Zvcm1EYXRhKGJvZHkpKSB7XG5cdFx0cmV0dXJuIGdldEZvcm1EYXRhTGVuZ3RoKHJlcXVlc3RbSU5URVJOQUxTXS5ib3VuZGFyeSk7XG5cdH1cblxuXHQvLyBCb2R5IGlzIHN0cmVhbVxuXHRyZXR1cm4gbnVsbDtcbn07XG5cbi8qKlxuICogV3JpdGUgYSBCb2R5IHRvIGEgTm9kZS5qcyBXcml0YWJsZVN0cmVhbSAoZS5nLiBodHRwLlJlcXVlc3QpIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge1N0cmVhbS5Xcml0YWJsZX0gZGVzdCBUaGUgc3RyZWFtIHRvIHdyaXRlIHRvLlxuICogQHBhcmFtIG9iai5ib2R5IEJvZHkgb2JqZWN0IGZyb20gdGhlIEJvZHkgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuY29uc3Qgd3JpdGVUb1N0cmVhbSA9IChkZXN0LCB7Ym9keX0pID0+IHtcblx0aWYgKGJvZHkgPT09IG51bGwpIHtcblx0XHQvLyBCb2R5IGlzIG51bGxcblx0XHRkZXN0LmVuZCgpO1xuXHR9IGVsc2UgaWYgKGlzQmxvYihib2R5KSkge1xuXHRcdC8vIEJvZHkgaXMgQmxvYlxuXHRcdGJvZHkuc3RyZWFtKCkucGlwZShkZXN0KTtcblx0fSBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIoYm9keSkpIHtcblx0XHQvLyBCb2R5IGlzIGJ1ZmZlclxuXHRcdGRlc3Qud3JpdGUoYm9keSk7XG5cdFx0ZGVzdC5lbmQoKTtcblx0fSBlbHNlIHtcblx0XHQvLyBCb2R5IGlzIHN0cmVhbVxuXHRcdGJvZHkucGlwZShkZXN0KTtcblx0fVxufTtcblxuLyoqXG4gKiBIZWFkZXJzLmpzXG4gKlxuICogSGVhZGVycyBjbGFzcyBvZmZlcnMgY29udmVuaWVudCBoZWxwZXJzXG4gKi9cblxuY29uc3QgdmFsaWRhdGVIZWFkZXJOYW1lID0gdHlwZW9mIGh0dHAudmFsaWRhdGVIZWFkZXJOYW1lID09PSAnZnVuY3Rpb24nID9cblx0aHR0cC52YWxpZGF0ZUhlYWRlck5hbWUgOlxuXHRuYW1lID0+IHtcblx0XHRpZiAoIS9eW1xcXmBcXC1cXHchIyQlJicqKy58fl0rJC8udGVzdChuYW1lKSkge1xuXHRcdFx0Y29uc3QgZXJyID0gbmV3IFR5cGVFcnJvcihgSGVhZGVyIG5hbWUgbXVzdCBiZSBhIHZhbGlkIEhUVFAgdG9rZW4gWyR7bmFtZX1dYCk7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXJyLCAnY29kZScsIHt2YWx1ZTogJ0VSUl9JTlZBTElEX0hUVFBfVE9LRU4nfSk7XG5cdFx0XHR0aHJvdyBlcnI7XG5cdFx0fVxuXHR9O1xuXG5jb25zdCB2YWxpZGF0ZUhlYWRlclZhbHVlID0gdHlwZW9mIGh0dHAudmFsaWRhdGVIZWFkZXJWYWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/XG5cdGh0dHAudmFsaWRhdGVIZWFkZXJWYWx1ZSA6XG5cdChuYW1lLCB2YWx1ZSkgPT4ge1xuXHRcdGlmICgvW15cXHRcXHUwMDIwLVxcdTAwN0VcXHUwMDgwLVxcdTAwRkZdLy50ZXN0KHZhbHVlKSkge1xuXHRcdFx0Y29uc3QgZXJyID0gbmV3IFR5cGVFcnJvcihgSW52YWxpZCBjaGFyYWN0ZXIgaW4gaGVhZGVyIGNvbnRlbnQgW1wiJHtuYW1lfVwiXWApO1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGVyciwgJ2NvZGUnLCB7dmFsdWU6ICdFUlJfSU5WQUxJRF9DSEFSJ30pO1xuXHRcdFx0dGhyb3cgZXJyO1xuXHRcdH1cblx0fTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7SGVhZGVycyB8IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCBJdGVyYWJsZTxyZWFkb25seSBbc3RyaW5nLCBzdHJpbmddPiB8IEl0ZXJhYmxlPEl0ZXJhYmxlPHN0cmluZz4+fSBIZWFkZXJzSW5pdFxuICovXG5cbi8qKlxuICogVGhpcyBGZXRjaCBBUEkgaW50ZXJmYWNlIGFsbG93cyB5b3UgdG8gcGVyZm9ybSB2YXJpb3VzIGFjdGlvbnMgb24gSFRUUCByZXF1ZXN0IGFuZCByZXNwb25zZSBoZWFkZXJzLlxuICogVGhlc2UgYWN0aW9ucyBpbmNsdWRlIHJldHJpZXZpbmcsIHNldHRpbmcsIGFkZGluZyB0bywgYW5kIHJlbW92aW5nLlxuICogQSBIZWFkZXJzIG9iamVjdCBoYXMgYW4gYXNzb2NpYXRlZCBoZWFkZXIgbGlzdCwgd2hpY2ggaXMgaW5pdGlhbGx5IGVtcHR5IGFuZCBjb25zaXN0cyBvZiB6ZXJvIG9yIG1vcmUgbmFtZSBhbmQgdmFsdWUgcGFpcnMuXG4gKiBZb3UgY2FuIGFkZCB0byB0aGlzIHVzaW5nIG1ldGhvZHMgbGlrZSBhcHBlbmQoKSAoc2VlIEV4YW1wbGVzLilcbiAqIEluIGFsbCBtZXRob2RzIG9mIHRoaXMgaW50ZXJmYWNlLCBoZWFkZXIgbmFtZXMgYXJlIG1hdGNoZWQgYnkgY2FzZS1pbnNlbnNpdGl2ZSBieXRlIHNlcXVlbmNlLlxuICpcbiAqL1xuY2xhc3MgSGVhZGVycyBleHRlbmRzIFVSTFNlYXJjaFBhcmFtcyB7XG5cdC8qKlxuXHQgKiBIZWFkZXJzIGNsYXNzXG5cdCAqXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0ge0hlYWRlcnNJbml0fSBbaW5pdF0gLSBSZXNwb25zZSBoZWFkZXJzXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihpbml0KSB7XG5cdFx0Ly8gVmFsaWRhdGUgYW5kIG5vcm1hbGl6ZSBpbml0IG9iamVjdCBpbiBbbmFtZSwgdmFsdWUocyldW11cblx0XHQvKiogQHR5cGUge3N0cmluZ1tdW119ICovXG5cdFx0bGV0IHJlc3VsdCA9IFtdO1xuXHRcdGlmIChpbml0IGluc3RhbmNlb2YgSGVhZGVycykge1xuXHRcdFx0Y29uc3QgcmF3ID0gaW5pdC5yYXcoKTtcblx0XHRcdGZvciAoY29uc3QgW25hbWUsIHZhbHVlc10gb2YgT2JqZWN0LmVudHJpZXMocmF3KSkge1xuXHRcdFx0XHRyZXN1bHQucHVzaCguLi52YWx1ZXMubWFwKHZhbHVlID0+IFtuYW1lLCB2YWx1ZV0pKTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKGluaXQgPT0gbnVsbCkgOyBlbHNlIGlmICh0eXBlb2YgaW5pdCA9PT0gJ29iamVjdCcgJiYgIXV0aWwudHlwZXMuaXNCb3hlZFByaW1pdGl2ZShpbml0KSkge1xuXHRcdFx0Y29uc3QgbWV0aG9kID0gaW5pdFtTeW1ib2wuaXRlcmF0b3JdO1xuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVxLW51bGwsIGVxZXFlcVxuXHRcdFx0aWYgKG1ldGhvZCA9PSBudWxsKSB7XG5cdFx0XHRcdC8vIFJlY29yZDxCeXRlU3RyaW5nLCBCeXRlU3RyaW5nPlxuXHRcdFx0XHRyZXN1bHQucHVzaCguLi5PYmplY3QuZW50cmllcyhpbml0KSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAodHlwZW9mIG1ldGhvZCAhPT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0hlYWRlciBwYWlycyBtdXN0IGJlIGl0ZXJhYmxlJyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTZXF1ZW5jZTxzZXF1ZW5jZTxCeXRlU3RyaW5nPj5cblx0XHRcdFx0Ly8gTm90ZTogcGVyIHNwZWMgd2UgaGF2ZSB0byBmaXJzdCBleGhhdXN0IHRoZSBsaXN0cyB0aGVuIHByb2Nlc3MgdGhlbVxuXHRcdFx0XHRyZXN1bHQgPSBbLi4uaW5pdF1cblx0XHRcdFx0XHQubWFwKHBhaXIgPT4ge1xuXHRcdFx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdFx0XHR0eXBlb2YgcGFpciAhPT0gJ29iamVjdCcgfHwgdXRpbC50eXBlcy5pc0JveGVkUHJpbWl0aXZlKHBhaXIpXG5cdFx0XHRcdFx0XHQpIHtcblx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRWFjaCBoZWFkZXIgcGFpciBtdXN0IGJlIGFuIGl0ZXJhYmxlIG9iamVjdCcpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXR1cm4gWy4uLnBhaXJdO1xuXHRcdFx0XHRcdH0pLm1hcChwYWlyID0+IHtcblx0XHRcdFx0XHRcdGlmIChwYWlyLmxlbmd0aCAhPT0gMikge1xuXHRcdFx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdFYWNoIGhlYWRlciBwYWlyIG11c3QgYmUgYSBuYW1lL3ZhbHVlIHR1cGxlJyk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHJldHVybiBbLi4ucGFpcl07XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZhaWxlZCB0byBjb25zdHJ1Y3QgXFwnSGVhZGVyc1xcJzogVGhlIHByb3ZpZGVkIHZhbHVlIGlzIG5vdCBvZiB0eXBlIFxcJyhzZXF1ZW5jZTxzZXF1ZW5jZTxCeXRlU3RyaW5nPj4gb3IgcmVjb3JkPEJ5dGVTdHJpbmcsIEJ5dGVTdHJpbmc+KScpO1xuXHRcdH1cblxuXHRcdC8vIFZhbGlkYXRlIGFuZCBsb3dlcmNhc2Vcblx0XHRyZXN1bHQgPVxuXHRcdFx0cmVzdWx0Lmxlbmd0aCA+IDAgP1xuXHRcdFx0XHRyZXN1bHQubWFwKChbbmFtZSwgdmFsdWVdKSA9PiB7XG5cdFx0XHRcdFx0dmFsaWRhdGVIZWFkZXJOYW1lKG5hbWUpO1xuXHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyVmFsdWUobmFtZSwgU3RyaW5nKHZhbHVlKSk7XG5cdFx0XHRcdFx0cmV0dXJuIFtTdHJpbmcobmFtZSkudG9Mb3dlckNhc2UoKSwgU3RyaW5nKHZhbHVlKV07XG5cdFx0XHRcdH0pIDpcblx0XHRcdFx0dW5kZWZpbmVkO1xuXG5cdFx0c3VwZXIocmVzdWx0KTtcblxuXHRcdC8vIFJldHVybmluZyBhIFByb3h5IHRoYXQgd2lsbCBsb3dlcmNhc2Uga2V5IG5hbWVzLCB2YWxpZGF0ZSBwYXJhbWV0ZXJzIGFuZCBzb3J0IGtleXNcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc3RydWN0b3ItcmV0dXJuXG5cdFx0cmV0dXJuIG5ldyBQcm94eSh0aGlzLCB7XG5cdFx0XHRnZXQodGFyZ2V0LCBwLCByZWNlaXZlcikge1xuXHRcdFx0XHRzd2l0Y2ggKHApIHtcblx0XHRcdFx0XHRjYXNlICdhcHBlbmQnOlxuXHRcdFx0XHRcdGNhc2UgJ3NldCc6XG5cdFx0XHRcdFx0XHRyZXR1cm4gKG5hbWUsIHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyTmFtZShuYW1lKTtcblx0XHRcdFx0XHRcdFx0dmFsaWRhdGVIZWFkZXJWYWx1ZShuYW1lLCBTdHJpbmcodmFsdWUpKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIFVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGVbcF0uY2FsbChcblx0XHRcdFx0XHRcdFx0XHRyZWNlaXZlcixcblx0XHRcdFx0XHRcdFx0XHRTdHJpbmcobmFtZSkudG9Mb3dlckNhc2UoKSxcblx0XHRcdFx0XHRcdFx0XHRTdHJpbmcodmFsdWUpXG5cdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdFx0Y2FzZSAnZGVsZXRlJzpcblx0XHRcdFx0XHRjYXNlICdoYXMnOlxuXHRcdFx0XHRcdGNhc2UgJ2dldEFsbCc6XG5cdFx0XHRcdFx0XHRyZXR1cm4gbmFtZSA9PiB7XG5cdFx0XHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyTmFtZShuYW1lKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIFVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGVbcF0uY2FsbChcblx0XHRcdFx0XHRcdFx0XHRyZWNlaXZlcixcblx0XHRcdFx0XHRcdFx0XHRTdHJpbmcobmFtZSkudG9Mb3dlckNhc2UoKVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdGNhc2UgJ2tleXMnOlxuXHRcdFx0XHRcdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdFx0XHRcdFx0dGFyZ2V0LnNvcnQoKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBTZXQoVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZS5rZXlzLmNhbGwodGFyZ2V0KSkua2V5cygpO1xuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRyZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwLCByZWNlaXZlcik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8qIGM4IGlnbm9yZSBuZXh0ICovXG5cdFx0fSk7XG5cdH1cblxuXHRnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG5cdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IubmFtZTtcblx0fVxuXG5cdHRvU3RyaW5nKCkge1xuXHRcdHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodGhpcyk7XG5cdH1cblxuXHRnZXQobmFtZSkge1xuXHRcdGNvbnN0IHZhbHVlcyA9IHRoaXMuZ2V0QWxsKG5hbWUpO1xuXHRcdGlmICh2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cblx0XHRsZXQgdmFsdWUgPSB2YWx1ZXMuam9pbignLCAnKTtcblx0XHRpZiAoL15jb250ZW50LWVuY29kaW5nJC9pLnRlc3QobmFtZSkpIHtcblx0XHRcdHZhbHVlID0gdmFsdWUudG9Mb3dlckNhc2UoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdmFsdWU7XG5cdH1cblxuXHRmb3JFYWNoKGNhbGxiYWNrKSB7XG5cdFx0Zm9yIChjb25zdCBuYW1lIG9mIHRoaXMua2V5cygpKSB7XG5cdFx0XHRjYWxsYmFjayh0aGlzLmdldChuYW1lKSwgbmFtZSk7XG5cdFx0fVxuXHR9XG5cblx0KiB2YWx1ZXMoKSB7XG5cdFx0Zm9yIChjb25zdCBuYW1lIG9mIHRoaXMua2V5cygpKSB7XG5cdFx0XHR5aWVsZCB0aGlzLmdldChuYW1lKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQHR5cGUgeygpID0+IEl0ZXJhYmxlSXRlcmF0b3I8W3N0cmluZywgc3RyaW5nXT59XG5cdCAqL1xuXHQqIGVudHJpZXMoKSB7XG5cdFx0Zm9yIChjb25zdCBuYW1lIG9mIHRoaXMua2V5cygpKSB7XG5cdFx0XHR5aWVsZCBbbmFtZSwgdGhpcy5nZXQobmFtZSldO1xuXHRcdH1cblx0fVxuXG5cdFtTeW1ib2wuaXRlcmF0b3JdKCkge1xuXHRcdHJldHVybiB0aGlzLmVudHJpZXMoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBOb2RlLWZldGNoIG5vbi1zcGVjIG1ldGhvZFxuXHQgKiByZXR1cm5pbmcgYWxsIGhlYWRlcnMgYW5kIHRoZWlyIHZhbHVlcyBhcyBhcnJheVxuXHQgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgc3RyaW5nW10+fVxuXHQgKi9cblx0cmF3KCkge1xuXHRcdHJldHVybiBbLi4udGhpcy5rZXlzKCldLnJlZHVjZSgocmVzdWx0LCBrZXkpID0+IHtcblx0XHRcdHJlc3VsdFtrZXldID0gdGhpcy5nZXRBbGwoa2V5KTtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fSwge30pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEZvciBiZXR0ZXIgY29uc29sZS5sb2coaGVhZGVycykgYW5kIGFsc28gdG8gY29udmVydCBIZWFkZXJzIGludG8gTm9kZS5qcyBSZXF1ZXN0IGNvbXBhdGlibGUgZm9ybWF0XG5cdCAqL1xuXHRbU3ltYm9sLmZvcignbm9kZWpzLnV0aWwuaW5zcGVjdC5jdXN0b20nKV0oKSB7XG5cdFx0cmV0dXJuIFsuLi50aGlzLmtleXMoKV0ucmVkdWNlKChyZXN1bHQsIGtleSkgPT4ge1xuXHRcdFx0Y29uc3QgdmFsdWVzID0gdGhpcy5nZXRBbGwoa2V5KTtcblx0XHRcdC8vIEh0dHAucmVxdWVzdCgpIG9ubHkgc3VwcG9ydHMgc3RyaW5nIGFzIEhvc3QgaGVhZGVyLlxuXHRcdFx0Ly8gVGhpcyBoYWNrIG1ha2VzIHNwZWNpZnlpbmcgY3VzdG9tIEhvc3QgaGVhZGVyIHBvc3NpYmxlLlxuXHRcdFx0aWYgKGtleSA9PT0gJ2hvc3QnKSB7XG5cdFx0XHRcdHJlc3VsdFtrZXldID0gdmFsdWVzWzBdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmVzdWx0W2tleV0gPSB2YWx1ZXMubGVuZ3RoID4gMSA/IHZhbHVlcyA6IHZhbHVlc1swXTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9LCB7fSk7XG5cdH1cbn1cblxuLyoqXG4gKiBSZS1zaGFwaW5nIG9iamVjdCBmb3IgV2ViIElETCB0ZXN0c1xuICogT25seSBuZWVkIHRvIGRvIGl0IGZvciBvdmVycmlkZGVuIG1ldGhvZHNcbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoXG5cdEhlYWRlcnMucHJvdG90eXBlLFxuXHRbJ2dldCcsICdlbnRyaWVzJywgJ2ZvckVhY2gnLCAndmFsdWVzJ10ucmVkdWNlKChyZXN1bHQsIHByb3BlcnR5KSA9PiB7XG5cdFx0cmVzdWx0W3Byb3BlcnR5XSA9IHtlbnVtZXJhYmxlOiB0cnVlfTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9LCB7fSlcbik7XG5cbi8qKlxuICogQ3JlYXRlIGEgSGVhZGVycyBvYmplY3QgZnJvbSBhbiBodHRwLkluY29taW5nTWVzc2FnZS5yYXdIZWFkZXJzLCBpZ25vcmluZyB0aG9zZSB0aGF0IGRvXG4gKiBub3QgY29uZm9ybSB0byBIVFRQIGdyYW1tYXIgcHJvZHVjdGlvbnMuXG4gKiBAcGFyYW0ge2ltcG9ydCgnaHR0cCcpLkluY29taW5nTWVzc2FnZVsncmF3SGVhZGVycyddfSBoZWFkZXJzXG4gKi9cbmZ1bmN0aW9uIGZyb21SYXdIZWFkZXJzKGhlYWRlcnMgPSBbXSkge1xuXHRyZXR1cm4gbmV3IEhlYWRlcnMoXG5cdFx0aGVhZGVyc1xuXHRcdFx0Ly8gU3BsaXQgaW50byBwYWlyc1xuXHRcdFx0LnJlZHVjZSgocmVzdWx0LCB2YWx1ZSwgaW5kZXgsIGFycmF5KSA9PiB7XG5cdFx0XHRcdGlmIChpbmRleCAlIDIgPT09IDApIHtcblx0XHRcdFx0XHRyZXN1bHQucHVzaChhcnJheS5zbGljZShpbmRleCwgaW5kZXggKyAyKSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0fSwgW10pXG5cdFx0XHQuZmlsdGVyKChbbmFtZSwgdmFsdWVdKSA9PiB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0dmFsaWRhdGVIZWFkZXJOYW1lKG5hbWUpO1xuXHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyVmFsdWUobmFtZSwgU3RyaW5nKHZhbHVlKSk7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH0gY2F0Y2gge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblxuXHQpO1xufVxuXG5jb25zdCByZWRpcmVjdFN0YXR1cyA9IG5ldyBTZXQoWzMwMSwgMzAyLCAzMDMsIDMwNywgMzA4XSk7XG5cbi8qKlxuICogUmVkaXJlY3QgY29kZSBtYXRjaGluZ1xuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBjb2RlIC0gU3RhdHVzIGNvZGVcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGlzUmVkaXJlY3QgPSBjb2RlID0+IHtcblx0cmV0dXJuIHJlZGlyZWN0U3RhdHVzLmhhcyhjb2RlKTtcbn07XG5cbi8qKlxuICogUmVzcG9uc2UuanNcbiAqXG4gKiBSZXNwb25zZSBjbGFzcyBwcm92aWRlcyBjb250ZW50IGRlY29kaW5nXG4gKi9cblxuY29uc3QgSU5URVJOQUxTJDEgPSBTeW1ib2woJ1Jlc3BvbnNlIGludGVybmFscycpO1xuXG4vKipcbiAqIFJlc3BvbnNlIGNsYXNzXG4gKlxuICogQHBhcmFtICAgU3RyZWFtICBib2R5ICBSZWFkYWJsZSBzdHJlYW1cbiAqIEBwYXJhbSAgIE9iamVjdCAgb3B0cyAgUmVzcG9uc2Ugb3B0aW9uc1xuICogQHJldHVybiAgVm9pZFxuICovXG5jbGFzcyBSZXNwb25zZSBleHRlbmRzIEJvZHkge1xuXHRjb25zdHJ1Y3Rvcihib2R5ID0gbnVsbCwgb3B0aW9ucyA9IHt9KSB7XG5cdFx0c3VwZXIoYm9keSwgb3B0aW9ucyk7XG5cblx0XHRjb25zdCBzdGF0dXMgPSBvcHRpb25zLnN0YXR1cyB8fCAyMDA7XG5cdFx0Y29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKG9wdGlvbnMuaGVhZGVycyk7XG5cblx0XHRpZiAoYm9keSAhPT0gbnVsbCAmJiAhaGVhZGVycy5oYXMoJ0NvbnRlbnQtVHlwZScpKSB7XG5cdFx0XHRjb25zdCBjb250ZW50VHlwZSA9IGV4dHJhY3RDb250ZW50VHlwZShib2R5KTtcblx0XHRcdGlmIChjb250ZW50VHlwZSkge1xuXHRcdFx0XHRoZWFkZXJzLmFwcGVuZCgnQ29udGVudC1UeXBlJywgY29udGVudFR5cGUpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXNbSU5URVJOQUxTJDFdID0ge1xuXHRcdFx0dXJsOiBvcHRpb25zLnVybCxcblx0XHRcdHN0YXR1cyxcblx0XHRcdHN0YXR1c1RleHQ6IG9wdGlvbnMuc3RhdHVzVGV4dCB8fCAnJyxcblx0XHRcdGhlYWRlcnMsXG5cdFx0XHRjb3VudGVyOiBvcHRpb25zLmNvdW50ZXIsXG5cdFx0XHRoaWdoV2F0ZXJNYXJrOiBvcHRpb25zLmhpZ2hXYXRlck1hcmtcblx0XHR9O1xuXHR9XG5cblx0Z2V0IHVybCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0udXJsIHx8ICcnO1xuXHR9XG5cblx0Z2V0IHN0YXR1cygpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uc3RhdHVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbnZlbmllbmNlIHByb3BlcnR5IHJlcHJlc2VudGluZyBpZiB0aGUgcmVxdWVzdCBlbmRlZCBub3JtYWxseVxuXHQgKi9cblx0Z2V0IG9rKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQxXS5zdGF0dXMgPj0gMjAwICYmIHRoaXNbSU5URVJOQUxTJDFdLnN0YXR1cyA8IDMwMDtcblx0fVxuXG5cdGdldCByZWRpcmVjdGVkKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQxXS5jb3VudGVyID4gMDtcblx0fVxuXG5cdGdldCBzdGF0dXNUZXh0KCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQxXS5zdGF0dXNUZXh0O1xuXHR9XG5cblx0Z2V0IGhlYWRlcnMoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLmhlYWRlcnM7XG5cdH1cblxuXHRnZXQgaGlnaFdhdGVyTWFyaygpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uaGlnaFdhdGVyTWFyaztcblx0fVxuXG5cdC8qKlxuXHQgKiBDbG9uZSB0aGlzIHJlc3BvbnNlXG5cdCAqXG5cdCAqIEByZXR1cm4gIFJlc3BvbnNlXG5cdCAqL1xuXHRjbG9uZSgpIHtcblx0XHRyZXR1cm4gbmV3IFJlc3BvbnNlKGNsb25lKHRoaXMsIHRoaXMuaGlnaFdhdGVyTWFyayksIHtcblx0XHRcdHVybDogdGhpcy51cmwsXG5cdFx0XHRzdGF0dXM6IHRoaXMuc3RhdHVzLFxuXHRcdFx0c3RhdHVzVGV4dDogdGhpcy5zdGF0dXNUZXh0LFxuXHRcdFx0aGVhZGVyczogdGhpcy5oZWFkZXJzLFxuXHRcdFx0b2s6IHRoaXMub2ssXG5cdFx0XHRyZWRpcmVjdGVkOiB0aGlzLnJlZGlyZWN0ZWQsXG5cdFx0XHRzaXplOiB0aGlzLnNpemVcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdXJsICAgIFRoZSBVUkwgdGhhdCB0aGUgbmV3IHJlc3BvbnNlIGlzIHRvIG9yaWdpbmF0ZSBmcm9tLlxuXHQgKiBAcGFyYW0ge251bWJlcn0gc3RhdHVzIEFuIG9wdGlvbmFsIHN0YXR1cyBjb2RlIGZvciB0aGUgcmVzcG9uc2UgKGUuZy4sIDMwMi4pXG5cdCAqIEByZXR1cm5zIHtSZXNwb25zZX0gICAgQSBSZXNwb25zZSBvYmplY3QuXG5cdCAqL1xuXHRzdGF0aWMgcmVkaXJlY3QodXJsLCBzdGF0dXMgPSAzMDIpIHtcblx0XHRpZiAoIWlzUmVkaXJlY3Qoc3RhdHVzKSkge1xuXHRcdFx0dGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ZhaWxlZCB0byBleGVjdXRlIFwicmVkaXJlY3RcIiBvbiBcInJlc3BvbnNlXCI6IEludmFsaWQgc3RhdHVzIGNvZGUnKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbmV3IFJlc3BvbnNlKG51bGwsIHtcblx0XHRcdGhlYWRlcnM6IHtcblx0XHRcdFx0bG9jYXRpb246IG5ldyBVUkwodXJsKS50b1N0cmluZygpXG5cdFx0XHR9LFxuXHRcdFx0c3RhdHVzXG5cdFx0fSk7XG5cdH1cblxuXHRnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG5cdFx0cmV0dXJuICdSZXNwb25zZSc7XG5cdH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoUmVzcG9uc2UucHJvdG90eXBlLCB7XG5cdHVybDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRzdGF0dXM6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0b2s6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0cmVkaXJlY3RlZDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRzdGF0dXNUZXh0OiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdGhlYWRlcnM6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0Y2xvbmU6IHtlbnVtZXJhYmxlOiB0cnVlfVxufSk7XG5cbmNvbnN0IGdldFNlYXJjaCA9IHBhcnNlZFVSTCA9PiB7XG5cdGlmIChwYXJzZWRVUkwuc2VhcmNoKSB7XG5cdFx0cmV0dXJuIHBhcnNlZFVSTC5zZWFyY2g7XG5cdH1cblxuXHRjb25zdCBsYXN0T2Zmc2V0ID0gcGFyc2VkVVJMLmhyZWYubGVuZ3RoIC0gMTtcblx0Y29uc3QgaGFzaCA9IHBhcnNlZFVSTC5oYXNoIHx8IChwYXJzZWRVUkwuaHJlZltsYXN0T2Zmc2V0XSA9PT0gJyMnID8gJyMnIDogJycpO1xuXHRyZXR1cm4gcGFyc2VkVVJMLmhyZWZbbGFzdE9mZnNldCAtIGhhc2gubGVuZ3RoXSA9PT0gJz8nID8gJz8nIDogJyc7XG59O1xuXG5jb25zdCBJTlRFUk5BTFMkMiA9IFN5bWJvbCgnUmVxdWVzdCBpbnRlcm5hbHMnKTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhbiBpbnN0YW5jZSBvZiBSZXF1ZXN0LlxuICpcbiAqIEBwYXJhbSAgeyp9IG9ialxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuY29uc3QgaXNSZXF1ZXN0ID0gb2JqZWN0ID0+IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdHR5cGVvZiBvYmplY3RbSU5URVJOQUxTJDJdID09PSAnb2JqZWN0J1xuXHQpO1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0IGNsYXNzXG4gKlxuICogQHBhcmFtICAgTWl4ZWQgICBpbnB1dCAgVXJsIG9yIFJlcXVlc3QgaW5zdGFuY2VcbiAqIEBwYXJhbSAgIE9iamVjdCAgaW5pdCAgIEN1c3RvbSBvcHRpb25zXG4gKiBAcmV0dXJuICBWb2lkXG4gKi9cbmNsYXNzIFJlcXVlc3QgZXh0ZW5kcyBCb2R5IHtcblx0Y29uc3RydWN0b3IoaW5wdXQsIGluaXQgPSB7fSkge1xuXHRcdGxldCBwYXJzZWRVUkw7XG5cblx0XHQvLyBOb3JtYWxpemUgaW5wdXQgYW5kIGZvcmNlIFVSTCB0byBiZSBlbmNvZGVkIGFzIFVURi04IChodHRwczovL2dpdGh1Yi5jb20vbm9kZS1mZXRjaC9ub2RlLWZldGNoL2lzc3Vlcy8yNDUpXG5cdFx0aWYgKGlzUmVxdWVzdChpbnB1dCkpIHtcblx0XHRcdHBhcnNlZFVSTCA9IG5ldyBVUkwoaW5wdXQudXJsKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cGFyc2VkVVJMID0gbmV3IFVSTChpbnB1dCk7XG5cdFx0XHRpbnB1dCA9IHt9O1xuXHRcdH1cblxuXHRcdGxldCBtZXRob2QgPSBpbml0Lm1ldGhvZCB8fCBpbnB1dC5tZXRob2QgfHwgJ0dFVCc7XG5cdFx0bWV0aG9kID0gbWV0aG9kLnRvVXBwZXJDYXNlKCk7XG5cblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXEtbnVsbCwgZXFlcWVxXG5cdFx0aWYgKCgoaW5pdC5ib2R5ICE9IG51bGwgfHwgaXNSZXF1ZXN0KGlucHV0KSkgJiYgaW5wdXQuYm9keSAhPT0gbnVsbCkgJiZcblx0XHRcdChtZXRob2QgPT09ICdHRVQnIHx8IG1ldGhvZCA9PT0gJ0hFQUQnKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignUmVxdWVzdCB3aXRoIEdFVC9IRUFEIG1ldGhvZCBjYW5ub3QgaGF2ZSBib2R5Jyk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgaW5wdXRCb2R5ID0gaW5pdC5ib2R5ID9cblx0XHRcdGluaXQuYm9keSA6XG5cdFx0XHQoaXNSZXF1ZXN0KGlucHV0KSAmJiBpbnB1dC5ib2R5ICE9PSBudWxsID9cblx0XHRcdFx0Y2xvbmUoaW5wdXQpIDpcblx0XHRcdFx0bnVsbCk7XG5cblx0XHRzdXBlcihpbnB1dEJvZHksIHtcblx0XHRcdHNpemU6IGluaXQuc2l6ZSB8fCBpbnB1dC5zaXplIHx8IDBcblx0XHR9KTtcblxuXHRcdGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyhpbml0LmhlYWRlcnMgfHwgaW5wdXQuaGVhZGVycyB8fCB7fSk7XG5cblx0XHRpZiAoaW5wdXRCb2R5ICE9PSBudWxsICYmICFoZWFkZXJzLmhhcygnQ29udGVudC1UeXBlJykpIHtcblx0XHRcdGNvbnN0IGNvbnRlbnRUeXBlID0gZXh0cmFjdENvbnRlbnRUeXBlKGlucHV0Qm9keSwgdGhpcyk7XG5cdFx0XHRpZiAoY29udGVudFR5cGUpIHtcblx0XHRcdFx0aGVhZGVycy5hcHBlbmQoJ0NvbnRlbnQtVHlwZScsIGNvbnRlbnRUeXBlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRsZXQgc2lnbmFsID0gaXNSZXF1ZXN0KGlucHV0KSA/XG5cdFx0XHRpbnB1dC5zaWduYWwgOlxuXHRcdFx0bnVsbDtcblx0XHRpZiAoJ3NpZ25hbCcgaW4gaW5pdCkge1xuXHRcdFx0c2lnbmFsID0gaW5pdC5zaWduYWw7XG5cdFx0fVxuXG5cdFx0aWYgKHNpZ25hbCAhPT0gbnVsbCAmJiAhaXNBYm9ydFNpZ25hbChzaWduYWwpKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBzaWduYWwgdG8gYmUgYW4gaW5zdGFuY2VvZiBBYm9ydFNpZ25hbCcpO1xuXHRcdH1cblxuXHRcdHRoaXNbSU5URVJOQUxTJDJdID0ge1xuXHRcdFx0bWV0aG9kLFxuXHRcdFx0cmVkaXJlY3Q6IGluaXQucmVkaXJlY3QgfHwgaW5wdXQucmVkaXJlY3QgfHwgJ2ZvbGxvdycsXG5cdFx0XHRoZWFkZXJzLFxuXHRcdFx0cGFyc2VkVVJMLFxuXHRcdFx0c2lnbmFsXG5cdFx0fTtcblxuXHRcdC8vIE5vZGUtZmV0Y2gtb25seSBvcHRpb25zXG5cdFx0dGhpcy5mb2xsb3cgPSBpbml0LmZvbGxvdyA9PT0gdW5kZWZpbmVkID8gKGlucHV0LmZvbGxvdyA9PT0gdW5kZWZpbmVkID8gMjAgOiBpbnB1dC5mb2xsb3cpIDogaW5pdC5mb2xsb3c7XG5cdFx0dGhpcy5jb21wcmVzcyA9IGluaXQuY29tcHJlc3MgPT09IHVuZGVmaW5lZCA/IChpbnB1dC5jb21wcmVzcyA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IGlucHV0LmNvbXByZXNzKSA6IGluaXQuY29tcHJlc3M7XG5cdFx0dGhpcy5jb3VudGVyID0gaW5pdC5jb3VudGVyIHx8IGlucHV0LmNvdW50ZXIgfHwgMDtcblx0XHR0aGlzLmFnZW50ID0gaW5pdC5hZ2VudCB8fCBpbnB1dC5hZ2VudDtcblx0XHR0aGlzLmhpZ2hXYXRlck1hcmsgPSBpbml0LmhpZ2hXYXRlck1hcmsgfHwgaW5wdXQuaGlnaFdhdGVyTWFyayB8fCAxNjM4NDtcblx0XHR0aGlzLmluc2VjdXJlSFRUUFBhcnNlciA9IGluaXQuaW5zZWN1cmVIVFRQUGFyc2VyIHx8IGlucHV0Lmluc2VjdXJlSFRUUFBhcnNlciB8fCBmYWxzZTtcblx0fVxuXG5cdGdldCBtZXRob2QoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDJdLm1ldGhvZDtcblx0fVxuXG5cdGdldCB1cmwoKSB7XG5cdFx0cmV0dXJuIHVybC5mb3JtYXQodGhpc1tJTlRFUk5BTFMkMl0ucGFyc2VkVVJMKTtcblx0fVxuXG5cdGdldCBoZWFkZXJzKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQyXS5oZWFkZXJzO1xuXHR9XG5cblx0Z2V0IHJlZGlyZWN0KCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQyXS5yZWRpcmVjdDtcblx0fVxuXG5cdGdldCBzaWduYWwoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDJdLnNpZ25hbDtcblx0fVxuXG5cdC8qKlxuXHQgKiBDbG9uZSB0aGlzIHJlcXVlc3Rcblx0ICpcblx0ICogQHJldHVybiAgUmVxdWVzdFxuXHQgKi9cblx0Y2xvbmUoKSB7XG5cdFx0cmV0dXJuIG5ldyBSZXF1ZXN0KHRoaXMpO1xuXHR9XG5cblx0Z2V0IFtTeW1ib2wudG9TdHJpbmdUYWddKCkge1xuXHRcdHJldHVybiAnUmVxdWVzdCc7XG5cdH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoUmVxdWVzdC5wcm90b3R5cGUsIHtcblx0bWV0aG9kOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHVybDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRoZWFkZXJzOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHJlZGlyZWN0OiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdGNsb25lOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHNpZ25hbDoge2VudW1lcmFibGU6IHRydWV9XG59KTtcblxuLyoqXG4gKiBDb252ZXJ0IGEgUmVxdWVzdCB0byBOb2RlLmpzIGh0dHAgcmVxdWVzdCBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSAgIFJlcXVlc3QgIEEgUmVxdWVzdCBpbnN0YW5jZVxuICogQHJldHVybiAgT2JqZWN0ICAgVGhlIG9wdGlvbnMgb2JqZWN0IHRvIGJlIHBhc3NlZCB0byBodHRwLnJlcXVlc3RcbiAqL1xuY29uc3QgZ2V0Tm9kZVJlcXVlc3RPcHRpb25zID0gcmVxdWVzdCA9PiB7XG5cdGNvbnN0IHtwYXJzZWRVUkx9ID0gcmVxdWVzdFtJTlRFUk5BTFMkMl07XG5cdGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyhyZXF1ZXN0W0lOVEVSTkFMUyQyXS5oZWFkZXJzKTtcblxuXHQvLyBGZXRjaCBzdGVwIDEuM1xuXHRpZiAoIWhlYWRlcnMuaGFzKCdBY2NlcHQnKSkge1xuXHRcdGhlYWRlcnMuc2V0KCdBY2NlcHQnLCAnKi8qJyk7XG5cdH1cblxuXHQvLyBIVFRQLW5ldHdvcmstb3ItY2FjaGUgZmV0Y2ggc3RlcHMgMi40LTIuN1xuXHRsZXQgY29udGVudExlbmd0aFZhbHVlID0gbnVsbDtcblx0aWYgKHJlcXVlc3QuYm9keSA9PT0gbnVsbCAmJiAvXihwb3N0fHB1dCkkL2kudGVzdChyZXF1ZXN0Lm1ldGhvZCkpIHtcblx0XHRjb250ZW50TGVuZ3RoVmFsdWUgPSAnMCc7XG5cdH1cblxuXHRpZiAocmVxdWVzdC5ib2R5ICE9PSBudWxsKSB7XG5cdFx0Y29uc3QgdG90YWxCeXRlcyA9IGdldFRvdGFsQnl0ZXMocmVxdWVzdCk7XG5cdFx0Ly8gU2V0IENvbnRlbnQtTGVuZ3RoIGlmIHRvdGFsQnl0ZXMgaXMgYSBudW1iZXIgKHRoYXQgaXMgbm90IE5hTilcblx0XHRpZiAodHlwZW9mIHRvdGFsQnl0ZXMgPT09ICdudW1iZXInICYmICFOdW1iZXIuaXNOYU4odG90YWxCeXRlcykpIHtcblx0XHRcdGNvbnRlbnRMZW5ndGhWYWx1ZSA9IFN0cmluZyh0b3RhbEJ5dGVzKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoY29udGVudExlbmd0aFZhbHVlKSB7XG5cdFx0aGVhZGVycy5zZXQoJ0NvbnRlbnQtTGVuZ3RoJywgY29udGVudExlbmd0aFZhbHVlKTtcblx0fVxuXG5cdC8vIEhUVFAtbmV0d29yay1vci1jYWNoZSBmZXRjaCBzdGVwIDIuMTFcblx0aWYgKCFoZWFkZXJzLmhhcygnVXNlci1BZ2VudCcpKSB7XG5cdFx0aGVhZGVycy5zZXQoJ1VzZXItQWdlbnQnLCAnbm9kZS1mZXRjaCcpO1xuXHR9XG5cblx0Ly8gSFRUUC1uZXR3b3JrLW9yLWNhY2hlIGZldGNoIHN0ZXAgMi4xNVxuXHRpZiAocmVxdWVzdC5jb21wcmVzcyAmJiAhaGVhZGVycy5oYXMoJ0FjY2VwdC1FbmNvZGluZycpKSB7XG5cdFx0aGVhZGVycy5zZXQoJ0FjY2VwdC1FbmNvZGluZycsICdnemlwLGRlZmxhdGUsYnInKTtcblx0fVxuXG5cdGxldCB7YWdlbnR9ID0gcmVxdWVzdDtcblx0aWYgKHR5cGVvZiBhZ2VudCA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdGFnZW50ID0gYWdlbnQocGFyc2VkVVJMKTtcblx0fVxuXG5cdGlmICghaGVhZGVycy5oYXMoJ0Nvbm5lY3Rpb24nKSAmJiAhYWdlbnQpIHtcblx0XHRoZWFkZXJzLnNldCgnQ29ubmVjdGlvbicsICdjbG9zZScpO1xuXHR9XG5cblx0Ly8gSFRUUC1uZXR3b3JrIGZldGNoIHN0ZXAgNC4yXG5cdC8vIGNodW5rZWQgZW5jb2RpbmcgaXMgaGFuZGxlZCBieSBOb2RlLmpzXG5cblx0Y29uc3Qgc2VhcmNoID0gZ2V0U2VhcmNoKHBhcnNlZFVSTCk7XG5cblx0Ly8gTWFudWFsbHkgc3ByZWFkIHRoZSBVUkwgb2JqZWN0IGluc3RlYWQgb2Ygc3ByZWFkIHN5bnRheFxuXHRjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcblx0XHRwYXRoOiBwYXJzZWRVUkwucGF0aG5hbWUgKyBzZWFyY2gsXG5cdFx0cGF0aG5hbWU6IHBhcnNlZFVSTC5wYXRobmFtZSxcblx0XHRob3N0bmFtZTogcGFyc2VkVVJMLmhvc3RuYW1lLFxuXHRcdHByb3RvY29sOiBwYXJzZWRVUkwucHJvdG9jb2wsXG5cdFx0cG9ydDogcGFyc2VkVVJMLnBvcnQsXG5cdFx0aGFzaDogcGFyc2VkVVJMLmhhc2gsXG5cdFx0c2VhcmNoOiBwYXJzZWRVUkwuc2VhcmNoLFxuXHRcdHF1ZXJ5OiBwYXJzZWRVUkwucXVlcnksXG5cdFx0aHJlZjogcGFyc2VkVVJMLmhyZWYsXG5cdFx0bWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcblx0XHRoZWFkZXJzOiBoZWFkZXJzW1N5bWJvbC5mb3IoJ25vZGVqcy51dGlsLmluc3BlY3QuY3VzdG9tJyldKCksXG5cdFx0aW5zZWN1cmVIVFRQUGFyc2VyOiByZXF1ZXN0Lmluc2VjdXJlSFRUUFBhcnNlcixcblx0XHRhZ2VudFxuXHR9O1xuXG5cdHJldHVybiByZXF1ZXN0T3B0aW9ucztcbn07XG5cbi8qKlxuICogQWJvcnRFcnJvciBpbnRlcmZhY2UgZm9yIGNhbmNlbGxlZCByZXF1ZXN0c1xuICovXG5jbGFzcyBBYm9ydEVycm9yIGV4dGVuZHMgRmV0Y2hCYXNlRXJyb3Ige1xuXHRjb25zdHJ1Y3RvcihtZXNzYWdlLCB0eXBlID0gJ2Fib3J0ZWQnKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgdHlwZSk7XG5cdH1cbn1cblxuLyoqXG4gKiBJbmRleC5qc1xuICpcbiAqIGEgcmVxdWVzdCBBUEkgY29tcGF0aWJsZSB3aXRoIHdpbmRvdy5mZXRjaFxuICpcbiAqIEFsbCBzcGVjIGFsZ29yaXRobSBzdGVwIG51bWJlcnMgYXJlIGJhc2VkIG9uIGh0dHBzOi8vZmV0Y2guc3BlYy53aGF0d2cub3JnL2NvbW1pdC1zbmFwc2hvdHMvYWU3MTY4MjJjYjNhNjE4NDMyMjZjZDA5MGVlZmM2NTg5NDQ2YzFkMi8uXG4gKi9cblxuY29uc3Qgc3VwcG9ydGVkU2NoZW1hcyA9IG5ldyBTZXQoWydkYXRhOicsICdodHRwOicsICdodHRwczonXSk7XG5cbi8qKlxuICogRmV0Y2ggZnVuY3Rpb25cbiAqXG4gKiBAcGFyYW0gICB7c3RyaW5nIHwgVVJMIHwgaW1wb3J0KCcuL3JlcXVlc3QnKS5kZWZhdWx0fSB1cmwgLSBBYnNvbHV0ZSB1cmwgb3IgUmVxdWVzdCBpbnN0YW5jZVxuICogQHBhcmFtICAgeyp9IFtvcHRpb25zX10gLSBGZXRjaCBvcHRpb25zXG4gKiBAcmV0dXJuICB7UHJvbWlzZTxpbXBvcnQoJy4vcmVzcG9uc2UnKS5kZWZhdWx0Pn1cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZmV0Y2godXJsLCBvcHRpb25zXykge1xuXHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdC8vIEJ1aWxkIHJlcXVlc3Qgb2JqZWN0XG5cdFx0Y29uc3QgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KHVybCwgb3B0aW9uc18pO1xuXHRcdGNvbnN0IG9wdGlvbnMgPSBnZXROb2RlUmVxdWVzdE9wdGlvbnMocmVxdWVzdCk7XG5cdFx0aWYgKCFzdXBwb3J0ZWRTY2hlbWFzLmhhcyhvcHRpb25zLnByb3RvY29sKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihgbm9kZS1mZXRjaCBjYW5ub3QgbG9hZCAke3VybH0uIFVSTCBzY2hlbWUgXCIke29wdGlvbnMucHJvdG9jb2wucmVwbGFjZSgvOiQvLCAnJyl9XCIgaXMgbm90IHN1cHBvcnRlZC5gKTtcblx0XHR9XG5cblx0XHRpZiAob3B0aW9ucy5wcm90b2NvbCA9PT0gJ2RhdGE6Jykge1xuXHRcdFx0Y29uc3QgZGF0YSA9IGRhdGFVcmlUb0J1ZmZlcihyZXF1ZXN0LnVybCk7XG5cdFx0XHRjb25zdCByZXNwb25zZSA9IG5ldyBSZXNwb25zZShkYXRhLCB7aGVhZGVyczogeydDb250ZW50LVR5cGUnOiBkYXRhLnR5cGVGdWxsfX0pO1xuXHRcdFx0cmVzb2x2ZShyZXNwb25zZSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gV3JhcCBodHRwLnJlcXVlc3QgaW50byBmZXRjaFxuXHRcdGNvbnN0IHNlbmQgPSAob3B0aW9ucy5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyBodHRwcyA6IGh0dHApLnJlcXVlc3Q7XG5cdFx0Y29uc3Qge3NpZ25hbH0gPSByZXF1ZXN0O1xuXHRcdGxldCByZXNwb25zZSA9IG51bGw7XG5cblx0XHRjb25zdCBhYm9ydCA9ICgpID0+IHtcblx0XHRcdGNvbnN0IGVycm9yID0gbmV3IEFib3J0RXJyb3IoJ1RoZSBvcGVyYXRpb24gd2FzIGFib3J0ZWQuJyk7XG5cdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0aWYgKHJlcXVlc3QuYm9keSAmJiByZXF1ZXN0LmJvZHkgaW5zdGFuY2VvZiBTdHJlYW0uUmVhZGFibGUpIHtcblx0XHRcdFx0cmVxdWVzdC5ib2R5LmRlc3Ryb3koZXJyb3IpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIXJlc3BvbnNlIHx8ICFyZXNwb25zZS5ib2R5KSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0cmVzcG9uc2UuYm9keS5lbWl0KCdlcnJvcicsIGVycm9yKTtcblx0XHR9O1xuXG5cdFx0aWYgKHNpZ25hbCAmJiBzaWduYWwuYWJvcnRlZCkge1xuXHRcdFx0YWJvcnQoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBhYm9ydEFuZEZpbmFsaXplID0gKCkgPT4ge1xuXHRcdFx0YWJvcnQoKTtcblx0XHRcdGZpbmFsaXplKCk7XG5cdFx0fTtcblxuXHRcdC8vIFNlbmQgcmVxdWVzdFxuXHRcdGNvbnN0IHJlcXVlc3RfID0gc2VuZChvcHRpb25zKTtcblxuXHRcdGlmIChzaWduYWwpIHtcblx0XHRcdHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0QW5kRmluYWxpemUpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGZpbmFsaXplID0gKCkgPT4ge1xuXHRcdFx0cmVxdWVzdF8uYWJvcnQoKTtcblx0XHRcdGlmIChzaWduYWwpIHtcblx0XHRcdFx0c2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnRBbmRGaW5hbGl6ZSk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdHJlcXVlc3RfLm9uKCdlcnJvcicsIGVyciA9PiB7XG5cdFx0XHRyZWplY3QobmV3IEZldGNoRXJyb3IoYHJlcXVlc3QgdG8gJHtyZXF1ZXN0LnVybH0gZmFpbGVkLCByZWFzb246ICR7ZXJyLm1lc3NhZ2V9YCwgJ3N5c3RlbScsIGVycikpO1xuXHRcdFx0ZmluYWxpemUoKTtcblx0XHR9KTtcblxuXHRcdHJlcXVlc3RfLm9uKCdyZXNwb25zZScsIHJlc3BvbnNlXyA9PiB7XG5cdFx0XHRyZXF1ZXN0Xy5zZXRUaW1lb3V0KDApO1xuXHRcdFx0Y29uc3QgaGVhZGVycyA9IGZyb21SYXdIZWFkZXJzKHJlc3BvbnNlXy5yYXdIZWFkZXJzKTtcblxuXHRcdFx0Ly8gSFRUUCBmZXRjaCBzdGVwIDVcblx0XHRcdGlmIChpc1JlZGlyZWN0KHJlc3BvbnNlXy5zdGF0dXNDb2RlKSkge1xuXHRcdFx0XHQvLyBIVFRQIGZldGNoIHN0ZXAgNS4yXG5cdFx0XHRcdGNvbnN0IGxvY2F0aW9uID0gaGVhZGVycy5nZXQoJ0xvY2F0aW9uJyk7XG5cblx0XHRcdFx0Ly8gSFRUUCBmZXRjaCBzdGVwIDUuM1xuXHRcdFx0XHRjb25zdCBsb2NhdGlvblVSTCA9IGxvY2F0aW9uID09PSBudWxsID8gbnVsbCA6IG5ldyBVUkwobG9jYXRpb24sIHJlcXVlc3QudXJsKTtcblxuXHRcdFx0XHQvLyBIVFRQIGZldGNoIHN0ZXAgNS41XG5cdFx0XHRcdHN3aXRjaCAocmVxdWVzdC5yZWRpcmVjdCkge1xuXHRcdFx0XHRcdGNhc2UgJ2Vycm9yJzpcblx0XHRcdFx0XHRcdHJlamVjdChuZXcgRmV0Y2hFcnJvcihgdXJpIHJlcXVlc3RlZCByZXNwb25kcyB3aXRoIGEgcmVkaXJlY3QsIHJlZGlyZWN0IG1vZGUgaXMgc2V0IHRvIGVycm9yOiAke3JlcXVlc3QudXJsfWAsICduby1yZWRpcmVjdCcpKTtcblx0XHRcdFx0XHRcdGZpbmFsaXplKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0Y2FzZSAnbWFudWFsJzpcblx0XHRcdFx0XHRcdC8vIE5vZGUtZmV0Y2gtc3BlY2lmaWMgc3RlcDogbWFrZSBtYW51YWwgcmVkaXJlY3QgYSBiaXQgZWFzaWVyIHRvIHVzZSBieSBzZXR0aW5nIHRoZSBMb2NhdGlvbiBoZWFkZXIgdmFsdWUgdG8gdGhlIHJlc29sdmVkIFVSTC5cblx0XHRcdFx0XHRcdGlmIChsb2NhdGlvblVSTCAhPT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0XHQvLyBIYW5kbGUgY29ycnVwdGVkIGhlYWRlclxuXHRcdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRcdGhlYWRlcnMuc2V0KCdMb2NhdGlvbicsIGxvY2F0aW9uVVJMKTtcblx0XHRcdFx0XHRcdFx0XHQvKiBjOCBpZ25vcmUgbmV4dCAzICovXG5cdFx0XHRcdFx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdmb2xsb3cnOiB7XG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgMlxuXHRcdFx0XHRcdFx0aWYgKGxvY2F0aW9uVVJMID09PSBudWxsKSB7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgNVxuXHRcdFx0XHRcdFx0aWYgKHJlcXVlc3QuY291bnRlciA+PSByZXF1ZXN0LmZvbGxvdykge1xuXHRcdFx0XHRcdFx0XHRyZWplY3QobmV3IEZldGNoRXJyb3IoYG1heGltdW0gcmVkaXJlY3QgcmVhY2hlZCBhdDogJHtyZXF1ZXN0LnVybH1gLCAnbWF4LXJlZGlyZWN0JykpO1xuXHRcdFx0XHRcdFx0XHRmaW5hbGl6ZSgpO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIEhUVFAtcmVkaXJlY3QgZmV0Y2ggc3RlcCA2IChjb3VudGVyIGluY3JlbWVudClcblx0XHRcdFx0XHRcdC8vIENyZWF0ZSBhIG5ldyBSZXF1ZXN0IG9iamVjdC5cblx0XHRcdFx0XHRcdGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuXHRcdFx0XHRcdFx0XHRoZWFkZXJzOiBuZXcgSGVhZGVycyhyZXF1ZXN0LmhlYWRlcnMpLFxuXHRcdFx0XHRcdFx0XHRmb2xsb3c6IHJlcXVlc3QuZm9sbG93LFxuXHRcdFx0XHRcdFx0XHRjb3VudGVyOiByZXF1ZXN0LmNvdW50ZXIgKyAxLFxuXHRcdFx0XHRcdFx0XHRhZ2VudDogcmVxdWVzdC5hZ2VudCxcblx0XHRcdFx0XHRcdFx0Y29tcHJlc3M6IHJlcXVlc3QuY29tcHJlc3MsXG5cdFx0XHRcdFx0XHRcdG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG5cdFx0XHRcdFx0XHRcdGJvZHk6IHJlcXVlc3QuYm9keSxcblx0XHRcdFx0XHRcdFx0c2lnbmFsOiByZXF1ZXN0LnNpZ25hbCxcblx0XHRcdFx0XHRcdFx0c2l6ZTogcmVxdWVzdC5zaXplXG5cdFx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgOVxuXHRcdFx0XHRcdFx0aWYgKHJlc3BvbnNlXy5zdGF0dXNDb2RlICE9PSAzMDMgJiYgcmVxdWVzdC5ib2R5ICYmIG9wdGlvbnNfLmJvZHkgaW5zdGFuY2VvZiBTdHJlYW0uUmVhZGFibGUpIHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KG5ldyBGZXRjaEVycm9yKCdDYW5ub3QgZm9sbG93IHJlZGlyZWN0IHdpdGggYm9keSBiZWluZyBhIHJlYWRhYmxlIHN0cmVhbScsICd1bnN1cHBvcnRlZC1yZWRpcmVjdCcpKTtcblx0XHRcdFx0XHRcdFx0ZmluYWxpemUoKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgMTFcblx0XHRcdFx0XHRcdGlmIChyZXNwb25zZV8uc3RhdHVzQ29kZSA9PT0gMzAzIHx8ICgocmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwMSB8fCByZXNwb25zZV8uc3RhdHVzQ29kZSA9PT0gMzAyKSAmJiByZXF1ZXN0Lm1ldGhvZCA9PT0gJ1BPU1QnKSkge1xuXHRcdFx0XHRcdFx0XHRyZXF1ZXN0T3B0aW9ucy5tZXRob2QgPSAnR0VUJztcblx0XHRcdFx0XHRcdFx0cmVxdWVzdE9wdGlvbnMuYm9keSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0XHRcdFx0cmVxdWVzdE9wdGlvbnMuaGVhZGVycy5kZWxldGUoJ2NvbnRlbnQtbGVuZ3RoJyk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIEhUVFAtcmVkaXJlY3QgZmV0Y2ggc3RlcCAxNVxuXHRcdFx0XHRcdFx0cmVzb2x2ZShmZXRjaChuZXcgUmVxdWVzdChsb2NhdGlvblVSTCwgcmVxdWVzdE9wdGlvbnMpKSk7XG5cdFx0XHRcdFx0XHRmaW5hbGl6ZSgpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHQvLyBEbyBub3RoaW5nXG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gUHJlcGFyZSByZXNwb25zZVxuXHRcdFx0cmVzcG9uc2VfLm9uY2UoJ2VuZCcsICgpID0+IHtcblx0XHRcdFx0aWYgKHNpZ25hbCkge1xuXHRcdFx0XHRcdHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0QW5kRmluYWxpemUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0bGV0IGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUocmVzcG9uc2VfLCBuZXcgU3RyZWFtLlBhc3NUaHJvdWdoKCksIGVycm9yID0+IHtcblx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdH0pO1xuXHRcdFx0Ly8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9wdWxsLzI5Mzc2XG5cdFx0XHRpZiAocHJvY2Vzcy52ZXJzaW9uIDwgJ3YxMi4xMCcpIHtcblx0XHRcdFx0cmVzcG9uc2VfLm9uKCdhYm9ydGVkJywgYWJvcnRBbmRGaW5hbGl6ZSk7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IHJlc3BvbnNlT3B0aW9ucyA9IHtcblx0XHRcdFx0dXJsOiByZXF1ZXN0LnVybCxcblx0XHRcdFx0c3RhdHVzOiByZXNwb25zZV8uc3RhdHVzQ29kZSxcblx0XHRcdFx0c3RhdHVzVGV4dDogcmVzcG9uc2VfLnN0YXR1c01lc3NhZ2UsXG5cdFx0XHRcdGhlYWRlcnMsXG5cdFx0XHRcdHNpemU6IHJlcXVlc3Quc2l6ZSxcblx0XHRcdFx0Y291bnRlcjogcmVxdWVzdC5jb3VudGVyLFxuXHRcdFx0XHRoaWdoV2F0ZXJNYXJrOiByZXF1ZXN0LmhpZ2hXYXRlck1hcmtcblx0XHRcdH07XG5cblx0XHRcdC8vIEhUVFAtbmV0d29yayBmZXRjaCBzdGVwIDEyLjEuMS4zXG5cdFx0XHRjb25zdCBjb2RpbmdzID0gaGVhZGVycy5nZXQoJ0NvbnRlbnQtRW5jb2RpbmcnKTtcblxuXHRcdFx0Ly8gSFRUUC1uZXR3b3JrIGZldGNoIHN0ZXAgMTIuMS4xLjQ6IGhhbmRsZSBjb250ZW50IGNvZGluZ3NcblxuXHRcdFx0Ly8gaW4gZm9sbG93aW5nIHNjZW5hcmlvcyB3ZSBpZ25vcmUgY29tcHJlc3Npb24gc3VwcG9ydFxuXHRcdFx0Ly8gMS4gY29tcHJlc3Npb24gc3VwcG9ydCBpcyBkaXNhYmxlZFxuXHRcdFx0Ly8gMi4gSEVBRCByZXF1ZXN0XG5cdFx0XHQvLyAzLiBubyBDb250ZW50LUVuY29kaW5nIGhlYWRlclxuXHRcdFx0Ly8gNC4gbm8gY29udGVudCByZXNwb25zZSAoMjA0KVxuXHRcdFx0Ly8gNS4gY29udGVudCBub3QgbW9kaWZpZWQgcmVzcG9uc2UgKDMwNClcblx0XHRcdGlmICghcmVxdWVzdC5jb21wcmVzcyB8fCByZXF1ZXN0Lm1ldGhvZCA9PT0gJ0hFQUQnIHx8IGNvZGluZ3MgPT09IG51bGwgfHwgcmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDIwNCB8fCByZXNwb25zZV8uc3RhdHVzQ29kZSA9PT0gMzA0KSB7XG5cdFx0XHRcdHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKGJvZHksIHJlc3BvbnNlT3B0aW9ucyk7XG5cdFx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZvciBOb2RlIHY2K1xuXHRcdFx0Ly8gQmUgbGVzcyBzdHJpY3Qgd2hlbiBkZWNvZGluZyBjb21wcmVzc2VkIHJlc3BvbnNlcywgc2luY2Ugc29tZXRpbWVzXG5cdFx0XHQvLyBzZXJ2ZXJzIHNlbmQgc2xpZ2h0bHkgaW52YWxpZCByZXNwb25zZXMgdGhhdCBhcmUgc3RpbGwgYWNjZXB0ZWRcblx0XHRcdC8vIGJ5IGNvbW1vbiBicm93c2Vycy5cblx0XHRcdC8vIEFsd2F5cyB1c2luZyBaX1NZTkNfRkxVU0ggaXMgd2hhdCBjVVJMIGRvZXMuXG5cdFx0XHRjb25zdCB6bGliT3B0aW9ucyA9IHtcblx0XHRcdFx0Zmx1c2g6IHpsaWIuWl9TWU5DX0ZMVVNILFxuXHRcdFx0XHRmaW5pc2hGbHVzaDogemxpYi5aX1NZTkNfRkxVU0hcblx0XHRcdH07XG5cblx0XHRcdC8vIEZvciBnemlwXG5cdFx0XHRpZiAoY29kaW5ncyA9PT0gJ2d6aXAnIHx8IGNvZGluZ3MgPT09ICd4LWd6aXAnKSB7XG5cdFx0XHRcdGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUoYm9keSwgemxpYi5jcmVhdGVHdW56aXAoemxpYk9wdGlvbnMpLCBlcnJvciA9PiB7XG5cdFx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdFx0fSk7XG5cdFx0XHRcdHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKGJvZHksIHJlc3BvbnNlT3B0aW9ucyk7XG5cdFx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZvciBkZWZsYXRlXG5cdFx0XHRpZiAoY29kaW5ncyA9PT0gJ2RlZmxhdGUnIHx8IGNvZGluZ3MgPT09ICd4LWRlZmxhdGUnKSB7XG5cdFx0XHRcdC8vIEhhbmRsZSB0aGUgaW5mYW1vdXMgcmF3IGRlZmxhdGUgcmVzcG9uc2UgZnJvbSBvbGQgc2VydmVyc1xuXHRcdFx0XHQvLyBhIGhhY2sgZm9yIG9sZCBJSVMgYW5kIEFwYWNoZSBzZXJ2ZXJzXG5cdFx0XHRcdGNvbnN0IHJhdyA9IFN0cmVhbS5waXBlbGluZShyZXNwb25zZV8sIG5ldyBTdHJlYW0uUGFzc1Rocm91Z2goKSwgZXJyb3IgPT4ge1xuXHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyYXcub25jZSgnZGF0YScsIGNodW5rID0+IHtcblx0XHRcdFx0XHQvLyBTZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zNzUxOTgyOFxuXHRcdFx0XHRcdGlmICgoY2h1bmtbMF0gJiAweDBGKSA9PT0gMHgwOCkge1xuXHRcdFx0XHRcdFx0Ym9keSA9IFN0cmVhbS5waXBlbGluZShib2R5LCB6bGliLmNyZWF0ZUluZmxhdGUoKSwgZXJyb3IgPT4ge1xuXHRcdFx0XHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUoYm9keSwgemxpYi5jcmVhdGVJbmZsYXRlUmF3KCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKGJvZHksIHJlc3BvbnNlT3B0aW9ucyk7XG5cdFx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZSk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZvciBiclxuXHRcdFx0aWYgKGNvZGluZ3MgPT09ICdicicpIHtcblx0XHRcdFx0Ym9keSA9IFN0cmVhbS5waXBlbGluZShib2R5LCB6bGliLmNyZWF0ZUJyb3RsaURlY29tcHJlc3MoKSwgZXJyb3IgPT4ge1xuXHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdGhlcndpc2UsIHVzZSByZXNwb25zZSBhcy1pc1xuXHRcdFx0cmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UoYm9keSwgcmVzcG9uc2VPcHRpb25zKTtcblx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdH0pO1xuXG5cdFx0d3JpdGVUb1N0cmVhbShyZXF1ZXN0XywgcmVxdWVzdCk7XG5cdH0pO1xufVxuXG5leHBvcnRzLkFib3J0RXJyb3IgPSBBYm9ydEVycm9yO1xuZXhwb3J0cy5GZXRjaEVycm9yID0gRmV0Y2hFcnJvcjtcbmV4cG9ydHMuSGVhZGVycyA9IEhlYWRlcnM7XG5leHBvcnRzLlJlcXVlc3QgPSBSZXF1ZXN0O1xuZXhwb3J0cy5SZXNwb25zZSA9IFJlc3BvbnNlO1xuZXhwb3J0cy5kZWZhdWx0ID0gZmV0Y2g7XG5leHBvcnRzLmlzUmVkaXJlY3QgPSBpc1JlZGlyZWN0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguY2pzLm1hcFxuIiwiZnVuY3Rpb24gbm9ybWFsaXplIChzdHIpIHtcbiAgcmV0dXJuIHN0clxuICAgICAgICAgIC5yZXBsYWNlKC9bXFwvXSsvZywgJy8nKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXC9cXD8vZywgJz8nKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXC9cXCMvZywgJyMnKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXDpcXC8vZywgJzovLycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGpvaW5lZCA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKS5qb2luKCcvJyk7XG4gIHJldHVybiBub3JtYWxpemUoam9pbmVkKTtcbn07IiwiLyoqXG4gKiB3ZWItc3RyZWFtcy1wb2x5ZmlsbCB2My4wLjFcbiAqL1xuLy8vIDxyZWZlcmVuY2UgbGliPVwiZXMyMDE1LnN5bWJvbFwiIC8+XG5jb25zdCBTeW1ib2xQb2x5ZmlsbCA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gJ3N5bWJvbCcgP1xuICAgIFN5bWJvbCA6XG4gICAgZGVzY3JpcHRpb24gPT4gYFN5bWJvbCgke2Rlc2NyaXB0aW9ufSlgO1xuXG4vLy8gPHJlZmVyZW5jZSBsaWI9XCJkb21cIiAvPlxuZnVuY3Rpb24gbm9vcCgpIHtcbiAgICAvLyBkbyBub3RoaW5nXG59XG5mdW5jdGlvbiBnZXRHbG9iYWxzKCkge1xuICAgIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHNlbGY7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3c7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHJldHVybiBnbG9iYWw7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5jb25zdCBnbG9iYWxzID0gZ2V0R2xvYmFscygpO1xuXG5mdW5jdGlvbiB0eXBlSXNPYmplY3QoeCkge1xuICAgIHJldHVybiAodHlwZW9mIHggPT09ICdvYmplY3QnICYmIHggIT09IG51bGwpIHx8IHR5cGVvZiB4ID09PSAnZnVuY3Rpb24nO1xufVxuY29uc3QgcmV0aHJvd0Fzc2VydGlvbkVycm9yUmVqZWN0aW9uID0gIG5vb3A7XG5cbmNvbnN0IG9yaWdpbmFsUHJvbWlzZSA9IFByb21pc2U7XG5jb25zdCBvcmlnaW5hbFByb21pc2VUaGVuID0gUHJvbWlzZS5wcm90b3R5cGUudGhlbjtcbmNvbnN0IG9yaWdpbmFsUHJvbWlzZVJlc29sdmUgPSBQcm9taXNlLnJlc29sdmUuYmluZChvcmlnaW5hbFByb21pc2UpO1xuY29uc3Qgb3JpZ2luYWxQcm9taXNlUmVqZWN0ID0gUHJvbWlzZS5yZWplY3QuYmluZChvcmlnaW5hbFByb21pc2UpO1xuZnVuY3Rpb24gbmV3UHJvbWlzZShleGVjdXRvcikge1xuICAgIHJldHVybiBuZXcgb3JpZ2luYWxQcm9taXNlKGV4ZWN1dG9yKTtcbn1cbmZ1bmN0aW9uIHByb21pc2VSZXNvbHZlZFdpdGgodmFsdWUpIHtcbiAgICByZXR1cm4gb3JpZ2luYWxQcm9taXNlUmVzb2x2ZSh2YWx1ZSk7XG59XG5mdW5jdGlvbiBwcm9taXNlUmVqZWN0ZWRXaXRoKHJlYXNvbikge1xuICAgIHJldHVybiBvcmlnaW5hbFByb21pc2VSZWplY3QocmVhc29uKTtcbn1cbmZ1bmN0aW9uIFBlcmZvcm1Qcm9taXNlVGhlbihwcm9taXNlLCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICAgIC8vIFRoZXJlIGRvZXNuJ3QgYXBwZWFyIHRvIGJlIGFueSB3YXkgdG8gY29ycmVjdGx5IGVtdWxhdGUgdGhlIGJlaGF2aW91ciBmcm9tIEphdmFTY3JpcHQsIHNvIHRoaXMgaXMganVzdCBhblxuICAgIC8vIGFwcHJveGltYXRpb24uXG4gICAgcmV0dXJuIG9yaWdpbmFsUHJvbWlzZVRoZW4uY2FsbChwcm9taXNlLCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCk7XG59XG5mdW5jdGlvbiB1cG9uUHJvbWlzZShwcm9taXNlLCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICAgIFBlcmZvcm1Qcm9taXNlVGhlbihQZXJmb3JtUHJvbWlzZVRoZW4ocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpLCB1bmRlZmluZWQsIHJldGhyb3dBc3NlcnRpb25FcnJvclJlamVjdGlvbik7XG59XG5mdW5jdGlvbiB1cG9uRnVsZmlsbG1lbnQocHJvbWlzZSwgb25GdWxmaWxsZWQpIHtcbiAgICB1cG9uUHJvbWlzZShwcm9taXNlLCBvbkZ1bGZpbGxlZCk7XG59XG5mdW5jdGlvbiB1cG9uUmVqZWN0aW9uKHByb21pc2UsIG9uUmVqZWN0ZWQpIHtcbiAgICB1cG9uUHJvbWlzZShwcm9taXNlLCB1bmRlZmluZWQsIG9uUmVqZWN0ZWQpO1xufVxuZnVuY3Rpb24gdHJhbnNmb3JtUHJvbWlzZVdpdGgocHJvbWlzZSwgZnVsZmlsbG1lbnRIYW5kbGVyLCByZWplY3Rpb25IYW5kbGVyKSB7XG4gICAgcmV0dXJuIFBlcmZvcm1Qcm9taXNlVGhlbihwcm9taXNlLCBmdWxmaWxsbWVudEhhbmRsZXIsIHJlamVjdGlvbkhhbmRsZXIpO1xufVxuZnVuY3Rpb24gc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShwcm9taXNlKSB7XG4gICAgUGVyZm9ybVByb21pc2VUaGVuKHByb21pc2UsIHVuZGVmaW5lZCwgcmV0aHJvd0Fzc2VydGlvbkVycm9yUmVqZWN0aW9uKTtcbn1cbmNvbnN0IHF1ZXVlTWljcm90YXNrID0gKCgpID0+IHtcbiAgICBjb25zdCBnbG9iYWxRdWV1ZU1pY3JvdGFzayA9IGdsb2JhbHMgJiYgZ2xvYmFscy5xdWV1ZU1pY3JvdGFzaztcbiAgICBpZiAodHlwZW9mIGdsb2JhbFF1ZXVlTWljcm90YXNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiBnbG9iYWxRdWV1ZU1pY3JvdGFzaztcbiAgICB9XG4gICAgY29uc3QgcmVzb2x2ZWRQcm9taXNlID0gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIHJldHVybiAoZm4pID0+IFBlcmZvcm1Qcm9taXNlVGhlbihyZXNvbHZlZFByb21pc2UsIGZuKTtcbn0pKCk7XG5mdW5jdGlvbiByZWZsZWN0Q2FsbChGLCBWLCBhcmdzKSB7XG4gICAgaWYgKHR5cGVvZiBGICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IGlzIG5vdCBhIGZ1bmN0aW9uJyk7XG4gICAgfVxuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbChGLCBWLCBhcmdzKTtcbn1cbmZ1bmN0aW9uIHByb21pc2VDYWxsKEYsIFYsIGFyZ3MpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aChyZWZsZWN0Q2FsbChGLCBWLCBhcmdzKSk7XG4gICAgfVxuICAgIGNhdGNoICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aCh2YWx1ZSk7XG4gICAgfVxufVxuXG4vLyBPcmlnaW5hbCBmcm9tIENocm9taXVtXG4vLyBodHRwczovL2Nocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjLysvMGFlZTQ0MzRhNGRiYTQyYTQyYWJhZWE5YmZiYzBjZDE5NmE2M2JjMS90aGlyZF9wYXJ0eS9ibGluay9yZW5kZXJlci9jb3JlL3N0cmVhbXMvU2ltcGxlUXVldWUuanNcbmNvbnN0IFFVRVVFX01BWF9BUlJBWV9TSVpFID0gMTYzODQ7XG4vKipcbiAqIFNpbXBsZSBxdWV1ZSBzdHJ1Y3R1cmUuXG4gKlxuICogQXZvaWRzIHNjYWxhYmlsaXR5IGlzc3VlcyB3aXRoIHVzaW5nIGEgcGFja2VkIGFycmF5IGRpcmVjdGx5IGJ5IHVzaW5nXG4gKiBtdWx0aXBsZSBhcnJheXMgaW4gYSBsaW5rZWQgbGlzdCBhbmQga2VlcGluZyB0aGUgYXJyYXkgc2l6ZSBib3VuZGVkLlxuICovXG5jbGFzcyBTaW1wbGVRdWV1ZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuX2N1cnNvciA9IDA7XG4gICAgICAgIHRoaXMuX3NpemUgPSAwO1xuICAgICAgICAvLyBfZnJvbnQgYW5kIF9iYWNrIGFyZSBhbHdheXMgZGVmaW5lZC5cbiAgICAgICAgdGhpcy5fZnJvbnQgPSB7XG4gICAgICAgICAgICBfZWxlbWVudHM6IFtdLFxuICAgICAgICAgICAgX25leHQ6IHVuZGVmaW5lZFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9iYWNrID0gdGhpcy5fZnJvbnQ7XG4gICAgICAgIC8vIFRoZSBjdXJzb3IgaXMgdXNlZCB0byBhdm9pZCBjYWxsaW5nIEFycmF5LnNoaWZ0KCkuXG4gICAgICAgIC8vIEl0IGNvbnRhaW5zIHRoZSBpbmRleCBvZiB0aGUgZnJvbnQgZWxlbWVudCBvZiB0aGUgYXJyYXkgaW5zaWRlIHRoZVxuICAgICAgICAvLyBmcm9udC1tb3N0IG5vZGUuIEl0IGlzIGFsd2F5cyBpbiB0aGUgcmFuZ2UgWzAsIFFVRVVFX01BWF9BUlJBWV9TSVpFKS5cbiAgICAgICAgdGhpcy5fY3Vyc29yID0gMDtcbiAgICAgICAgLy8gV2hlbiB0aGVyZSBpcyBvbmx5IG9uZSBub2RlLCBzaXplID09PSBlbGVtZW50cy5sZW5ndGggLSBjdXJzb3IuXG4gICAgICAgIHRoaXMuX3NpemUgPSAwO1xuICAgIH1cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2l6ZTtcbiAgICB9XG4gICAgLy8gRm9yIGV4Y2VwdGlvbiBzYWZldHksIHRoaXMgbWV0aG9kIGlzIHN0cnVjdHVyZWQgaW4gb3JkZXI6XG4gICAgLy8gMS4gUmVhZCBzdGF0ZVxuICAgIC8vIDIuIENhbGN1bGF0ZSByZXF1aXJlZCBzdGF0ZSBtdXRhdGlvbnNcbiAgICAvLyAzLiBQZXJmb3JtIHN0YXRlIG11dGF0aW9uc1xuICAgIHB1c2goZWxlbWVudCkge1xuICAgICAgICBjb25zdCBvbGRCYWNrID0gdGhpcy5fYmFjaztcbiAgICAgICAgbGV0IG5ld0JhY2sgPSBvbGRCYWNrO1xuICAgICAgICBpZiAob2xkQmFjay5fZWxlbWVudHMubGVuZ3RoID09PSBRVUVVRV9NQVhfQVJSQVlfU0laRSAtIDEpIHtcbiAgICAgICAgICAgIG5ld0JhY2sgPSB7XG4gICAgICAgICAgICAgICAgX2VsZW1lbnRzOiBbXSxcbiAgICAgICAgICAgICAgICBfbmV4dDogdW5kZWZpbmVkXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIC8vIHB1c2goKSBpcyB0aGUgbXV0YXRpb24gbW9zdCBsaWtlbHkgdG8gdGhyb3cgYW4gZXhjZXB0aW9uLCBzbyBpdFxuICAgICAgICAvLyBnb2VzIGZpcnN0LlxuICAgICAgICBvbGRCYWNrLl9lbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgICBpZiAobmV3QmFjayAhPT0gb2xkQmFjaykge1xuICAgICAgICAgICAgdGhpcy5fYmFjayA9IG5ld0JhY2s7XG4gICAgICAgICAgICBvbGRCYWNrLl9uZXh0ID0gbmV3QmFjaztcbiAgICAgICAgfVxuICAgICAgICArK3RoaXMuX3NpemU7XG4gICAgfVxuICAgIC8vIExpa2UgcHVzaCgpLCBzaGlmdCgpIGZvbGxvd3MgdGhlIHJlYWQgLT4gY2FsY3VsYXRlIC0+IG11dGF0ZSBwYXR0ZXJuIGZvclxuICAgIC8vIGV4Y2VwdGlvbiBzYWZldHkuXG4gICAgc2hpZnQoKSB7IC8vIG11c3Qgbm90IGJlIGNhbGxlZCBvbiBhbiBlbXB0eSBxdWV1ZVxuICAgICAgICBjb25zdCBvbGRGcm9udCA9IHRoaXMuX2Zyb250O1xuICAgICAgICBsZXQgbmV3RnJvbnQgPSBvbGRGcm9udDtcbiAgICAgICAgY29uc3Qgb2xkQ3Vyc29yID0gdGhpcy5fY3Vyc29yO1xuICAgICAgICBsZXQgbmV3Q3Vyc29yID0gb2xkQ3Vyc29yICsgMTtcbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSBvbGRGcm9udC5fZWxlbWVudHM7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50c1tvbGRDdXJzb3JdO1xuICAgICAgICBpZiAobmV3Q3Vyc29yID09PSBRVUVVRV9NQVhfQVJSQVlfU0laRSkge1xuICAgICAgICAgICAgbmV3RnJvbnQgPSBvbGRGcm9udC5fbmV4dDtcbiAgICAgICAgICAgIG5ld0N1cnNvciA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTm8gbXV0YXRpb25zIGJlZm9yZSB0aGlzIHBvaW50LlxuICAgICAgICAtLXRoaXMuX3NpemU7XG4gICAgICAgIHRoaXMuX2N1cnNvciA9IG5ld0N1cnNvcjtcbiAgICAgICAgaWYgKG9sZEZyb250ICE9PSBuZXdGcm9udCkge1xuICAgICAgICAgICAgdGhpcy5fZnJvbnQgPSBuZXdGcm9udDtcbiAgICAgICAgfVxuICAgICAgICAvLyBQZXJtaXQgc2hpZnRlZCBlbGVtZW50IHRvIGJlIGdhcmJhZ2UgY29sbGVjdGVkLlxuICAgICAgICBlbGVtZW50c1tvbGRDdXJzb3JdID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gICAgLy8gVGhlIHRyaWNreSB0aGluZyBhYm91dCBmb3JFYWNoKCkgaXMgdGhhdCBpdCBjYW4gYmUgY2FsbGVkXG4gICAgLy8gcmUtZW50cmFudGx5LiBUaGUgcXVldWUgbWF5IGJlIG11dGF0ZWQgaW5zaWRlIHRoZSBjYWxsYmFjay4gSXQgaXMgZWFzeSB0b1xuICAgIC8vIHNlZSB0aGF0IHB1c2goKSB3aXRoaW4gdGhlIGNhbGxiYWNrIGhhcyBubyBuZWdhdGl2ZSBlZmZlY3RzIHNpbmNlIHRoZSBlbmRcbiAgICAvLyBvZiB0aGUgcXVldWUgaXMgY2hlY2tlZCBmb3Igb24gZXZlcnkgaXRlcmF0aW9uLiBJZiBzaGlmdCgpIGlzIGNhbGxlZFxuICAgIC8vIHJlcGVhdGVkbHkgd2l0aGluIHRoZSBjYWxsYmFjayB0aGVuIHRoZSBuZXh0IGl0ZXJhdGlvbiBtYXkgcmV0dXJuIGFuXG4gICAgLy8gZWxlbWVudCB0aGF0IGhhcyBiZWVuIHJlbW92ZWQuIEluIHRoaXMgY2FzZSB0aGUgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWRcbiAgICAvLyB3aXRoIHVuZGVmaW5lZCB2YWx1ZXMgdW50aWwgd2UgZWl0aGVyIFwiY2F0Y2ggdXBcIiB3aXRoIGVsZW1lbnRzIHRoYXQgc3RpbGxcbiAgICAvLyBleGlzdCBvciByZWFjaCB0aGUgYmFjayBvZiB0aGUgcXVldWUuXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICBsZXQgaSA9IHRoaXMuX2N1cnNvcjtcbiAgICAgICAgbGV0IG5vZGUgPSB0aGlzLl9mcm9udDtcbiAgICAgICAgbGV0IGVsZW1lbnRzID0gbm9kZS5fZWxlbWVudHM7XG4gICAgICAgIHdoaWxlIChpICE9PSBlbGVtZW50cy5sZW5ndGggfHwgbm9kZS5fbmV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoaSA9PT0gZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUuX25leHQ7XG4gICAgICAgICAgICAgICAgZWxlbWVudHMgPSBub2RlLl9lbGVtZW50cztcbiAgICAgICAgICAgICAgICBpID0gMDtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhbGxiYWNrKGVsZW1lbnRzW2ldKTtcbiAgICAgICAgICAgICsraTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBSZXR1cm4gdGhlIGVsZW1lbnQgdGhhdCB3b3VsZCBiZSByZXR1cm5lZCBpZiBzaGlmdCgpIHdhcyBjYWxsZWQgbm93LFxuICAgIC8vIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSBxdWV1ZS5cbiAgICBwZWVrKCkgeyAvLyBtdXN0IG5vdCBiZSBjYWxsZWQgb24gYW4gZW1wdHkgcXVldWVcbiAgICAgICAgY29uc3QgZnJvbnQgPSB0aGlzLl9mcm9udDtcbiAgICAgICAgY29uc3QgY3Vyc29yID0gdGhpcy5fY3Vyc29yO1xuICAgICAgICByZXR1cm4gZnJvbnQuX2VsZW1lbnRzW2N1cnNvcl07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNJbml0aWFsaXplKHJlYWRlciwgc3RyZWFtKSB7XG4gICAgcmVhZGVyLl9vd25lclJlYWRhYmxlU3RyZWFtID0gc3RyZWFtO1xuICAgIHN0cmVhbS5fcmVhZGVyID0gcmVhZGVyO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAncmVhZGFibGUnKSB7XG4gICAgICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZShyZWFkZXIpO1xuICAgIH1cbiAgICBlbHNlIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHJlYWRlcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHJlYWRlciwgc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxufVxuLy8gQSBjbGllbnQgb2YgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyIGFuZCBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIgbWF5IHVzZSB0aGVzZSBmdW5jdGlvbnMgZGlyZWN0bHkgdG8gYnlwYXNzIHN0YXRlXG4vLyBjaGVjay5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbChyZWFkZXIsIHJlYXNvbikge1xuICAgIGNvbnN0IHN0cmVhbSA9IHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbTtcbiAgICByZXR1cm4gUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCByZWFzb24pO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpIHtcbiAgICBpZiAocmVhZGVyLl9vd25lclJlYWRhYmxlU3RyZWFtLl9zdGF0ZSA9PT0gJ3JlYWRhYmxlJykge1xuICAgICAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlamVjdChyZWFkZXIsIG5ldyBUeXBlRXJyb3IoYFJlYWRlciB3YXMgcmVsZWFzZWQgYW5kIGNhbiBubyBsb25nZXIgYmUgdXNlZCB0byBtb25pdG9yIHRoZSBzdHJlYW0ncyBjbG9zZWRuZXNzYCkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQocmVhZGVyLCBuZXcgVHlwZUVycm9yKGBSZWFkZXIgd2FzIHJlbGVhc2VkIGFuZCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgdG8gbW9uaXRvciB0aGUgc3RyZWFtJ3MgY2xvc2VkbmVzc2ApKTtcbiAgICB9XG4gICAgcmVhZGVyLl9vd25lclJlYWRhYmxlU3RyZWFtLl9yZWFkZXIgPSB1bmRlZmluZWQ7XG4gICAgcmVhZGVyLl9vd25lclJlYWRhYmxlU3RyZWFtID0gdW5kZWZpbmVkO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIHJlYWRlcnMuXG5mdW5jdGlvbiByZWFkZXJMb2NrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcignQ2Fubm90ICcgKyBuYW1lICsgJyBhIHN0cmVhbSB1c2luZyBhIHJlbGVhc2VkIHJlYWRlcicpO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZShyZWFkZXIpIHtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID0gcmVqZWN0O1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZChyZWFkZXIsIHJlYXNvbikge1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZShyZWFkZXIpO1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVqZWN0KHJlYWRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQocmVhZGVyKSB7XG4gICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplKHJlYWRlcik7XG4gICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNvbHZlKHJlYWRlcik7XG59XG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlamVjdChyZWFkZXIsIHJlYXNvbikge1xuICAgIGlmIChyZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlKHJlYWRlci5fY2xvc2VkUHJvbWlzZSk7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdChyZWFzb24pO1xuICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QgPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlc2V0VG9SZWplY3RlZChyZWFkZXIsIHJlYXNvbikge1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQocmVhZGVyLCByZWFzb24pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNvbHZlKHJlYWRlcikge1xuICAgIGlmIChyZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUodW5kZWZpbmVkKTtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID0gdW5kZWZpbmVkO1xufVxuXG5jb25zdCBBYm9ydFN0ZXBzID0gU3ltYm9sUG9seWZpbGwoJ1tbQWJvcnRTdGVwc11dJyk7XG5jb25zdCBFcnJvclN0ZXBzID0gU3ltYm9sUG9seWZpbGwoJ1tbRXJyb3JTdGVwc11dJyk7XG5jb25zdCBDYW5jZWxTdGVwcyA9IFN5bWJvbFBvbHlmaWxsKCdbW0NhbmNlbFN0ZXBzXV0nKTtcbmNvbnN0IFB1bGxTdGVwcyA9IFN5bWJvbFBvbHlmaWxsKCdbW1B1bGxTdGVwc11dJyk7XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5jb3JlXCIgLz5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL051bWJlci9pc0Zpbml0ZSNQb2x5ZmlsbFxuY29uc3QgTnVtYmVySXNGaW5pdGUgPSBOdW1iZXIuaXNGaW5pdGUgfHwgZnVuY3Rpb24gKHgpIHtcbiAgICByZXR1cm4gdHlwZW9mIHggPT09ICdudW1iZXInICYmIGlzRmluaXRlKHgpO1xufTtcblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZXMyMDE1LmNvcmVcIiAvPlxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTWF0aC90cnVuYyNQb2x5ZmlsbFxuY29uc3QgTWF0aFRydW5jID0gTWF0aC50cnVuYyB8fCBmdW5jdGlvbiAodikge1xuICAgIHJldHVybiB2IDwgMCA/IE1hdGguY2VpbCh2KSA6IE1hdGguZmxvb3Iodik7XG59O1xuXG4vLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNpZGwtZGljdGlvbmFyaWVzXG5mdW5jdGlvbiBpc0RpY3Rpb25hcnkoeCkge1xuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIHggPT09ICdmdW5jdGlvbic7XG59XG5mdW5jdGlvbiBhc3NlcnREaWN0aW9uYXJ5KG9iaiwgY29udGV4dCkge1xuICAgIGlmIChvYmogIT09IHVuZGVmaW5lZCAmJiAhaXNEaWN0aW9uYXJ5KG9iaikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYW4gb2JqZWN0LmApO1xuICAgIH1cbn1cbi8vIGh0dHBzOi8vaGV5Y2FtLmdpdGh1Yi5pby93ZWJpZGwvI2lkbC1jYWxsYmFjay1mdW5jdGlvbnNcbmZ1bmN0aW9uIGFzc2VydEZ1bmN0aW9uKHgsIGNvbnRleHQpIHtcbiAgICBpZiAodHlwZW9mIHggIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYSBmdW5jdGlvbi5gKTtcbiAgICB9XG59XG4vLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNpZGwtb2JqZWN0XG5mdW5jdGlvbiBpc09iamVjdCh4KSB7XG4gICAgcmV0dXJuICh0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCkgfHwgdHlwZW9mIHggPT09ICdmdW5jdGlvbic7XG59XG5mdW5jdGlvbiBhc3NlcnRPYmplY3QoeCwgY29udGV4dCkge1xuICAgIGlmICghaXNPYmplY3QoeCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYW4gb2JqZWN0LmApO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGFzc2VydFJlcXVpcmVkQXJndW1lbnQoeCwgcG9zaXRpb24sIGNvbnRleHQpIHtcbiAgICBpZiAoeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFBhcmFtZXRlciAke3Bvc2l0aW9ufSBpcyByZXF1aXJlZCBpbiAnJHtjb250ZXh0fScuYCk7XG4gICAgfVxufVxuZnVuY3Rpb24gYXNzZXJ0UmVxdWlyZWRGaWVsZCh4LCBmaWVsZCwgY29udGV4dCkge1xuICAgIGlmICh4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtmaWVsZH0gaXMgcmVxdWlyZWQgaW4gJyR7Y29udGV4dH0nLmApO1xuICAgIH1cbn1cbi8vIGh0dHBzOi8vaGV5Y2FtLmdpdGh1Yi5pby93ZWJpZGwvI2lkbC11bnJlc3RyaWN0ZWQtZG91YmxlXG5mdW5jdGlvbiBjb252ZXJ0VW5yZXN0cmljdGVkRG91YmxlKHZhbHVlKSB7XG4gICAgcmV0dXJuIE51bWJlcih2YWx1ZSk7XG59XG5mdW5jdGlvbiBjZW5zb3JOZWdhdGl2ZVplcm8oeCkge1xuICAgIHJldHVybiB4ID09PSAwID8gMCA6IHg7XG59XG5mdW5jdGlvbiBpbnRlZ2VyUGFydCh4KSB7XG4gICAgcmV0dXJuIGNlbnNvck5lZ2F0aXZlWmVybyhNYXRoVHJ1bmMoeCkpO1xufVxuLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jaWRsLXVuc2lnbmVkLWxvbmctbG9uZ1xuZnVuY3Rpb24gY29udmVydFVuc2lnbmVkTG9uZ0xvbmdXaXRoRW5mb3JjZVJhbmdlKHZhbHVlLCBjb250ZXh0KSB7XG4gICAgY29uc3QgbG93ZXJCb3VuZCA9IDA7XG4gICAgY29uc3QgdXBwZXJCb3VuZCA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSO1xuICAgIGxldCB4ID0gTnVtYmVyKHZhbHVlKTtcbiAgICB4ID0gY2Vuc29yTmVnYXRpdmVaZXJvKHgpO1xuICAgIGlmICghTnVtYmVySXNGaW5pdGUoeCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYSBmaW5pdGUgbnVtYmVyYCk7XG4gICAgfVxuICAgIHggPSBpbnRlZ2VyUGFydCh4KTtcbiAgICBpZiAoeCA8IGxvd2VyQm91bmQgfHwgeCA+IHVwcGVyQm91bmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBvdXRzaWRlIHRoZSBhY2NlcHRlZCByYW5nZSBvZiAke2xvd2VyQm91bmR9IHRvICR7dXBwZXJCb3VuZH0sIGluY2x1c2l2ZWApO1xuICAgIH1cbiAgICBpZiAoIU51bWJlcklzRmluaXRlKHgpIHx8IHggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8vIFRPRE8gVXNlIEJpZ0ludCBpZiBzdXBwb3J0ZWQ/XG4gICAgLy8gbGV0IHhCaWdJbnQgPSBCaWdJbnQoaW50ZWdlclBhcnQoeCkpO1xuICAgIC8vIHhCaWdJbnQgPSBCaWdJbnQuYXNVaW50Tig2NCwgeEJpZ0ludCk7XG4gICAgLy8gcmV0dXJuIE51bWJlcih4QmlnSW50KTtcbiAgICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0UmVhZGFibGVTdHJlYW0oeCwgY29udGV4dCkge1xuICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbSh4KSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NvbnRleHR9IGlzIG5vdCBhIFJlYWRhYmxlU3RyZWFtLmApO1xuICAgIH1cbn1cblxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gQWNxdWlyZVJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcihzdHJlYW0pIHtcbiAgICByZXR1cm4gbmV3IFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcihzdHJlYW0pO1xufVxuLy8gUmVhZGFibGVTdHJlYW0gQVBJIGV4cG9zZWQgZm9yIGNvbnRyb2xsZXJzLlxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1BZGRSZWFkUmVxdWVzdChzdHJlYW0sIHJlYWRSZXF1ZXN0KSB7XG4gICAgc3RyZWFtLl9yZWFkZXIuX3JlYWRSZXF1ZXN0cy5wdXNoKHJlYWRSZXF1ZXN0KTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRSZXF1ZXN0KHN0cmVhbSwgY2h1bmssIGRvbmUpIHtcbiAgICBjb25zdCByZWFkZXIgPSBzdHJlYW0uX3JlYWRlcjtcbiAgICBjb25zdCByZWFkUmVxdWVzdCA9IHJlYWRlci5fcmVhZFJlcXVlc3RzLnNoaWZ0KCk7XG4gICAgaWYgKGRvbmUpIHtcbiAgICAgICAgcmVhZFJlcXVlc3QuX2Nsb3NlU3RlcHMoKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlYWRSZXF1ZXN0Ll9jaHVua1N0ZXBzKGNodW5rKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pIHtcbiAgICByZXR1cm4gc3RyZWFtLl9yZWFkZXIuX3JlYWRSZXF1ZXN0cy5sZW5ndGg7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUhhc0RlZmF1bHRSZWFkZXIoc3RyZWFtKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIEEgZGVmYXVsdCByZWFkZXIgdmVuZGVkIGJ5IGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciB7XG4gICAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQoc3RyZWFtLCAxLCAnUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyJyk7XG4gICAgICAgIGFzc2VydFJlYWRhYmxlU3RyZWFtKHN0cmVhbSwgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZChzdHJlYW0pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGlzIHN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGxvY2tlZCBmb3IgZXhjbHVzaXZlIHJlYWRpbmcgYnkgYW5vdGhlciByZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNJbml0aWFsaXplKHRoaXMsIHN0cmVhbSk7XG4gICAgICAgIHRoaXMuX3JlYWRSZXF1ZXN0cyA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHdpbGwgYmUgZnVsZmlsbGVkIHdoZW4gdGhlIHN0cmVhbSBiZWNvbWVzIGNsb3NlZCxcbiAgICAgKiBvciByZWplY3RlZCBpZiB0aGUgc3RyZWFtIGV2ZXIgZXJyb3JzIG9yIHRoZSByZWFkZXIncyBsb2NrIGlzIHJlbGVhc2VkIGJlZm9yZSB0aGUgc3RyZWFtIGZpbmlzaGVzIGNsb3NpbmcuXG4gICAgICovXG4gICAgZ2V0IGNsb3NlZCgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlZCcpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2VkUHJvbWlzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIHJlYWRlciBpcyBhY3RpdmUsIGJlaGF2ZXMgdGhlIHNhbWUgYXMge0BsaW5rIFJlYWRhYmxlU3RyZWFtLmNhbmNlbCB8IHN0cmVhbS5jYW5jZWwocmVhc29uKX0uXG4gICAgICovXG4gICAgY2FuY2VsKHJlYXNvbiA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbignY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lclJlYWRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHJlYWRlckxvY2tFeGNlcHRpb24oJ2NhbmNlbCcpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljQ2FuY2VsKHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgYWxsb3dzIGFjY2VzcyB0byB0aGUgbmV4dCBjaHVuayBmcm9tIHRoZSBzdHJlYW0ncyBpbnRlcm5hbCBxdWV1ZSwgaWYgYXZhaWxhYmxlLlxuICAgICAqXG4gICAgICogSWYgcmVhZGluZyBhIGNodW5rIGNhdXNlcyB0aGUgcXVldWUgdG8gYmVjb21lIGVtcHR5LCBtb3JlIGRhdGEgd2lsbCBiZSBwdWxsZWQgZnJvbSB0aGUgdW5kZXJseWluZyBzb3VyY2UuXG4gICAgICovXG4gICAgcmVhZCgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlYWQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbigncmVhZCBmcm9tJykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNvbHZlUHJvbWlzZTtcbiAgICAgICAgbGV0IHJlamVjdFByb21pc2U7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgIHJlamVjdFByb21pc2UgPSByZWplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZWFkUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9jaHVua1N0ZXBzOiBjaHVuayA9PiByZXNvbHZlUHJvbWlzZSh7IHZhbHVlOiBjaHVuaywgZG9uZTogZmFsc2UgfSksXG4gICAgICAgICAgICBfY2xvc2VTdGVwczogKCkgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH0pLFxuICAgICAgICAgICAgX2Vycm9yU3RlcHM6IGUgPT4gcmVqZWN0UHJvbWlzZShlKVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJSZWFkKHRoaXMsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbGVhc2VzIHRoZSByZWFkZXIncyBsb2NrIG9uIHRoZSBjb3JyZXNwb25kaW5nIHN0cmVhbS4gQWZ0ZXIgdGhlIGxvY2sgaXMgcmVsZWFzZWQsIHRoZSByZWFkZXIgaXMgbm8gbG9uZ2VyIGFjdGl2ZS5cbiAgICAgKiBJZiB0aGUgYXNzb2NpYXRlZCBzdHJlYW0gaXMgZXJyb3JlZCB3aGVuIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmVhZGVyIHdpbGwgYXBwZWFyIGVycm9yZWQgaW4gdGhlIHNhbWUgd2F5XG4gICAgICogZnJvbSBub3cgb247IG90aGVyd2lzZSwgdGhlIHJlYWRlciB3aWxsIGFwcGVhciBjbG9zZWQuXG4gICAgICpcbiAgICAgKiBBIHJlYWRlcidzIGxvY2sgY2Fubm90IGJlIHJlbGVhc2VkIHdoaWxlIGl0IHN0aWxsIGhhcyBhIHBlbmRpbmcgcmVhZCByZXF1ZXN0LCBpLmUuLCBpZiBhIHByb21pc2UgcmV0dXJuZWQgYnlcbiAgICAgKiB0aGUgcmVhZGVyJ3Mge0BsaW5rIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5yZWFkIHwgcmVhZCgpfSBtZXRob2QgaGFzIG5vdCB5ZXQgYmVlbiBzZXR0bGVkLiBBdHRlbXB0aW5nIHRvXG4gICAgICogZG8gc28gd2lsbCB0aHJvdyBhIGBUeXBlRXJyb3JgIGFuZCBsZWF2ZSB0aGUgcmVhZGVyIGxvY2tlZCB0byB0aGUgc3RyZWFtLlxuICAgICAqL1xuICAgIHJlbGVhc2VMb2NrKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbigncmVsZWFzZUxvY2snKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3JlYWRSZXF1ZXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUcmllZCB0byByZWxlYXNlIGEgcmVhZGVyIGxvY2sgd2hlbiB0aGF0IHJlYWRlciBoYXMgcGVuZGluZyByZWFkKCkgY2FsbHMgdW4tc2V0dGxlZCcpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UodGhpcyk7XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyLnByb3RvdHlwZSwge1xuICAgIGNhbmNlbDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcmVhZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcmVsZWFzZUxvY2s6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGNsb3NlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXInLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbi8vIEFic3RyYWN0IG9wZXJhdGlvbnMgZm9yIHRoZSByZWFkZXJzLlxuZnVuY3Rpb24gSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19yZWFkUmVxdWVzdHMnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZChyZWFkZXIsIHJlYWRSZXF1ZXN0KSB7XG4gICAgY29uc3Qgc3RyZWFtID0gcmVhZGVyLl9vd25lclJlYWRhYmxlU3RyZWFtO1xuICAgIHN0cmVhbS5fZGlzdHVyYmVkID0gdHJ1ZTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmVhZFJlcXVlc3QuX2Nsb3NlU3RlcHMoKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJlYWRSZXF1ZXN0Ll9lcnJvclN0ZXBzKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3RyZWFtLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXJbUHVsbFN0ZXBzXShyZWFkUmVxdWVzdCk7XG4gICAgfVxufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyLnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJgKTtcbn1cblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZXMyMDE4LmFzeW5jaXRlcmFibGVcIiAvPlxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uICovXG5jb25zdCBBc3luY0l0ZXJhdG9yUHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKE9iamVjdC5nZXRQcm90b3R5cGVPZihhc3luYyBmdW5jdGlvbiogKCkgeyB9KS5wcm90b3R5cGUpO1xuXG4vLy8gPHJlZmVyZW5jZSBsaWI9XCJlczIwMTguYXN5bmNpdGVyYWJsZVwiIC8+XG5jbGFzcyBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JJbXBsIHtcbiAgICBjb25zdHJ1Y3RvcihyZWFkZXIsIHByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgdGhpcy5fb25nb2luZ1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuX2lzRmluaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fcmVhZGVyID0gcmVhZGVyO1xuICAgICAgICB0aGlzLl9wcmV2ZW50Q2FuY2VsID0gcHJldmVudENhbmNlbDtcbiAgICB9XG4gICAgbmV4dCgpIHtcbiAgICAgICAgY29uc3QgbmV4dFN0ZXBzID0gKCkgPT4gdGhpcy5fbmV4dFN0ZXBzKCk7XG4gICAgICAgIHRoaXMuX29uZ29pbmdQcm9taXNlID0gdGhpcy5fb25nb2luZ1Byb21pc2UgP1xuICAgICAgICAgICAgdHJhbnNmb3JtUHJvbWlzZVdpdGgodGhpcy5fb25nb2luZ1Byb21pc2UsIG5leHRTdGVwcywgbmV4dFN0ZXBzKSA6XG4gICAgICAgICAgICBuZXh0U3RlcHMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29uZ29pbmdQcm9taXNlO1xuICAgIH1cbiAgICByZXR1cm4odmFsdWUpIHtcbiAgICAgICAgY29uc3QgcmV0dXJuU3RlcHMgPSAoKSA9PiB0aGlzLl9yZXR1cm5TdGVwcyh2YWx1ZSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9vbmdvaW5nUHJvbWlzZSA/XG4gICAgICAgICAgICB0cmFuc2Zvcm1Qcm9taXNlV2l0aCh0aGlzLl9vbmdvaW5nUHJvbWlzZSwgcmV0dXJuU3RlcHMsIHJldHVyblN0ZXBzKSA6XG4gICAgICAgICAgICByZXR1cm5TdGVwcygpO1xuICAgIH1cbiAgICBfbmV4dFN0ZXBzKCkge1xuICAgICAgICBpZiAodGhpcy5faXNGaW5pc2hlZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVhZGVyID0gdGhpcy5fcmVhZGVyO1xuICAgICAgICBpZiAocmVhZGVyLl9vd25lclJlYWRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHJlYWRlckxvY2tFeGNlcHRpb24oJ2l0ZXJhdGUnKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc29sdmVQcm9taXNlO1xuICAgICAgICBsZXQgcmVqZWN0UHJvbWlzZTtcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZVByb21pc2UgPSByZXNvbHZlO1xuICAgICAgICAgICAgcmVqZWN0UHJvbWlzZSA9IHJlamVjdDtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlYWRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX2NodW5rU3RlcHM6IGNodW5rID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vbmdvaW5nUHJvbWlzZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGJlIGRlbGF5ZWQgYnkgb25lIG1pY3JvdGFzaywgb3RoZXJ3aXNlIHdlIHN0b3AgcHVsbGluZyB0b28gZWFybHkgd2hpY2ggYnJlYWtzIGEgdGVzdC5cbiAgICAgICAgICAgICAgICAvLyBGSVhNRSBJcyB0aGlzIGEgYnVnIGluIHRoZSBzcGVjaWZpY2F0aW9uLCBvciBpbiB0aGUgdGVzdD9cbiAgICAgICAgICAgICAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiByZXNvbHZlUHJvbWlzZSh7IHZhbHVlOiBjaHVuaywgZG9uZTogZmFsc2UgfSkpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb25nb2luZ1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNGaW5pc2hlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgICAgIHJlc29sdmVQcm9taXNlKHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfZXJyb3JTdGVwczogcmVhc29uID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vbmdvaW5nUHJvbWlzZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0ZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHJlYWRlcik7XG4gICAgICAgICAgICAgICAgcmVqZWN0UHJvbWlzZShyZWFzb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJSZWFkKHJlYWRlciwgcmVhZFJlcXVlc3QpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgX3JldHVyblN0ZXBzKHZhbHVlKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsgdmFsdWUsIGRvbmU6IHRydWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faXNGaW5pc2hlZCA9IHRydWU7XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHRoaXMuX3JlYWRlcjtcbiAgICAgICAgaWYgKHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFkZXJMb2NrRXhjZXB0aW9uKCdmaW5pc2ggaXRlcmF0aW5nJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fcHJldmVudENhbmNlbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljQ2FuY2VsKHJlYWRlciwgdmFsdWUpO1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKHJlc3VsdCwgKCkgPT4gKHsgdmFsdWUsIGRvbmU6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKTtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgoeyB2YWx1ZSwgZG9uZTogdHJ1ZSB9KTtcbiAgICB9XG59XG5jb25zdCBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JQcm90b3R5cGUgPSB7XG4gICAgbmV4dCgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQXN5bmNJdGVyYXRvckJyYW5kQ2hlY2tFeGNlcHRpb24oJ25leHQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2FzeW5jSXRlcmF0b3JJbXBsLm5leHQoKTtcbiAgICB9LFxuICAgIHJldHVybih2YWx1ZSkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW1Bc3luY0l0ZXJhdG9yQnJhbmRDaGVja0V4Y2VwdGlvbigncmV0dXJuJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hc3luY0l0ZXJhdG9ySW1wbC5yZXR1cm4odmFsdWUpO1xuICAgIH1cbn07XG5pZiAoQXN5bmNJdGVyYXRvclByb3RvdHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKFJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvclByb3RvdHlwZSwgQXN5bmNJdGVyYXRvclByb3RvdHlwZSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW0uXG5mdW5jdGlvbiBBY3F1aXJlUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yKHN0cmVhbSwgcHJldmVudENhbmNlbCkge1xuICAgIGNvbnN0IHJlYWRlciA9IEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKTtcbiAgICBjb25zdCBpbXBsID0gbmV3IFJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvckltcGwocmVhZGVyLCBwcmV2ZW50Q2FuY2VsKTtcbiAgICBjb25zdCBpdGVyYXRvciA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlKTtcbiAgICBpdGVyYXRvci5fYXN5bmNJdGVyYXRvckltcGwgPSBpbXBsO1xuICAgIHJldHVybiBpdGVyYXRvcjtcbn1cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfYXN5bmNJdGVyYXRvckltcGwnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQXN5bmNJdGVyYXRvckJyYW5kQ2hlY2tFeGNlcHRpb24obmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVTdGVhbUFzeW5jSXRlcmF0b3JgKTtcbn1cblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZXMyMDE1LmNvcmVcIiAvPlxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvTnVtYmVyL2lzTmFOI1BvbHlmaWxsXG5jb25zdCBOdW1iZXJJc05hTiA9IE51bWJlci5pc05hTiB8fCBmdW5jdGlvbiAoeCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4geCAhPT0geDtcbn07XG5cbmZ1bmN0aW9uIElzRmluaXRlTm9uTmVnYXRpdmVOdW1iZXIodikge1xuICAgIGlmICghSXNOb25OZWdhdGl2ZU51bWJlcih2KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh2ID09PSBJbmZpbml0eSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gSXNOb25OZWdhdGl2ZU51bWJlcih2KSB7XG4gICAgaWYgKHR5cGVvZiB2ICE9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChOdW1iZXJJc05hTih2KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh2IDwgMCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBEZXF1ZXVlVmFsdWUoY29udGFpbmVyKSB7XG4gICAgY29uc3QgcGFpciA9IGNvbnRhaW5lci5fcXVldWUuc2hpZnQoKTtcbiAgICBjb250YWluZXIuX3F1ZXVlVG90YWxTaXplIC09IHBhaXIuc2l6ZTtcbiAgICBpZiAoY29udGFpbmVyLl9xdWV1ZVRvdGFsU2l6ZSA8IDApIHtcbiAgICAgICAgY29udGFpbmVyLl9xdWV1ZVRvdGFsU2l6ZSA9IDA7XG4gICAgfVxuICAgIHJldHVybiBwYWlyLnZhbHVlO1xufVxuZnVuY3Rpb24gRW5xdWV1ZVZhbHVlV2l0aFNpemUoY29udGFpbmVyLCB2YWx1ZSwgc2l6ZSkge1xuICAgIHNpemUgPSBOdW1iZXIoc2l6ZSk7XG4gICAgaWYgKCFJc0Zpbml0ZU5vbk5lZ2F0aXZlTnVtYmVyKHNpemUpKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdTaXplIG11c3QgYmUgYSBmaW5pdGUsIG5vbi1OYU4sIG5vbi1uZWdhdGl2ZSBudW1iZXIuJyk7XG4gICAgfVxuICAgIGNvbnRhaW5lci5fcXVldWUucHVzaCh7IHZhbHVlLCBzaXplIH0pO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgKz0gc2l6ZTtcbn1cbmZ1bmN0aW9uIFBlZWtRdWV1ZVZhbHVlKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IHBhaXIgPSBjb250YWluZXIuX3F1ZXVlLnBlZWsoKTtcbiAgICByZXR1cm4gcGFpci52YWx1ZTtcbn1cbmZ1bmN0aW9uIFJlc2V0UXVldWUoY29udGFpbmVyKSB7XG4gICAgY29udGFpbmVyLl9xdWV1ZSA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgPSAwO1xufVxuXG5mdW5jdGlvbiBDcmVhdGVBcnJheUZyb21MaXN0KGVsZW1lbnRzKSB7XG4gICAgLy8gV2UgdXNlIGFycmF5cyB0byByZXByZXNlbnQgbGlzdHMsIHNvIHRoaXMgaXMgYmFzaWNhbGx5IGEgbm8tb3AuXG4gICAgLy8gRG8gYSBzbGljZSB0aG91Z2gganVzdCBpbiBjYXNlIHdlIGhhcHBlbiB0byBkZXBlbmQgb24gdGhlIHVuaXF1ZS1uZXNzLlxuICAgIHJldHVybiBlbGVtZW50cy5zbGljZSgpO1xufVxuZnVuY3Rpb24gQ29weURhdGFCbG9ja0J5dGVzKGRlc3QsIGRlc3RPZmZzZXQsIHNyYywgc3JjT2Zmc2V0LCBuKSB7XG4gICAgbmV3IFVpbnQ4QXJyYXkoZGVzdCkuc2V0KG5ldyBVaW50OEFycmF5KHNyYywgc3JjT2Zmc2V0LCBuKSwgZGVzdE9mZnNldCk7XG59XG4vLyBOb3QgaW1wbGVtZW50ZWQgY29ycmVjdGx5XG5mdW5jdGlvbiBUcmFuc2ZlckFycmF5QnVmZmVyKE8pIHtcbiAgICByZXR1cm4gTztcbn1cbi8vIE5vdCBpbXBsZW1lbnRlZCBjb3JyZWN0bHlcbmZ1bmN0aW9uIElzRGV0YWNoZWRCdWZmZXIoTykge1xuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBBIHB1bGwtaW50byByZXF1ZXN0IGluIGEge0BsaW5rIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJ9LlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgY29uc3RydWN0b3InKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmlldyBmb3Igd3JpdGluZyBpbiB0bywgb3IgYG51bGxgIGlmIHRoZSBCWU9CIHJlcXVlc3QgaGFzIGFscmVhZHkgYmVlbiByZXNwb25kZWQgdG8uXG4gICAgICovXG4gICAgZ2V0IHZpZXcoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieW9iUmVxdWVzdEJyYW5kQ2hlY2tFeGNlcHRpb24oJ3ZpZXcnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fdmlldztcbiAgICB9XG4gICAgcmVzcG9uZChieXRlc1dyaXR0ZW4pIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbigncmVzcG9uZCcpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQoYnl0ZXNXcml0dGVuLCAxLCAncmVzcG9uZCcpO1xuICAgICAgICBieXRlc1dyaXR0ZW4gPSBjb252ZXJ0VW5zaWduZWRMb25nTG9uZ1dpdGhFbmZvcmNlUmFuZ2UoYnl0ZXNXcml0dGVuLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIGlmICh0aGlzLl9hc3NvY2lhdGVkUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGlzIEJZT0IgcmVxdWVzdCBoYXMgYmVlbiBpbnZhbGlkYXRlZCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc0RldGFjaGVkQnVmZmVyKHRoaXMuX3ZpZXcuYnVmZmVyKSkgO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZCh0aGlzLl9hc3NvY2lhdGVkUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciwgYnl0ZXNXcml0dGVuKTtcbiAgICB9XG4gICAgcmVzcG9uZFdpdGhOZXdWaWV3KHZpZXcpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbigncmVzcG9uZFdpdGhOZXdWaWV3Jyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudCh2aWV3LCAxLCAncmVzcG9uZFdpdGhOZXdWaWV3Jyk7XG4gICAgICAgIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KHZpZXcpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdZb3UgY2FuIG9ubHkgcmVzcG9uZCB3aXRoIGFycmF5IGJ1ZmZlciB2aWV3cycpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2aWV3LmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NodW5rIG11c3QgaGF2ZSBub24temVybyBieXRlTGVuZ3RoJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpZXcuYnVmZmVyLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGNodW5rJ3MgYnVmZmVyIG11c3QgaGF2ZSBub24temVybyBieXRlTGVuZ3RoYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoaXMgQllPQiByZXF1ZXN0IGhhcyBiZWVuIGludmFsaWRhdGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRXaXRoTmV3Vmlldyh0aGlzLl9hc3NvY2lhdGVkUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciwgdmlldyk7XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdC5wcm90b3R5cGUsIHtcbiAgICByZXNwb25kOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZXNwb25kV2l0aE5ld1ZpZXc6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHZpZXc6IHsgZW51bWVyYWJsZTogdHJ1ZSB9XG59KTtcbmlmICh0eXBlb2YgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1JlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QnLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbi8qKlxuICogQWxsb3dzIGNvbnRyb2wgb2YgYSB7QGxpbmsgUmVhZGFibGVTdHJlYW0gfCByZWFkYWJsZSBieXRlIHN0cmVhbX0ncyBzdGF0ZSBhbmQgaW50ZXJuYWwgcXVldWUuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IEJZT0IgcHVsbCByZXF1ZXN0LCBvciBgbnVsbGAgaWYgdGhlcmUgaXNuJ3Qgb25lLlxuICAgICAqL1xuICAgIGdldCBieW9iUmVxdWVzdCgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVTdHJlYW1Db250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbignYnlvYlJlcXVlc3QnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fYnlvYlJlcXVlc3QgPT09IG51bGwgJiYgdGhpcy5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBmaXJzdERlc2NyaXB0b3IgPSB0aGlzLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICAgICAgICAgIGNvbnN0IHZpZXcgPSBuZXcgVWludDhBcnJheShmaXJzdERlc2NyaXB0b3IuYnVmZmVyLCBmaXJzdERlc2NyaXB0b3IuYnl0ZU9mZnNldCArIGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCwgZmlyc3REZXNjcmlwdG9yLmJ5dGVMZW5ndGggLSBmaXJzdERlc2NyaXB0b3IuYnl0ZXNGaWxsZWQpO1xuICAgICAgICAgICAgY29uc3QgYnlvYlJlcXVlc3QgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlKTtcbiAgICAgICAgICAgIFNldFVwUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdChieW9iUmVxdWVzdCwgdGhpcywgdmlldyk7XG4gICAgICAgICAgICB0aGlzLl9ieW9iUmVxdWVzdCA9IGJ5b2JSZXF1ZXN0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9ieW9iUmVxdWVzdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIGNvbnRyb2xsZWQgc3RyZWFtJ3MgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzXG4gICAgICogb3Zlci1mdWxsLiBBbiB1bmRlcmx5aW5nIGJ5dGUgc291cmNlIG91Z2h0IHRvIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSB3aGVuIGFuZCBob3cgdG8gYXBwbHkgYmFja3ByZXNzdXJlLlxuICAgICAqL1xuICAgIGdldCBkZXNpcmVkU2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVTdHJlYW1Db250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbignZGVzaXJlZFNpemUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldERlc2lyZWRTaXplKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIGNvbnRyb2xsZWQgcmVhZGFibGUgc3RyZWFtLiBDb25zdW1lcnMgd2lsbCBzdGlsbCBiZSBhYmxlIHRvIHJlYWQgYW55IHByZXZpb3VzbHktZW5xdWV1ZWQgY2h1bmtzIGZyb21cbiAgICAgKiB0aGUgc3RyZWFtLCBidXQgb25jZSB0aG9zZSBhcmUgcmVhZCwgdGhlIHN0cmVhbSB3aWxsIGJlY29tZSBjbG9zZWQuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlU3RyZWFtQ29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2Nsb3NlUmVxdWVzdGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkOyBkbyBub3QgY2xvc2UgaXQgYWdhaW4hJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICAgICAgaWYgKHN0YXRlICE9PSAncmVhZGFibGUnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgc3RyZWFtIChpbiAke3N0YXRlfSBzdGF0ZSkgaXMgbm90IGluIHRoZSByZWFkYWJsZSBzdGF0ZSBhbmQgY2Fubm90IGJlIGNsb3NlZGApO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuaykge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlbnF1ZXVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChjaHVuaywgMSwgJ2VucXVldWUnKTtcbiAgICAgICAgaWYgKCFBcnJheUJ1ZmZlci5pc1ZpZXcoY2h1bmspKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjaHVuayBtdXN0IGJlIGFuIGFycmF5IGJ1ZmZlciB2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NodW5rIG11c3QgaGF2ZSBub24temVybyBieXRlTGVuZ3RoJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNodW5rLmJ1ZmZlci5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBjaHVuaydzIGJ1ZmZlciBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aGApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9jbG9zZVJlcXVlc3RlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc3RyZWFtIGlzIGNsb3NlZCBvciBkcmFpbmluZycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbS5fc3RhdGU7XG4gICAgICAgIGlmIChzdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHN0cmVhbSAoaW4gJHtzdGF0ZX0gc3RhdGUpIGlzIG5vdCBpbiB0aGUgcmVhZGFibGUgc3RhdGUgYW5kIGNhbm5vdCBiZSBlbnF1ZXVlZCB0b2ApO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlKHRoaXMsIGNodW5rKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXJyb3JzIHRoZSBjb250cm9sbGVkIHJlYWRhYmxlIHN0cmVhbSwgbWFraW5nIGFsbCBmdXR1cmUgaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuXG4gICAgICovXG4gICAgZXJyb3IoZSA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcih0aGlzLCBlKTtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtDYW5jZWxTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIGlmICh0aGlzLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0RGVzY3JpcHRvciA9IHRoaXMuX3BlbmRpbmdQdWxsSW50b3MucGVlaygpO1xuICAgICAgICAgICAgZmlyc3REZXNjcmlwdG9yLmJ5dGVzRmlsbGVkID0gMDtcbiAgICAgICAgfVxuICAgICAgICBSZXNldFF1ZXVlKHRoaXMpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9jYW5jZWxBbGdvcml0aG0ocmVhc29uKTtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtQdWxsU3RlcHNdKHJlYWRSZXF1ZXN0KSB7XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgICAgIGlmICh0aGlzLl9xdWV1ZVRvdGFsU2l6ZSA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5fcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgIHRoaXMuX3F1ZXVlVG90YWxTaXplIC09IGVudHJ5LmJ5dGVMZW5ndGg7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbih0aGlzKTtcbiAgICAgICAgICAgIGNvbnN0IHZpZXcgPSBuZXcgVWludDhBcnJheShlbnRyeS5idWZmZXIsIGVudHJ5LmJ5dGVPZmZzZXQsIGVudHJ5LmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgcmVhZFJlcXVlc3QuX2NodW5rU3RlcHModmlldyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXV0b0FsbG9jYXRlQ2h1bmtTaXplID0gdGhpcy5fYXV0b0FsbG9jYXRlQ2h1bmtTaXplO1xuICAgICAgICBpZiAoYXV0b0FsbG9jYXRlQ2h1bmtTaXplICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxldCBidWZmZXI7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihhdXRvQWxsb2NhdGVDaHVua1NpemUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGJ1ZmZlckUpIHtcbiAgICAgICAgICAgICAgICByZWFkUmVxdWVzdC5fZXJyb3JTdGVwcyhidWZmZXJFKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBwdWxsSW50b0Rlc2NyaXB0b3IgPSB7XG4gICAgICAgICAgICAgICAgYnVmZmVyLFxuICAgICAgICAgICAgICAgIGJ5dGVPZmZzZXQ6IDAsXG4gICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogYXV0b0FsbG9jYXRlQ2h1bmtTaXplLFxuICAgICAgICAgICAgICAgIGJ5dGVzRmlsbGVkOiAwLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRTaXplOiAxLFxuICAgICAgICAgICAgICAgIHZpZXdDb25zdHJ1Y3RvcjogVWludDhBcnJheSxcbiAgICAgICAgICAgICAgICByZWFkZXJUeXBlOiAnZGVmYXVsdCdcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9wZW5kaW5nUHVsbEludG9zLnB1c2gocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbUFkZFJlYWRSZXF1ZXN0KHN0cmVhbSwgcmVhZFJlcXVlc3QpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSwge1xuICAgIGNsb3NlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlbnF1ZXVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgYnlvYlJlcXVlc3Q6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGRlc2lyZWRTaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5cbmZ1bmN0aW9uIElzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gSXNSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0KHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHNob3VsZFB1bGwgPSBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hvdWxkQ2FsbFB1bGwoY29udHJvbGxlcik7XG4gICAgaWYgKCFzaG91bGRQdWxsKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNvbnRyb2xsZXIuX3B1bGxpbmcpIHtcbiAgICAgICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb250cm9sbGVyLl9wdWxsaW5nID0gdHJ1ZTtcbiAgICAvLyBUT0RPOiBUZXN0IGNvbnRyb2xsZXIgYXJndW1lbnRcbiAgICBjb25zdCBwdWxsUHJvbWlzZSA9IGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0oKTtcbiAgICB1cG9uUHJvbWlzZShwdWxsUHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICBjb250cm9sbGVyLl9wdWxsaW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChjb250cm9sbGVyLl9wdWxsQWdhaW4pIHtcbiAgICAgICAgICAgIGNvbnRyb2xsZXIuX3B1bGxBZ2FpbiA9IGZhbHNlO1xuICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG4gICAgICAgIH1cbiAgICB9LCBlID0+IHtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGUpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyUGVuZGluZ1B1bGxJbnRvcyhjb250cm9sbGVyKSB7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckludmFsaWRhdGVCWU9CUmVxdWVzdChjb250cm9sbGVyKTtcbiAgICBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ29tbWl0UHVsbEludG9EZXNjcmlwdG9yKHN0cmVhbSwgcHVsbEludG9EZXNjcmlwdG9yKSB7XG4gICAgbGV0IGRvbmUgPSBmYWxzZTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGZpbGxlZFZpZXcgPSBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ29udmVydFB1bGxJbnRvRGVzY3JpcHRvcihwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgIGlmIChwdWxsSW50b0Rlc2NyaXB0b3IucmVhZGVyVHlwZSA9PT0gJ2RlZmF1bHQnKSB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRSZXF1ZXN0KHN0cmVhbSwgZmlsbGVkVmlldywgZG9uZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbUZ1bGZpbGxSZWFkSW50b1JlcXVlc3Qoc3RyZWFtLCBmaWxsZWRWaWV3LCBkb25lKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ29udmVydFB1bGxJbnRvRGVzY3JpcHRvcihwdWxsSW50b0Rlc2NyaXB0b3IpIHtcbiAgICBjb25zdCBieXRlc0ZpbGxlZCA9IHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZDtcbiAgICBjb25zdCBlbGVtZW50U2l6ZSA9IHB1bGxJbnRvRGVzY3JpcHRvci5lbGVtZW50U2l6ZTtcbiAgICByZXR1cm4gbmV3IHB1bGxJbnRvRGVzY3JpcHRvci52aWV3Q29uc3RydWN0b3IocHVsbEludG9EZXNjcmlwdG9yLmJ1ZmZlciwgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVPZmZzZXQsIGJ5dGVzRmlsbGVkIC8gZWxlbWVudFNpemUpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSB7XG4gICAgY29udHJvbGxlci5fcXVldWUucHVzaCh7IGJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCB9KTtcbiAgICBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSArPSBieXRlTGVuZ3RoO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxQdWxsSW50b0Rlc2NyaXB0b3JGcm9tUXVldWUoY29udHJvbGxlciwgcHVsbEludG9EZXNjcmlwdG9yKSB7XG4gICAgY29uc3QgZWxlbWVudFNpemUgPSBwdWxsSW50b0Rlc2NyaXB0b3IuZWxlbWVudFNpemU7XG4gICAgY29uc3QgY3VycmVudEFsaWduZWRCeXRlcyA9IHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZCAtIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZCAlIGVsZW1lbnRTaXplO1xuICAgIGNvbnN0IG1heEJ5dGVzVG9Db3B5ID0gTWF0aC5taW4oY29udHJvbGxlci5fcXVldWVUb3RhbFNpemUsIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlTGVuZ3RoIC0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkKTtcbiAgICBjb25zdCBtYXhCeXRlc0ZpbGxlZCA9IHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZCArIG1heEJ5dGVzVG9Db3B5O1xuICAgIGNvbnN0IG1heEFsaWduZWRCeXRlcyA9IG1heEJ5dGVzRmlsbGVkIC0gbWF4Qnl0ZXNGaWxsZWQgJSBlbGVtZW50U2l6ZTtcbiAgICBsZXQgdG90YWxCeXRlc1RvQ29weVJlbWFpbmluZyA9IG1heEJ5dGVzVG9Db3B5O1xuICAgIGxldCByZWFkeSA9IGZhbHNlO1xuICAgIGlmIChtYXhBbGlnbmVkQnl0ZXMgPiBjdXJyZW50QWxpZ25lZEJ5dGVzKSB7XG4gICAgICAgIHRvdGFsQnl0ZXNUb0NvcHlSZW1haW5pbmcgPSBtYXhBbGlnbmVkQnl0ZXMgLSBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQ7XG4gICAgICAgIHJlYWR5ID0gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgcXVldWUgPSBjb250cm9sbGVyLl9xdWV1ZTtcbiAgICB3aGlsZSAodG90YWxCeXRlc1RvQ29weVJlbWFpbmluZyA+IDApIHtcbiAgICAgICAgY29uc3QgaGVhZE9mUXVldWUgPSBxdWV1ZS5wZWVrKCk7XG4gICAgICAgIGNvbnN0IGJ5dGVzVG9Db3B5ID0gTWF0aC5taW4odG90YWxCeXRlc1RvQ29weVJlbWFpbmluZywgaGVhZE9mUXVldWUuYnl0ZUxlbmd0aCk7XG4gICAgICAgIGNvbnN0IGRlc3RTdGFydCA9IHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlT2Zmc2V0ICsgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkO1xuICAgICAgICBDb3B5RGF0YUJsb2NrQnl0ZXMocHVsbEludG9EZXNjcmlwdG9yLmJ1ZmZlciwgZGVzdFN0YXJ0LCBoZWFkT2ZRdWV1ZS5idWZmZXIsIGhlYWRPZlF1ZXVlLmJ5dGVPZmZzZXQsIGJ5dGVzVG9Db3B5KTtcbiAgICAgICAgaWYgKGhlYWRPZlF1ZXVlLmJ5dGVMZW5ndGggPT09IGJ5dGVzVG9Db3B5KSB7XG4gICAgICAgICAgICBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaGVhZE9mUXVldWUuYnl0ZU9mZnNldCArPSBieXRlc1RvQ29weTtcbiAgICAgICAgICAgIGhlYWRPZlF1ZXVlLmJ5dGVMZW5ndGggLT0gYnl0ZXNUb0NvcHk7XG4gICAgICAgIH1cbiAgICAgICAgY29udHJvbGxlci5fcXVldWVUb3RhbFNpemUgLT0gYnl0ZXNUb0NvcHk7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsSGVhZFB1bGxJbnRvRGVzY3JpcHRvcihjb250cm9sbGVyLCBieXRlc1RvQ29weSwgcHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgdG90YWxCeXRlc1RvQ29weVJlbWFpbmluZyAtPSBieXRlc1RvQ29weTtcbiAgICB9XG4gICAgcmV0dXJuIHJlYWR5O1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxIZWFkUHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIsIHNpemUsIHB1bGxJbnRvRGVzY3JpcHRvcikge1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJJbnZhbGlkYXRlQllPQlJlcXVlc3QoY29udHJvbGxlcik7XG4gICAgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICs9IHNpemU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbihjb250cm9sbGVyKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID09PSAwICYmIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQ2xvc2UoY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySW52YWxpZGF0ZUJZT0JSZXF1ZXN0KGNvbnRyb2xsZXIpIHtcbiAgICBpZiAoY29udHJvbGxlci5fYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb250cm9sbGVyLl9ieW9iUmVxdWVzdC5fYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIgPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYnlvYlJlcXVlc3QuX3ZpZXcgPSBudWxsO1xuICAgIGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID0gbnVsbDtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJQcm9jZXNzUHVsbEludG9EZXNjcmlwdG9yc1VzaW5nUXVldWUoY29udHJvbGxlcikge1xuICAgIHdoaWxlIChjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHVsbEludG9EZXNjcmlwdG9yID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgICAgIGlmIChSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpKSB7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8oY29udHJvbGxlcik7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ29tbWl0UHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8oY29udHJvbGxlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBsZXQgZWxlbWVudFNpemUgPSAxO1xuICAgIGlmICh2aWV3LmNvbnN0cnVjdG9yICE9PSBEYXRhVmlldykge1xuICAgICAgICBlbGVtZW50U2l6ZSA9IHZpZXcuY29uc3RydWN0b3IuQllURVNfUEVSX0VMRU1FTlQ7XG4gICAgfVxuICAgIGNvbnN0IGN0b3IgPSB2aWV3LmNvbnN0cnVjdG9yO1xuICAgIGNvbnN0IGJ1ZmZlciA9IFRyYW5zZmVyQXJyYXlCdWZmZXIodmlldy5idWZmZXIpO1xuICAgIGNvbnN0IHB1bGxJbnRvRGVzY3JpcHRvciA9IHtcbiAgICAgICAgYnVmZmVyLFxuICAgICAgICBieXRlT2Zmc2V0OiB2aWV3LmJ5dGVPZmZzZXQsXG4gICAgICAgIGJ5dGVMZW5ndGg6IHZpZXcuYnl0ZUxlbmd0aCxcbiAgICAgICAgYnl0ZXNGaWxsZWQ6IDAsXG4gICAgICAgIGVsZW1lbnRTaXplLFxuICAgICAgICB2aWV3Q29uc3RydWN0b3I6IGN0b3IsXG4gICAgICAgIHJlYWRlclR5cGU6ICdieW9iJ1xuICAgIH07XG4gICAgaWYgKGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MubGVuZ3RoID4gMCkge1xuICAgICAgICBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnB1c2gocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgLy8gTm8gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoKSBjYWxsIHNpbmNlOlxuICAgICAgICAvLyAtIE5vIGNoYW5nZSBoYXBwZW5zIG9uIGRlc2lyZWRTaXplXG4gICAgICAgIC8vIC0gVGhlIHNvdXJjZSBoYXMgYWxyZWFkeSBiZWVuIG5vdGlmaWVkIG9mIHRoYXQgdGhlcmUncyBhdCBsZWFzdCAxIHBlbmRpbmcgcmVhZCh2aWV3KVxuICAgICAgICBSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIGNvbnN0IGVtcHR5VmlldyA9IG5ldyBjdG9yKHB1bGxJbnRvRGVzY3JpcHRvci5idWZmZXIsIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlT2Zmc2V0LCAwKTtcbiAgICAgICAgcmVhZEludG9SZXF1ZXN0Ll9jbG9zZVN0ZXBzKGVtcHR5Vmlldyk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID4gMCkge1xuICAgICAgICBpZiAoUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxQdWxsSW50b0Rlc2NyaXB0b3JGcm9tUXVldWUoY29udHJvbGxlciwgcHVsbEludG9EZXNjcmlwdG9yKSkge1xuICAgICAgICAgICAgY29uc3QgZmlsbGVkVmlldyA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb252ZXJ0UHVsbEludG9EZXNjcmlwdG9yKHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbihjb250cm9sbGVyKTtcbiAgICAgICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fY2h1bmtTdGVwcyhmaWxsZWRWaWV3KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udHJvbGxlci5fY2xvc2VSZXF1ZXN0ZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGUgPSBuZXcgVHlwZUVycm9yKCdJbnN1ZmZpY2llbnQgYnl0ZXMgdG8gZmlsbCBlbGVtZW50cyBpbiB0aGUgZ2l2ZW4gYnVmZmVyJyk7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSk7XG4gICAgICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Vycm9yU3RlcHMoZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wdXNoKHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgUmVhZGFibGVTdHJlYW1BZGRSZWFkSW50b1JlcXVlc3Qoc3RyZWFtLCByZWFkSW50b1JlcXVlc3QpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRJbkNsb3NlZFN0YXRlKGNvbnRyb2xsZXIsIGZpcnN0RGVzY3JpcHRvcikge1xuICAgIGZpcnN0RGVzY3JpcHRvci5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKGZpcnN0RGVzY3JpcHRvci5idWZmZXIpO1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgaWYgKFJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIHdoaWxlIChSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRJbnRvUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHB1bGxJbnRvRGVzY3JpcHRvciA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaGlmdFBlbmRpbmdQdWxsSW50byhjb250cm9sbGVyKTtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb21taXRQdWxsSW50b0Rlc2NyaXB0b3Ioc3RyZWFtLCBwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRJblJlYWRhYmxlU3RhdGUoY29udHJvbGxlciwgYnl0ZXNXcml0dGVuLCBwdWxsSW50b0Rlc2NyaXB0b3IpIHtcbiAgICBpZiAocHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICsgYnl0ZXNXcml0dGVuID4gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2J5dGVzV3JpdHRlbiBvdXQgb2YgcmFuZ2UnKTtcbiAgICB9XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxIZWFkUHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIsIGJ5dGVzV3JpdHRlbiwgcHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICBpZiAocHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkIDwgcHVsbEludG9EZXNjcmlwdG9yLmVsZW1lbnRTaXplKSB7XG4gICAgICAgIC8vIFRPRE86IEZpZ3VyZSBvdXQgd2hldGhlciB3ZSBzaG91bGQgZGV0YWNoIHRoZSBidWZmZXIgb3Igbm90IGhlcmUuXG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclNoaWZ0UGVuZGluZ1B1bGxJbnRvKGNvbnRyb2xsZXIpO1xuICAgIGNvbnN0IHJlbWFpbmRlclNpemUgPSBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQgJSBwdWxsSW50b0Rlc2NyaXB0b3IuZWxlbWVudFNpemU7XG4gICAgaWYgKHJlbWFpbmRlclNpemUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGVuZCA9IHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlT2Zmc2V0ICsgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkO1xuICAgICAgICBjb25zdCByZW1haW5kZXIgPSBwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLnNsaWNlKGVuZCAtIHJlbWFpbmRlclNpemUsIGVuZCk7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlQ2h1bmtUb1F1ZXVlKGNvbnRyb2xsZXIsIHJlbWFpbmRlciwgMCwgcmVtYWluZGVyLmJ5dGVMZW5ndGgpO1xuICAgIH1cbiAgICBwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyID0gVHJhbnNmZXJBcnJheUJ1ZmZlcihwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyKTtcbiAgICBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQgLT0gcmVtYWluZGVyU2l6ZTtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ29tbWl0UHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclByb2Nlc3NQdWxsSW50b0Rlc2NyaXB0b3JzVXNpbmdRdWV1ZShjb250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW50ZXJuYWwoY29udHJvbGxlciwgYnl0ZXNXcml0dGVuKSB7XG4gICAgY29uc3QgZmlyc3REZXNjcmlwdG9yID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIGlmIChieXRlc1dyaXR0ZW4gIT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2J5dGVzV3JpdHRlbiBtdXN0IGJlIDAgd2hlbiBjYWxsaW5nIHJlc3BvbmQoKSBvbiBhIGNsb3NlZCBzdHJlYW0nKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluQ2xvc2VkU3RhdGUoY29udHJvbGxlciwgZmlyc3REZXNjcmlwdG9yKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5SZWFkYWJsZVN0YXRlKGNvbnRyb2xsZXIsIGJ5dGVzV3JpdHRlbiwgZmlyc3REZXNjcmlwdG9yKTtcbiAgICB9XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8oY29udHJvbGxlcikge1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnNoaWZ0KCk7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckludmFsaWRhdGVCWU9CUmVxdWVzdChjb250cm9sbGVyKTtcbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghY29udHJvbGxlci5fc3RhcnRlZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChSZWFkYWJsZVN0cmVhbUhhc0RlZmF1bHRSZWFkZXIoc3RyZWFtKSAmJiBSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKFJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlcihzdHJlYW0pICYmIFJlYWRhYmxlU3RyZWFtR2V0TnVtUmVhZEludG9SZXF1ZXN0cyhzdHJlYW0pID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZGVzaXJlZFNpemUgPSBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyR2V0RGVzaXJlZFNpemUoY29udHJvbGxlcik7XG4gICAgaWYgKGRlc2lyZWRTaXplID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKSB7XG4gICAgY29udHJvbGxlci5fcHVsbEFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9jYW5jZWxBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG59XG4vLyBBIGNsaWVudCBvZiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIG1heSB1c2UgdGhlc2UgZnVuY3Rpb25zIGRpcmVjdGx5IHRvIGJ5cGFzcyBzdGF0ZSBjaGVjay5cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoY29udHJvbGxlci5fY2xvc2VSZXF1ZXN0ZWQgfHwgc3RyZWFtLl9zdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSA+IDApIHtcbiAgICAgICAgY29udHJvbGxlci5fY2xvc2VSZXF1ZXN0ZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZmlyc3RQZW5kaW5nUHVsbEludG8gPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICAgICAgaWYgKGZpcnN0UGVuZGluZ1B1bGxJbnRvLmJ5dGVzRmlsbGVkID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZSA9IG5ldyBUeXBlRXJyb3IoJ0luc3VmZmljaWVudCBieXRlcyB0byBmaWxsIGVsZW1lbnRzIGluIHRoZSBnaXZlbiBidWZmZXInKTtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKTtcbiAgICBSZWFkYWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgaWYgKGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkIHx8IHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBidWZmZXIgPSBjaHVuay5idWZmZXI7XG4gICAgY29uc3QgYnl0ZU9mZnNldCA9IGNodW5rLmJ5dGVPZmZzZXQ7XG4gICAgY29uc3QgYnl0ZUxlbmd0aCA9IGNodW5rLmJ5dGVMZW5ndGg7XG4gICAgY29uc3QgdHJhbnNmZXJyZWRCdWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKGJ1ZmZlcik7XG4gICAgaWYgKFJlYWRhYmxlU3RyZWFtSGFzRGVmYXVsdFJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIGlmIChSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pID09PSAwKSB7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCB0cmFuc2ZlcnJlZEJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2ZlcnJlZFZpZXcgPSBuZXcgVWludDhBcnJheSh0cmFuc2ZlcnJlZEJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUZ1bGZpbGxSZWFkUmVxdWVzdChzdHJlYW0sIHRyYW5zZmVycmVkVmlldywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKFJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIC8vIFRPRE86IElkZWFsbHkgaW4gdGhpcyBicmFuY2ggZGV0YWNoaW5nIHNob3VsZCBoYXBwZW4gb25seSBpZiB0aGUgYnVmZmVyIGlzIG5vdCBjb25zdW1lZCBmdWxseS5cbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgdHJhbnNmZXJyZWRCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHJvY2Vzc1B1bGxJbnRvRGVzY3JpcHRvcnNVc2luZ1F1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgdHJhbnNmZXJyZWRCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgIH1cbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhclBlbmRpbmdQdWxsSW50b3MoY29udHJvbGxlcik7XG4gICAgUmVzZXRRdWV1ZShjb250cm9sbGVyKTtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgIFJlYWRhYmxlU3RyZWFtRXJyb3Ioc3RyZWFtLCBlKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNIC0gY29udHJvbGxlci5fcXVldWVUb3RhbFNpemU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZChjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4pIHtcbiAgICBieXRlc1dyaXR0ZW4gPSBOdW1iZXIoYnl0ZXNXcml0dGVuKTtcbiAgICBpZiAoIUlzRmluaXRlTm9uTmVnYXRpdmVOdW1iZXIoYnl0ZXNXcml0dGVuKSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYnl0ZXNXcml0dGVuIG11c3QgYmUgYSBmaW5pdGUnKTtcbiAgICB9XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRJbnRlcm5hbChjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4pO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRXaXRoTmV3Vmlldyhjb250cm9sbGVyLCB2aWV3KSB7XG4gICAgY29uc3QgZmlyc3REZXNjcmlwdG9yID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgaWYgKGZpcnN0RGVzY3JpcHRvci5ieXRlT2Zmc2V0ICsgZmlyc3REZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICE9PSB2aWV3LmJ5dGVPZmZzZXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSByZWdpb24gc3BlY2lmaWVkIGJ5IHZpZXcgZG9lcyBub3QgbWF0Y2ggYnlvYlJlcXVlc3QnKTtcbiAgICB9XG4gICAgaWYgKGZpcnN0RGVzY3JpcHRvci5ieXRlTGVuZ3RoICE9PSB2aWV3LmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBidWZmZXIgb2YgdmlldyBoYXMgZGlmZmVyZW50IGNhcGFjaXR5IHRoYW4gYnlvYlJlcXVlc3QnKTtcbiAgICB9XG4gICAgZmlyc3REZXNjcmlwdG9yLmJ1ZmZlciA9IHZpZXcuYnVmZmVyO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW50ZXJuYWwoY29udHJvbGxlciwgdmlldy5ieXRlTGVuZ3RoKTtcbn1cbmZ1bmN0aW9uIFNldFVwUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcihzdHJlYW0sIGNvbnRyb2xsZXIsIHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmssIGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSkge1xuICAgIGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0gPSBzdHJlYW07XG4gICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fcHVsbGluZyA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID0gbnVsbDtcbiAgICAvLyBOZWVkIHRvIHNldCB0aGUgc2xvdHMgc28gdGhhdCB0aGUgYXNzZXJ0IGRvZXNuJ3QgZmlyZS4gSW4gdGhlIHNwZWMgdGhlIHNsb3RzIGFscmVhZHkgZXhpc3QgaW1wbGljaXRseS5cbiAgICBjb250cm9sbGVyLl9xdWV1ZSA9IGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID0gdW5kZWZpbmVkO1xuICAgIFJlc2V0UXVldWUoY29udHJvbGxlcik7XG4gICAgY29udHJvbGxlci5fY2xvc2VSZXF1ZXN0ZWQgPSBmYWxzZTtcbiAgICBjb250cm9sbGVyLl9zdGFydGVkID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lIV00gPSBoaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0gPSBwdWxsQWxnb3JpdGhtO1xuICAgIGNvbnRyb2xsZXIuX2NhbmNlbEFsZ29yaXRobSA9IGNhbmNlbEFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9hdXRvQWxsb2NhdGVDaHVua1NpemUgPSBhdXRvQWxsb2NhdGVDaHVua1NpemU7XG4gICAgY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcyA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIHN0cmVhbS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyID0gY29udHJvbGxlcjtcbiAgICBjb25zdCBzdGFydFJlc3VsdCA9IHN0YXJ0QWxnb3JpdGhtKCk7XG4gICAgdXBvblByb21pc2UocHJvbWlzZVJlc29sdmVkV2l0aChzdGFydFJlc3VsdCksICgpID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpO1xuICAgIH0sIHIgPT4ge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgcik7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGcm9tVW5kZXJseWluZ1NvdXJjZShzdHJlYW0sIHVuZGVybHlpbmdCeXRlU291cmNlLCBoaWdoV2F0ZXJNYXJrKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5wcm90b3R5cGUpO1xuICAgIGxldCBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBsZXQgcHVsbEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBsZXQgY2FuY2VsQWxnb3JpdGhtID0gKCkgPT4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIGlmICh1bmRlcmx5aW5nQnl0ZVNvdXJjZS5zdGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN0YXJ0QWxnb3JpdGhtID0gKCkgPT4gdW5kZXJseWluZ0J5dGVTb3VyY2Uuc3RhcnQoY29udHJvbGxlcik7XG4gICAgfVxuICAgIGlmICh1bmRlcmx5aW5nQnl0ZVNvdXJjZS5wdWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcHVsbEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdCeXRlU291cmNlLnB1bGwoY29udHJvbGxlcik7XG4gICAgfVxuICAgIGlmICh1bmRlcmx5aW5nQnl0ZVNvdXJjZS5jYW5jZWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjYW5jZWxBbGdvcml0aG0gPSByZWFzb24gPT4gdW5kZXJseWluZ0J5dGVTb3VyY2UuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuICAgIGNvbnN0IGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSA9IHVuZGVybHlpbmdCeXRlU291cmNlLmF1dG9BbGxvY2F0ZUNodW5rU2l6ZTtcbiAgICBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBhdXRvQWxsb2NhdGVDaHVua1NpemUpO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0KHJlcXVlc3QsIGNvbnRyb2xsZXIsIHZpZXcpIHtcbiAgICByZXF1ZXN0Ll9hc3NvY2lhdGVkUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgcmVxdWVzdC5fdmlldyA9IHZpZXc7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdC5cbmZ1bmN0aW9uIGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3RgKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLlxuZnVuY3Rpb24gYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcmApO1xufVxuXG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW0uXG5mdW5jdGlvbiBBY3F1aXJlUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHN0cmVhbSkge1xuICAgIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHN0cmVhbSk7XG59XG4vLyBSZWFkYWJsZVN0cmVhbSBBUEkgZXhwb3NlZCBmb3IgY29udHJvbGxlcnMuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIHJlYWRJbnRvUmVxdWVzdCkge1xuICAgIHN0cmVhbS5fcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLnB1c2gocmVhZEludG9SZXF1ZXN0KTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIGNodW5rLCBkb25lKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgY29uc3QgcmVhZEludG9SZXF1ZXN0ID0gcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLnNoaWZ0KCk7XG4gICAgaWYgKGRvbmUpIHtcbiAgICAgICAgcmVhZEludG9SZXF1ZXN0Ll9jbG9zZVN0ZXBzKGNodW5rKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fY2h1bmtTdGVwcyhjaHVuayk7XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkSW50b1JlcXVlc3RzKHN0cmVhbSkge1xuICAgIHJldHVybiBzdHJlYW0uX3JlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5sZW5ndGg7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUhhc0JZT0JSZWFkZXIoc3RyZWFtKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIEEgQllPQiByZWFkZXIgdmVuZGVkIGJ5IGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlciB7XG4gICAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQoc3RyZWFtLCAxLCAnUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyJyk7XG4gICAgICAgIGFzc2VydFJlYWRhYmxlU3RyZWFtKHN0cmVhbSwgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZChzdHJlYW0pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGlzIHN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGxvY2tlZCBmb3IgZXhjbHVzaXZlIHJlYWRpbmcgYnkgYW5vdGhlciByZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcihzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjb25zdHJ1Y3QgYSBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIgZm9yIGEgc3RyZWFtIG5vdCBjb25zdHJ1Y3RlZCB3aXRoIGEgYnl0ZSAnICtcbiAgICAgICAgICAgICAgICAnc291cmNlJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZSh0aGlzLCBzdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWFkSW50b1JlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBmdWxmaWxsZWQgd2hlbiB0aGUgc3RyZWFtIGJlY29tZXMgY2xvc2VkLCBvciByZWplY3RlZCBpZiB0aGUgc3RyZWFtIGV2ZXIgZXJyb3JzIG9yXG4gICAgICogdGhlIHJlYWRlcidzIGxvY2sgaXMgcmVsZWFzZWQgYmVmb3JlIHRoZSBzdHJlYW0gZmluaXNoZXMgY2xvc2luZy5cbiAgICAgKi9cbiAgICBnZXQgY2xvc2VkKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChieW9iUmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbignY2xvc2VkJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9zZWRQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcmVhZGVyIGlzIGFjdGl2ZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QGxpbmsgUmVhZGFibGVTdHJlYW0uY2FuY2VsIHwgc3RyZWFtLmNhbmNlbChyZWFzb24pfS5cbiAgICAgKi9cbiAgICBjYW5jZWwocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdjYW5jZWwnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbignY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNDYW5jZWwodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gcmVhZHMgYnl0ZXMgaW50byB2aWV3LCBhbmQgcmV0dXJucyBhIHByb21pc2UgcmVzb2x2ZWQgd2l0aCB0aGUgcmVzdWx0LlxuICAgICAqXG4gICAgICogSWYgcmVhZGluZyBhIGNodW5rIGNhdXNlcyB0aGUgcXVldWUgdG8gYmVjb21lIGVtcHR5LCBtb3JlIGRhdGEgd2lsbCBiZSBwdWxsZWQgZnJvbSB0aGUgdW5kZXJseWluZyBzb3VyY2UuXG4gICAgICovXG4gICAgcmVhZCh2aWV3KSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KHZpZXcpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCd2aWV3IG11c3QgYmUgYW4gYXJyYXkgYnVmZmVyIHZpZXcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpZXcuYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcigndmlldyBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmlldy5idWZmZXIuYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcihgdmlldydzIGJ1ZmZlciBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aGApKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFkZXJMb2NrRXhjZXB0aW9uKCdyZWFkIGZyb20nKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc29sdmVQcm9taXNlO1xuICAgICAgICBsZXQgcmVqZWN0UHJvbWlzZTtcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZVByb21pc2UgPSByZXNvbHZlO1xuICAgICAgICAgICAgcmVqZWN0UHJvbWlzZSA9IHJlamVjdDtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlYWRJbnRvUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9jaHVua1N0ZXBzOiBjaHVuayA9PiByZXNvbHZlUHJvbWlzZSh7IHZhbHVlOiBjaHVuaywgZG9uZTogZmFsc2UgfSksXG4gICAgICAgICAgICBfY2xvc2VTdGVwczogY2h1bmsgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IHRydWUgfSksXG4gICAgICAgICAgICBfZXJyb3JTdGVwczogZSA9PiByZWplY3RQcm9taXNlKGUpXG4gICAgICAgIH07XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlclJlYWQodGhpcywgdmlldywgcmVhZEludG9SZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbGVhc2VzIHRoZSByZWFkZXIncyBsb2NrIG9uIHRoZSBjb3JyZXNwb25kaW5nIHN0cmVhbS4gQWZ0ZXIgdGhlIGxvY2sgaXMgcmVsZWFzZWQsIHRoZSByZWFkZXIgaXMgbm8gbG9uZ2VyIGFjdGl2ZS5cbiAgICAgKiBJZiB0aGUgYXNzb2NpYXRlZCBzdHJlYW0gaXMgZXJyb3JlZCB3aGVuIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmVhZGVyIHdpbGwgYXBwZWFyIGVycm9yZWQgaW4gdGhlIHNhbWUgd2F5XG4gICAgICogZnJvbSBub3cgb247IG90aGVyd2lzZSwgdGhlIHJlYWRlciB3aWxsIGFwcGVhciBjbG9zZWQuXG4gICAgICpcbiAgICAgKiBBIHJlYWRlcidzIGxvY2sgY2Fubm90IGJlIHJlbGVhc2VkIHdoaWxlIGl0IHN0aWxsIGhhcyBhIHBlbmRpbmcgcmVhZCByZXF1ZXN0LCBpLmUuLCBpZiBhIHByb21pc2UgcmV0dXJuZWQgYnlcbiAgICAgKiB0aGUgcmVhZGVyJ3Mge0BsaW5rIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlci5yZWFkIHwgcmVhZCgpfSBtZXRob2QgaGFzIG5vdCB5ZXQgYmVlbiBzZXR0bGVkLiBBdHRlbXB0aW5nIHRvXG4gICAgICogZG8gc28gd2lsbCB0aHJvdyBhIGBUeXBlRXJyb3JgIGFuZCBsZWF2ZSB0aGUgcmVhZGVyIGxvY2tlZCB0byB0aGUgc3RyZWFtLlxuICAgICAqL1xuICAgIHJlbGVhc2VMb2NrKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieW9iUmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbigncmVsZWFzZUxvY2snKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3JlYWRJbnRvUmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVHJpZWQgdG8gcmVsZWFzZSBhIHJlYWRlciBsb2NrIHdoZW4gdGhhdCByZWFkZXIgaGFzIHBlbmRpbmcgcmVhZCgpIGNhbGxzIHVuLXNldHRsZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHRoaXMpO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlci5wcm90b3R5cGUsIHtcbiAgICBjYW5jZWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlYWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlbGVhc2VMb2NrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBjbG9zZWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9XG59KTtcbmlmICh0eXBlb2YgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgcmVhZGVycy5cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfcmVhZEludG9SZXF1ZXN0cycpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkKHJlYWRlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KSB7XG4gICAgY29uc3Qgc3RyZWFtID0gcmVhZGVyLl9vd25lclJlYWRhYmxlU3RyZWFtO1xuICAgIHN0cmVhbS5fZGlzdHVyYmVkID0gdHJ1ZTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fZXJyb3JTdGVwcyhzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJQdWxsSW50byhzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KTtcbiAgICB9XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyLlxuZnVuY3Rpb24gYnlvYlJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24obmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlcmApO1xufVxuXG5mdW5jdGlvbiBFeHRyYWN0SGlnaFdhdGVyTWFyayhzdHJhdGVneSwgZGVmYXVsdEhXTSkge1xuICAgIGNvbnN0IHsgaGlnaFdhdGVyTWFyayB9ID0gc3RyYXRlZ3k7XG4gICAgaWYgKGhpZ2hXYXRlck1hcmsgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZGVmYXVsdEhXTTtcbiAgICB9XG4gICAgaWYgKE51bWJlcklzTmFOKGhpZ2hXYXRlck1hcmspIHx8IGhpZ2hXYXRlck1hcmsgPCAwKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIGhpZ2hXYXRlck1hcmsnKTtcbiAgICB9XG4gICAgcmV0dXJuIGhpZ2hXYXRlck1hcms7XG59XG5mdW5jdGlvbiBFeHRyYWN0U2l6ZUFsZ29yaXRobShzdHJhdGVneSkge1xuICAgIGNvbnN0IHsgc2l6ZSB9ID0gc3RyYXRlZ3k7XG4gICAgaWYgKCFzaXplKSB7XG4gICAgICAgIHJldHVybiAoKSA9PiAxO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZTtcbn1cblxuZnVuY3Rpb24gY29udmVydFF1ZXVpbmdTdHJhdGVneShpbml0LCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShpbml0LCBjb250ZXh0KTtcbiAgICBjb25zdCBoaWdoV2F0ZXJNYXJrID0gaW5pdCA9PT0gbnVsbCB8fCBpbml0ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBpbml0LmhpZ2hXYXRlck1hcms7XG4gICAgY29uc3Qgc2l6ZSA9IGluaXQgPT09IG51bGwgfHwgaW5pdCA9PT0gdm9pZCAwID8gdm9pZCAwIDogaW5pdC5zaXplO1xuICAgIHJldHVybiB7XG4gICAgICAgIGhpZ2hXYXRlck1hcms6IGhpZ2hXYXRlck1hcmsgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGNvbnZlcnRVbnJlc3RyaWN0ZWREb3VibGUoaGlnaFdhdGVyTWFyayksXG4gICAgICAgIHNpemU6IHNpemUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGNvbnZlcnRRdWV1aW5nU3RyYXRlZ3lTaXplKHNpemUsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3NpemUnIHRoYXRgKVxuICAgIH07XG59XG5mdW5jdGlvbiBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5U2l6ZShmbiwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gY2h1bmsgPT4gY29udmVydFVucmVzdHJpY3RlZERvdWJsZShmbihjaHVuaykpO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1Npbmsob3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KG9yaWdpbmFsLCBjb250ZXh0KTtcbiAgICBjb25zdCBhYm9ydCA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5hYm9ydDtcbiAgICBjb25zdCBjbG9zZSA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5jbG9zZTtcbiAgICBjb25zdCBzdGFydCA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5zdGFydDtcbiAgICBjb25zdCB0eXBlID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnR5cGU7XG4gICAgY29uc3Qgd3JpdGUgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwud3JpdGU7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYWJvcnQ6IGFib3J0ID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU2lua0Fib3J0Q2FsbGJhY2soYWJvcnQsIG9yaWdpbmFsLCBgJHtjb250ZXh0fSBoYXMgbWVtYmVyICdhYm9ydCcgdGhhdGApLFxuICAgICAgICBjbG9zZTogY2xvc2UgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuZGVybHlpbmdTaW5rQ2xvc2VDYWxsYmFjayhjbG9zZSwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ2Nsb3NlJyB0aGF0YCksXG4gICAgICAgIHN0YXJ0OiBzdGFydCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VW5kZXJseWluZ1NpbmtTdGFydENhbGxiYWNrKHN0YXJ0LCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnc3RhcnQnIHRoYXRgKSxcbiAgICAgICAgd3JpdGU6IHdyaXRlID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU2lua1dyaXRlQ2FsbGJhY2sod3JpdGUsIG9yaWdpbmFsLCBgJHtjb250ZXh0fSBoYXMgbWVtYmVyICd3cml0ZScgdGhhdGApLFxuICAgICAgICB0eXBlXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU2lua0Fib3J0Q2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAocmVhc29uKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtyZWFzb25dKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU2lua0Nsb3NlQ2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAoKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU2lua1N0YXJ0Q2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAoY29udHJvbGxlcikgPT4gcmVmbGVjdENhbGwoZm4sIG9yaWdpbmFsLCBbY29udHJvbGxlcl0pO1xufVxuZnVuY3Rpb24gY29udmVydFVuZGVybHlpbmdTaW5rV3JpdGVDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjaHVuaywgY29udHJvbGxlcikgPT4gcHJvbWlzZUNhbGwoZm4sIG9yaWdpbmFsLCBbY2h1bmssIGNvbnRyb2xsZXJdKTtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0V3JpdGFibGVTdHJlYW0oeCwgY29udGV4dCkge1xuICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh4KSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NvbnRleHR9IGlzIG5vdCBhIFdyaXRhYmxlU3RyZWFtLmApO1xuICAgIH1cbn1cblxuLyoqXG4gKiBBIHdyaXRhYmxlIHN0cmVhbSByZXByZXNlbnRzIGEgZGVzdGluYXRpb24gZm9yIGRhdGEsIGludG8gd2hpY2ggeW91IGNhbiB3cml0ZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFdyaXRhYmxlU3RyZWFtIHtcbiAgICBjb25zdHJ1Y3RvcihyYXdVbmRlcmx5aW5nU2luayA9IHt9LCByYXdTdHJhdGVneSA9IHt9KSB7XG4gICAgICAgIGlmIChyYXdVbmRlcmx5aW5nU2luayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByYXdVbmRlcmx5aW5nU2luayA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhc3NlcnRPYmplY3QocmF3VW5kZXJseWluZ1NpbmssICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdHJhdGVneSA9IGNvbnZlcnRRdWV1aW5nU3RyYXRlZ3kocmF3U3RyYXRlZ3ksICdTZWNvbmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIGNvbnN0IHVuZGVybHlpbmdTaW5rID0gY29udmVydFVuZGVybHlpbmdTaW5rKHJhd1VuZGVybHlpbmdTaW5rLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbSh0aGlzKTtcbiAgICAgICAgY29uc3QgdHlwZSA9IHVuZGVybHlpbmdTaW5rLnR5cGU7XG4gICAgICAgIGlmICh0eXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbnZhbGlkIHR5cGUgaXMgc3BlY2lmaWVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2l6ZUFsZ29yaXRobSA9IEV4dHJhY3RTaXplQWxnb3JpdGhtKHN0cmF0ZWd5KTtcbiAgICAgICAgY29uc3QgaGlnaFdhdGVyTWFyayA9IEV4dHJhY3RIaWdoV2F0ZXJNYXJrKHN0cmF0ZWd5LCAxKTtcbiAgICAgICAgU2V0VXBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTaW5rKHRoaXMsIHVuZGVybHlpbmdTaW5rLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgd3JpdGFibGUgc3RyZWFtIGlzIGxvY2tlZCB0byBhIHdyaXRlci5cbiAgICAgKi9cbiAgICBnZXQgbG9ja2VkKCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24oJ2xvY2tlZCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBYm9ydHMgdGhlIHN0cmVhbSwgc2lnbmFsaW5nIHRoYXQgdGhlIHByb2R1Y2VyIGNhbiBubyBsb25nZXIgc3VjY2Vzc2Z1bGx5IHdyaXRlIHRvIHRoZSBzdHJlYW0gYW5kIGl0IGlzIHRvIGJlXG4gICAgICogaW1tZWRpYXRlbHkgbW92ZWQgdG8gYW4gZXJyb3JlZCBzdGF0ZSwgd2l0aCBhbnkgcXVldWVkLXVwIHdyaXRlcyBkaXNjYXJkZWQuIFRoaXMgd2lsbCBhbHNvIGV4ZWN1dGUgYW55IGFib3J0XG4gICAgICogbWVjaGFuaXNtIG9mIHRoZSB1bmRlcmx5aW5nIHNpbmsuXG4gICAgICpcbiAgICAgKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGZ1bGZpbGwgaWYgdGhlIHN0cmVhbSBzaHV0cyBkb3duIHN1Y2Nlc3NmdWxseSwgb3IgcmVqZWN0IGlmIHRoZSB1bmRlcmx5aW5nIHNpbmsgc2lnbmFsZWRcbiAgICAgKiB0aGF0IHRoZXJlIHdhcyBhbiBlcnJvciBkb2luZyBzby4gQWRkaXRpb25hbGx5LCBpdCB3aWxsIHJlamVjdCB3aXRoIGEgYFR5cGVFcnJvcmAgKHdpdGhvdXQgYXR0ZW1wdGluZyB0byBjYW5jZWxcbiAgICAgKiB0aGUgc3RyZWFtKSBpZiB0aGUgc3RyZWFtIGlzIGN1cnJlbnRseSBsb2NrZWQuXG4gICAgICovXG4gICAgYWJvcnQocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbignYWJvcnQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBhYm9ydCBhIHN0cmVhbSB0aGF0IGFscmVhZHkgaGFzIGEgd3JpdGVyJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUFib3J0KHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgc3RyZWFtLiBUaGUgdW5kZXJseWluZyBzaW5rIHdpbGwgZmluaXNoIHByb2Nlc3NpbmcgYW55IHByZXZpb3VzbHktd3JpdHRlbiBjaHVua3MsIGJlZm9yZSBpbnZva2luZyBpdHNcbiAgICAgKiBjbG9zZSBiZWhhdmlvci4gRHVyaW5nIHRoaXMgdGltZSBhbnkgZnVydGhlciBhdHRlbXB0cyB0byB3cml0ZSB3aWxsIGZhaWwgKHdpdGhvdXQgZXJyb3JpbmcgdGhlIHN0cmVhbSkuXG4gICAgICpcbiAgICAgKiBUaGUgbWV0aG9kIHJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCBmdWxmaWxsIGlmIGFsbCByZW1haW5pbmcgY2h1bmtzIGFyZSBzdWNjZXNzZnVsbHkgd3JpdHRlbiBhbmQgdGhlIHN0cmVhbVxuICAgICAqIHN1Y2Nlc3NmdWxseSBjbG9zZXMsIG9yIHJlamVjdHMgaWYgYW4gZXJyb3IgaXMgZW5jb3VudGVyZWQgZHVyaW5nIHRoaXMgcHJvY2Vzcy4gQWRkaXRpb25hbGx5LCBpdCB3aWxsIHJlamVjdCB3aXRoXG4gICAgICogYSBgVHlwZUVycm9yYCAod2l0aG91dCBhdHRlbXB0aW5nIHRvIGNhbmNlbCB0aGUgc3RyZWFtKSBpZiB0aGUgc3RyZWFtIGlzIGN1cnJlbnRseSBsb2NrZWQuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbignY2xvc2UnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjbG9zZSBhIHN0cmVhbSB0aGF0IGFscmVhZHkgaGFzIGEgd3JpdGVyJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodCh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcignQ2Fubm90IGNsb3NlIGFuIGFscmVhZHktY2xvc2luZyBzdHJlYW0nKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtQ2xvc2UodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB7QGxpbmsgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyIHwgd3JpdGVyfSBhbmQgbG9ja3MgdGhlIHN0cmVhbSB0byB0aGUgbmV3IHdyaXRlci4gV2hpbGUgdGhlIHN0cmVhbVxuICAgICAqIGlzIGxvY2tlZCwgbm8gb3RoZXIgd3JpdGVyIGNhbiBiZSBhY3F1aXJlZCB1bnRpbCB0aGlzIG9uZSBpcyByZWxlYXNlZC5cbiAgICAgKlxuICAgICAqIFRoaXMgZnVuY3Rpb25hbGl0eSBpcyBlc3BlY2lhbGx5IHVzZWZ1bCBmb3IgY3JlYXRpbmcgYWJzdHJhY3Rpb25zIHRoYXQgZGVzaXJlIHRoZSBhYmlsaXR5IHRvIHdyaXRlIHRvIGEgc3RyZWFtXG4gICAgICogd2l0aG91dCBpbnRlcnJ1cHRpb24gb3IgaW50ZXJsZWF2aW5nLiBCeSBnZXR0aW5nIGEgd3JpdGVyIGZvciB0aGUgc3RyZWFtLCB5b3UgY2FuIGVuc3VyZSBub2JvZHkgZWxzZSBjYW4gd3JpdGUgYXRcbiAgICAgKiB0aGUgc2FtZSB0aW1lLCB3aGljaCB3b3VsZCBjYXVzZSB0aGUgcmVzdWx0aW5nIHdyaXR0ZW4gZGF0YSB0byBiZSB1bnByZWRpY3RhYmxlIGFuZCBwcm9iYWJseSB1c2VsZXNzLlxuICAgICAqL1xuICAgIGdldFdyaXRlcigpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uKCdnZXRXcml0ZXInKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQWNxdWlyZVdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBhYm9ydDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2U6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGdldFdyaXRlcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgbG9ja2VkOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnV3JpdGFibGVTdHJlYW0nLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbi8vIEFic3RyYWN0IG9wZXJhdGlvbnMgZm9yIHRoZSBXcml0YWJsZVN0cmVhbS5cbmZ1bmN0aW9uIEFjcXVpcmVXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoc3RyZWFtKSB7XG4gICAgcmV0dXJuIG5ldyBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoc3RyZWFtKTtcbn1cbi8vIFRocm93cyBpZiBhbmQgb25seSBpZiBzdGFydEFsZ29yaXRobSB0aHJvd3MuXG5mdW5jdGlvbiBDcmVhdGVXcml0YWJsZVN0cmVhbShzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyayA9IDEsIHNpemVBbGdvcml0aG0gPSAoKSA9PiAxKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gT2JqZWN0LmNyZWF0ZShXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUpO1xuICAgIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbShzdHJlYW0pO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbmZ1bmN0aW9uIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ3dyaXRhYmxlJztcbiAgICAvLyBUaGUgZXJyb3IgdGhhdCB3aWxsIGJlIHJlcG9ydGVkIGJ5IG5ldyBtZXRob2QgY2FsbHMgb25jZSB0aGUgc3RhdGUgYmVjb21lcyBlcnJvcmVkLiBPbmx5IHNldCB3aGVuIFtbc3RhdGVdXSBpc1xuICAgIC8vICdlcnJvcmluZycgb3IgJ2Vycm9yZWQnLiBNYXkgYmUgc2V0IHRvIGFuIHVuZGVmaW5lZCB2YWx1ZS5cbiAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fd3JpdGVyID0gdW5kZWZpbmVkO1xuICAgIC8vIEluaXRpYWxpemUgdG8gdW5kZWZpbmVkIGZpcnN0IGJlY2F1c2UgdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBjb250cm9sbGVyIGNoZWNrcyB0aGlzXG4gICAgLy8gdmFyaWFibGUgdG8gdmFsaWRhdGUgdGhlIGNhbGxlci5cbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlciA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGlzIHF1ZXVlIGlzIHBsYWNlZCBoZXJlIGluc3RlYWQgb2YgdGhlIHdyaXRlciBjbGFzcyBpbiBvcmRlciB0byBhbGxvdyBmb3IgcGFzc2luZyBhIHdyaXRlciB0byB0aGUgbmV4dCBkYXRhXG4gICAgLy8gcHJvZHVjZXIgd2l0aG91dCB3YWl0aW5nIGZvciB0aGUgcXVldWVkIHdyaXRlcyB0byBmaW5pc2guXG4gICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgLy8gV3JpdGUgcmVxdWVzdHMgYXJlIHJlbW92ZWQgZnJvbSBfd3JpdGVSZXF1ZXN0cyB3aGVuIHdyaXRlKCkgaXMgY2FsbGVkIG9uIHRoZSB1bmRlcmx5aW5nIHNpbmsuIFRoaXMgcHJldmVudHNcbiAgICAvLyB0aGVtIGZyb20gYmVpbmcgZXJyb25lb3VzbHkgcmVqZWN0ZWQgb24gZXJyb3IuIElmIGEgd3JpdGUoKSBjYWxsIGlzIGluLWZsaWdodCwgdGhlIHJlcXVlc3QgaXMgc3RvcmVkIGhlcmUuXG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGUgcHJvbWlzZSB0aGF0IHdhcyByZXR1cm5lZCBmcm9tIHdyaXRlci5jbG9zZSgpLiBTdG9yZWQgaGVyZSBiZWNhdXNlIGl0IG1heSBiZSBmdWxmaWxsZWQgYWZ0ZXIgdGhlIHdyaXRlclxuICAgIC8vIGhhcyBiZWVuIGRldGFjaGVkLlxuICAgIHN0cmVhbS5fY2xvc2VSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIC8vIENsb3NlIHJlcXVlc3QgaXMgcmVtb3ZlZCBmcm9tIF9jbG9zZVJlcXVlc3Qgd2hlbiBjbG9zZSgpIGlzIGNhbGxlZCBvbiB0aGUgdW5kZXJseWluZyBzaW5rLiBUaGlzIHByZXZlbnRzIGl0XG4gICAgLy8gZnJvbSBiZWluZyBlcnJvbmVvdXNseSByZWplY3RlZCBvbiBlcnJvci4gSWYgYSBjbG9zZSgpIGNhbGwgaXMgaW4tZmxpZ2h0LCB0aGUgcmVxdWVzdCBpcyBzdG9yZWQgaGVyZS5cbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIC8vIFRoZSBwcm9taXNlIHRoYXQgd2FzIHJldHVybmVkIGZyb20gd3JpdGVyLmFib3J0KCkuIFRoaXMgbWF5IGFsc28gYmUgZnVsZmlsbGVkIGFmdGVyIHRoZSB3cml0ZXIgaGFzIGRldGFjaGVkLlxuICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGUgYmFja3ByZXNzdXJlIHNpZ25hbCBzZXQgYnkgdGhlIGNvbnRyb2xsZXIuXG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW0oeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ193cml0YWJsZVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gSXNXcml0YWJsZVN0cmVhbUxvY2tlZChzdHJlYW0pIHtcbiAgICBpZiAoc3RyZWFtLl93cml0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1BYm9ydChzdHJlYW0sIHJlYXNvbikge1xuICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnIHx8IHN0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgaWYgKHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QuX3Byb21pc2U7XG4gICAgfVxuICAgIGxldCB3YXNBbHJlYWR5RXJyb3JpbmcgPSBmYWxzZTtcbiAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgd2FzQWxyZWFkeUVycm9yaW5nID0gdHJ1ZTtcbiAgICAgICAgLy8gcmVhc29uIHdpbGwgbm90IGJlIHVzZWQsIHNvIGRvbid0IGtlZXAgYSByZWZlcmVuY2UgdG8gaXQuXG4gICAgICAgIHJlYXNvbiA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfcHJvbWlzZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgX3Jlc29sdmU6IHJlc29sdmUsXG4gICAgICAgICAgICBfcmVqZWN0OiByZWplY3QsXG4gICAgICAgICAgICBfcmVhc29uOiByZWFzb24sXG4gICAgICAgICAgICBfd2FzQWxyZWFkeUVycm9yaW5nOiB3YXNBbHJlYWR5RXJyb3JpbmdcbiAgICAgICAgfTtcbiAgICB9KTtcbiAgICBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QuX3Byb21pc2UgPSBwcm9taXNlO1xuICAgIGlmICghd2FzQWxyZWFkeUVycm9yaW5nKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtU3RhcnRFcnJvcmluZyhzdHJlYW0sIHJlYXNvbik7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1DbG9zZShzdHJlYW0pIHtcbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJyB8fCBzdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoYFRoZSBzdHJlYW0gKGluICR7c3RhdGV9IHN0YXRlKSBpcyBub3QgaW4gdGhlIHdyaXRhYmxlIHN0YXRlIGFuZCBjYW5ub3QgYmUgY2xvc2VkYCkpO1xuICAgIH1cbiAgICBjb25zdCBwcm9taXNlID0gbmV3UHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGNsb3NlUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9yZXNvbHZlOiByZXNvbHZlLFxuICAgICAgICAgICAgX3JlamVjdDogcmVqZWN0XG4gICAgICAgIH07XG4gICAgICAgIHN0cmVhbS5fY2xvc2VSZXF1ZXN0ID0gY2xvc2VSZXF1ZXN0O1xuICAgIH0pO1xuICAgIGNvbnN0IHdyaXRlciA9IHN0cmVhbS5fd3JpdGVyO1xuICAgIGlmICh3cml0ZXIgIT09IHVuZGVmaW5lZCAmJiBzdHJlYW0uX2JhY2twcmVzc3VyZSAmJiBzdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSh3cml0ZXIpO1xuICAgIH1cbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2Uoc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuLy8gV3JpdGFibGVTdHJlYW0gQVBJIGV4cG9zZWQgZm9yIGNvbnRyb2xsZXJzLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1BZGRXcml0ZVJlcXVlc3Qoc3RyZWFtKSB7XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB3cml0ZVJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfcmVzb2x2ZTogcmVzb2x2ZSxcbiAgICAgICAgICAgIF9yZWplY3Q6IHJlamVjdFxuICAgICAgICB9O1xuICAgICAgICBzdHJlYW0uX3dyaXRlUmVxdWVzdHMucHVzaCh3cml0ZVJlcXVlc3QpO1xuICAgIH0pO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWFsV2l0aFJlamVjdGlvbihzdHJlYW0sIGVycm9yKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICBXcml0YWJsZVN0cmVhbVN0YXJ0RXJyb3Jpbmcoc3RyZWFtLCBlcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgV3JpdGFibGVTdHJlYW1GaW5pc2hFcnJvcmluZyhzdHJlYW0pO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1TdGFydEVycm9yaW5nKHN0cmVhbSwgcmVhc29uKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyO1xuICAgIHN0cmVhbS5fc3RhdGUgPSAnZXJyb3JpbmcnO1xuICAgIHN0cmVhbS5fc3RvcmVkRXJyb3IgPSByZWFzb247XG4gICAgY29uc3Qgd3JpdGVyID0gc3RyZWFtLl93cml0ZXI7XG4gICAgaWYgKHdyaXRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZVJlYWR5UHJvbWlzZVJlamVjdGVkKHdyaXRlciwgcmVhc29uKTtcbiAgICB9XG4gICAgaWYgKCFXcml0YWJsZVN0cmVhbUhhc09wZXJhdGlvbk1hcmtlZEluRmxpZ2h0KHN0cmVhbSkgJiYgY29udHJvbGxlci5fc3RhcnRlZCkge1xuICAgICAgICBXcml0YWJsZVN0cmVhbUZpbmlzaEVycm9yaW5nKHN0cmVhbSk7XG4gICAgfVxufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1GaW5pc2hFcnJvcmluZyhzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ2Vycm9yZWQnO1xuICAgIHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyW0Vycm9yU3RlcHNdKCk7XG4gICAgY29uc3Qgc3RvcmVkRXJyb3IgPSBzdHJlYW0uX3N0b3JlZEVycm9yO1xuICAgIHN0cmVhbS5fd3JpdGVSZXF1ZXN0cy5mb3JFYWNoKHdyaXRlUmVxdWVzdCA9PiB7XG4gICAgICAgIHdyaXRlUmVxdWVzdC5fcmVqZWN0KHN0b3JlZEVycm9yKTtcbiAgICB9KTtcbiAgICBzdHJlYW0uX3dyaXRlUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICBpZiAoc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1SZWplY3RDbG9zZUFuZENsb3NlZFByb21pc2VJZk5lZWRlZChzdHJlYW0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGFib3J0UmVxdWVzdCA9IHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdDtcbiAgICBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGFib3J0UmVxdWVzdC5fd2FzQWxyZWFkeUVycm9yaW5nKSB7XG4gICAgICAgIGFib3J0UmVxdWVzdC5fcmVqZWN0KHN0b3JlZEVycm9yKTtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1SZWplY3RDbG9zZUFuZENsb3NlZFByb21pc2VJZk5lZWRlZChzdHJlYW0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHByb21pc2UgPSBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcltBYm9ydFN0ZXBzXShhYm9ydFJlcXVlc3QuX3JlYXNvbik7XG4gICAgdXBvblByb21pc2UocHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICBhYm9ydFJlcXVlc3QuX3Jlc29sdmUoKTtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1SZWplY3RDbG9zZUFuZENsb3NlZFByb21pc2VJZk5lZWRlZChzdHJlYW0pO1xuICAgIH0sIChyZWFzb24pID0+IHtcbiAgICAgICAgYWJvcnRSZXF1ZXN0Ll9yZWplY3QocmVhc29uKTtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1SZWplY3RDbG9zZUFuZENsb3NlZFByb21pc2VJZk5lZWRlZChzdHJlYW0pO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodFdyaXRlKHN0cmVhbSkge1xuICAgIHN0cmVhbS5faW5GbGlnaHRXcml0ZVJlcXVlc3QuX3Jlc29sdmUodW5kZWZpbmVkKTtcbiAgICBzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ID0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodFdyaXRlV2l0aEVycm9yKHN0cmVhbSwgZXJyb3IpIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0Ll9yZWplY3QoZXJyb3IpO1xuICAgIHN0cmVhbS5faW5GbGlnaHRXcml0ZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgV3JpdGFibGVTdHJlYW1EZWFsV2l0aFJlamVjdGlvbihzdHJlYW0sIGVycm9yKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0Ll9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIC8vIFRoZSBlcnJvciB3YXMgdG9vIGxhdGUgdG8gZG8gYW55dGhpbmcsIHNvIGl0IGlzIGlnbm9yZWQuXG4gICAgICAgIHN0cmVhbS5fc3RvcmVkRXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0Ll9yZXNvbHZlKCk7XG4gICAgICAgICAgICBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RyZWFtLl9zdGF0ZSA9ICdjbG9zZWQnO1xuICAgIGNvbnN0IHdyaXRlciA9IHN0cmVhbS5fd3JpdGVyO1xuICAgIGlmICh3cml0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlc29sdmUod3JpdGVyKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0Q2xvc2VXaXRoRXJyb3Ioc3RyZWFtLCBlcnJvcikge1xuICAgIHN0cmVhbS5faW5GbGlnaHRDbG9zZVJlcXVlc3QuX3JlamVjdChlcnJvcik7XG4gICAgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBOZXZlciBleGVjdXRlIHNpbmsgYWJvcnQoKSBhZnRlciBzaW5rIGNsb3NlKCkuXG4gICAgaWYgKHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdC5fcmVqZWN0KGVycm9yKTtcbiAgICAgICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBXcml0YWJsZVN0cmVhbURlYWxXaXRoUmVqZWN0aW9uKHN0cmVhbSwgZXJyb3IpO1xufVxuLy8gVE9ETyhyaWNlYSk6IEZpeCBhbHBoYWJldGljYWwgb3JkZXIuXG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pIHtcbiAgICBpZiAoc3RyZWFtLl9jbG9zZVJlcXVlc3QgPT09IHVuZGVmaW5lZCAmJiBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtSGFzT3BlcmF0aW9uTWFya2VkSW5GbGlnaHQoc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5faW5GbGlnaHRXcml0ZVJlcXVlc3QgPT09IHVuZGVmaW5lZCAmJiBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtTWFya0Nsb3NlUmVxdWVzdEluRmxpZ2h0KHN0cmVhbSkge1xuICAgIHN0cmVhbS5faW5GbGlnaHRDbG9zZVJlcXVlc3QgPSBzdHJlYW0uX2Nsb3NlUmVxdWVzdDtcbiAgICBzdHJlYW0uX2Nsb3NlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtTWFya0ZpcnN0V3JpdGVSZXF1ZXN0SW5GbGlnaHQoc3RyZWFtKSB7XG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCA9IHN0cmVhbS5fd3JpdGVSZXF1ZXN0cy5zaGlmdCgpO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1SZWplY3RDbG9zZUFuZENsb3NlZFByb21pc2VJZk5lZWRlZChzdHJlYW0pIHtcbiAgICBpZiAoc3RyZWFtLl9jbG9zZVJlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdHJlYW0uX2Nsb3NlUmVxdWVzdC5fcmVqZWN0KHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgICAgICBzdHJlYW0uX2Nsb3NlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3Qgd3JpdGVyID0gc3RyZWFtLl93cml0ZXI7XG4gICAgaWYgKHdyaXRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVqZWN0KHdyaXRlciwgc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpIHtcbiAgICBjb25zdCB3cml0ZXIgPSBzdHJlYW0uX3dyaXRlcjtcbiAgICBpZiAod3JpdGVyICE9PSB1bmRlZmluZWQgJiYgYmFja3ByZXNzdXJlICE9PSBzdHJlYW0uX2JhY2twcmVzc3VyZSkge1xuICAgICAgICBpZiAoYmFja3ByZXNzdXJlKSB7XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzZXQod3JpdGVyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNvbHZlKHdyaXRlcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSBiYWNrcHJlc3N1cmU7XG59XG4vKipcbiAqIEEgZGVmYXVsdCB3cml0ZXIgdmVuZGVkIGJ5IGEge0BsaW5rIFdyaXRhYmxlU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciB7XG4gICAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQoc3RyZWFtLCAxLCAnV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyJyk7XG4gICAgICAgIGFzc2VydFdyaXRhYmxlU3RyZWFtKHN0cmVhbSwgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNXcml0YWJsZVN0cmVhbUxvY2tlZChzdHJlYW0pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGlzIHN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGxvY2tlZCBmb3IgZXhjbHVzaXZlIHdyaXRpbmcgYnkgYW5vdGhlciB3cml0ZXInKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9vd25lcldyaXRhYmxlU3RyZWFtID0gc3RyZWFtO1xuICAgICAgICBzdHJlYW0uX3dyaXRlciA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICAgICAgaWYgKHN0YXRlID09PSAnd3JpdGFibGUnKSB7XG4gICAgICAgICAgICBpZiAoIVdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkgJiYgc3RyZWFtLl9iYWNrcHJlc3N1cmUpIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGF0ZSA9PT0gJ2Vycm9yaW5nJykge1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHRoaXMsIHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHRoaXMpO1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZCh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHN0b3JlZEVycm9yID0gc3RyZWFtLl9zdG9yZWRFcnJvcjtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh0aGlzLCBzdG9yZWRFcnJvcik7XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHRoaXMsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHdpbGwgYmUgZnVsZmlsbGVkIHdoZW4gdGhlIHN0cmVhbSBiZWNvbWVzIGNsb3NlZCwgb3IgcmVqZWN0ZWQgaWYgdGhlIHN0cmVhbSBldmVyIGVycm9ycyBvclxuICAgICAqIHRoZSB3cml0ZXLigJlzIGxvY2sgaXMgcmVsZWFzZWQgYmVmb3JlIHRoZSBzdHJlYW0gZmluaXNoZXMgY2xvc2luZy5cbiAgICAgKi9cbiAgICBnZXQgY2xvc2VkKCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyQnJhbmRDaGVja0V4Y2VwdGlvbignY2xvc2VkJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9zZWRQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgc3RyZWFt4oCZcyBpbnRlcm5hbCBxdWV1ZS4gSXQgY2FuIGJlIG5lZ2F0aXZlLCBpZiB0aGUgcXVldWUgaXMgb3Zlci1mdWxsLlxuICAgICAqIEEgcHJvZHVjZXIgY2FuIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSB0aGUgcmlnaHQgYW1vdW50IG9mIGRhdGEgdG8gd3JpdGUuXG4gICAgICpcbiAgICAgKiBJdCB3aWxsIGJlIGBudWxsYCBpZiB0aGUgc3RyZWFtIGNhbm5vdCBiZSBzdWNjZXNzZnVsbHkgd3JpdHRlbiB0byAoZHVlIHRvIGVpdGhlciBiZWluZyBlcnJvcmVkLCBvciBoYXZpbmcgYW4gYWJvcnRcbiAgICAgKiBxdWV1ZWQgdXApLiBJdCB3aWxsIHJldHVybiB6ZXJvIGlmIHRoZSBzdHJlYW0gaXMgY2xvc2VkLiBBbmQgdGhlIGdldHRlciB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBpbnZva2VkIHdoZW5cbiAgICAgKiB0aGUgd3JpdGVy4oCZcyBsb2NrIGlzIHJlbGVhc2VkLlxuICAgICAqL1xuICAgIGdldCBkZXNpcmVkU2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Rlc2lyZWRTaXplJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyV3JpdGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdFdyaXRlckxvY2tFeGNlcHRpb24oJ2Rlc2lyZWRTaXplJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckdldERlc2lyZWRTaXplKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHdpbGwgYmUgZnVsZmlsbGVkIHdoZW4gdGhlIGRlc2lyZWQgc2l6ZSB0byBmaWxsIHRoZSBzdHJlYW3igJlzIGludGVybmFsIHF1ZXVlIHRyYW5zaXRpb25zXG4gICAgICogZnJvbSBub24tcG9zaXRpdmUgdG8gcG9zaXRpdmUsIHNpZ25hbGluZyB0aGF0IGl0IGlzIG5vIGxvbmdlciBhcHBseWluZyBiYWNrcHJlc3N1cmUuIE9uY2UgdGhlIGRlc2lyZWQgc2l6ZSBkaXBzXG4gICAgICogYmFjayB0byB6ZXJvIG9yIGJlbG93LCB0aGUgZ2V0dGVyIHdpbGwgcmV0dXJuIGEgbmV3IHByb21pc2UgdGhhdCBzdGF5cyBwZW5kaW5nIHVudGlsIHRoZSBuZXh0IHRyYW5zaXRpb24uXG4gICAgICpcbiAgICAgKiBJZiB0aGUgc3RyZWFtIGJlY29tZXMgZXJyb3JlZCBvciBhYm9ydGVkLCBvciB0aGUgd3JpdGVy4oCZcyBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGJlY29tZVxuICAgICAqIHJlamVjdGVkLlxuICAgICAqL1xuICAgIGdldCByZWFkeSgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlYWR5JykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWFkeVByb21pc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSByZWFkZXIgaXMgYWN0aXZlLCBiZWhhdmVzIHRoZSBzYW1lIGFzIHtAbGluayBXcml0YWJsZVN0cmVhbS5hYm9ydCB8IHN0cmVhbS5hYm9ydChyZWFzb24pfS5cbiAgICAgKi9cbiAgICBhYm9ydChyZWFzb24gPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Fib3J0JykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lcldyaXRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJMb2NrRXhjZXB0aW9uKCdhYm9ydCcpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQWJvcnQodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIHJlYWRlciBpcyBhY3RpdmUsIGJlaGF2ZXMgdGhlIHNhbWUgYXMge0BsaW5rIFdyaXRhYmxlU3RyZWFtLmNsb3NlIHwgc3RyZWFtLmNsb3NlKCl9LlxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyQnJhbmRDaGVja0V4Y2VwdGlvbignY2xvc2UnKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbTtcbiAgICAgICAgaWYgKHN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbignY2xvc2UnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjbG9zZSBhbiBhbHJlYWR5LWNsb3Npbmcgc3RyZWFtJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVsZWFzZXMgdGhlIHdyaXRlcuKAmXMgbG9jayBvbiB0aGUgY29ycmVzcG9uZGluZyBzdHJlYW0uIEFmdGVyIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgd3JpdGVyIGlzIG5vIGxvbmdlciBhY3RpdmUuXG4gICAgICogSWYgdGhlIGFzc29jaWF0ZWQgc3RyZWFtIGlzIGVycm9yZWQgd2hlbiB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHdyaXRlciB3aWxsIGFwcGVhciBlcnJvcmVkIGluIHRoZSBzYW1lIHdheSBmcm9tXG4gICAgICogbm93IG9uOyBvdGhlcndpc2UsIHRoZSB3cml0ZXIgd2lsbCBhcHBlYXIgY2xvc2VkLlxuICAgICAqXG4gICAgICogTm90ZSB0aGF0IHRoZSBsb2NrIGNhbiBzdGlsbCBiZSByZWxlYXNlZCBldmVuIGlmIHNvbWUgb25nb2luZyB3cml0ZXMgaGF2ZSBub3QgeWV0IGZpbmlzaGVkIChpLmUuIGV2ZW4gaWYgdGhlXG4gICAgICogcHJvbWlzZXMgcmV0dXJuZWQgZnJvbSBwcmV2aW91cyBjYWxscyB0byB7QGxpbmsgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyLndyaXRlIHwgd3JpdGUoKX0gaGF2ZSBub3QgeWV0IHNldHRsZWQpLlxuICAgICAqIEl04oCZcyBub3QgbmVjZXNzYXJ5IHRvIGhvbGQgdGhlIGxvY2sgb24gdGhlIHdyaXRlciBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoZSB3cml0ZTsgdGhlIGxvY2sgaW5zdGVhZCBzaW1wbHkgcHJldmVudHNcbiAgICAgKiBvdGhlciBwcm9kdWNlcnMgZnJvbSB3cml0aW5nIGluIGFuIGludGVybGVhdmVkIG1hbm5lci5cbiAgICAgKi9cbiAgICByZWxlYXNlTG9jaygpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlbGVhc2VMb2NrJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbTtcbiAgICAgICAgaWYgKHN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyUmVsZWFzZSh0aGlzKTtcbiAgICB9XG4gICAgd3JpdGUoY2h1bmsgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3dyaXRlJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lcldyaXRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJMb2NrRXhjZXB0aW9uKCd3cml0ZSB0bycpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyV3JpdGUodGhpcywgY2h1bmspO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5wcm90b3R5cGUsIHtcbiAgICBhYm9ydDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2U6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlbGVhc2VMb2NrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB3cml0ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2VkOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBkZXNpcmVkU2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcmVhZHk6IHsgZW51bWVyYWJsZTogdHJ1ZSB9XG59KTtcbmlmICh0eXBlb2YgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyLlxuZnVuY3Rpb24gSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19vd25lcldyaXRhYmxlU3RyZWFtJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbi8vIEEgY2xpZW50IG9mIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciBtYXkgdXNlIHRoZXNlIGZ1bmN0aW9ucyBkaXJlY3RseSB0byBieXBhc3Mgc3RhdGUgY2hlY2suXG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJBYm9ydCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGNvbnN0IHN0cmVhbSA9IHdyaXRlci5fb3duZXJXcml0YWJsZVN0cmVhbTtcbiAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1BYm9ydChzdHJlYW0sIHJlYXNvbik7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJDbG9zZSh3cml0ZXIpIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckNsb3NlV2l0aEVycm9yUHJvcGFnYXRpb24od3JpdGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQoc3RyZWFtKSB8fCBzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICAgIHJldHVybiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJDbG9zZSh3cml0ZXIpO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyRW5zdXJlQ2xvc2VkUHJvbWlzZVJlamVjdGVkKHdyaXRlciwgZXJyb3IpIHtcbiAgICBpZiAod3JpdGVyLl9jbG9zZWRQcm9taXNlU3RhdGUgPT09ICdwZW5kaW5nJykge1xuICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCh3cml0ZXIsIGVycm9yKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVzZXRUb1JlamVjdGVkKHdyaXRlciwgZXJyb3IpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZVJlYWR5UHJvbWlzZVJlamVjdGVkKHdyaXRlciwgZXJyb3IpIHtcbiAgICBpZiAod3JpdGVyLl9yZWFkeVByb21pc2VTdGF0ZSA9PT0gJ3BlbmRpbmcnKSB7XG4gICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZWplY3Qod3JpdGVyLCBlcnJvcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzZXRUb1JlamVjdGVkKHdyaXRlciwgZXJyb3IpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckdldERlc2lyZWRTaXplKHdyaXRlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IHdyaXRlci5fb3duZXJXcml0YWJsZVN0cmVhbTtcbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JlZCcgfHwgc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUoc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyUmVsZWFzZSh3cml0ZXIpIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgY29uc3QgcmVsZWFzZWRFcnJvciA9IG5ldyBUeXBlRXJyb3IoYFdyaXRlciB3YXMgcmVsZWFzZWQgYW5kIGNhbiBubyBsb25nZXIgYmUgdXNlZCB0byBtb25pdG9yIHRoZSBzdHJlYW0ncyBjbG9zZWRuZXNzYCk7XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyRW5zdXJlUmVhZHlQcm9taXNlUmVqZWN0ZWQod3JpdGVyLCByZWxlYXNlZEVycm9yKTtcbiAgICAvLyBUaGUgc3RhdGUgdHJhbnNpdGlvbnMgdG8gXCJlcnJvcmVkXCIgYmVmb3JlIHRoZSBzaW5rIGFib3J0KCkgbWV0aG9kIHJ1bnMsIGJ1dCB0aGUgd3JpdGVyLmNsb3NlZCBwcm9taXNlIGlzIG5vdFxuICAgIC8vIHJlamVjdGVkIHVudGlsIGFmdGVyd2FyZHMuIFRoaXMgbWVhbnMgdGhhdCBzaW1wbHkgdGVzdGluZyBzdGF0ZSB3aWxsIG5vdCB3b3JrLlxuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZUNsb3NlZFByb21pc2VSZWplY3RlZCh3cml0ZXIsIHJlbGVhc2VkRXJyb3IpO1xuICAgIHN0cmVhbS5fd3JpdGVyID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fb3duZXJXcml0YWJsZVN0cmVhbSA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcldyaXRlKHdyaXRlciwgY2h1bmspIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgY29uc3QgY29udHJvbGxlciA9IHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyO1xuICAgIGNvbnN0IGNodW5rU2l6ZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRDaHVua1NpemUoY29udHJvbGxlciwgY2h1bmspO1xuICAgIGlmIChzdHJlYW0gIT09IHdyaXRlci5fb3duZXJXcml0YWJsZVN0cmVhbSkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbignd3JpdGUgdG8nKSk7XG4gICAgfVxuICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gICAgaWYgKFdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkgfHwgc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoJ1RoZSBzdHJlYW0gaXMgY2xvc2luZyBvciBjbG9zZWQgYW5kIGNhbm5vdCBiZSB3cml0dGVuIHRvJykpO1xuICAgIH1cbiAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICAgIGNvbnN0IHByb21pc2UgPSBXcml0YWJsZVN0cmVhbUFkZFdyaXRlUmVxdWVzdChzdHJlYW0pO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJXcml0ZShjb250cm9sbGVyLCBjaHVuaywgY2h1bmtTaXplKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbmNvbnN0IGNsb3NlU2VudGluZWwgPSB7fTtcbi8qKlxuICogQWxsb3dzIGNvbnRyb2wgb2YgYSB7QGxpbmsgV3JpdGFibGVTdHJlYW0gfCB3cml0YWJsZSBzdHJlYW19J3Mgc3RhdGUgYW5kIGludGVybmFsIHF1ZXVlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgY29uc3RydWN0b3InKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBjb250cm9sbGVkIHdyaXRhYmxlIHN0cmVhbSwgbWFraW5nIGFsbCBmdXR1cmUgaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyByYXJlbHkgdXNlZCwgc2luY2UgdXN1YWxseSBpdCBzdWZmaWNlcyB0byByZXR1cm4gYSByZWplY3RlZCBwcm9taXNlIGZyb20gb25lIG9mIHRoZSB1bmRlcmx5aW5nXG4gICAgICogc2luaydzIG1ldGhvZHMuIEhvd2V2ZXIsIGl0IGNhbiBiZSB1c2VmdWwgZm9yIHN1ZGRlbmx5IHNodXR0aW5nIGRvd24gYSBzdHJlYW0gaW4gcmVzcG9uc2UgdG8gYW4gZXZlbnQgb3V0c2lkZSB0aGVcbiAgICAgKiBub3JtYWwgbGlmZWN5Y2xlIG9mIGludGVyYWN0aW9ucyB3aXRoIHRoZSB1bmRlcmx5aW5nIHNpbmsuXG4gICAgICovXG4gICAgZXJyb3IoZSA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUuZXJyb3IgY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGF0ZSA9IHRoaXMuX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbS5fc3RhdGU7XG4gICAgICAgIGlmIChzdGF0ZSAhPT0gJ3dyaXRhYmxlJykge1xuICAgICAgICAgICAgLy8gVGhlIHN0cmVhbSBpcyBjbG9zZWQsIGVycm9yZWQgb3Igd2lsbCBiZSBzb29uLiBUaGUgc2luayBjYW4ndCBkbyBhbnl0aGluZyB1c2VmdWwgaWYgaXQgZ2V0cyBhbiBlcnJvciBoZXJlLCBzb1xuICAgICAgICAgICAgLy8ganVzdCB0cmVhdCBpdCBhcyBhIG5vLW9wLlxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcih0aGlzLCBlKTtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtBYm9ydFN0ZXBzXShyZWFzb24pIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fYWJvcnRBbGdvcml0aG0ocmVhc29uKTtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtFcnJvclN0ZXBzXSgpIHtcbiAgICAgICAgUmVzZXRRdWV1ZSh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLnByb3RvdHlwZSwge1xuICAgIGVycm9yOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGltcGxlbWVudGluZyBpbnRlcmZhY2UgcmVxdWlyZWQgYnkgdGhlIFdyaXRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gSXNXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIFNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcihzdHJlYW0sIGNvbnRyb2xsZXIsIHN0YXJ0QWxnb3JpdGhtLCB3cml0ZUFsZ29yaXRobSwgY2xvc2VBbGdvcml0aG0sIGFib3J0QWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtID0gc3RyZWFtO1xuICAgIHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyID0gY29udHJvbGxlcjtcbiAgICAvLyBOZWVkIHRvIHNldCB0aGUgc2xvdHMgc28gdGhhdCB0aGUgYXNzZXJ0IGRvZXNuJ3QgZmlyZS4gSW4gdGhlIHNwZWMgdGhlIHNsb3RzIGFscmVhZHkgZXhpc3QgaW1wbGljaXRseS5cbiAgICBjb250cm9sbGVyLl9xdWV1ZSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSA9IHVuZGVmaW5lZDtcbiAgICBSZXNldFF1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgICBjb250cm9sbGVyLl9zdHJhdGVneVNpemVBbGdvcml0aG0gPSBzaXplQWxnb3JpdGhtO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNID0gaGlnaFdhdGVyTWFyaztcbiAgICBjb250cm9sbGVyLl93cml0ZUFsZ29yaXRobSA9IHdyaXRlQWxnb3JpdGhtO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlQWxnb3JpdGhtID0gY2xvc2VBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fYWJvcnRBbGdvcml0aG0gPSBhYm9ydEFsZ29yaXRobTtcbiAgICBjb25zdCBiYWNrcHJlc3N1cmUgPSBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0QmFja3ByZXNzdXJlKGNvbnRyb2xsZXIpO1xuICAgIFdyaXRhYmxlU3RyZWFtVXBkYXRlQmFja3ByZXNzdXJlKHN0cmVhbSwgYmFja3ByZXNzdXJlKTtcbiAgICBjb25zdCBzdGFydFJlc3VsdCA9IHN0YXJ0QWxnb3JpdGhtKCk7XG4gICAgY29uc3Qgc3RhcnRQcm9taXNlID0gcHJvbWlzZVJlc29sdmVkV2l0aChzdGFydFJlc3VsdCk7XG4gICAgdXBvblByb21pc2Uoc3RhcnRQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQoY29udHJvbGxlcik7XG4gICAgfSwgciA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBXcml0YWJsZVN0cmVhbURlYWxXaXRoUmVqZWN0aW9uKHN0cmVhbSwgcik7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJGcm9tVW5kZXJseWluZ1Npbmsoc3RyZWFtLCB1bmRlcmx5aW5nU2luaywgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSkge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBsZXQgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlZmluZWQ7XG4gICAgbGV0IHdyaXRlQWxnb3JpdGhtID0gKCkgPT4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIGxldCBjbG9zZUFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBsZXQgYWJvcnRBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgaWYgKHVuZGVybHlpbmdTaW5rLnN0YXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nU2luay5zdGFydChjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTaW5rLndyaXRlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgd3JpdGVBbGdvcml0aG0gPSBjaHVuayA9PiB1bmRlcmx5aW5nU2luay53cml0ZShjaHVuaywgY29udHJvbGxlcik7XG4gICAgfVxuICAgIGlmICh1bmRlcmx5aW5nU2luay5jbG9zZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNsb3NlQWxnb3JpdGhtID0gKCkgPT4gdW5kZXJseWluZ1NpbmsuY2xvc2UoKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTaW5rLmFib3J0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYWJvcnRBbGdvcml0aG0gPSByZWFzb24gPT4gdW5kZXJseWluZ1NpbmsuYWJvcnQocmVhc29uKTtcbiAgICB9XG4gICAgU2V0VXBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHdyaXRlQWxnb3JpdGhtLCBjbG9zZUFsZ29yaXRobSwgYWJvcnRBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmssIHNpemVBbGdvcml0aG0pO1xufVxuLy8gQ2xlYXJBbGdvcml0aG1zIG1heSBiZSBjYWxsZWQgdHdpY2UuIEVycm9yaW5nIHRoZSBzYW1lIHN0cmVhbSBpbiBtdWx0aXBsZSB3YXlzIHdpbGwgb2Z0ZW4gcmVzdWx0IGluIHJlZHVuZGFudCBjYWxscy5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcikge1xuICAgIGNvbnRyb2xsZXIuX3dyaXRlQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX2Fib3J0QWxnb3JpdGhtID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZShjb250cm9sbGVyKSB7XG4gICAgRW5xdWV1ZVZhbHVlV2l0aFNpemUoY29udHJvbGxlciwgY2xvc2VTZW50aW5lbCwgMCk7XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckFkdmFuY2VRdWV1ZUlmTmVlZGVkKGNvbnRyb2xsZXIpO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldENodW5rU2l6ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBjb250cm9sbGVyLl9zdHJhdGVneVNpemVBbGdvcml0aG0oY2h1bmspO1xuICAgIH1cbiAgICBjYXRjaCAoY2h1bmtTaXplRSkge1xuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3JJZk5lZWRlZChjb250cm9sbGVyLCBjaHVua1NpemVFKTtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplKGNvbnRyb2xsZXIpIHtcbiAgICByZXR1cm4gY29udHJvbGxlci5fc3RyYXRlZ3lIV00gLSBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJXcml0ZShjb250cm9sbGVyLCBjaHVuaywgY2h1bmtTaXplKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgRW5xdWV1ZVZhbHVlV2l0aFNpemUoY29udHJvbGxlciwgY2h1bmssIGNodW5rU2l6ZSk7XG4gICAgfVxuICAgIGNhdGNoIChlbnF1ZXVlRSkge1xuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3JJZk5lZWRlZChjb250cm9sbGVyLCBlbnF1ZXVlRSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIGlmICghV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQoc3RyZWFtKSAmJiBzdHJlYW0uX3N0YXRlID09PSAnd3JpdGFibGUnKSB7XG4gICAgICAgIGNvbnN0IGJhY2twcmVzc3VyZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRCYWNrcHJlc3N1cmUoY29udHJvbGxlcik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtVXBkYXRlQmFja3ByZXNzdXJlKHN0cmVhbSwgYmFja3ByZXNzdXJlKTtcbiAgICB9XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckFkdmFuY2VRdWV1ZUlmTmVlZGVkKGNvbnRyb2xsZXIpO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIuXG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbTtcbiAgICBpZiAoIWNvbnRyb2xsZXIuX3N0YXJ0ZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yaW5nJykge1xuICAgICAgICBXcml0YWJsZVN0cmVhbUZpbmlzaEVycm9yaW5nKHN0cmVhbSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlID0gUGVla1F1ZXVlVmFsdWUoY29udHJvbGxlcik7XG4gICAgaWYgKHZhbHVlID09PSBjbG9zZVNlbnRpbmVsKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQcm9jZXNzQ2xvc2UoY29udHJvbGxlcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc1dyaXRlKGNvbnRyb2xsZXIsIHZhbHVlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3JJZk5lZWRlZChjb250cm9sbGVyLCBlcnJvcikge1xuICAgIGlmIChjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW0uX3N0YXRlID09PSAnd3JpdGFibGUnKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlcnJvcik7XG4gICAgfVxufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NDbG9zZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIFdyaXRhYmxlU3RyZWFtTWFya0Nsb3NlUmVxdWVzdEluRmxpZ2h0KHN0cmVhbSk7XG4gICAgRGVxdWV1ZVZhbHVlKGNvbnRyb2xsZXIpO1xuICAgIGNvbnN0IHNpbmtDbG9zZVByb21pc2UgPSBjb250cm9sbGVyLl9jbG9zZUFsZ29yaXRobSgpO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgdXBvblByb21pc2Uoc2lua0Nsb3NlUHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICBXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0Q2xvc2Uoc3RyZWFtKTtcbiAgICB9LCByZWFzb24gPT4ge1xuICAgICAgICBXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0Q2xvc2VXaXRoRXJyb3Ioc3RyZWFtLCByZWFzb24pO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NXcml0ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbTtcbiAgICBXcml0YWJsZVN0cmVhbU1hcmtGaXJzdFdyaXRlUmVxdWVzdEluRmxpZ2h0KHN0cmVhbSk7XG4gICAgY29uc3Qgc2lua1dyaXRlUHJvbWlzZSA9IGNvbnRyb2xsZXIuX3dyaXRlQWxnb3JpdGhtKGNodW5rKTtcbiAgICB1cG9uUHJvbWlzZShzaW5rV3JpdGVQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZShzdHJlYW0pO1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgICAgIERlcXVldWVWYWx1ZShjb250cm9sbGVyKTtcbiAgICAgICAgaWYgKCFXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pICYmIHN0YXRlID09PSAnd3JpdGFibGUnKSB7XG4gICAgICAgICAgICBjb25zdCBiYWNrcHJlc3N1cmUgPSBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0QmFja3ByZXNzdXJlKGNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpO1xuICAgICAgICB9XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJBZHZhbmNlUXVldWVJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByZWFzb24gPT4ge1xuICAgICAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKTtcbiAgICAgICAgfVxuICAgICAgICBXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0V3JpdGVXaXRoRXJyb3Ioc3RyZWFtLCByZWFzb24pO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldEJhY2twcmVzc3VyZShjb250cm9sbGVyKSB7XG4gICAgY29uc3QgZGVzaXJlZFNpemUgPSBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUoY29udHJvbGxlcik7XG4gICAgcmV0dXJuIGRlc2lyZWRTaXplIDw9IDA7XG59XG4vLyBBIGNsaWVudCBvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIG1heSB1c2UgdGhlc2UgZnVuY3Rpb25zIGRpcmVjdGx5IHRvIGJ5cGFzcyBzdGF0ZSBjaGVjay5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlcnJvcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbTtcbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgIFdyaXRhYmxlU3RyZWFtU3RhcnRFcnJvcmluZyhzdHJlYW0sIGVycm9yKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBXcml0YWJsZVN0cmVhbS5cbmZ1bmN0aW9uIHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24obmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgV3JpdGFibGVTdHJlYW1gKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIuXG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyQnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyYCk7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCAnICsgbmFtZSArICcgYSBzdHJlYW0gdXNpbmcgYSByZWxlYXNlZCB3cml0ZXInKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpIHtcbiAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID0gcmVqZWN0O1xuICAgICAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VTdGF0ZSA9ICdwZW5kaW5nJztcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUod3JpdGVyKTtcbiAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCh3cml0ZXIsIHJlYXNvbik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHdyaXRlcikge1xuICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xuICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVzb2x2ZSh3cml0ZXIpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZWplY3Qod3JpdGVyLCByZWFzb24pIHtcbiAgICBpZiAod3JpdGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZSh3cml0ZXIuX2Nsb3NlZFByb21pc2UpO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QocmVhc29uKTtcbiAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZVN0YXRlID0gJ3JlamVjdGVkJztcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVzZXRUb1JlamVjdGVkKHdyaXRlciwgcmVhc29uKSB7XG4gICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh3cml0ZXIsIHJlYXNvbik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlc29sdmUod3JpdGVyKSB7XG4gICAgaWYgKHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlU3RhdGUgPSAncmVzb2x2ZWQnO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemUod3JpdGVyKSB7XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3JlamVjdCA9IHJlamVjdDtcbiAgICB9KTtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZVN0YXRlID0gJ3BlbmRpbmcnO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHdyaXRlciwgcmVhc29uKSB7XG4gICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemUod3JpdGVyKTtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVqZWN0KHdyaXRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZCh3cml0ZXIpIHtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNvbHZlKHdyaXRlcik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVqZWN0KHdyaXRlciwgcmVhc29uKSB7XG4gICAgaWYgKHdyaXRlci5fcmVhZHlQcm9taXNlX3JlamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZSh3cml0ZXIuX3JlYWR5UHJvbWlzZSk7XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0KHJlYXNvbik7XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZWplY3QgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VTdGF0ZSA9ICdyZWplY3RlZCc7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzZXQod3JpdGVyKSB7XG4gICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemUod3JpdGVyKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNldFRvUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc29sdmUod3JpdGVyKSB7XG4gICAgaWYgKHdyaXRlci5fcmVhZHlQcm9taXNlX3Jlc29sdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3Jlc29sdmUodW5kZWZpbmVkKTtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZVN0YXRlID0gJ2Z1bGZpbGxlZCc7XG59XG5cbmZ1bmN0aW9uIGlzQWJvcnRTaWduYWwodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyB8fCB2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUuYWJvcnRlZCA9PT0gJ2Jvb2xlYW4nO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgLy8gQWJvcnRTaWduYWwucHJvdG90eXBlLmFib3J0ZWQgdGhyb3dzIGlmIGl0cyBicmFuZCBjaGVjayBmYWlsc1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG4vLy8gPHJlZmVyZW5jZSBsaWI9XCJkb21cIiAvPlxuY29uc3QgTmF0aXZlRE9NRXhjZXB0aW9uID0gdHlwZW9mIERPTUV4Y2VwdGlvbiAhPT0gJ3VuZGVmaW5lZCcgPyBET01FeGNlcHRpb24gOiB1bmRlZmluZWQ7XG5cbi8vLyA8cmVmZXJlbmNlIHR5cGVzPVwibm9kZVwiIC8+XG5mdW5jdGlvbiBpc0RPTUV4Y2VwdGlvbkNvbnN0cnVjdG9yKGN0b3IpIHtcbiAgICBpZiAoISh0eXBlb2YgY3RvciA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgY3RvciA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgbmV3IGN0b3IoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNhdGNoIChfYSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuZnVuY3Rpb24gY3JlYXRlRE9NRXhjZXB0aW9uUG9seWZpbGwoKSB7XG4gICAgY29uc3QgY3RvciA9IGZ1bmN0aW9uIERPTUV4Y2VwdGlvbihtZXNzYWdlLCBuYW1lKSB7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgJyc7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWUgfHwgJ0Vycm9yJztcbiAgICAgICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgICAgICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0b3IucHJvdG90eXBlLCAnY29uc3RydWN0b3InLCB7IHZhbHVlOiBjdG9yLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0pO1xuICAgIHJldHVybiBjdG9yO1xufVxuY29uc3QgRE9NRXhjZXB0aW9uJDEgPSBpc0RPTUV4Y2VwdGlvbkNvbnN0cnVjdG9yKE5hdGl2ZURPTUV4Y2VwdGlvbikgPyBOYXRpdmVET01FeGNlcHRpb24gOiBjcmVhdGVET01FeGNlcHRpb25Qb2x5ZmlsbCgpO1xuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbVBpcGVUbyhzb3VyY2UsIGRlc3QsIHByZXZlbnRDbG9zZSwgcHJldmVudEFib3J0LCBwcmV2ZW50Q2FuY2VsLCBzaWduYWwpIHtcbiAgICBjb25zdCByZWFkZXIgPSBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHNvdXJjZSk7XG4gICAgY29uc3Qgd3JpdGVyID0gQWNxdWlyZVdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcihkZXN0KTtcbiAgICBzb3VyY2UuX2Rpc3R1cmJlZCA9IHRydWU7XG4gICAgbGV0IHNodXR0aW5nRG93biA9IGZhbHNlO1xuICAgIC8vIFRoaXMgaXMgdXNlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBzcGVjJ3MgcmVxdWlyZW1lbnQgdGhhdCB3ZSB3YWl0IGZvciBvbmdvaW5nIHdyaXRlcyBkdXJpbmcgc2h1dGRvd24uXG4gICAgbGV0IGN1cnJlbnRXcml0ZSA9IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICByZXR1cm4gbmV3UHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGxldCBhYm9ydEFsZ29yaXRobTtcbiAgICAgICAgaWYgKHNpZ25hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBhYm9ydEFsZ29yaXRobSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBET01FeGNlcHRpb24kMSgnQWJvcnRlZCcsICdBYm9ydEVycm9yJyk7XG4gICAgICAgICAgICAgICAgY29uc3QgYWN0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICAgIGlmICghcHJldmVudEFib3J0KSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVzdC5fc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1BYm9ydChkZXN0LCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFwcmV2ZW50Q2FuY2VsKSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlLl9zdGF0ZSA9PT0gJ3JlYWRhYmxlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbUNhbmNlbChzb3VyY2UsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzaHV0ZG93bldpdGhBY3Rpb24oKCkgPT4gUHJvbWlzZS5hbGwoYWN0aW9ucy5tYXAoYWN0aW9uID0+IGFjdGlvbigpKSksIHRydWUsIGVycm9yKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgICAgICAgICBhYm9ydEFsZ29yaXRobSgpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0QWxnb3JpdGhtKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBVc2luZyByZWFkZXIgYW5kIHdyaXRlciwgcmVhZCBhbGwgY2h1bmtzIGZyb20gdGhpcyBhbmQgd3JpdGUgdGhlbSB0byBkZXN0XG4gICAgICAgIC8vIC0gQmFja3ByZXNzdXJlIG11c3QgYmUgZW5mb3JjZWRcbiAgICAgICAgLy8gLSBTaHV0ZG93biBtdXN0IHN0b3AgYWxsIGFjdGl2aXR5XG4gICAgICAgIGZ1bmN0aW9uIHBpcGVMb29wKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ld1Byb21pc2UoKHJlc29sdmVMb29wLCByZWplY3RMb29wKSA9PiB7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gbmV4dChkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlTG9vcCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVXNlIGBQZXJmb3JtUHJvbWlzZVRoZW5gIGluc3RlYWQgb2YgYHVwb25Qcm9taXNlYCB0byBhdm9pZFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWRkaW5nIHVubmVjZXNzYXJ5IGAuY2F0Y2gocmV0aHJvd0Fzc2VydGlvbkVycm9yUmVqZWN0aW9uKWAgaGFuZGxlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgIFBlcmZvcm1Qcm9taXNlVGhlbihwaXBlU3RlcCgpLCBuZXh0LCByZWplY3RMb29wKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuZXh0KGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHBpcGVTdGVwKCkge1xuICAgICAgICAgICAgaWYgKHNodXR0aW5nRG93bikge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFBlcmZvcm1Qcm9taXNlVGhlbih3cml0ZXIuX3JlYWR5UHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXdQcm9taXNlKChyZXNvbHZlUmVhZCwgcmVqZWN0UmVhZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJSZWFkKHJlYWRlciwge1xuICAgICAgICAgICAgICAgICAgICAgICAgX2NodW5rU3RlcHM6IGNodW5rID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50V3JpdGUgPSBQZXJmb3JtUHJvbWlzZVRoZW4oV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyV3JpdGUod3JpdGVyLCBjaHVuayksIHVuZGVmaW5lZCwgbm9vcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZVJlYWQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiByZXNvbHZlUmVhZCh0cnVlKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIF9lcnJvclN0ZXBzOiByZWplY3RSZWFkXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRXJyb3JzIG11c3QgYmUgcHJvcGFnYXRlZCBmb3J3YXJkXG4gICAgICAgIGlzT3JCZWNvbWVzRXJyb3JlZChzb3VyY2UsIHJlYWRlci5fY2xvc2VkUHJvbWlzZSwgc3RvcmVkRXJyb3IgPT4ge1xuICAgICAgICAgICAgaWYgKCFwcmV2ZW50QWJvcnQpIHtcbiAgICAgICAgICAgICAgICBzaHV0ZG93bldpdGhBY3Rpb24oKCkgPT4gV3JpdGFibGVTdHJlYW1BYm9ydChkZXN0LCBzdG9yZWRFcnJvciksIHRydWUsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNodXRkb3duKHRydWUsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEVycm9ycyBtdXN0IGJlIHByb3BhZ2F0ZWQgYmFja3dhcmRcbiAgICAgICAgaXNPckJlY29tZXNFcnJvcmVkKGRlc3QsIHdyaXRlci5fY2xvc2VkUHJvbWlzZSwgc3RvcmVkRXJyb3IgPT4ge1xuICAgICAgICAgICAgaWYgKCFwcmV2ZW50Q2FuY2VsKSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd25XaXRoQWN0aW9uKCgpID0+IFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHNvdXJjZSwgc3RvcmVkRXJyb3IpLCB0cnVlLCBzdG9yZWRFcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaHV0ZG93bih0cnVlLCBzdG9yZWRFcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBDbG9zaW5nIG11c3QgYmUgcHJvcGFnYXRlZCBmb3J3YXJkXG4gICAgICAgIGlzT3JCZWNvbWVzQ2xvc2VkKHNvdXJjZSwgcmVhZGVyLl9jbG9zZWRQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXByZXZlbnRDbG9zZSkge1xuICAgICAgICAgICAgICAgIHNodXRkb3duV2l0aEFjdGlvbigoKSA9PiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJDbG9zZVdpdGhFcnJvclByb3BhZ2F0aW9uKHdyaXRlcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIENsb3NpbmcgbXVzdCBiZSBwcm9wYWdhdGVkIGJhY2t3YXJkXG4gICAgICAgIGlmIChXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChkZXN0KSB8fCBkZXN0Ll9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlc3RDbG9zZWQgPSBuZXcgVHlwZUVycm9yKCd0aGUgZGVzdGluYXRpb24gd3JpdGFibGUgc3RyZWFtIGNsb3NlZCBiZWZvcmUgYWxsIGRhdGEgY291bGQgYmUgcGlwZWQgdG8gaXQnKTtcbiAgICAgICAgICAgIGlmICghcHJldmVudENhbmNlbCkge1xuICAgICAgICAgICAgICAgIHNodXRkb3duV2l0aEFjdGlvbigoKSA9PiBSZWFkYWJsZVN0cmVhbUNhbmNlbChzb3VyY2UsIGRlc3RDbG9zZWQpLCB0cnVlLCBkZXN0Q2xvc2VkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNodXRkb3duKHRydWUsIGRlc3RDbG9zZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHNldFByb21pc2VJc0hhbmRsZWRUb1RydWUocGlwZUxvb3AoKSk7XG4gICAgICAgIGZ1bmN0aW9uIHdhaXRGb3JXcml0ZXNUb0ZpbmlzaCgpIHtcbiAgICAgICAgICAgIC8vIEFub3RoZXIgd3JpdGUgbWF5IGhhdmUgc3RhcnRlZCB3aGlsZSB3ZSB3ZXJlIHdhaXRpbmcgb24gdGhpcyBjdXJyZW50V3JpdGUsIHNvIHdlIGhhdmUgdG8gYmUgc3VyZSB0byB3YWl0XG4gICAgICAgICAgICAvLyBmb3IgdGhhdCB0b28uXG4gICAgICAgICAgICBjb25zdCBvbGRDdXJyZW50V3JpdGUgPSBjdXJyZW50V3JpdGU7XG4gICAgICAgICAgICByZXR1cm4gUGVyZm9ybVByb21pc2VUaGVuKGN1cnJlbnRXcml0ZSwgKCkgPT4gb2xkQ3VycmVudFdyaXRlICE9PSBjdXJyZW50V3JpdGUgPyB3YWl0Rm9yV3JpdGVzVG9GaW5pc2goKSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNPckJlY29tZXNFcnJvcmVkKHN0cmVhbSwgcHJvbWlzZSwgYWN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBvblJlamVjdGlvbihwcm9taXNlLCBhY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGlzT3JCZWNvbWVzQ2xvc2VkKHN0cmVhbSwgcHJvbWlzZSwgYWN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHVwb25GdWxmaWxsbWVudChwcm9taXNlLCBhY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHNodXRkb3duV2l0aEFjdGlvbihhY3Rpb24sIG9yaWdpbmFsSXNFcnJvciwgb3JpZ2luYWxFcnJvcikge1xuICAgICAgICAgICAgaWYgKHNodXR0aW5nRG93bikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNodXR0aW5nRG93biA9IHRydWU7XG4gICAgICAgICAgICBpZiAoZGVzdC5fc3RhdGUgPT09ICd3cml0YWJsZScgJiYgIVdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KGRlc3QpKSB7XG4gICAgICAgICAgICAgICAgdXBvbkZ1bGZpbGxtZW50KHdhaXRGb3JXcml0ZXNUb0ZpbmlzaCgpLCBkb1RoZVJlc3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZG9UaGVSZXN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiBkb1RoZVJlc3QoKSB7XG4gICAgICAgICAgICAgICAgdXBvblByb21pc2UoYWN0aW9uKCksICgpID0+IGZpbmFsaXplKG9yaWdpbmFsSXNFcnJvciwgb3JpZ2luYWxFcnJvciksIG5ld0Vycm9yID0+IGZpbmFsaXplKHRydWUsIG5ld0Vycm9yKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gc2h1dGRvd24oaXNFcnJvciwgZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChzaHV0dGluZ0Rvd24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaHV0dGluZ0Rvd24gPSB0cnVlO1xuICAgICAgICAgICAgaWYgKGRlc3QuX3N0YXRlID09PSAnd3JpdGFibGUnICYmICFXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChkZXN0KSkge1xuICAgICAgICAgICAgICAgIHVwb25GdWxmaWxsbWVudCh3YWl0Rm9yV3JpdGVzVG9GaW5pc2goKSwgKCkgPT4gZmluYWxpemUoaXNFcnJvciwgZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpbmFsaXplKGlzRXJyb3IsIGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBmaW5hbGl6ZShpc0Vycm9yLCBlcnJvcikge1xuICAgICAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyUmVsZWFzZSh3cml0ZXIpO1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgaWYgKHNpZ25hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnRBbGdvcml0aG0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzRXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59XG5cbi8qKlxuICogQWxsb3dzIGNvbnRyb2wgb2YgYSB7QGxpbmsgUmVhZGFibGVTdHJlYW0gfCByZWFkYWJsZSBzdHJlYW19J3Mgc3RhdGUgYW5kIGludGVybmFsIHF1ZXVlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgY29uc3RydWN0b3InKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIGNvbnRyb2xsZWQgc3RyZWFtJ3MgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzXG4gICAgICogb3Zlci1mdWxsLiBBbiB1bmRlcmx5aW5nIHNvdXJjZSBvdWdodCB0byB1c2UgdGhpcyBpbmZvcm1hdGlvbiB0byBkZXRlcm1pbmUgd2hlbiBhbmQgaG93IHRvIGFwcGx5IGJhY2twcmVzc3VyZS5cbiAgICAgKi9cbiAgICBnZXQgZGVzaXJlZFNpemUoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBkZWZhdWx0Q29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Rlc2lyZWRTaXplJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZSh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBjb250cm9sbGVkIHJlYWRhYmxlIHN0cmVhbS4gQ29uc3VtZXJzIHdpbGwgc3RpbGwgYmUgYWJsZSB0byByZWFkIGFueSBwcmV2aW91c2x5LWVucXVldWVkIGNodW5rcyBmcm9tXG4gICAgICogdGhlIHN0cmVhbSwgYnV0IG9uY2UgdGhvc2UgYXJlIHJlYWQsIHRoZSBzdHJlYW0gd2lsbCBiZWNvbWUgY2xvc2VkLlxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdjbG9zZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGlzIG5vdCBpbiBhIHN0YXRlIHRoYXQgcGVybWl0cyBjbG9zZScpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuayA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlbnF1ZXVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FuQ2xvc2VPckVucXVldWUodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBzdHJlYW0gaXMgbm90IGluIGEgc3RhdGUgdGhhdCBwZXJtaXRzIGVucXVldWUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUodGhpcywgY2h1bmspO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFcnJvcnMgdGhlIGNvbnRyb2xsZWQgcmVhZGFibGUgc3RyZWFtLCBtYWtpbmcgYWxsIGZ1dHVyZSBpbnRlcmFjdGlvbnMgd2l0aCBpdCBmYWlsIHdpdGggdGhlIGdpdmVuIGVycm9yIGBlYC5cbiAgICAgKi9cbiAgICBlcnJvcihlID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBkZWZhdWx0Q29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Vycm9yJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKHRoaXMsIGUpO1xuICAgIH1cbiAgICAvKiogQGludGVybmFsICovXG4gICAgW0NhbmNlbFN0ZXBzXShyZWFzb24pIHtcbiAgICAgICAgUmVzZXRRdWV1ZSh0aGlzKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fY2FuY2VsQWxnb3JpdGhtKHJlYXNvbik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXModGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBbUHVsbFN0ZXBzXShyZWFkUmVxdWVzdCkge1xuICAgICAgICBjb25zdCBzdHJlYW0gPSB0aGlzLl9jb250cm9sbGVkUmVhZGFibGVTdHJlYW07XG4gICAgICAgIGlmICh0aGlzLl9xdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBjaHVuayA9IERlcXVldWVWYWx1ZSh0aGlzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jbG9zZVJlcXVlc3RlZCAmJiB0aGlzLl9xdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKHRoaXMpO1xuICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVhZFJlcXVlc3QuX2NodW5rU3RlcHMoY2h1bmspO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1BZGRSZWFkUmVxdWVzdChzdHJlYW0sIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBjbG9zZTogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgZW5xdWV1ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgZXJyb3I6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGRlc2lyZWRTaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc2hvdWxkUHVsbCA9IFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKTtcbiAgICBpZiAoIXNob3VsZFB1bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcHVsbGluZykge1xuICAgICAgICBjb250cm9sbGVyLl9wdWxsQWdhaW4gPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSB0cnVlO1xuICAgIGNvbnN0IHB1bGxQcm9taXNlID0gY29udHJvbGxlci5fcHVsbEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHB1bGxQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIuX3B1bGxBZ2Fpbikge1xuICAgICAgICAgICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gZmFsc2U7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICAgICAgfVxuICAgIH0sIGUgPT4ge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSk7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyU2hvdWxkQ2FsbFB1bGwoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbTtcbiAgICBpZiAoIVJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYW5DbG9zZU9yRW5xdWV1ZShjb250cm9sbGVyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghY29udHJvbGxlci5fc3RhcnRlZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkgJiYgUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGRlc2lyZWRTaXplID0gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplKGNvbnRyb2xsZXIpO1xuICAgIGlmIChkZXNpcmVkU2l6ZSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcikge1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fY2FuY2VsQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbn1cbi8vIEEgY2xpZW50IG9mIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIgbWF5IHVzZSB0aGVzZSBmdW5jdGlvbnMgZGlyZWN0bHkgdG8gYnlwYXNzIHN0YXRlIGNoZWNrLlxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKGNvbnRyb2xsZXIpIHtcbiAgICBpZiAoIVJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYW5DbG9zZU9yRW5xdWV1ZShjb250cm9sbGVyKSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbTtcbiAgICBjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCA9IHRydWU7XG4gICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgICAgICBSZWFkYWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUoY29udHJvbGxlciwgY2h1bmspIHtcbiAgICBpZiAoIVJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYW5DbG9zZU9yRW5xdWV1ZShjb250cm9sbGVyKSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbTtcbiAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZChzdHJlYW0pICYmIFJlYWRhYmxlU3RyZWFtR2V0TnVtUmVhZFJlcXVlc3RzKHN0cmVhbSkgPiAwKSB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRSZXF1ZXN0KHN0cmVhbSwgY2h1bmssIGZhbHNlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGxldCBjaHVua1NpemU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjaHVua1NpemUgPSBjb250cm9sbGVyLl9zdHJhdGVneVNpemVBbGdvcml0aG0oY2h1bmspO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChjaHVua1NpemVFKSB7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgY2h1bmtTaXplRSk7XG4gICAgICAgICAgICB0aHJvdyBjaHVua1NpemVFO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250cm9sbGVyLCBjaHVuaywgY2h1bmtTaXplKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZW5xdWV1ZUUpIHtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlbnF1ZXVlRSk7XG4gICAgICAgICAgICB0aHJvdyBlbnF1ZXVlRTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlICE9PSAncmVhZGFibGUnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgUmVzZXRRdWV1ZShjb250cm9sbGVyKTtcbiAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgIFJlYWRhYmxlU3RyZWFtRXJyb3Ioc3RyZWFtLCBlKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVTdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gY29udHJvbGxlci5fc3RyYXRlZ3lIV00gLSBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZTtcbn1cbi8vIFRoaXMgaXMgdXNlZCBpbiB0aGUgaW1wbGVtZW50YXRpb24gb2YgVHJhbnNmb3JtU3RyZWFtLlxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckhhc0JhY2twcmVzc3VyZShjb250cm9sbGVyKSB7XG4gICAgaWYgKFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKCFjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCAmJiBzdGF0ZSA9PT0gJ3JlYWRhYmxlJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSkge1xuICAgIGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbSA9IHN0cmVhbTtcbiAgICBjb250cm9sbGVyLl9xdWV1ZSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSA9IHVuZGVmaW5lZDtcbiAgICBSZXNldFF1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgICBjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBZ2FpbiA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSBmYWxzZTtcbiAgICBjb250cm9sbGVyLl9zdHJhdGVneVNpemVBbGdvcml0aG0gPSBzaXplQWxnb3JpdGhtO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNID0gaGlnaFdhdGVyTWFyaztcbiAgICBjb250cm9sbGVyLl9wdWxsQWxnb3JpdGhtID0gcHVsbEFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9jYW5jZWxBbGdvcml0aG0gPSBjYW5jZWxBbGdvcml0aG07XG4gICAgc3RyZWFtLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuICAgIGNvbnN0IHN0YXJ0UmVzdWx0ID0gc3RhcnRBbGdvcml0aG0oKTtcbiAgICB1cG9uUHJvbWlzZShwcm9taXNlUmVzb2x2ZWRXaXRoKHN0YXJ0UmVzdWx0KSwgKCkgPT4ge1xuICAgICAgICBjb250cm9sbGVyLl9zdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG4gICAgfSwgciA9PiB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCByKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFNldFVwUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU291cmNlKHN0cmVhbSwgdW5kZXJseWluZ1NvdXJjZSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSkge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBsZXQgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlZmluZWQ7XG4gICAgbGV0IHB1bGxBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgbGV0IGNhbmNlbEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodW5kZXJseWluZ1NvdXJjZS5zdGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN0YXJ0QWxnb3JpdGhtID0gKCkgPT4gdW5kZXJseWluZ1NvdXJjZS5zdGFydChjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTb3VyY2UucHVsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHB1bGxBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nU291cmNlLnB1bGwoY29udHJvbGxlcik7XG4gICAgfVxuICAgIGlmICh1bmRlcmx5aW5nU291cmNlLmNhbmNlbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNhbmNlbEFsZ29yaXRobSA9IHJlYXNvbiA9PiB1bmRlcmx5aW5nU291cmNlLmNhbmNlbChyZWFzb24pO1xuICAgIH1cbiAgICBTZXRVcFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLlxuZnVuY3Rpb24gZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcmApO1xufVxuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbVRlZShzdHJlYW0sIGNsb25lRm9yQnJhbmNoMikge1xuICAgIGNvbnN0IHJlYWRlciA9IEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKTtcbiAgICBsZXQgcmVhZGluZyA9IGZhbHNlO1xuICAgIGxldCBjYW5jZWxlZDEgPSBmYWxzZTtcbiAgICBsZXQgY2FuY2VsZWQyID0gZmFsc2U7XG4gICAgbGV0IHJlYXNvbjE7XG4gICAgbGV0IHJlYXNvbjI7XG4gICAgbGV0IGJyYW5jaDE7XG4gICAgbGV0IGJyYW5jaDI7XG4gICAgbGV0IHJlc29sdmVDYW5jZWxQcm9taXNlO1xuICAgIGNvbnN0IGNhbmNlbFByb21pc2UgPSBuZXdQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gICAgZnVuY3Rpb24gcHVsbEFsZ29yaXRobSgpIHtcbiAgICAgICAgaWYgKHJlYWRpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVhZGluZyA9IHRydWU7XG4gICAgICAgIGNvbnN0IHJlYWRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX2NodW5rU3RlcHM6IHZhbHVlID0+IHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGJlIGRlbGF5ZWQgYSBtaWNyb3Rhc2sgYmVjYXVzZSBpdCB0YWtlcyBhdCBsZWFzdCBhIG1pY3JvdGFzayB0byBkZXRlY3QgZXJyb3JzICh1c2luZ1xuICAgICAgICAgICAgICAgIC8vIHJlYWRlci5fY2xvc2VkUHJvbWlzZSBiZWxvdyksIGFuZCB3ZSB3YW50IGVycm9ycyBpbiBzdHJlYW0gdG8gZXJyb3IgYm90aCBicmFuY2hlcyBpbW1lZGlhdGVseS4gV2UgY2Fubm90IGxldFxuICAgICAgICAgICAgICAgIC8vIHN1Y2Nlc3NmdWwgc3luY2hyb25vdXNseS1hdmFpbGFibGUgcmVhZHMgZ2V0IGFoZWFkIG9mIGFzeW5jaHJvbm91c2x5LWF2YWlsYWJsZSBlcnJvcnMuXG4gICAgICAgICAgICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWFkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlMSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZTIgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gd2F5IHRvIGFjY2VzcyB0aGUgY2xvbmluZyBjb2RlIHJpZ2h0IG5vdyBpbiB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBhZGQgb25lIHRoZW4gd2UnbGwgbmVlZCBhbiBpbXBsZW1lbnRhdGlvbiBmb3Igc2VyaWFsaXphYmxlIG9iamVjdHMuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmICghY2FuY2VsZWQyICYmIGNsb25lRm9yQnJhbmNoMikge1xuICAgICAgICAgICAgICAgICAgICAvLyAgIHZhbHVlMiA9IFN0cnVjdHVyZWREZXNlcmlhbGl6ZShTdHJ1Y3R1cmVkU2VyaWFsaXplKHZhbHVlMikpO1xuICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIHZhbHVlMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgdmFsdWUyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgX2Vycm9yU3RlcHM6ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZWFkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQocmVhZGVyLCByZWFkUmVxdWVzdCk7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNhbmNlbDFBbGdvcml0aG0ocmVhc29uKSB7XG4gICAgICAgIGNhbmNlbGVkMSA9IHRydWU7XG4gICAgICAgIHJlYXNvbjEgPSByZWFzb247XG4gICAgICAgIGlmIChjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXBvc2l0ZVJlYXNvbiA9IENyZWF0ZUFycmF5RnJvbUxpc3QoW3JlYXNvbjEsIHJlYXNvbjJdKTtcbiAgICAgICAgICAgIGNvbnN0IGNhbmNlbFJlc3VsdCA9IFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgY29tcG9zaXRlUmVhc29uKTtcbiAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKGNhbmNlbFJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbmNlbFByb21pc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNhbmNlbDJBbGdvcml0aG0ocmVhc29uKSB7XG4gICAgICAgIGNhbmNlbGVkMiA9IHRydWU7XG4gICAgICAgIHJlYXNvbjIgPSByZWFzb247XG4gICAgICAgIGlmIChjYW5jZWxlZDEpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXBvc2l0ZVJlYXNvbiA9IENyZWF0ZUFycmF5RnJvbUxpc3QoW3JlYXNvbjEsIHJlYXNvbjJdKTtcbiAgICAgICAgICAgIGNvbnN0IGNhbmNlbFJlc3VsdCA9IFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgY29tcG9zaXRlUmVhc29uKTtcbiAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKGNhbmNlbFJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbmNlbFByb21pc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHN0YXJ0QWxnb3JpdGhtKCkge1xuICAgICAgICAvLyBkbyBub3RoaW5nXG4gICAgfVxuICAgIGJyYW5jaDEgPSBDcmVhdGVSZWFkYWJsZVN0cmVhbShzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsMUFsZ29yaXRobSk7XG4gICAgYnJhbmNoMiA9IENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWwyQWxnb3JpdGhtKTtcbiAgICB1cG9uUmVqZWN0aW9uKHJlYWRlci5fY2xvc2VkUHJvbWlzZSwgKHIpID0+IHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgcik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIHIpO1xuICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSh1bmRlZmluZWQpO1xuICAgIH0pO1xuICAgIHJldHVybiBbYnJhbmNoMSwgYnJhbmNoMl07XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nRGVmYXVsdE9yQnl0ZVNvdXJjZShzb3VyY2UsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KHNvdXJjZSwgY29udGV4dCk7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSBzb3VyY2U7XG4gICAgY29uc3QgYXV0b0FsbG9jYXRlQ2h1bmtTaXplID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLmF1dG9BbGxvY2F0ZUNodW5rU2l6ZTtcbiAgICBjb25zdCBjYW5jZWwgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuY2FuY2VsO1xuICAgIGNvbnN0IHB1bGwgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwucHVsbDtcbiAgICBjb25zdCBzdGFydCA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5zdGFydDtcbiAgICBjb25zdCB0eXBlID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnR5cGU7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYXV0b0FsbG9jYXRlQ2h1bmtTaXplOiBhdXRvQWxsb2NhdGVDaHVua1NpemUgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuc2lnbmVkTG9uZ0xvbmdXaXRoRW5mb3JjZVJhbmdlKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnYXV0b0FsbG9jYXRlQ2h1bmtTaXplJyB0aGF0YCksXG4gICAgICAgIGNhbmNlbDogY2FuY2VsID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlQ2FuY2VsQ2FsbGJhY2soY2FuY2VsLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnY2FuY2VsJyB0aGF0YCksXG4gICAgICAgIHB1bGw6IHB1bGwgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuZGVybHlpbmdTb3VyY2VQdWxsQ2FsbGJhY2socHVsbCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3B1bGwnIHRoYXRgKSxcbiAgICAgICAgc3RhcnQ6IHN0YXJ0ID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHR5cGU6IHR5cGUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGNvbnZlcnRSZWFkYWJsZVN0cmVhbVR5cGUodHlwZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAndHlwZScgdGhhdGApXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlQ2FuY2VsQ2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAocmVhc29uKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtyZWFzb25dKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlUHVsbENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHByb21pc2VDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlU3RhcnRDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjb250cm9sbGVyKSA9PiByZWZsZWN0Q2FsbChmbiwgb3JpZ2luYWwsIFtjb250cm9sbGVyXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0UmVhZGFibGVTdHJlYW1UeXBlKHR5cGUsIGNvbnRleHQpIHtcbiAgICB0eXBlID0gYCR7dHlwZX1gO1xuICAgIGlmICh0eXBlICE9PSAnYnl0ZXMnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gJyR7dHlwZX0nIGlzIG5vdCBhIHZhbGlkIGVudW1lcmF0aW9uIHZhbHVlIGZvciBSZWFkYWJsZVN0cmVhbVR5cGVgKTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWFkZXJPcHRpb25zKG9wdGlvbnMsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KG9wdGlvbnMsIGNvbnRleHQpO1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubW9kZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtb2RlOiBtb2RlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0UmVhZGFibGVTdHJlYW1SZWFkZXJNb2RlKG1vZGUsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ21vZGUnIHRoYXRgKVxuICAgIH07XG59XG5mdW5jdGlvbiBjb252ZXJ0UmVhZGFibGVTdHJlYW1SZWFkZXJNb2RlKG1vZGUsIGNvbnRleHQpIHtcbiAgICBtb2RlID0gYCR7bW9kZX1gO1xuICAgIGlmIChtb2RlICE9PSAnYnlvYicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSAnJHttb2RlfScgaXMgbm90IGEgdmFsaWQgZW51bWVyYXRpb24gdmFsdWUgZm9yIFJlYWRhYmxlU3RyZWFtUmVhZGVyTW9kZWApO1xuICAgIH1cbiAgICByZXR1cm4gbW9kZTtcbn1cblxuZnVuY3Rpb24gY29udmVydEl0ZXJhdG9yT3B0aW9ucyhvcHRpb25zLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShvcHRpb25zLCBjb250ZXh0KTtcbiAgICBjb25zdCBwcmV2ZW50Q2FuY2VsID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDYW5jZWw7XG4gICAgcmV0dXJuIHsgcHJldmVudENhbmNlbDogQm9vbGVhbihwcmV2ZW50Q2FuY2VsKSB9O1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UGlwZU9wdGlvbnMob3B0aW9ucywgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkob3B0aW9ucywgY29udGV4dCk7XG4gICAgY29uc3QgcHJldmVudEFib3J0ID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRBYm9ydDtcbiAgICBjb25zdCBwcmV2ZW50Q2FuY2VsID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDYW5jZWw7XG4gICAgY29uc3QgcHJldmVudENsb3NlID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDbG9zZTtcbiAgICBjb25zdCBzaWduYWwgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMuc2lnbmFsO1xuICAgIGlmIChzaWduYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhc3NlcnRBYm9ydFNpZ25hbChzaWduYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3NpZ25hbCcgdGhhdGApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBwcmV2ZW50QWJvcnQ6IEJvb2xlYW4ocHJldmVudEFib3J0KSxcbiAgICAgICAgcHJldmVudENhbmNlbDogQm9vbGVhbihwcmV2ZW50Q2FuY2VsKSxcbiAgICAgICAgcHJldmVudENsb3NlOiBCb29sZWFuKHByZXZlbnRDbG9zZSksXG4gICAgICAgIHNpZ25hbFxuICAgIH07XG59XG5mdW5jdGlvbiBhc3NlcnRBYm9ydFNpZ25hbChzaWduYWwsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzQWJvcnRTaWduYWwoc2lnbmFsKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NvbnRleHR9IGlzIG5vdCBhbiBBYm9ydFNpZ25hbC5gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpcihwYWlyLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShwYWlyLCBjb250ZXh0KTtcbiAgICBjb25zdCByZWFkYWJsZSA9IHBhaXIgPT09IG51bGwgfHwgcGFpciA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFpci5yZWFkYWJsZTtcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKHJlYWRhYmxlLCAncmVhZGFibGUnLCAnUmVhZGFibGVXcml0YWJsZVBhaXInKTtcbiAgICBhc3NlcnRSZWFkYWJsZVN0cmVhbShyZWFkYWJsZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAncmVhZGFibGUnIHRoYXRgKTtcbiAgICBjb25zdCB3cml0YWJsZSA9IHBhaXIgPT09IG51bGwgfHwgcGFpciA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFpci53cml0YWJsZTtcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKHdyaXRhYmxlLCAnd3JpdGFibGUnLCAnUmVhZGFibGVXcml0YWJsZVBhaXInKTtcbiAgICBhc3NlcnRXcml0YWJsZVN0cmVhbSh3cml0YWJsZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnd3JpdGFibGUnIHRoYXRgKTtcbiAgICByZXR1cm4geyByZWFkYWJsZSwgd3JpdGFibGUgfTtcbn1cblxuLyoqXG4gKiBBIHJlYWRhYmxlIHN0cmVhbSByZXByZXNlbnRzIGEgc291cmNlIG9mIGRhdGEsIGZyb20gd2hpY2ggeW91IGNhbiByZWFkLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVTdHJlYW0ge1xuICAgIGNvbnN0cnVjdG9yKHJhd1VuZGVybHlpbmdTb3VyY2UgPSB7fSwgcmF3U3RyYXRlZ3kgPSB7fSkge1xuICAgICAgICBpZiAocmF3VW5kZXJseWluZ1NvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByYXdVbmRlcmx5aW5nU291cmNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFzc2VydE9iamVjdChyYXdVbmRlcmx5aW5nU291cmNlLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyYXRlZ3kgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5KHJhd1N0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCB1bmRlcmx5aW5nU291cmNlID0gY29udmVydFVuZGVybHlpbmdEZWZhdWx0T3JCeXRlU291cmNlKHJhd1VuZGVybHlpbmdTb3VyY2UsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgSW5pdGlhbGl6ZVJlYWRhYmxlU3RyZWFtKHRoaXMpO1xuICAgICAgICBpZiAodW5kZXJseWluZ1NvdXJjZS50eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgICAgICBpZiAoc3RyYXRlZ3kuc2l6ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBzdHJhdGVneSBmb3IgYSBieXRlIHN0cmVhbSBjYW5ub3QgaGF2ZSBhIHNpemUgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGhpZ2hXYXRlck1hcmsgPSBFeHRyYWN0SGlnaFdhdGVyTWFyayhzdHJhdGVneSwgMCk7XG4gICAgICAgICAgICBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGcm9tVW5kZXJseWluZ1NvdXJjZSh0aGlzLCB1bmRlcmx5aW5nU291cmNlLCBoaWdoV2F0ZXJNYXJrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShzdHJhdGVneSk7XG4gICAgICAgICAgICBjb25zdCBoaWdoV2F0ZXJNYXJrID0gRXh0cmFjdEhpZ2hXYXRlck1hcmsoc3RyYXRlZ3ksIDEpO1xuICAgICAgICAgICAgU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2UodGhpcywgdW5kZXJseWluZ1NvdXJjZSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hldGhlciBvciBub3QgdGhlIHJlYWRhYmxlIHN0cmVhbSBpcyBsb2NrZWQgdG8gYSB7QGxpbmsgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyIHwgcmVhZGVyfS5cbiAgICAgKi9cbiAgICBnZXQgbG9ja2VkKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnbG9ja2VkJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIElzUmVhZGFibGVTdHJlYW1Mb2NrZWQodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgdGhlIHN0cmVhbSwgc2lnbmFsaW5nIGEgbG9zcyBvZiBpbnRlcmVzdCBpbiB0aGUgc3RyZWFtIGJ5IGEgY29uc3VtZXIuXG4gICAgICpcbiAgICAgKiBUaGUgc3VwcGxpZWQgYHJlYXNvbmAgYXJndW1lbnQgd2lsbCBiZSBnaXZlbiB0byB0aGUgdW5kZXJseWluZyBzb3VyY2UncyB7QGxpbmsgVW5kZXJseWluZ1NvdXJjZS5jYW5jZWwgfCBjYW5jZWwoKX1cbiAgICAgKiBtZXRob2QsIHdoaWNoIG1pZ2h0IG9yIG1pZ2h0IG5vdCB1c2UgaXQuXG4gICAgICovXG4gICAgY2FuY2VsKHJlYXNvbiA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FuY2VsIGEgc3RyZWFtIHRoYXQgYWxyZWFkeSBoYXMgYSByZWFkZXInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIGdldFJlYWRlcihyYXdPcHRpb25zID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdnZXRSZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0gY29udmVydFJlYWRlck9wdGlvbnMocmF3T3B0aW9ucywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAob3B0aW9ucy5tb2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBBY3F1aXJlUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpO1xuICAgIH1cbiAgICBwaXBlVGhyb3VnaChyYXdUcmFuc2Zvcm0sIHJhd09wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgncGlwZVRocm91Z2gnKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHJhd1RyYW5zZm9ybSwgMSwgJ3BpcGVUaHJvdWdoJyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpcihyYXdUcmFuc2Zvcm0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbnZlcnRQaXBlT3B0aW9ucyhyYXdPcHRpb25zLCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUaHJvdWdoIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFJlYWRhYmxlU3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQodHJhbnNmb3JtLndyaXRhYmxlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUaHJvdWdoIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFdyaXRhYmxlU3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IFJlYWRhYmxlU3RyZWFtUGlwZVRvKHRoaXMsIHRyYW5zZm9ybS53cml0YWJsZSwgb3B0aW9ucy5wcmV2ZW50Q2xvc2UsIG9wdGlvbnMucHJldmVudEFib3J0LCBvcHRpb25zLnByZXZlbnRDYW5jZWwsIG9wdGlvbnMuc2lnbmFsKTtcbiAgICAgICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShwcm9taXNlKTtcbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybS5yZWFkYWJsZTtcbiAgICB9XG4gICAgcGlwZVRvKGRlc3RpbmF0aW9uLCByYXdPcHRpb25zID0ge30pIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3BpcGVUbycpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVzdGluYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoYFBhcmFtZXRlciAxIGlzIHJlcXVpcmVkIGluICdwaXBlVG8nLmApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZS5waXBlVG8ncyBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgV3JpdGFibGVTdHJlYW1gKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBvcHRpb25zID0gY29udmVydFBpcGVPcHRpb25zKHJhd09wdGlvbnMsICdTZWNvbmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUucGlwZVRvIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFJlYWRhYmxlU3RyZWFtJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUbyBjYW5ub3QgYmUgdXNlZCBvbiBhIGxvY2tlZCBXcml0YWJsZVN0cmVhbScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVTdHJlYW1QaXBlVG8odGhpcywgZGVzdGluYXRpb24sIG9wdGlvbnMucHJldmVudENsb3NlLCBvcHRpb25zLnByZXZlbnRBYm9ydCwgb3B0aW9ucy5wcmV2ZW50Q2FuY2VsLCBvcHRpb25zLnNpZ25hbCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRlZXMgdGhpcyByZWFkYWJsZSBzdHJlYW0sIHJldHVybmluZyBhIHR3by1lbGVtZW50IGFycmF5IGNvbnRhaW5pbmcgdGhlIHR3byByZXN1bHRpbmcgYnJhbmNoZXMgYXNcbiAgICAgKiBuZXcge0BsaW5rIFJlYWRhYmxlU3RyZWFtfSBpbnN0YW5jZXMuXG4gICAgICpcbiAgICAgKiBUZWVpbmcgYSBzdHJlYW0gd2lsbCBsb2NrIGl0LCBwcmV2ZW50aW5nIGFueSBvdGhlciBjb25zdW1lciBmcm9tIGFjcXVpcmluZyBhIHJlYWRlci5cbiAgICAgKiBUbyBjYW5jZWwgdGhlIHN0cmVhbSwgY2FuY2VsIGJvdGggb2YgdGhlIHJlc3VsdGluZyBicmFuY2hlczsgYSBjb21wb3NpdGUgY2FuY2VsbGF0aW9uIHJlYXNvbiB3aWxsIHRoZW4gYmVcbiAgICAgKiBwcm9wYWdhdGVkIHRvIHRoZSBzdHJlYW0ncyB1bmRlcmx5aW5nIHNvdXJjZS5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCB0aGUgY2h1bmtzIHNlZW4gaW4gZWFjaCBicmFuY2ggd2lsbCBiZSB0aGUgc2FtZSBvYmplY3QuIElmIHRoZSBjaHVua3MgYXJlIG5vdCBpbW11dGFibGUsXG4gICAgICogdGhpcyBjb3VsZCBhbGxvdyBpbnRlcmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGJyYW5jaGVzLlxuICAgICAqL1xuICAgIHRlZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3RlZScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJyYW5jaGVzID0gUmVhZGFibGVTdHJlYW1UZWUodGhpcyk7XG4gICAgICAgIHJldHVybiBDcmVhdGVBcnJheUZyb21MaXN0KGJyYW5jaGVzKTtcbiAgICB9XG4gICAgdmFsdWVzKHJhd09wdGlvbnMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3ZhbHVlcycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb252ZXJ0SXRlcmF0b3JPcHRpb25zKHJhd09wdGlvbnMsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgcmV0dXJuIEFjcXVpcmVSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IodGhpcywgb3B0aW9ucy5wcmV2ZW50Q2FuY2VsKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBjYW5jZWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGdldFJlYWRlcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcGlwZVRocm91Z2g6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHBpcGVUbzogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgdGVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB2YWx1ZXM6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGxvY2tlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1JlYWRhYmxlU3RyZWFtJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLmFzeW5jSXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwuYXN5bmNJdGVyYXRvciwge1xuICAgICAgICB2YWx1ZTogUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnZhbHVlcyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuLy8gVGhyb3dzIGlmIGFuZCBvbmx5IGlmIHN0YXJ0QWxnb3JpdGhtIHRocm93cy5cbmZ1bmN0aW9uIENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmsgPSAxLCBzaXplQWxnb3JpdGhtID0gKCkgPT4gMSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlKTtcbiAgICBJbml0aWFsaXplUmVhZGFibGVTdHJlYW0oc3RyZWFtKTtcbiAgICBjb25zdCBjb250cm9sbGVyID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLnByb3RvdHlwZSk7XG4gICAgU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbmZ1bmN0aW9uIEluaXRpYWxpemVSZWFkYWJsZVN0cmVhbShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ3JlYWRhYmxlJztcbiAgICBzdHJlYW0uX3JlYWRlciA9IHVuZGVmaW5lZDtcbiAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fZGlzdHVyYmVkID0gZmFsc2U7XG59XG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfcmVhZGFibGVTdHJlYW1Db250cm9sbGVyJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5fcmVhZGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbi8vIFJlYWRhYmxlU3RyZWFtIEFQSSBleHBvc2VkIGZvciBjb250cm9sbGVycy5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgcmVhc29uKSB7XG4gICAgc3RyZWFtLl9kaXN0dXJiZWQgPSB0cnVlO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIH1cbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbiAgICBSZWFkYWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG4gICAgY29uc3Qgc291cmNlQ2FuY2VsUHJvbWlzZSA9IHN0cmVhbS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyW0NhbmNlbFN0ZXBzXShyZWFzb24pO1xuICAgIHJldHVybiB0cmFuc2Zvcm1Qcm9taXNlV2l0aChzb3VyY2VDYW5jZWxQcm9taXNlLCBub29wKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKSB7XG4gICAgc3RyZWFtLl9zdGF0ZSA9ICdjbG9zZWQnO1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5fcmVhZGVyO1xuICAgIGlmIChyZWFkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJlYWRlci5fcmVhZFJlcXVlc3RzLmZvckVhY2gocmVhZFJlcXVlc3QgPT4ge1xuICAgICAgICAgICAgcmVhZFJlcXVlc3QuX2Nsb3NlU3RlcHMoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRlci5fcmVhZFJlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgfVxuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzb2x2ZShyZWFkZXIpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1FcnJvcihzdHJlYW0sIGUpIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ2Vycm9yZWQnO1xuICAgIHN0cmVhbS5fc3RvcmVkRXJyb3IgPSBlO1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5fcmVhZGVyO1xuICAgIGlmIChyZWFkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJlYWRlci5fcmVhZFJlcXVlc3RzLmZvckVhY2gocmVhZFJlcXVlc3QgPT4ge1xuICAgICAgICAgICAgcmVhZFJlcXVlc3QuX2Vycm9yU3RlcHMoZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZWFkZXIuX3JlYWRSZXF1ZXN0cyA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLmZvckVhY2gocmVhZEludG9SZXF1ZXN0ID0+IHtcbiAgICAgICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fZXJyb3JTdGVwcyhlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cyA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIH1cbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlamVjdChyZWFkZXIsIGUpO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQxKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtYCk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRRdWV1aW5nU3RyYXRlZ3lJbml0KGluaXQsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KGluaXQsIGNvbnRleHQpO1xuICAgIGNvbnN0IGhpZ2hXYXRlck1hcmsgPSBpbml0ID09PSBudWxsIHx8IGluaXQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGluaXQuaGlnaFdhdGVyTWFyaztcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKGhpZ2hXYXRlck1hcmssICdoaWdoV2F0ZXJNYXJrJywgJ1F1ZXVpbmdTdHJhdGVneUluaXQnKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBoaWdoV2F0ZXJNYXJrOiBjb252ZXJ0VW5yZXN0cmljdGVkRG91YmxlKGhpZ2hXYXRlck1hcmspXG4gICAgfTtcbn1cblxuY29uc3QgYnl0ZUxlbmd0aFNpemVGdW5jdGlvbiA9IGZ1bmN0aW9uIHNpemUoY2h1bmspIHtcbiAgICByZXR1cm4gY2h1bmsuYnl0ZUxlbmd0aDtcbn07XG4vKipcbiAqIEEgcXVldWluZyBzdHJhdGVneSB0aGF0IGNvdW50cyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIGVhY2ggY2h1bmsuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQob3B0aW9ucywgMSwgJ0J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3knKTtcbiAgICAgICAgb3B0aW9ucyA9IGNvbnZlcnRRdWV1aW5nU3RyYXRlZ3lJbml0KG9wdGlvbnMsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgdGhpcy5fYnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsgPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGhpZ2ggd2F0ZXIgbWFyayBwcm92aWRlZCB0byB0aGUgY29uc3RydWN0b3IuXG4gICAgICovXG4gICAgZ2V0IGhpZ2hXYXRlck1hcmsoKSB7XG4gICAgICAgIGlmICghSXNCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlTGVuZ3RoQnJhbmRDaGVja0V4Y2VwdGlvbignaGlnaFdhdGVyTWFyaycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9ieXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWVhc3VyZXMgdGhlIHNpemUgb2YgYGNodW5rYCBieSByZXR1cm5pbmcgdGhlIHZhbHVlIG9mIGl0cyBgYnl0ZUxlbmd0aGAgcHJvcGVydHkuXG4gICAgICovXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIGlmICghSXNCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlTGVuZ3RoQnJhbmRDaGVja0V4Y2VwdGlvbignc2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBieXRlTGVuZ3RoU2l6ZUZ1bmN0aW9uO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kucHJvdG90eXBlLCB7XG4gICAgaGlnaFdhdGVyTWFyazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgc2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneScsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kuXG5mdW5jdGlvbiBieXRlTGVuZ3RoQnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3lgKTtcbn1cbmZ1bmN0aW9uIElzQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneSh4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuY29uc3QgY291bnRTaXplRnVuY3Rpb24gPSBmdW5jdGlvbiBzaXplKCkge1xuICAgIHJldHVybiAxO1xufTtcbi8qKlxuICogQSBxdWV1aW5nIHN0cmF0ZWd5IHRoYXQgY291bnRzIHRoZSBudW1iZXIgb2YgY2h1bmtzLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgQ291bnRRdWV1aW5nU3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChvcHRpb25zLCAxLCAnQ291bnRRdWV1aW5nU3RyYXRlZ3knKTtcbiAgICAgICAgb3B0aW9ucyA9IGNvbnZlcnRRdWV1aW5nU3RyYXRlZ3lJbml0KG9wdGlvbnMsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgdGhpcy5fY291bnRRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBoaWdoIHdhdGVyIG1hcmsgcHJvdmlkZWQgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgICAqL1xuICAgIGdldCBoaWdoV2F0ZXJNYXJrKCkge1xuICAgICAgICBpZiAoIUlzQ291bnRRdWV1aW5nU3RyYXRlZ3kodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGNvdW50QnJhbmRDaGVja0V4Y2VwdGlvbignaGlnaFdhdGVyTWFyaycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jb3VudFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcms7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1lYXN1cmVzIHRoZSBzaXplIG9mIGBjaHVua2AgYnkgYWx3YXlzIHJldHVybmluZyAxLlxuICAgICAqIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSB0b3RhbCBxdWV1ZSBzaXplIGlzIGEgY291bnQgb2YgdGhlIG51bWJlciBvZiBjaHVua3MgaW4gdGhlIHF1ZXVlLlxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICBpZiAoIUlzQ291bnRRdWV1aW5nU3RyYXRlZ3kodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGNvdW50QnJhbmRDaGVja0V4Y2VwdGlvbignc2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb3VudFNpemVGdW5jdGlvbjtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhDb3VudFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUsIHtcbiAgICBoaWdoV2F0ZXJNYXJrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBzaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb3VudFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnQ291bnRRdWV1aW5nU3RyYXRlZ3knLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBDb3VudFF1ZXVpbmdTdHJhdGVneS5cbmZ1bmN0aW9uIGNvdW50QnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYENvdW50UXVldWluZ1N0cmF0ZWd5LnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBDb3VudFF1ZXVpbmdTdHJhdGVneWApO1xufVxuZnVuY3Rpb24gSXNDb3VudFF1ZXVpbmdTdHJhdGVneSh4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvdW50UXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyaycpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2Zvcm1lcihvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkob3JpZ2luYWwsIGNvbnRleHQpO1xuICAgIGNvbnN0IGZsdXNoID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLmZsdXNoO1xuICAgIGNvbnN0IHJlYWRhYmxlVHlwZSA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5yZWFkYWJsZVR5cGU7XG4gICAgY29uc3Qgc3RhcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuc3RhcnQ7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnRyYW5zZm9ybTtcbiAgICBjb25zdCB3cml0YWJsZVR5cGUgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwud3JpdGFibGVUeXBlO1xuICAgIHJldHVybiB7XG4gICAgICAgIGZsdXNoOiBmbHVzaCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VHJhbnNmb3JtZXJGbHVzaENhbGxiYWNrKGZsdXNoLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnZmx1c2gnIHRoYXRgKSxcbiAgICAgICAgcmVhZGFibGVUeXBlLFxuICAgICAgICBzdGFydDogc3RhcnQgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFRyYW5zZm9ybWVyU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNmb3JtID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrKHRyYW5zZm9ybSwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3RyYW5zZm9ybScgdGhhdGApLFxuICAgICAgICB3cml0YWJsZVR5cGVcbiAgICB9O1xufVxuZnVuY3Rpb24gY29udmVydFRyYW5zZm9ybWVyRmx1c2hDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjb250cm9sbGVyKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtjb250cm9sbGVyXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VHJhbnNmb3JtZXJTdGFydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHJlZmxlY3RDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNodW5rLCBjb250cm9sbGVyKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtjaHVuaywgY29udHJvbGxlcl0pO1xufVxuXG4vLyBDbGFzcyBUcmFuc2Zvcm1TdHJlYW1cbi8qKlxuICogQSB0cmFuc2Zvcm0gc3RyZWFtIGNvbnNpc3RzIG9mIGEgcGFpciBvZiBzdHJlYW1zOiBhIHtAbGluayBXcml0YWJsZVN0cmVhbSB8IHdyaXRhYmxlIHN0cmVhbX0sXG4gKiBrbm93biBhcyBpdHMgd3JpdGFibGUgc2lkZSwgYW5kIGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtIHwgcmVhZGFibGUgc3RyZWFtfSwga25vd24gYXMgaXRzIHJlYWRhYmxlIHNpZGUuXG4gKiBJbiBhIG1hbm5lciBzcGVjaWZpYyB0byB0aGUgdHJhbnNmb3JtIHN0cmVhbSBpbiBxdWVzdGlvbiwgd3JpdGVzIHRvIHRoZSB3cml0YWJsZSBzaWRlIHJlc3VsdCBpbiBuZXcgZGF0YSBiZWluZ1xuICogbWFkZSBhdmFpbGFibGUgZm9yIHJlYWRpbmcgZnJvbSB0aGUgcmVhZGFibGUgc2lkZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFRyYW5zZm9ybVN0cmVhbSB7XG4gICAgY29uc3RydWN0b3IocmF3VHJhbnNmb3JtZXIgPSB7fSwgcmF3V3JpdGFibGVTdHJhdGVneSA9IHt9LCByYXdSZWFkYWJsZVN0cmF0ZWd5ID0ge30pIHtcbiAgICAgICAgaWYgKHJhd1RyYW5zZm9ybWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJhd1RyYW5zZm9ybWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3cml0YWJsZVN0cmF0ZWd5ID0gY29udmVydFF1ZXVpbmdTdHJhdGVneShyYXdXcml0YWJsZVN0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCByZWFkYWJsZVN0cmF0ZWd5ID0gY29udmVydFF1ZXVpbmdTdHJhdGVneShyYXdSZWFkYWJsZVN0cmF0ZWd5LCAnVGhpcmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gY29udmVydFRyYW5zZm9ybWVyKHJhd1RyYW5zZm9ybWVyLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci5yZWFkYWJsZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgcmVhZGFibGVUeXBlIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci53cml0YWJsZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgd3JpdGFibGVUeXBlIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlSGlnaFdhdGVyTWFyayA9IEV4dHJhY3RIaWdoV2F0ZXJNYXJrKHJlYWRhYmxlU3RyYXRlZ3ksIDApO1xuICAgICAgICBjb25zdCByZWFkYWJsZVNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShyZWFkYWJsZVN0cmF0ZWd5KTtcbiAgICAgICAgY29uc3Qgd3JpdGFibGVIaWdoV2F0ZXJNYXJrID0gRXh0cmFjdEhpZ2hXYXRlck1hcmsod3JpdGFibGVTdHJhdGVneSwgMSk7XG4gICAgICAgIGNvbnN0IHdyaXRhYmxlU2l6ZUFsZ29yaXRobSA9IEV4dHJhY3RTaXplQWxnb3JpdGhtKHdyaXRhYmxlU3RyYXRlZ3kpO1xuICAgICAgICBsZXQgc3RhcnRQcm9taXNlX3Jlc29sdmU7XG4gICAgICAgIGNvbnN0IHN0YXJ0UHJvbWlzZSA9IG5ld1Byb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBJbml0aWFsaXplVHJhbnNmb3JtU3RyZWFtKHRoaXMsIHN0YXJ0UHJvbWlzZSwgd3JpdGFibGVIaWdoV2F0ZXJNYXJrLCB3cml0YWJsZVNpemVBbGdvcml0aG0sIHJlYWRhYmxlSGlnaFdhdGVyTWFyaywgcmVhZGFibGVTaXplQWxnb3JpdGhtKTtcbiAgICAgICAgU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21UcmFuc2Zvcm1lcih0aGlzLCB0cmFuc2Zvcm1lcik7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci5zdGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSh0cmFuc2Zvcm1lci5zdGFydCh0aGlzLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWFkYWJsZSBzaWRlIG9mIHRoZSB0cmFuc2Zvcm0gc3RyZWFtLlxuICAgICAqL1xuICAgIGdldCByZWFkYWJsZSgpIHtcbiAgICAgICAgaWYgKCFJc1RyYW5zZm9ybVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdyZWFkYWJsZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWFkYWJsZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHdyaXRhYmxlIHNpZGUgb2YgdGhlIHRyYW5zZm9ybSBzdHJlYW0uXG4gICAgICovXG4gICAgZ2V0IHdyaXRhYmxlKCkge1xuICAgICAgICBpZiAoIUlzVHJhbnNmb3JtU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDIoJ3dyaXRhYmxlJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3dyaXRhYmxlO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFRyYW5zZm9ybVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICByZWFkYWJsZTogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgd3JpdGFibGU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9XG59KTtcbmlmICh0eXBlb2YgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRyYW5zZm9ybVN0cmVhbS5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnVHJhbnNmb3JtU3RyZWFtJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG5mdW5jdGlvbiBJbml0aWFsaXplVHJhbnNmb3JtU3RyZWFtKHN0cmVhbSwgc3RhcnRQcm9taXNlLCB3cml0YWJsZUhpZ2hXYXRlck1hcmssIHdyaXRhYmxlU2l6ZUFsZ29yaXRobSwgcmVhZGFibGVIaWdoV2F0ZXJNYXJrLCByZWFkYWJsZVNpemVBbGdvcml0aG0pIHtcbiAgICBmdW5jdGlvbiBzdGFydEFsZ29yaXRobSgpIHtcbiAgICAgICAgcmV0dXJuIHN0YXJ0UHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gd3JpdGVBbGdvcml0aG0oY2h1bmspIHtcbiAgICAgICAgcmV0dXJuIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRTaW5rV3JpdGVBbGdvcml0aG0oc3RyZWFtLCBjaHVuayk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGFib3J0QWxnb3JpdGhtKHJlYXNvbikge1xuICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtBYm9ydEFsZ29yaXRobShzdHJlYW0sIHJlYXNvbik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNsb3NlQWxnb3JpdGhtKCkge1xuICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtDbG9zZUFsZ29yaXRobShzdHJlYW0pO1xuICAgIH1cbiAgICBzdHJlYW0uX3dyaXRhYmxlID0gQ3JlYXRlV3JpdGFibGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHdyaXRlQWxnb3JpdGhtLCBjbG9zZUFsZ29yaXRobSwgYWJvcnRBbGdvcml0aG0sIHdyaXRhYmxlSGlnaFdhdGVyTWFyaywgd3JpdGFibGVTaXplQWxnb3JpdGhtKTtcbiAgICBmdW5jdGlvbiBwdWxsQWxnb3JpdGhtKCkge1xuICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNvdXJjZVB1bGxBbGdvcml0aG0oc3RyZWFtKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2FuY2VsQWxnb3JpdGhtKHJlYXNvbikge1xuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1FcnJvcldyaXRhYmxlQW5kVW5ibG9ja1dyaXRlKHN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgc3RyZWFtLl9yZWFkYWJsZSA9IENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIHJlYWRhYmxlSGlnaFdhdGVyTWFyaywgcmVhZGFibGVTaXplQWxnb3JpdGhtKTtcbiAgICAvLyBUaGUgW1tiYWNrcHJlc3N1cmVdXSBzbG90IGlzIHNldCB0byB1bmRlZmluZWQgc28gdGhhdCBpdCBjYW4gYmUgaW5pdGlhbGlzZWQgYnkgVHJhbnNmb3JtU3RyZWFtU2V0QmFja3ByZXNzdXJlLlxuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZSA9IHVuZGVmaW5lZDtcbiAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUoc3RyZWFtLCB0cnVlKTtcbiAgICBzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXIgPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBJc1RyYW5zZm9ybVN0cmVhbSh4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLy8gVGhpcyBpcyBhIG5vLW9wIGlmIGJvdGggc2lkZXMgYXJlIGFscmVhZHkgZXJyb3JlZC5cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbUVycm9yKHN0cmVhbSwgZSkge1xuICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihzdHJlYW0uX3JlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGUpO1xuICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUoc3RyZWFtLCBlKTtcbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUoc3RyZWFtLCBlKSB7XG4gICAgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoc3RyZWFtLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyKTtcbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3JJZk5lZWRlZChzdHJlYW0uX3dyaXRhYmxlLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIsIGUpO1xuICAgIGlmIChzdHJlYW0uX2JhY2twcmVzc3VyZSkge1xuICAgICAgICAvLyBQcmV0ZW5kIHRoYXQgcHVsbCgpIHdhcyBjYWxsZWQgdG8gcGVybWl0IGFueSBwZW5kaW5nIHdyaXRlKCkgY2FsbHMgdG8gY29tcGxldGUuIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZSgpXG4gICAgICAgIC8vIGNhbm5vdCBiZSBjYWxsZWQgZnJvbSBlbnF1ZXVlKCkgb3IgcHVsbCgpIG9uY2UgdGhlIFJlYWRhYmxlU3RyZWFtIGlzIGVycm9yZWQsIHNvIHRoaXMgd2lsbCB3aWxsIGJlIHRoZSBmaW5hbCB0aW1lXG4gICAgICAgIC8vIF9iYWNrcHJlc3N1cmUgaXMgc2V0LlxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUoc3RyZWFtLCBmYWxzZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtU2V0QmFja3ByZXNzdXJlKHN0cmVhbSwgYmFja3ByZXNzdXJlKSB7XG4gICAgLy8gUGFzc2VzIGFsc28gd2hlbiBjYWxsZWQgZHVyaW5nIGNvbnN0cnVjdGlvbi5cbiAgICBpZiAoc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlX3Jlc29sdmUoKTtcbiAgICB9XG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlID0gbmV3UHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlX3Jlc29sdmUgPSByZXNvbHZlO1xuICAgIH0pO1xuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlID0gYmFja3ByZXNzdXJlO1xufVxuLy8gQ2xhc3MgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJcbi8qKlxuICogQWxsb3dzIGNvbnRyb2wgb2YgdGhlIHtAbGluayBSZWFkYWJsZVN0cmVhbX0gYW5kIHtAbGluayBXcml0YWJsZVN0cmVhbX0gb2YgdGhlIGFzc29jaWF0ZWQge0BsaW5rIFRyYW5zZm9ybVN0cmVhbX0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgY29uc3RydWN0b3InKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIHJlYWRhYmxlIHNpZGXigJlzIGludGVybmFsIHF1ZXVlLiBJdCBjYW4gYmUgbmVnYXRpdmUsIGlmIHRoZSBxdWV1ZSBpcyBvdmVyLWZ1bGwuXG4gICAgICovXG4gICAgZ2V0IGRlc2lyZWRTaXplKCkge1xuICAgICAgICBpZiAoIUlzVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlQ29udHJvbGxlciA9IHRoaXMuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW0uX3JlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUocmVhZGFibGVDb250cm9sbGVyKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuayA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdlbnF1ZXVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlKHRoaXMsIGNodW5rKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXJyb3JzIGJvdGggdGhlIHJlYWRhYmxlIHNpZGUgYW5kIHRoZSB3cml0YWJsZSBzaWRlIG9mIHRoZSBjb250cm9sbGVkIHRyYW5zZm9ybSBzdHJlYW0sIG1ha2luZyBhbGwgZnV0dXJlXG4gICAgICogaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuIEFueSBjaHVua3MgcXVldWVkIGZvciB0cmFuc2Zvcm1hdGlvbiB3aWxsIGJlIGRpc2NhcmRlZC5cbiAgICAgKi9cbiAgICBlcnJvcihyZWFzb24gPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBkZWZhdWx0Q29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnZXJyb3InKTtcbiAgICAgICAgfVxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgcmVhZGFibGUgc2lkZSBhbmQgZXJyb3JzIHRoZSB3cml0YWJsZSBzaWRlIG9mIHRoZSBjb250cm9sbGVkIHRyYW5zZm9ybSBzdHJlYW0uIFRoaXMgaXMgdXNlZnVsIHdoZW4gdGhlXG4gICAgICogdHJhbnNmb3JtZXIgb25seSBuZWVkcyB0byBjb25zdW1lIGEgcG9ydGlvbiBvZiB0aGUgY2h1bmtzIHdyaXR0ZW4gdG8gdGhlIHdyaXRhYmxlIHNpZGUuXG4gICAgICovXG4gICAgdGVybWluYXRlKCkge1xuICAgICAgICBpZiAoIUlzVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCd0ZXJtaW5hdGUnKTtcbiAgICAgICAgfVxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclRlcm1pbmF0ZSh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBlbnF1ZXVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgdGVybWluYXRlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBkZXNpcmVkU2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBUcmFuc2Zvcm0gU3RyZWFtIERlZmF1bHQgQ29udHJvbGxlciBBYnN0cmFjdCBPcGVyYXRpb25zXG5mdW5jdGlvbiBJc1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBTZXRVcFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgdHJhbnNmb3JtQWxnb3JpdGhtLCBmbHVzaEFsZ29yaXRobSkge1xuICAgIGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW0gPSBzdHJlYW07XG4gICAgc3RyZWFtLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyID0gY29udHJvbGxlcjtcbiAgICBjb250cm9sbGVyLl90cmFuc2Zvcm1BbGdvcml0aG0gPSB0cmFuc2Zvcm1BbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fZmx1c2hBbGdvcml0aG0gPSBmbHVzaEFsZ29yaXRobTtcbn1cbmZ1bmN0aW9uIFNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJGcm9tVHJhbnNmb3JtZXIoc3RyZWFtLCB0cmFuc2Zvcm1lcikge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyLnByb3RvdHlwZSk7XG4gICAgbGV0IHRyYW5zZm9ybUFsZ29yaXRobSA9IChjaHVuaykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlKGNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKHRyYW5zZm9ybVJlc3VsdEUpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHRyYW5zZm9ybVJlc3VsdEUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBsZXQgZmx1c2hBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgaWYgKHRyYW5zZm9ybWVyLnRyYW5zZm9ybSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRyYW5zZm9ybUFsZ29yaXRobSA9IGNodW5rID0+IHRyYW5zZm9ybWVyLnRyYW5zZm9ybShjaHVuaywgY29udHJvbGxlcik7XG4gICAgfVxuICAgIGlmICh0cmFuc2Zvcm1lci5mbHVzaCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZsdXNoQWxnb3JpdGhtID0gKCkgPT4gdHJhbnNmb3JtZXIuZmx1c2goY29udHJvbGxlcik7XG4gICAgfVxuICAgIFNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCB0cmFuc2Zvcm1BbGdvcml0aG0sIGZsdXNoQWxnb3JpdGhtKTtcbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpIHtcbiAgICBjb250cm9sbGVyLl90cmFuc2Zvcm1BbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fZmx1c2hBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUoY29udHJvbGxlciwgY2h1bmspIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkVHJhbnNmb3JtU3RyZWFtO1xuICAgIGNvbnN0IHJlYWRhYmxlQ29udHJvbGxlciA9IHN0cmVhbS5fcmVhZGFibGUuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcjtcbiAgICBpZiAoIVJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYW5DbG9zZU9yRW5xdWV1ZShyZWFkYWJsZUNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlYWRhYmxlIHNpZGUgaXMgbm90IGluIGEgc3RhdGUgdGhhdCBwZXJtaXRzIGVucXVldWUnKTtcbiAgICB9XG4gICAgLy8gV2UgdGhyb3R0bGUgdHJhbnNmb3JtIGludm9jYXRpb25zIGJhc2VkIG9uIHRoZSBiYWNrcHJlc3N1cmUgb2YgdGhlIFJlYWRhYmxlU3RyZWFtLCBidXQgd2Ugc3RpbGxcbiAgICAvLyBhY2NlcHQgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlKCkgY2FsbHMuXG4gICAgdHJ5IHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUocmVhZGFibGVDb250cm9sbGVyLCBjaHVuayk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIC8vIFRoaXMgaGFwcGVucyB3aGVuIHJlYWRhYmxlU3RyYXRlZ3kuc2l6ZSgpIHRocm93cy5cbiAgICAgICAgVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZShzdHJlYW0sIGUpO1xuICAgICAgICB0aHJvdyBzdHJlYW0uX3JlYWRhYmxlLl9zdG9yZWRFcnJvcjtcbiAgICB9XG4gICAgY29uc3QgYmFja3ByZXNzdXJlID0gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckhhc0JhY2twcmVzc3VyZShyZWFkYWJsZUNvbnRyb2xsZXIpO1xuICAgIGlmIChiYWNrcHJlc3N1cmUgIT09IHN0cmVhbS5fYmFja3ByZXNzdXJlKSB7XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIHRydWUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSkge1xuICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW0sIGUpO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQZXJmb3JtVHJhbnNmb3JtKGNvbnRyb2xsZXIsIGNodW5rKSB7XG4gICAgY29uc3QgdHJhbnNmb3JtUHJvbWlzZSA9IGNvbnRyb2xsZXIuX3RyYW5zZm9ybUFsZ29yaXRobShjaHVuayk7XG4gICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKHRyYW5zZm9ybVByb21pc2UsIHVuZGVmaW5lZCwgciA9PiB7XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW0sIHIpO1xuICAgICAgICB0aHJvdyByO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJUZXJtaW5hdGUoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW07XG4gICAgY29uc3QgcmVhZGFibGVDb250cm9sbGVyID0gc3RyZWFtLl9yZWFkYWJsZS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyO1xuICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZShyZWFkYWJsZUNvbnRyb2xsZXIpO1xuICAgIGNvbnN0IGVycm9yID0gbmV3IFR5cGVFcnJvcignVHJhbnNmb3JtU3RyZWFtIHRlcm1pbmF0ZWQnKTtcbiAgICBUcmFuc2Zvcm1TdHJlYW1FcnJvcldyaXRhYmxlQW5kVW5ibG9ja1dyaXRlKHN0cmVhbSwgZXJyb3IpO1xufVxuLy8gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmsgQWxnb3JpdGhtc1xuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtXcml0ZUFsZ29yaXRobShzdHJlYW0sIGNodW5rKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IHN0cmVhbS5fdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlcjtcbiAgICBpZiAoc3RyZWFtLl9iYWNrcHJlc3N1cmUpIHtcbiAgICAgICAgY29uc3QgYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZSA9IHN0cmVhbS5fYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZTtcbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKGJhY2twcmVzc3VyZUNoYW5nZVByb21pc2UsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHdyaXRhYmxlID0gc3RyZWFtLl93cml0YWJsZTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXRlID0gd3JpdGFibGUuX3N0YXRlO1xuICAgICAgICAgICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgd3JpdGFibGUuX3N0b3JlZEVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyUGVyZm9ybVRyYW5zZm9ybShjb250cm9sbGVyLCBjaHVuayk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQZXJmb3JtVHJhbnNmb3JtKGNvbnRyb2xsZXIsIGNodW5rKTtcbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRTaW5rQWJvcnRBbGdvcml0aG0oc3RyZWFtLCByZWFzb24pIHtcbiAgICAvLyBhYm9ydCgpIGlzIG5vdCBjYWxsZWQgc3luY2hyb25vdXNseSwgc28gaXQgaXMgcG9zc2libGUgZm9yIGFib3J0KCkgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIHN0cmVhbSBpcyBhbHJlYWR5XG4gICAgLy8gZXJyb3JlZC5cbiAgICBUcmFuc2Zvcm1TdHJlYW1FcnJvcihzdHJlYW0sIHJlYXNvbik7XG4gICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRTaW5rQ2xvc2VBbGdvcml0aG0oc3RyZWFtKSB7XG4gICAgLy8gc3RyZWFtLl9yZWFkYWJsZSBjYW5ub3QgY2hhbmdlIGFmdGVyIGNvbnN0cnVjdGlvbiwgc28gY2FjaGluZyBpdCBhY3Jvc3MgYSBjYWxsIHRvIHVzZXIgY29kZSBpcyBzYWZlLlxuICAgIGNvbnN0IHJlYWRhYmxlID0gc3RyZWFtLl9yZWFkYWJsZTtcbiAgICBjb25zdCBjb250cm9sbGVyID0gc3RyZWFtLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyO1xuICAgIGNvbnN0IGZsdXNoUHJvbWlzZSA9IGNvbnRyb2xsZXIuX2ZsdXNoQWxnb3JpdGhtKCk7XG4gICAgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgLy8gUmV0dXJuIGEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCB3aXRoIHVuZGVmaW5lZCBvbiBzdWNjZXNzLlxuICAgIHJldHVybiB0cmFuc2Zvcm1Qcm9taXNlV2l0aChmbHVzaFByb21pc2UsICgpID0+IHtcbiAgICAgICAgaWYgKHJlYWRhYmxlLl9zdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyByZWFkYWJsZS5fc3RvcmVkRXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKHJlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgIH0sIHIgPT4ge1xuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1FcnJvcihzdHJlYW0sIHIpO1xuICAgICAgICB0aHJvdyByZWFkYWJsZS5fc3RvcmVkRXJyb3I7XG4gICAgfSk7XG59XG4vLyBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U291cmNlIEFsZ29yaXRobXNcbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRTb3VyY2VQdWxsQWxnb3JpdGhtKHN0cmVhbSkge1xuICAgIC8vIEludmFyaWFudC4gRW5mb3JjZWQgYnkgdGhlIHByb21pc2VzIHJldHVybmVkIGJ5IHN0YXJ0KCkgYW5kIHB1bGwoKS5cbiAgICBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUoc3RyZWFtLCBmYWxzZSk7XG4gICAgLy8gUHJldmVudCB0aGUgbmV4dCBwdWxsKCkgY2FsbCB1bnRpbCB0aGVyZSBpcyBiYWNrcHJlc3N1cmUuXG4gICAgcmV0dXJuIHN0cmVhbS5fYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlci5cbmZ1bmN0aW9uIGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyYCk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgVHJhbnNmb3JtU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgVHJhbnNmb3JtU3RyZWFtLnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBUcmFuc2Zvcm1TdHJlYW1gKTtcbn1cblxuZXhwb3J0IHsgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneSwgQ291bnRRdWV1aW5nU3RyYXRlZ3ksIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIsIFJlYWRhYmxlU3RyZWFtLCBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIsIFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QsIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIsIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciwgVHJhbnNmb3JtU3RyZWFtLCBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciwgV3JpdGFibGVTdHJlYW0sIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIsIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cG9ueWZpbGwuZXMyMDE4Lm1qcy5tYXBcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNyeXB0b1wiKTs7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cFwiKTs7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cHNcIik7OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInN0cmVhbVwiKTs7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidXJsXCIpOzsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1dGlsXCIpOzsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ6bGliXCIpOzsiLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHRpZihfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdKSB7XG5cdFx0cmV0dXJuIF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0uZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIG1vZHVsZSBleHBvcnRzIG11c3QgYmUgcmV0dXJuZWQgZnJvbSBydW50aW1lIHNvIGVudHJ5IGlubGluaW5nIGlzIGRpc2FibGVkXG4vLyBzdGFydHVwXG4vLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbnJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDk5MCk7XG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyJdLCJzb3VyY2VSb290IjoiIn0= +"use strict"; -/***/ }), -/***/ 622: -/***/ (function(module) { +// TODO: +// * support 1 nested multipart level +// (see second multipart example here: +// http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data) +// * support limits.fieldNameSize +// -- this will require modifications to utils.parseParams + +const { Readable } = __nccwpck_require__(4492) +const { inherits } = __nccwpck_require__(7261) + +const Dicer = __nccwpck_require__(2960) + +const parseParams = __nccwpck_require__(1854) +const decodeText = __nccwpck_require__(4619) +const basename = __nccwpck_require__(8647) +const getLimit = __nccwpck_require__(1467) + +const RE_BOUNDARY = /^boundary$/i +const RE_FIELD = /^form-data$/i +const RE_CHARSET = /^charset$/i +const RE_FILENAME = /^filename$/i +const RE_NAME = /^name$/i + +Multipart.detect = /^multipart\/form-data/i +function Multipart (boy, cfg) { + let i + let len + const self = this + let boundary + const limits = cfg.limits + const isPartAFile = cfg.isPartAFile || ((fieldName, contentType, fileName) => (contentType === 'application/octet-stream' || fileName !== undefined)) + const parsedConType = cfg.parsedConType || [] + const defCharset = cfg.defCharset || 'utf8' + const preservePath = cfg.preservePath + const fileOpts = { highWaterMark: cfg.fileHwm } + + for (i = 0, len = parsedConType.length; i < len; ++i) { + if (Array.isArray(parsedConType[i]) && + RE_BOUNDARY.test(parsedConType[i][0])) { + boundary = parsedConType[i][1] + break + } + } -module.exports = require("path"); + function checkFinished () { + if (nends === 0 && finished && !boy._done) { + finished = false + self.end() + } + } -/***/ }), + if (typeof boundary !== 'string') { throw new Error('Multipart: Boundary not found') } + + const fieldSizeLimit = getLimit(limits, 'fieldSize', 1 * 1024 * 1024) + const fileSizeLimit = getLimit(limits, 'fileSize', Infinity) + const filesLimit = getLimit(limits, 'files', Infinity) + const fieldsLimit = getLimit(limits, 'fields', Infinity) + const partsLimit = getLimit(limits, 'parts', Infinity) + const headerPairsLimit = getLimit(limits, 'headerPairs', 2000) + const headerSizeLimit = getLimit(limits, 'headerSize', 80 * 1024) + + let nfiles = 0 + let nfields = 0 + let nends = 0 + let curFile + let curField + let finished = false + + this._needDrain = false + this._pause = false + this._cb = undefined + this._nparts = 0 + this._boy = boy + + const parserCfg = { + boundary, + maxHeaderPairs: headerPairsLimit, + maxHeaderSize: headerSizeLimit, + partHwm: fileOpts.highWaterMark, + highWaterMark: cfg.highWaterMark + } -/***/ 669: -/***/ (function(module) { + this.parser = new Dicer(parserCfg) + this.parser.on('drain', function () { + self._needDrain = false + if (self._cb && !self._pause) { + const cb = self._cb + self._cb = undefined + cb() + } + }).on('part', function onPart (part) { + if (++self._nparts > partsLimit) { + self.parser.removeListener('part', onPart) + self.parser.on('part', skipPart) + boy.hitPartsLimit = true + boy.emit('partsLimit') + return skipPart(part) + } -module.exports = require("util"); + // hack because streams2 _always_ doesn't emit 'end' until nextTick, so let + // us emit 'end' early since we know the part has ended if we are already + // seeing the next part + if (curField) { + const field = curField + field.emit('end') + field.removeAllListeners('end') + } -/***/ }), + part.on('header', function (header) { + let contype + let fieldname + let parsed + let charset + let encoding + let filename + let nsize = 0 + + if (header['content-type']) { + parsed = parseParams(header['content-type'][0]) + if (parsed[0]) { + contype = parsed[0].toLowerCase() + for (i = 0, len = parsed.length; i < len; ++i) { + if (RE_CHARSET.test(parsed[i][0])) { + charset = parsed[i][1].toLowerCase() + break + } + } + } + } -/***/ 747: -/***/ (function(module) { + if (contype === undefined) { contype = 'text/plain' } + if (charset === undefined) { charset = defCharset } + + if (header['content-disposition']) { + parsed = parseParams(header['content-disposition'][0]) + if (!RE_FIELD.test(parsed[0])) { return skipPart(part) } + for (i = 0, len = parsed.length; i < len; ++i) { + if (RE_NAME.test(parsed[i][0])) { + fieldname = parsed[i][1] + } else if (RE_FILENAME.test(parsed[i][0])) { + filename = parsed[i][1] + if (!preservePath) { filename = basename(filename) } + } + } + } else { return skipPart(part) } -module.exports = require("fs"); + if (header['content-transfer-encoding']) { encoding = header['content-transfer-encoding'][0].toLowerCase() } else { encoding = '7bit' } -/***/ }), + let onData, + onEnd -/***/ 761: -/***/ (function(module) { + if (isPartAFile(fieldname, contype, filename)) { + // file/binary field + if (nfiles === filesLimit) { + if (!boy.hitFilesLimit) { + boy.hitFilesLimit = true + boy.emit('filesLimit') + } + return skipPart(part) + } -module.exports = require("zlib"); + ++nfiles -/***/ }), + if (!boy._events.file) { + self.parser._ignore() + return + } -/***/ 762: -/***/ (function(module) { + ++nends + const file = new FileStream(fileOpts) + curFile = file + file.on('end', function () { + --nends + self._pause = false + checkFinished() + if (self._cb && !self._needDrain) { + const cb = self._cb + self._cb = undefined + cb() + } + }) + file._read = function (n) { + if (!self._pause) { return } + self._pause = false + if (self._cb && !self._needDrain) { + const cb = self._cb + self._cb = undefined + cb() + } + } + boy.emit('file', fieldname, file, filename, encoding, contype) + + onData = function (data) { + if ((nsize += data.length) > fileSizeLimit) { + const extralen = fileSizeLimit - nsize + data.length + if (extralen > 0) { file.push(data.slice(0, extralen)) } + file.truncated = true + file.bytesRead = fileSizeLimit + part.removeAllListeners('data') + file.emit('limit') + return + } else if (!file.push(data)) { self._pause = true } + + file.bytesRead = nsize + } -// API -module.exports = abort; + onEnd = function () { + curFile = undefined + file.push(null) + } + } else { + // non-file field + if (nfields === fieldsLimit) { + if (!boy.hitFieldsLimit) { + boy.hitFieldsLimit = true + boy.emit('fieldsLimit') + } + return skipPart(part) + } -/** - * Aborts leftover active jobs - * - * @param {object} state - current state object - */ -function abort(state) -{ - Object.keys(state.jobs).forEach(clean.bind(state)); + ++nfields + ++nends + let buffer = '' + let truncated = false + curField = part + + onData = function (data) { + if ((nsize += data.length) > fieldSizeLimit) { + const extralen = (fieldSizeLimit - (nsize - data.length)) + buffer += data.toString('binary', 0, extralen) + truncated = true + part.removeAllListeners('data') + } else { buffer += data.toString('binary') } + } - // reset leftover jobs - state.jobs = {}; + onEnd = function () { + curField = undefined + if (buffer.length) { buffer = decodeText(buffer, 'binary', charset) } + boy.emit('field', fieldname, buffer, false, truncated, encoding, contype) + --nends + checkFinished() + } + } + + /* As of node@2efe4ab761666 (v0.10.29+/v0.11.14+), busboy had become + broken. Streams2/streams3 is a huge black box of confusion, but + somehow overriding the sync state seems to fix things again (and still + seems to work for previous node versions). + */ + part._readableState.sync = false + + part.on('data', onData) + part.on('end', onEnd) + }).on('error', function (err) { + if (curFile) { curFile.emit('error', err) } + }) + }).on('error', function (err) { + boy.emit('error', err) + }).on('finish', function () { + finished = true + checkFinished() + }) } -/** - * Cleans up leftover job by invoking abort function for the provided job id - * - * @this state - * @param {string|number} key - job id to abort - */ -function clean(key) -{ - if (typeof this.jobs[key] == 'function') - { - this.jobs[key](); +Multipart.prototype.write = function (chunk, cb) { + const r = this.parser.write(chunk) + if (r && !this._pause) { + cb() + } else { + this._needDrain = !r + this._cb = cb + } +} + +Multipart.prototype.end = function () { + const self = this + + if (self.parser.writable) { + self.parser.end() + } else if (!self._boy._done) { + process.nextTick(function () { + self._boy._done = true + self._boy.emit('finish') + }) } } +function skipPart (part) { + part.resume() +} + +function FileStream (opts) { + Readable.call(this, opts) + + this.bytesRead = 0 + + this.truncated = false +} + +inherits(FileStream, Readable) + +FileStream.prototype._read = function (n) {} + +module.exports = Multipart + /***/ }), -/***/ 769: -/***/ (function(__unusedmodule, exports, __webpack_require__) { +/***/ 8306: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -/*! - * mime-types - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ +const Decoder = __nccwpck_require__(7100) +const decodeText = __nccwpck_require__(4619) +const getLimit = __nccwpck_require__(1467) -/** - * Module dependencies. - * @private - */ +const RE_CHARSET = /^charset$/i -var db = __webpack_require__(128) -var extname = __webpack_require__(622).extname +UrlEncoded.detect = /^application\/x-www-form-urlencoded/i +function UrlEncoded (boy, cfg) { + const limits = cfg.limits + const parsedConType = cfg.parsedConType + this.boy = boy -/** - * Module variables. - * @private - */ + this.fieldSizeLimit = getLimit(limits, 'fieldSize', 1 * 1024 * 1024) + this.fieldNameSizeLimit = getLimit(limits, 'fieldNameSize', 100) + this.fieldsLimit = getLimit(limits, 'fields', Infinity) -var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/ -var TEXT_TYPE_REGEXP = /^text\//i + let charset + for (var i = 0, len = parsedConType.length; i < len; ++i) { // eslint-disable-line no-var + if (Array.isArray(parsedConType[i]) && + RE_CHARSET.test(parsedConType[i][0])) { + charset = parsedConType[i][1].toLowerCase() + break + } + } -/** - * Module exports. - * @public - */ + if (charset === undefined) { charset = cfg.defCharset || 'utf8' } + + this.decoder = new Decoder() + this.charset = charset + this._fields = 0 + this._state = 'key' + this._checkingBytes = true + this._bytesKey = 0 + this._bytesVal = 0 + this._key = '' + this._val = '' + this._keyTrunc = false + this._valTrunc = false + this._hitLimit = false +} -exports.charset = charset -exports.charsets = { lookup: charset } -exports.contentType = contentType -exports.extension = extension -exports.extensions = Object.create(null) -exports.lookup = lookup -exports.types = Object.create(null) +UrlEncoded.prototype.write = function (data, cb) { + if (this._fields === this.fieldsLimit) { + if (!this.boy.hitFieldsLimit) { + this.boy.hitFieldsLimit = true + this.boy.emit('fieldsLimit') + } + return cb() + } -// Populate the extensions/types maps -populateMaps(exports.extensions, exports.types) + let idxeq; let idxamp; let i; let p = 0; const len = data.length + + while (p < len) { + if (this._state === 'key') { + idxeq = idxamp = undefined + for (i = p; i < len; ++i) { + if (!this._checkingBytes) { ++p } + if (data[i] === 0x3D/* = */) { + idxeq = i + break + } else if (data[i] === 0x26/* & */) { + idxamp = i + break + } + if (this._checkingBytes && this._bytesKey === this.fieldNameSizeLimit) { + this._hitLimit = true + break + } else if (this._checkingBytes) { ++this._bytesKey } + } -/** - * Get the default charset for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ + if (idxeq !== undefined) { + // key with assignment + if (idxeq > p) { this._key += this.decoder.write(data.toString('binary', p, idxeq)) } + this._state = 'val' + + this._hitLimit = false + this._checkingBytes = true + this._val = '' + this._bytesVal = 0 + this._valTrunc = false + this.decoder.reset() + + p = idxeq + 1 + } else if (idxamp !== undefined) { + // key with no assignment + ++this._fields + let key; const keyTrunc = this._keyTrunc + if (idxamp > p) { key = (this._key += this.decoder.write(data.toString('binary', p, idxamp))) } else { key = this._key } + + this._hitLimit = false + this._checkingBytes = true + this._key = '' + this._bytesKey = 0 + this._keyTrunc = false + this.decoder.reset() + + if (key.length) { + this.boy.emit('field', decodeText(key, 'binary', this.charset), + '', + keyTrunc, + false) + } -function charset (type) { - if (!type || typeof type !== 'string') { - return false + p = idxamp + 1 + if (this._fields === this.fieldsLimit) { return cb() } + } else if (this._hitLimit) { + // we may not have hit the actual limit if there are encoded bytes... + if (i > p) { this._key += this.decoder.write(data.toString('binary', p, i)) } + p = i + if ((this._bytesKey = this._key.length) === this.fieldNameSizeLimit) { + // yep, we actually did hit the limit + this._checkingBytes = false + this._keyTrunc = true + } + } else { + if (p < len) { this._key += this.decoder.write(data.toString('binary', p)) } + p = len + } + } else { + idxamp = undefined + for (i = p; i < len; ++i) { + if (!this._checkingBytes) { ++p } + if (data[i] === 0x26/* & */) { + idxamp = i + break + } + if (this._checkingBytes && this._bytesVal === this.fieldSizeLimit) { + this._hitLimit = true + break + } else if (this._checkingBytes) { ++this._bytesVal } + } + + if (idxamp !== undefined) { + ++this._fields + if (idxamp > p) { this._val += this.decoder.write(data.toString('binary', p, idxamp)) } + this.boy.emit('field', decodeText(this._key, 'binary', this.charset), + decodeText(this._val, 'binary', this.charset), + this._keyTrunc, + this._valTrunc) + this._state = 'key' + + this._hitLimit = false + this._checkingBytes = true + this._key = '' + this._bytesKey = 0 + this._keyTrunc = false + this.decoder.reset() + + p = idxamp + 1 + if (this._fields === this.fieldsLimit) { return cb() } + } else if (this._hitLimit) { + // we may not have hit the actual limit if there are encoded bytes... + if (i > p) { this._val += this.decoder.write(data.toString('binary', p, i)) } + p = i + if ((this._val === '' && this.fieldSizeLimit === 0) || + (this._bytesVal = this._val.length) === this.fieldSizeLimit) { + // yep, we actually did hit the limit + this._checkingBytes = false + this._valTrunc = true + } + } else { + if (p < len) { this._val += this.decoder.write(data.toString('binary', p)) } + p = len + } + } + } + cb() +} + +UrlEncoded.prototype.end = function () { + if (this.boy._done) { return } + + if (this._state === 'key' && this._key.length > 0) { + this.boy.emit('field', decodeText(this._key, 'binary', this.charset), + '', + this._keyTrunc, + false) + } else if (this._state === 'val') { + this.boy.emit('field', decodeText(this._key, 'binary', this.charset), + decodeText(this._val, 'binary', this.charset), + this._keyTrunc, + this._valTrunc) + } + this.boy._done = true + this.boy.emit('finish') +} + +module.exports = UrlEncoded + + +/***/ }), + +/***/ 7100: +/***/ ((module) => { + +"use strict"; + + +const RE_PLUS = /\+/g + +const HEX = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +] + +function Decoder () { + this.buffer = undefined +} +Decoder.prototype.write = function (str) { + // Replace '+' with ' ' before decoding + str = str.replace(RE_PLUS, ' ') + let res = '' + let i = 0; let p = 0; const len = str.length + for (; i < len; ++i) { + if (this.buffer !== undefined) { + if (!HEX[str.charCodeAt(i)]) { + res += '%' + this.buffer + this.buffer = undefined + --i // retry character + } else { + this.buffer += str[i] + ++p + if (this.buffer.length === 2) { + res += String.fromCharCode(parseInt(this.buffer, 16)) + this.buffer = undefined + } + } + } else if (str[i] === '%') { + if (i > p) { + res += str.substring(p, i) + p = i + } + this.buffer = '' + ++p + } } + if (p < len && this.buffer === undefined) { res += str.substring(p) } + return res +} +Decoder.prototype.reset = function () { + this.buffer = undefined +} + +module.exports = Decoder + + +/***/ }), - // TODO: use media-typer - var match = EXTRACT_TYPE_REGEXP.exec(type) - var mime = match && db[match[1].toLowerCase()] +/***/ 8647: +/***/ ((module) => { - if (mime && mime.charset) { - return mime.charset - } +"use strict"; - // default text/* to utf-8 - if (match && TEXT_TYPE_REGEXP.test(match[1])) { - return 'UTF-8' - } - return false +module.exports = function basename (path) { + if (typeof path !== 'string') { return '' } + for (var i = path.length - 1; i >= 0; --i) { // eslint-disable-line no-var + switch (path.charCodeAt(i)) { + case 0x2F: // '/' + case 0x5C: // '\' + path = path.slice(i + 1) + return (path === '..' || path === '.' ? '' : path) + } + } + return (path === '..' || path === '.' ? '' : path) } -/** - * Create a full Content-Type header given a MIME type or extension. - * - * @param {string} str - * @return {boolean|string} - */ -function contentType (str) { - // TODO: should this even be in this module? - if (!str || typeof str !== 'string') { - return false - } +/***/ }), - var mime = str.indexOf('/') === -1 - ? exports.lookup(str) - : str +/***/ 4619: +/***/ (function(module) { - if (!mime) { - return false - } +"use strict"; - // TODO: use content-type or other module - if (mime.indexOf('charset') === -1) { - var charset = exports.charset(mime) - if (charset) mime += '; charset=' + charset.toLowerCase() - } - return mime +// Node has always utf-8 +const utf8Decoder = new TextDecoder('utf-8') +const textDecoders = new Map([ + ['utf-8', utf8Decoder], + ['utf8', utf8Decoder] +]) + +function getDecoder (charset) { + let lc + while (true) { + switch (charset) { + case 'utf-8': + case 'utf8': + return decoders.utf8 + case 'latin1': + case 'ascii': // TODO: Make these a separate, strict decoder? + case 'us-ascii': + case 'iso-8859-1': + case 'iso8859-1': + case 'iso88591': + case 'iso_8859-1': + case 'windows-1252': + case 'iso_8859-1:1987': + case 'cp1252': + case 'x-cp1252': + return decoders.latin1 + case 'utf16le': + case 'utf-16le': + case 'ucs2': + case 'ucs-2': + return decoders.utf16le + case 'base64': + return decoders.base64 + default: + if (lc === undefined) { + lc = true + charset = charset.toLowerCase() + continue + } + return decoders.other.bind(charset) + } + } } -/** - * Get the default extension for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ +const decoders = { + utf8: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + data = Buffer.from(data, sourceEncoding) + } + return data.utf8Slice(0, data.length) + }, -function extension (type) { - if (!type || typeof type !== 'string') { - return false - } + latin1: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + return data + } + return data.latin1Slice(0, data.length) + }, - // TODO: use media-typer - var match = EXTRACT_TYPE_REGEXP.exec(type) + utf16le: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + data = Buffer.from(data, sourceEncoding) + } + return data.ucs2Slice(0, data.length) + }, - // get extensions - var exts = match && exports.extensions[match[1].toLowerCase()] + base64: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + data = Buffer.from(data, sourceEncoding) + } + return data.base64Slice(0, data.length) + }, - if (!exts || !exts.length) { - return false + other: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + data = Buffer.from(data, sourceEncoding) + } + + if (textDecoders.has(this.toString())) { + try { + return textDecoders.get(this).decode(data) + } catch (e) { } + } + return typeof data === 'string' + ? data + : data.toString() } +} - return exts[0] +function decodeText (text, sourceEncoding, destEncoding) { + if (text) { + return getDecoder(destEncoding)(text, sourceEncoding) + } + return text } -/** - * Lookup the MIME type for a file path/extension. - * - * @param {string} path - * @return {boolean|string} - */ +module.exports = decodeText -function lookup (path) { - if (!path || typeof path !== 'string') { - return false - } - // get the extension ("ext" or ".ext" or full path) - var extension = extname('x.' + path) - .toLowerCase() - .substr(1) +/***/ }), - if (!extension) { - return false - } +/***/ 1467: +/***/ ((module) => { - return exports.types[extension] || false -} +"use strict"; -/** - * Populate the extensions and types maps. - * @private - */ -function populateMaps (extensions, types) { - // source preference (least -> most) - var preference = ['nginx', 'apache', undefined, 'iana'] +module.exports = function getLimit (limits, name, defaultLimit) { + if ( + !limits || + limits[name] === undefined || + limits[name] === null + ) { return defaultLimit } - Object.keys(db).forEach(function forEachMimeType (type) { - var mime = db[type] - var exts = mime.extensions + if ( + typeof limits[name] !== 'number' || + isNaN(limits[name]) + ) { throw new TypeError('Limit ' + name + ' is not a valid number') } - if (!exts || !exts.length) { - return - } + return limits[name] +} - // mime -> extensions - extensions[type] = exts - // extension -> mime - for (var i = 0; i < exts.length; i++) { - var extension = exts[i] +/***/ }), - if (types[extension]) { - var from = preference.indexOf(db[types[extension]].source) - var to = preference.indexOf(mime.source) +/***/ 1854: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (types[extension] !== 'application/octet-stream' && - (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) { - // skip the remapping - continue - } - } +"use strict"; +/* eslint-disable object-property-newline */ + + +const decodeText = __nccwpck_require__(4619) + +const RE_ENCODED = /%[a-fA-F0-9][a-fA-F0-9]/g + +const EncodedLookup = { + '%00': '\x00', '%01': '\x01', '%02': '\x02', '%03': '\x03', '%04': '\x04', + '%05': '\x05', '%06': '\x06', '%07': '\x07', '%08': '\x08', '%09': '\x09', + '%0a': '\x0a', '%0A': '\x0a', '%0b': '\x0b', '%0B': '\x0b', '%0c': '\x0c', + '%0C': '\x0c', '%0d': '\x0d', '%0D': '\x0d', '%0e': '\x0e', '%0E': '\x0e', + '%0f': '\x0f', '%0F': '\x0f', '%10': '\x10', '%11': '\x11', '%12': '\x12', + '%13': '\x13', '%14': '\x14', '%15': '\x15', '%16': '\x16', '%17': '\x17', + '%18': '\x18', '%19': '\x19', '%1a': '\x1a', '%1A': '\x1a', '%1b': '\x1b', + '%1B': '\x1b', '%1c': '\x1c', '%1C': '\x1c', '%1d': '\x1d', '%1D': '\x1d', + '%1e': '\x1e', '%1E': '\x1e', '%1f': '\x1f', '%1F': '\x1f', '%20': '\x20', + '%21': '\x21', '%22': '\x22', '%23': '\x23', '%24': '\x24', '%25': '\x25', + '%26': '\x26', '%27': '\x27', '%28': '\x28', '%29': '\x29', '%2a': '\x2a', + '%2A': '\x2a', '%2b': '\x2b', '%2B': '\x2b', '%2c': '\x2c', '%2C': '\x2c', + '%2d': '\x2d', '%2D': '\x2d', '%2e': '\x2e', '%2E': '\x2e', '%2f': '\x2f', + '%2F': '\x2f', '%30': '\x30', '%31': '\x31', '%32': '\x32', '%33': '\x33', + '%34': '\x34', '%35': '\x35', '%36': '\x36', '%37': '\x37', '%38': '\x38', + '%39': '\x39', '%3a': '\x3a', '%3A': '\x3a', '%3b': '\x3b', '%3B': '\x3b', + '%3c': '\x3c', '%3C': '\x3c', '%3d': '\x3d', '%3D': '\x3d', '%3e': '\x3e', + '%3E': '\x3e', '%3f': '\x3f', '%3F': '\x3f', '%40': '\x40', '%41': '\x41', + '%42': '\x42', '%43': '\x43', '%44': '\x44', '%45': '\x45', '%46': '\x46', + '%47': '\x47', '%48': '\x48', '%49': '\x49', '%4a': '\x4a', '%4A': '\x4a', + '%4b': '\x4b', '%4B': '\x4b', '%4c': '\x4c', '%4C': '\x4c', '%4d': '\x4d', + '%4D': '\x4d', '%4e': '\x4e', '%4E': '\x4e', '%4f': '\x4f', '%4F': '\x4f', + '%50': '\x50', '%51': '\x51', '%52': '\x52', '%53': '\x53', '%54': '\x54', + '%55': '\x55', '%56': '\x56', '%57': '\x57', '%58': '\x58', '%59': '\x59', + '%5a': '\x5a', '%5A': '\x5a', '%5b': '\x5b', '%5B': '\x5b', '%5c': '\x5c', + '%5C': '\x5c', '%5d': '\x5d', '%5D': '\x5d', '%5e': '\x5e', '%5E': '\x5e', + '%5f': '\x5f', '%5F': '\x5f', '%60': '\x60', '%61': '\x61', '%62': '\x62', + '%63': '\x63', '%64': '\x64', '%65': '\x65', '%66': '\x66', '%67': '\x67', + '%68': '\x68', '%69': '\x69', '%6a': '\x6a', '%6A': '\x6a', '%6b': '\x6b', + '%6B': '\x6b', '%6c': '\x6c', '%6C': '\x6c', '%6d': '\x6d', '%6D': '\x6d', + '%6e': '\x6e', '%6E': '\x6e', '%6f': '\x6f', '%6F': '\x6f', '%70': '\x70', + '%71': '\x71', '%72': '\x72', '%73': '\x73', '%74': '\x74', '%75': '\x75', + '%76': '\x76', '%77': '\x77', '%78': '\x78', '%79': '\x79', '%7a': '\x7a', + '%7A': '\x7a', '%7b': '\x7b', '%7B': '\x7b', '%7c': '\x7c', '%7C': '\x7c', + '%7d': '\x7d', '%7D': '\x7d', '%7e': '\x7e', '%7E': '\x7e', '%7f': '\x7f', + '%7F': '\x7f', '%80': '\x80', '%81': '\x81', '%82': '\x82', '%83': '\x83', + '%84': '\x84', '%85': '\x85', '%86': '\x86', '%87': '\x87', '%88': '\x88', + '%89': '\x89', '%8a': '\x8a', '%8A': '\x8a', '%8b': '\x8b', '%8B': '\x8b', + '%8c': '\x8c', '%8C': '\x8c', '%8d': '\x8d', '%8D': '\x8d', '%8e': '\x8e', + '%8E': '\x8e', '%8f': '\x8f', '%8F': '\x8f', '%90': '\x90', '%91': '\x91', + '%92': '\x92', '%93': '\x93', '%94': '\x94', '%95': '\x95', '%96': '\x96', + '%97': '\x97', '%98': '\x98', '%99': '\x99', '%9a': '\x9a', '%9A': '\x9a', + '%9b': '\x9b', '%9B': '\x9b', '%9c': '\x9c', '%9C': '\x9c', '%9d': '\x9d', + '%9D': '\x9d', '%9e': '\x9e', '%9E': '\x9e', '%9f': '\x9f', '%9F': '\x9f', + '%a0': '\xa0', '%A0': '\xa0', '%a1': '\xa1', '%A1': '\xa1', '%a2': '\xa2', + '%A2': '\xa2', '%a3': '\xa3', '%A3': '\xa3', '%a4': '\xa4', '%A4': '\xa4', + '%a5': '\xa5', '%A5': '\xa5', '%a6': '\xa6', '%A6': '\xa6', '%a7': '\xa7', + '%A7': '\xa7', '%a8': '\xa8', '%A8': '\xa8', '%a9': '\xa9', '%A9': '\xa9', + '%aa': '\xaa', '%Aa': '\xaa', '%aA': '\xaa', '%AA': '\xaa', '%ab': '\xab', + '%Ab': '\xab', '%aB': '\xab', '%AB': '\xab', '%ac': '\xac', '%Ac': '\xac', + '%aC': '\xac', '%AC': '\xac', '%ad': '\xad', '%Ad': '\xad', '%aD': '\xad', + '%AD': '\xad', '%ae': '\xae', '%Ae': '\xae', '%aE': '\xae', '%AE': '\xae', + '%af': '\xaf', '%Af': '\xaf', '%aF': '\xaf', '%AF': '\xaf', '%b0': '\xb0', + '%B0': '\xb0', '%b1': '\xb1', '%B1': '\xb1', '%b2': '\xb2', '%B2': '\xb2', + '%b3': '\xb3', '%B3': '\xb3', '%b4': '\xb4', '%B4': '\xb4', '%b5': '\xb5', + '%B5': '\xb5', '%b6': '\xb6', '%B6': '\xb6', '%b7': '\xb7', '%B7': '\xb7', + '%b8': '\xb8', '%B8': '\xb8', '%b9': '\xb9', '%B9': '\xb9', '%ba': '\xba', + '%Ba': '\xba', '%bA': '\xba', '%BA': '\xba', '%bb': '\xbb', '%Bb': '\xbb', + '%bB': '\xbb', '%BB': '\xbb', '%bc': '\xbc', '%Bc': '\xbc', '%bC': '\xbc', + '%BC': '\xbc', '%bd': '\xbd', '%Bd': '\xbd', '%bD': '\xbd', '%BD': '\xbd', + '%be': '\xbe', '%Be': '\xbe', '%bE': '\xbe', '%BE': '\xbe', '%bf': '\xbf', + '%Bf': '\xbf', '%bF': '\xbf', '%BF': '\xbf', '%c0': '\xc0', '%C0': '\xc0', + '%c1': '\xc1', '%C1': '\xc1', '%c2': '\xc2', '%C2': '\xc2', '%c3': '\xc3', + '%C3': '\xc3', '%c4': '\xc4', '%C4': '\xc4', '%c5': '\xc5', '%C5': '\xc5', + '%c6': '\xc6', '%C6': '\xc6', '%c7': '\xc7', '%C7': '\xc7', '%c8': '\xc8', + '%C8': '\xc8', '%c9': '\xc9', '%C9': '\xc9', '%ca': '\xca', '%Ca': '\xca', + '%cA': '\xca', '%CA': '\xca', '%cb': '\xcb', '%Cb': '\xcb', '%cB': '\xcb', + '%CB': '\xcb', '%cc': '\xcc', '%Cc': '\xcc', '%cC': '\xcc', '%CC': '\xcc', + '%cd': '\xcd', '%Cd': '\xcd', '%cD': '\xcd', '%CD': '\xcd', '%ce': '\xce', + '%Ce': '\xce', '%cE': '\xce', '%CE': '\xce', '%cf': '\xcf', '%Cf': '\xcf', + '%cF': '\xcf', '%CF': '\xcf', '%d0': '\xd0', '%D0': '\xd0', '%d1': '\xd1', + '%D1': '\xd1', '%d2': '\xd2', '%D2': '\xd2', '%d3': '\xd3', '%D3': '\xd3', + '%d4': '\xd4', '%D4': '\xd4', '%d5': '\xd5', '%D5': '\xd5', '%d6': '\xd6', + '%D6': '\xd6', '%d7': '\xd7', '%D7': '\xd7', '%d8': '\xd8', '%D8': '\xd8', + '%d9': '\xd9', '%D9': '\xd9', '%da': '\xda', '%Da': '\xda', '%dA': '\xda', + '%DA': '\xda', '%db': '\xdb', '%Db': '\xdb', '%dB': '\xdb', '%DB': '\xdb', + '%dc': '\xdc', '%Dc': '\xdc', '%dC': '\xdc', '%DC': '\xdc', '%dd': '\xdd', + '%Dd': '\xdd', '%dD': '\xdd', '%DD': '\xdd', '%de': '\xde', '%De': '\xde', + '%dE': '\xde', '%DE': '\xde', '%df': '\xdf', '%Df': '\xdf', '%dF': '\xdf', + '%DF': '\xdf', '%e0': '\xe0', '%E0': '\xe0', '%e1': '\xe1', '%E1': '\xe1', + '%e2': '\xe2', '%E2': '\xe2', '%e3': '\xe3', '%E3': '\xe3', '%e4': '\xe4', + '%E4': '\xe4', '%e5': '\xe5', '%E5': '\xe5', '%e6': '\xe6', '%E6': '\xe6', + '%e7': '\xe7', '%E7': '\xe7', '%e8': '\xe8', '%E8': '\xe8', '%e9': '\xe9', + '%E9': '\xe9', '%ea': '\xea', '%Ea': '\xea', '%eA': '\xea', '%EA': '\xea', + '%eb': '\xeb', '%Eb': '\xeb', '%eB': '\xeb', '%EB': '\xeb', '%ec': '\xec', + '%Ec': '\xec', '%eC': '\xec', '%EC': '\xec', '%ed': '\xed', '%Ed': '\xed', + '%eD': '\xed', '%ED': '\xed', '%ee': '\xee', '%Ee': '\xee', '%eE': '\xee', + '%EE': '\xee', '%ef': '\xef', '%Ef': '\xef', '%eF': '\xef', '%EF': '\xef', + '%f0': '\xf0', '%F0': '\xf0', '%f1': '\xf1', '%F1': '\xf1', '%f2': '\xf2', + '%F2': '\xf2', '%f3': '\xf3', '%F3': '\xf3', '%f4': '\xf4', '%F4': '\xf4', + '%f5': '\xf5', '%F5': '\xf5', '%f6': '\xf6', '%F6': '\xf6', '%f7': '\xf7', + '%F7': '\xf7', '%f8': '\xf8', '%F8': '\xf8', '%f9': '\xf9', '%F9': '\xf9', + '%fa': '\xfa', '%Fa': '\xfa', '%fA': '\xfa', '%FA': '\xfa', '%fb': '\xfb', + '%Fb': '\xfb', '%fB': '\xfb', '%FB': '\xfb', '%fc': '\xfc', '%Fc': '\xfc', + '%fC': '\xfc', '%FC': '\xfc', '%fd': '\xfd', '%Fd': '\xfd', '%fD': '\xfd', + '%FD': '\xfd', '%fe': '\xfe', '%Fe': '\xfe', '%fE': '\xfe', '%FE': '\xfe', + '%ff': '\xff', '%Ff': '\xff', '%fF': '\xff', '%FF': '\xff' +} - // set the extension -> mime - types[extension] = type +function encodedReplacer (match) { + return EncodedLookup[match] +} + +const STATE_KEY = 0 +const STATE_VALUE = 1 +const STATE_CHARSET = 2 +const STATE_LANG = 3 + +function parseParams (str) { + const res = [] + let state = STATE_KEY + let charset = '' + let inquote = false + let escaping = false + let p = 0 + let tmp = '' + const len = str.length + + for (var i = 0; i < len; ++i) { // eslint-disable-line no-var + const char = str[i] + if (char === '\\' && inquote) { + if (escaping) { escaping = false } else { + escaping = true + continue + } + } else if (char === '"') { + if (!escaping) { + if (inquote) { + inquote = false + state = STATE_KEY + } else { inquote = true } + continue + } else { escaping = false } + } else { + if (escaping && inquote) { tmp += '\\' } + escaping = false + if ((state === STATE_CHARSET || state === STATE_LANG) && char === "'") { + if (state === STATE_CHARSET) { + state = STATE_LANG + charset = tmp.substring(1) + } else { state = STATE_VALUE } + tmp = '' + continue + } else if (state === STATE_KEY && + (char === '*' || char === '=') && + res.length) { + state = char === '*' + ? STATE_CHARSET + : STATE_VALUE + res[p] = [tmp, undefined] + tmp = '' + continue + } else if (!inquote && char === ';') { + state = STATE_KEY + if (charset) { + if (tmp.length) { + tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer), + 'binary', + charset) + } + charset = '' + } else if (tmp.length) { + tmp = decodeText(tmp, 'binary', 'utf8') + } + if (res[p] === undefined) { res[p] = tmp } else { res[p][1] = tmp } + tmp = '' + ++p + continue + } else if (!inquote && (char === ' ' || char === '\t')) { continue } } - }) + tmp += char + } + if (charset && tmp.length) { + tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer), + 'binary', + charset) + } else if (tmp) { + tmp = decodeText(tmp, 'binary', 'utf8') + } + + if (res[p] === undefined) { + if (tmp) { res[p] = tmp } + } else { res[p][1] = tmp } + + return res } +module.exports = parseParams + /***/ }), -/***/ 792: -/***/ (function(module, __unusedexports, __webpack_require__) { +/***/ 9857: +/***/ ((module) => { -var defer = __webpack_require__(154); +"use strict"; +module.exports = JSON.parse('{"application/1d-interleaved-parityfec":{"source":"iana"},"application/3gpdash-qoe-report+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/3gpp-ims+xml":{"source":"iana","compressible":true},"application/3gpphal+json":{"source":"iana","compressible":true},"application/3gpphalforms+json":{"source":"iana","compressible":true},"application/a2l":{"source":"iana"},"application/ace+cbor":{"source":"iana"},"application/activemessage":{"source":"iana"},"application/activity+json":{"source":"iana","compressible":true},"application/alto-costmap+json":{"source":"iana","compressible":true},"application/alto-costmapfilter+json":{"source":"iana","compressible":true},"application/alto-directory+json":{"source":"iana","compressible":true},"application/alto-endpointcost+json":{"source":"iana","compressible":true},"application/alto-endpointcostparams+json":{"source":"iana","compressible":true},"application/alto-endpointprop+json":{"source":"iana","compressible":true},"application/alto-endpointpropparams+json":{"source":"iana","compressible":true},"application/alto-error+json":{"source":"iana","compressible":true},"application/alto-networkmap+json":{"source":"iana","compressible":true},"application/alto-networkmapfilter+json":{"source":"iana","compressible":true},"application/alto-updatestreamcontrol+json":{"source":"iana","compressible":true},"application/alto-updatestreamparams+json":{"source":"iana","compressible":true},"application/aml":{"source":"iana"},"application/andrew-inset":{"source":"iana","extensions":["ez"]},"application/applefile":{"source":"iana"},"application/applixware":{"source":"apache","extensions":["aw"]},"application/at+jwt":{"source":"iana"},"application/atf":{"source":"iana"},"application/atfx":{"source":"iana"},"application/atom+xml":{"source":"iana","compressible":true,"extensions":["atom"]},"application/atomcat+xml":{"source":"iana","compressible":true,"extensions":["atomcat"]},"application/atomdeleted+xml":{"source":"iana","compressible":true,"extensions":["atomdeleted"]},"application/atomicmail":{"source":"iana"},"application/atomsvc+xml":{"source":"iana","compressible":true,"extensions":["atomsvc"]},"application/atsc-dwd+xml":{"source":"iana","compressible":true,"extensions":["dwd"]},"application/atsc-dynamic-event-message":{"source":"iana"},"application/atsc-held+xml":{"source":"iana","compressible":true,"extensions":["held"]},"application/atsc-rdt+json":{"source":"iana","compressible":true},"application/atsc-rsat+xml":{"source":"iana","compressible":true,"extensions":["rsat"]},"application/atxml":{"source":"iana"},"application/auth-policy+xml":{"source":"iana","compressible":true},"application/bacnet-xdd+zip":{"source":"iana","compressible":false},"application/batch-smtp":{"source":"iana"},"application/bdoc":{"compressible":false,"extensions":["bdoc"]},"application/beep+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/calendar+json":{"source":"iana","compressible":true},"application/calendar+xml":{"source":"iana","compressible":true,"extensions":["xcs"]},"application/call-completion":{"source":"iana"},"application/cals-1840":{"source":"iana"},"application/captive+json":{"source":"iana","compressible":true},"application/cbor":{"source":"iana"},"application/cbor-seq":{"source":"iana"},"application/cccex":{"source":"iana"},"application/ccmp+xml":{"source":"iana","compressible":true},"application/ccxml+xml":{"source":"iana","compressible":true,"extensions":["ccxml"]},"application/cdfx+xml":{"source":"iana","compressible":true,"extensions":["cdfx"]},"application/cdmi-capability":{"source":"iana","extensions":["cdmia"]},"application/cdmi-container":{"source":"iana","extensions":["cdmic"]},"application/cdmi-domain":{"source":"iana","extensions":["cdmid"]},"application/cdmi-object":{"source":"iana","extensions":["cdmio"]},"application/cdmi-queue":{"source":"iana","extensions":["cdmiq"]},"application/cdni":{"source":"iana"},"application/cea":{"source":"iana"},"application/cea-2018+xml":{"source":"iana","compressible":true},"application/cellml+xml":{"source":"iana","compressible":true},"application/cfw":{"source":"iana"},"application/city+json":{"source":"iana","compressible":true},"application/clr":{"source":"iana"},"application/clue+xml":{"source":"iana","compressible":true},"application/clue_info+xml":{"source":"iana","compressible":true},"application/cms":{"source":"iana"},"application/cnrp+xml":{"source":"iana","compressible":true},"application/coap-group+json":{"source":"iana","compressible":true},"application/coap-payload":{"source":"iana"},"application/commonground":{"source":"iana"},"application/conference-info+xml":{"source":"iana","compressible":true},"application/cose":{"source":"iana"},"application/cose-key":{"source":"iana"},"application/cose-key-set":{"source":"iana"},"application/cpl+xml":{"source":"iana","compressible":true,"extensions":["cpl"]},"application/csrattrs":{"source":"iana"},"application/csta+xml":{"source":"iana","compressible":true},"application/cstadata+xml":{"source":"iana","compressible":true},"application/csvm+json":{"source":"iana","compressible":true},"application/cu-seeme":{"source":"apache","extensions":["cu"]},"application/cwt":{"source":"iana"},"application/cybercash":{"source":"iana"},"application/dart":{"compressible":true},"application/dash+xml":{"source":"iana","compressible":true,"extensions":["mpd"]},"application/dash-patch+xml":{"source":"iana","compressible":true,"extensions":["mpp"]},"application/dashdelta":{"source":"iana"},"application/davmount+xml":{"source":"iana","compressible":true,"extensions":["davmount"]},"application/dca-rft":{"source":"iana"},"application/dcd":{"source":"iana"},"application/dec-dx":{"source":"iana"},"application/dialog-info+xml":{"source":"iana","compressible":true},"application/dicom":{"source":"iana"},"application/dicom+json":{"source":"iana","compressible":true},"application/dicom+xml":{"source":"iana","compressible":true},"application/dii":{"source":"iana"},"application/dit":{"source":"iana"},"application/dns":{"source":"iana"},"application/dns+json":{"source":"iana","compressible":true},"application/dns-message":{"source":"iana"},"application/docbook+xml":{"source":"apache","compressible":true,"extensions":["dbk"]},"application/dots+cbor":{"source":"iana"},"application/dskpp+xml":{"source":"iana","compressible":true},"application/dssc+der":{"source":"iana","extensions":["dssc"]},"application/dssc+xml":{"source":"iana","compressible":true,"extensions":["xdssc"]},"application/dvcs":{"source":"iana"},"application/ecmascript":{"source":"iana","compressible":true,"extensions":["es","ecma"]},"application/edi-consent":{"source":"iana"},"application/edi-x12":{"source":"iana","compressible":false},"application/edifact":{"source":"iana","compressible":false},"application/efi":{"source":"iana"},"application/elm+json":{"source":"iana","charset":"UTF-8","compressible":true},"application/elm+xml":{"source":"iana","compressible":true},"application/emergencycalldata.cap+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/emergencycalldata.comment+xml":{"source":"iana","compressible":true},"application/emergencycalldata.control+xml":{"source":"iana","compressible":true},"application/emergencycalldata.deviceinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.ecall.msd":{"source":"iana"},"application/emergencycalldata.providerinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.serviceinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.subscriberinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.veds+xml":{"source":"iana","compressible":true},"application/emma+xml":{"source":"iana","compressible":true,"extensions":["emma"]},"application/emotionml+xml":{"source":"iana","compressible":true,"extensions":["emotionml"]},"application/encaprtp":{"source":"iana"},"application/epp+xml":{"source":"iana","compressible":true},"application/epub+zip":{"source":"iana","compressible":false,"extensions":["epub"]},"application/eshop":{"source":"iana"},"application/exi":{"source":"iana","extensions":["exi"]},"application/expect-ct-report+json":{"source":"iana","compressible":true},"application/express":{"source":"iana","extensions":["exp"]},"application/fastinfoset":{"source":"iana"},"application/fastsoap":{"source":"iana"},"application/fdt+xml":{"source":"iana","compressible":true,"extensions":["fdt"]},"application/fhir+json":{"source":"iana","charset":"UTF-8","compressible":true},"application/fhir+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/fido.trusted-apps+json":{"compressible":true},"application/fits":{"source":"iana"},"application/flexfec":{"source":"iana"},"application/font-sfnt":{"source":"iana"},"application/font-tdpfr":{"source":"iana","extensions":["pfr"]},"application/font-woff":{"source":"iana","compressible":false},"application/framework-attributes+xml":{"source":"iana","compressible":true},"application/geo+json":{"source":"iana","compressible":true,"extensions":["geojson"]},"application/geo+json-seq":{"source":"iana"},"application/geopackage+sqlite3":{"source":"iana"},"application/geoxacml+xml":{"source":"iana","compressible":true},"application/gltf-buffer":{"source":"iana"},"application/gml+xml":{"source":"iana","compressible":true,"extensions":["gml"]},"application/gpx+xml":{"source":"apache","compressible":true,"extensions":["gpx"]},"application/gxf":{"source":"apache","extensions":["gxf"]},"application/gzip":{"source":"iana","compressible":false,"extensions":["gz"]},"application/h224":{"source":"iana"},"application/held+xml":{"source":"iana","compressible":true},"application/hjson":{"extensions":["hjson"]},"application/http":{"source":"iana"},"application/hyperstudio":{"source":"iana","extensions":["stk"]},"application/ibe-key-request+xml":{"source":"iana","compressible":true},"application/ibe-pkg-reply+xml":{"source":"iana","compressible":true},"application/ibe-pp-data":{"source":"iana"},"application/iges":{"source":"iana"},"application/im-iscomposing+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/index":{"source":"iana"},"application/index.cmd":{"source":"iana"},"application/index.obj":{"source":"iana"},"application/index.response":{"source":"iana"},"application/index.vnd":{"source":"iana"},"application/inkml+xml":{"source":"iana","compressible":true,"extensions":["ink","inkml"]},"application/iotp":{"source":"iana"},"application/ipfix":{"source":"iana","extensions":["ipfix"]},"application/ipp":{"source":"iana"},"application/isup":{"source":"iana"},"application/its+xml":{"source":"iana","compressible":true,"extensions":["its"]},"application/java-archive":{"source":"apache","compressible":false,"extensions":["jar","war","ear"]},"application/java-serialized-object":{"source":"apache","compressible":false,"extensions":["ser"]},"application/java-vm":{"source":"apache","compressible":false,"extensions":["class"]},"application/javascript":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["js","mjs"]},"application/jf2feed+json":{"source":"iana","compressible":true},"application/jose":{"source":"iana"},"application/jose+json":{"source":"iana","compressible":true},"application/jrd+json":{"source":"iana","compressible":true},"application/jscalendar+json":{"source":"iana","compressible":true},"application/json":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["json","map"]},"application/json-patch+json":{"source":"iana","compressible":true},"application/json-seq":{"source":"iana"},"application/json5":{"extensions":["json5"]},"application/jsonml+json":{"source":"apache","compressible":true,"extensions":["jsonml"]},"application/jwk+json":{"source":"iana","compressible":true},"application/jwk-set+json":{"source":"iana","compressible":true},"application/jwt":{"source":"iana"},"application/kpml-request+xml":{"source":"iana","compressible":true},"application/kpml-response+xml":{"source":"iana","compressible":true},"application/ld+json":{"source":"iana","compressible":true,"extensions":["jsonld"]},"application/lgr+xml":{"source":"iana","compressible":true,"extensions":["lgr"]},"application/link-format":{"source":"iana"},"application/load-control+xml":{"source":"iana","compressible":true},"application/lost+xml":{"source":"iana","compressible":true,"extensions":["lostxml"]},"application/lostsync+xml":{"source":"iana","compressible":true},"application/lpf+zip":{"source":"iana","compressible":false},"application/lxf":{"source":"iana"},"application/mac-binhex40":{"source":"iana","extensions":["hqx"]},"application/mac-compactpro":{"source":"apache","extensions":["cpt"]},"application/macwriteii":{"source":"iana"},"application/mads+xml":{"source":"iana","compressible":true,"extensions":["mads"]},"application/manifest+json":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["webmanifest"]},"application/marc":{"source":"iana","extensions":["mrc"]},"application/marcxml+xml":{"source":"iana","compressible":true,"extensions":["mrcx"]},"application/mathematica":{"source":"iana","extensions":["ma","nb","mb"]},"application/mathml+xml":{"source":"iana","compressible":true,"extensions":["mathml"]},"application/mathml-content+xml":{"source":"iana","compressible":true},"application/mathml-presentation+xml":{"source":"iana","compressible":true},"application/mbms-associated-procedure-description+xml":{"source":"iana","compressible":true},"application/mbms-deregister+xml":{"source":"iana","compressible":true},"application/mbms-envelope+xml":{"source":"iana","compressible":true},"application/mbms-msk+xml":{"source":"iana","compressible":true},"application/mbms-msk-response+xml":{"source":"iana","compressible":true},"application/mbms-protection-description+xml":{"source":"iana","compressible":true},"application/mbms-reception-report+xml":{"source":"iana","compressible":true},"application/mbms-register+xml":{"source":"iana","compressible":true},"application/mbms-register-response+xml":{"source":"iana","compressible":true},"application/mbms-schedule+xml":{"source":"iana","compressible":true},"application/mbms-user-service-description+xml":{"source":"iana","compressible":true},"application/mbox":{"source":"iana","extensions":["mbox"]},"application/media-policy-dataset+xml":{"source":"iana","compressible":true,"extensions":["mpf"]},"application/media_control+xml":{"source":"iana","compressible":true},"application/mediaservercontrol+xml":{"source":"iana","compressible":true,"extensions":["mscml"]},"application/merge-patch+json":{"source":"iana","compressible":true},"application/metalink+xml":{"source":"apache","compressible":true,"extensions":["metalink"]},"application/metalink4+xml":{"source":"iana","compressible":true,"extensions":["meta4"]},"application/mets+xml":{"source":"iana","compressible":true,"extensions":["mets"]},"application/mf4":{"source":"iana"},"application/mikey":{"source":"iana"},"application/mipc":{"source":"iana"},"application/missing-blocks+cbor-seq":{"source":"iana"},"application/mmt-aei+xml":{"source":"iana","compressible":true,"extensions":["maei"]},"application/mmt-usd+xml":{"source":"iana","compressible":true,"extensions":["musd"]},"application/mods+xml":{"source":"iana","compressible":true,"extensions":["mods"]},"application/moss-keys":{"source":"iana"},"application/moss-signature":{"source":"iana"},"application/mosskey-data":{"source":"iana"},"application/mosskey-request":{"source":"iana"},"application/mp21":{"source":"iana","extensions":["m21","mp21"]},"application/mp4":{"source":"iana","extensions":["mp4s","m4p"]},"application/mpeg4-generic":{"source":"iana"},"application/mpeg4-iod":{"source":"iana"},"application/mpeg4-iod-xmt":{"source":"iana"},"application/mrb-consumer+xml":{"source":"iana","compressible":true},"application/mrb-publish+xml":{"source":"iana","compressible":true},"application/msc-ivr+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/msc-mixer+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/msword":{"source":"iana","compressible":false,"extensions":["doc","dot"]},"application/mud+json":{"source":"iana","compressible":true},"application/multipart-core":{"source":"iana"},"application/mxf":{"source":"iana","extensions":["mxf"]},"application/n-quads":{"source":"iana","extensions":["nq"]},"application/n-triples":{"source":"iana","extensions":["nt"]},"application/nasdata":{"source":"iana"},"application/news-checkgroups":{"source":"iana","charset":"US-ASCII"},"application/news-groupinfo":{"source":"iana","charset":"US-ASCII"},"application/news-transmission":{"source":"iana"},"application/nlsml+xml":{"source":"iana","compressible":true},"application/node":{"source":"iana","extensions":["cjs"]},"application/nss":{"source":"iana"},"application/oauth-authz-req+jwt":{"source":"iana"},"application/oblivious-dns-message":{"source":"iana"},"application/ocsp-request":{"source":"iana"},"application/ocsp-response":{"source":"iana"},"application/octet-stream":{"source":"iana","compressible":false,"extensions":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]},"application/oda":{"source":"iana","extensions":["oda"]},"application/odm+xml":{"source":"iana","compressible":true},"application/odx":{"source":"iana"},"application/oebps-package+xml":{"source":"iana","compressible":true,"extensions":["opf"]},"application/ogg":{"source":"iana","compressible":false,"extensions":["ogx"]},"application/omdoc+xml":{"source":"apache","compressible":true,"extensions":["omdoc"]},"application/onenote":{"source":"apache","extensions":["onetoc","onetoc2","onetmp","onepkg"]},"application/opc-nodeset+xml":{"source":"iana","compressible":true},"application/oscore":{"source":"iana"},"application/oxps":{"source":"iana","extensions":["oxps"]},"application/p21":{"source":"iana"},"application/p21+zip":{"source":"iana","compressible":false},"application/p2p-overlay+xml":{"source":"iana","compressible":true,"extensions":["relo"]},"application/parityfec":{"source":"iana"},"application/passport":{"source":"iana"},"application/patch-ops-error+xml":{"source":"iana","compressible":true,"extensions":["xer"]},"application/pdf":{"source":"iana","compressible":false,"extensions":["pdf"]},"application/pdx":{"source":"iana"},"application/pem-certificate-chain":{"source":"iana"},"application/pgp-encrypted":{"source":"iana","compressible":false,"extensions":["pgp"]},"application/pgp-keys":{"source":"iana","extensions":["asc"]},"application/pgp-signature":{"source":"iana","extensions":["asc","sig"]},"application/pics-rules":{"source":"apache","extensions":["prf"]},"application/pidf+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/pidf-diff+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/pkcs10":{"source":"iana","extensions":["p10"]},"application/pkcs12":{"source":"iana"},"application/pkcs7-mime":{"source":"iana","extensions":["p7m","p7c"]},"application/pkcs7-signature":{"source":"iana","extensions":["p7s"]},"application/pkcs8":{"source":"iana","extensions":["p8"]},"application/pkcs8-encrypted":{"source":"iana"},"application/pkix-attr-cert":{"source":"iana","extensions":["ac"]},"application/pkix-cert":{"source":"iana","extensions":["cer"]},"application/pkix-crl":{"source":"iana","extensions":["crl"]},"application/pkix-pkipath":{"source":"iana","extensions":["pkipath"]},"application/pkixcmp":{"source":"iana","extensions":["pki"]},"application/pls+xml":{"source":"iana","compressible":true,"extensions":["pls"]},"application/poc-settings+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/postscript":{"source":"iana","compressible":true,"extensions":["ai","eps","ps"]},"application/ppsp-tracker+json":{"source":"iana","compressible":true},"application/problem+json":{"source":"iana","compressible":true},"application/problem+xml":{"source":"iana","compressible":true},"application/provenance+xml":{"source":"iana","compressible":true,"extensions":["provx"]},"application/prs.alvestrand.titrax-sheet":{"source":"iana"},"application/prs.cww":{"source":"iana","extensions":["cww"]},"application/prs.cyn":{"source":"iana","charset":"7-BIT"},"application/prs.hpub+zip":{"source":"iana","compressible":false},"application/prs.nprend":{"source":"iana"},"application/prs.plucker":{"source":"iana"},"application/prs.rdf-xml-crypt":{"source":"iana"},"application/prs.xsf+xml":{"source":"iana","compressible":true},"application/pskc+xml":{"source":"iana","compressible":true,"extensions":["pskcxml"]},"application/pvd+json":{"source":"iana","compressible":true},"application/qsig":{"source":"iana"},"application/raml+yaml":{"compressible":true,"extensions":["raml"]},"application/raptorfec":{"source":"iana"},"application/rdap+json":{"source":"iana","compressible":true},"application/rdf+xml":{"source":"iana","compressible":true,"extensions":["rdf","owl"]},"application/reginfo+xml":{"source":"iana","compressible":true,"extensions":["rif"]},"application/relax-ng-compact-syntax":{"source":"iana","extensions":["rnc"]},"application/remote-printing":{"source":"iana"},"application/reputon+json":{"source":"iana","compressible":true},"application/resource-lists+xml":{"source":"iana","compressible":true,"extensions":["rl"]},"application/resource-lists-diff+xml":{"source":"iana","compressible":true,"extensions":["rld"]},"application/rfc+xml":{"source":"iana","compressible":true},"application/riscos":{"source":"iana"},"application/rlmi+xml":{"source":"iana","compressible":true},"application/rls-services+xml":{"source":"iana","compressible":true,"extensions":["rs"]},"application/route-apd+xml":{"source":"iana","compressible":true,"extensions":["rapd"]},"application/route-s-tsid+xml":{"source":"iana","compressible":true,"extensions":["sls"]},"application/route-usd+xml":{"source":"iana","compressible":true,"extensions":["rusd"]},"application/rpki-ghostbusters":{"source":"iana","extensions":["gbr"]},"application/rpki-manifest":{"source":"iana","extensions":["mft"]},"application/rpki-publication":{"source":"iana"},"application/rpki-roa":{"source":"iana","extensions":["roa"]},"application/rpki-updown":{"source":"iana"},"application/rsd+xml":{"source":"apache","compressible":true,"extensions":["rsd"]},"application/rss+xml":{"source":"apache","compressible":true,"extensions":["rss"]},"application/rtf":{"source":"iana","compressible":true,"extensions":["rtf"]},"application/rtploopback":{"source":"iana"},"application/rtx":{"source":"iana"},"application/samlassertion+xml":{"source":"iana","compressible":true},"application/samlmetadata+xml":{"source":"iana","compressible":true},"application/sarif+json":{"source":"iana","compressible":true},"application/sarif-external-properties+json":{"source":"iana","compressible":true},"application/sbe":{"source":"iana"},"application/sbml+xml":{"source":"iana","compressible":true,"extensions":["sbml"]},"application/scaip+xml":{"source":"iana","compressible":true},"application/scim+json":{"source":"iana","compressible":true},"application/scvp-cv-request":{"source":"iana","extensions":["scq"]},"application/scvp-cv-response":{"source":"iana","extensions":["scs"]},"application/scvp-vp-request":{"source":"iana","extensions":["spq"]},"application/scvp-vp-response":{"source":"iana","extensions":["spp"]},"application/sdp":{"source":"iana","extensions":["sdp"]},"application/secevent+jwt":{"source":"iana"},"application/senml+cbor":{"source":"iana"},"application/senml+json":{"source":"iana","compressible":true},"application/senml+xml":{"source":"iana","compressible":true,"extensions":["senmlx"]},"application/senml-etch+cbor":{"source":"iana"},"application/senml-etch+json":{"source":"iana","compressible":true},"application/senml-exi":{"source":"iana"},"application/sensml+cbor":{"source":"iana"},"application/sensml+json":{"source":"iana","compressible":true},"application/sensml+xml":{"source":"iana","compressible":true,"extensions":["sensmlx"]},"application/sensml-exi":{"source":"iana"},"application/sep+xml":{"source":"iana","compressible":true},"application/sep-exi":{"source":"iana"},"application/session-info":{"source":"iana"},"application/set-payment":{"source":"iana"},"application/set-payment-initiation":{"source":"iana","extensions":["setpay"]},"application/set-registration":{"source":"iana"},"application/set-registration-initiation":{"source":"iana","extensions":["setreg"]},"application/sgml":{"source":"iana"},"application/sgml-open-catalog":{"source":"iana"},"application/shf+xml":{"source":"iana","compressible":true,"extensions":["shf"]},"application/sieve":{"source":"iana","extensions":["siv","sieve"]},"application/simple-filter+xml":{"source":"iana","compressible":true},"application/simple-message-summary":{"source":"iana"},"application/simplesymbolcontainer":{"source":"iana"},"application/sipc":{"source":"iana"},"application/slate":{"source":"iana"},"application/smil":{"source":"iana"},"application/smil+xml":{"source":"iana","compressible":true,"extensions":["smi","smil"]},"application/smpte336m":{"source":"iana"},"application/soap+fastinfoset":{"source":"iana"},"application/soap+xml":{"source":"iana","compressible":true},"application/sparql-query":{"source":"iana","extensions":["rq"]},"application/sparql-results+xml":{"source":"iana","compressible":true,"extensions":["srx"]},"application/spdx+json":{"source":"iana","compressible":true},"application/spirits-event+xml":{"source":"iana","compressible":true},"application/sql":{"source":"iana"},"application/srgs":{"source":"iana","extensions":["gram"]},"application/srgs+xml":{"source":"iana","compressible":true,"extensions":["grxml"]},"application/sru+xml":{"source":"iana","compressible":true,"extensions":["sru"]},"application/ssdl+xml":{"source":"apache","compressible":true,"extensions":["ssdl"]},"application/ssml+xml":{"source":"iana","compressible":true,"extensions":["ssml"]},"application/stix+json":{"source":"iana","compressible":true},"application/swid+xml":{"source":"iana","compressible":true,"extensions":["swidtag"]},"application/tamp-apex-update":{"source":"iana"},"application/tamp-apex-update-confirm":{"source":"iana"},"application/tamp-community-update":{"source":"iana"},"application/tamp-community-update-confirm":{"source":"iana"},"application/tamp-error":{"source":"iana"},"application/tamp-sequence-adjust":{"source":"iana"},"application/tamp-sequence-adjust-confirm":{"source":"iana"},"application/tamp-status-query":{"source":"iana"},"application/tamp-status-response":{"source":"iana"},"application/tamp-update":{"source":"iana"},"application/tamp-update-confirm":{"source":"iana"},"application/tar":{"compressible":true},"application/taxii+json":{"source":"iana","compressible":true},"application/td+json":{"source":"iana","compressible":true},"application/tei+xml":{"source":"iana","compressible":true,"extensions":["tei","teicorpus"]},"application/tetra_isi":{"source":"iana"},"application/thraud+xml":{"source":"iana","compressible":true,"extensions":["tfi"]},"application/timestamp-query":{"source":"iana"},"application/timestamp-reply":{"source":"iana"},"application/timestamped-data":{"source":"iana","extensions":["tsd"]},"application/tlsrpt+gzip":{"source":"iana"},"application/tlsrpt+json":{"source":"iana","compressible":true},"application/tnauthlist":{"source":"iana"},"application/token-introspection+jwt":{"source":"iana"},"application/toml":{"compressible":true,"extensions":["toml"]},"application/trickle-ice-sdpfrag":{"source":"iana"},"application/trig":{"source":"iana","extensions":["trig"]},"application/ttml+xml":{"source":"iana","compressible":true,"extensions":["ttml"]},"application/tve-trigger":{"source":"iana"},"application/tzif":{"source":"iana"},"application/tzif-leap":{"source":"iana"},"application/ubjson":{"compressible":false,"extensions":["ubj"]},"application/ulpfec":{"source":"iana"},"application/urc-grpsheet+xml":{"source":"iana","compressible":true},"application/urc-ressheet+xml":{"source":"iana","compressible":true,"extensions":["rsheet"]},"application/urc-targetdesc+xml":{"source":"iana","compressible":true,"extensions":["td"]},"application/urc-uisocketdesc+xml":{"source":"iana","compressible":true},"application/vcard+json":{"source":"iana","compressible":true},"application/vcard+xml":{"source":"iana","compressible":true},"application/vemmi":{"source":"iana"},"application/vividence.scriptfile":{"source":"apache"},"application/vnd.1000minds.decision-model+xml":{"source":"iana","compressible":true,"extensions":["1km"]},"application/vnd.3gpp-prose+xml":{"source":"iana","compressible":true},"application/vnd.3gpp-prose-pc3ch+xml":{"source":"iana","compressible":true},"application/vnd.3gpp-v2x-local-service-information":{"source":"iana"},"application/vnd.3gpp.5gnas":{"source":"iana"},"application/vnd.3gpp.access-transfer-events+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.bsf+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.gmop+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.gtpc":{"source":"iana"},"application/vnd.3gpp.interworking-data":{"source":"iana"},"application/vnd.3gpp.lpp":{"source":"iana"},"application/vnd.3gpp.mc-signalling-ear":{"source":"iana"},"application/vnd.3gpp.mcdata-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-payload":{"source":"iana"},"application/vnd.3gpp.mcdata-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-signalling":{"source":"iana"},"application/vnd.3gpp.mcdata-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-floor-request+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-location-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-mbms-usage-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-signed+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-ue-init-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-affiliation-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-location-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-mbms-usage-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-transmission-request+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mid-call+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.ngap":{"source":"iana"},"application/vnd.3gpp.pfcp":{"source":"iana"},"application/vnd.3gpp.pic-bw-large":{"source":"iana","extensions":["plb"]},"application/vnd.3gpp.pic-bw-small":{"source":"iana","extensions":["psb"]},"application/vnd.3gpp.pic-bw-var":{"source":"iana","extensions":["pvb"]},"application/vnd.3gpp.s1ap":{"source":"iana"},"application/vnd.3gpp.sms":{"source":"iana"},"application/vnd.3gpp.sms+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.srvcc-ext+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.srvcc-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.state-and-event-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.ussd+xml":{"source":"iana","compressible":true},"application/vnd.3gpp2.bcmcsinfo+xml":{"source":"iana","compressible":true},"application/vnd.3gpp2.sms":{"source":"iana"},"application/vnd.3gpp2.tcap":{"source":"iana","extensions":["tcap"]},"application/vnd.3lightssoftware.imagescal":{"source":"iana"},"application/vnd.3m.post-it-notes":{"source":"iana","extensions":["pwn"]},"application/vnd.accpac.simply.aso":{"source":"iana","extensions":["aso"]},"application/vnd.accpac.simply.imp":{"source":"iana","extensions":["imp"]},"application/vnd.acucobol":{"source":"iana","extensions":["acu"]},"application/vnd.acucorp":{"source":"iana","extensions":["atc","acutc"]},"application/vnd.adobe.air-application-installer-package+zip":{"source":"apache","compressible":false,"extensions":["air"]},"application/vnd.adobe.flash.movie":{"source":"iana"},"application/vnd.adobe.formscentral.fcdt":{"source":"iana","extensions":["fcdt"]},"application/vnd.adobe.fxp":{"source":"iana","extensions":["fxp","fxpl"]},"application/vnd.adobe.partial-upload":{"source":"iana"},"application/vnd.adobe.xdp+xml":{"source":"iana","compressible":true,"extensions":["xdp"]},"application/vnd.adobe.xfdf":{"source":"iana","extensions":["xfdf"]},"application/vnd.aether.imp":{"source":"iana"},"application/vnd.afpc.afplinedata":{"source":"iana"},"application/vnd.afpc.afplinedata-pagedef":{"source":"iana"},"application/vnd.afpc.cmoca-cmresource":{"source":"iana"},"application/vnd.afpc.foca-charset":{"source":"iana"},"application/vnd.afpc.foca-codedfont":{"source":"iana"},"application/vnd.afpc.foca-codepage":{"source":"iana"},"application/vnd.afpc.modca":{"source":"iana"},"application/vnd.afpc.modca-cmtable":{"source":"iana"},"application/vnd.afpc.modca-formdef":{"source":"iana"},"application/vnd.afpc.modca-mediummap":{"source":"iana"},"application/vnd.afpc.modca-objectcontainer":{"source":"iana"},"application/vnd.afpc.modca-overlay":{"source":"iana"},"application/vnd.afpc.modca-pagesegment":{"source":"iana"},"application/vnd.age":{"source":"iana","extensions":["age"]},"application/vnd.ah-barcode":{"source":"iana"},"application/vnd.ahead.space":{"source":"iana","extensions":["ahead"]},"application/vnd.airzip.filesecure.azf":{"source":"iana","extensions":["azf"]},"application/vnd.airzip.filesecure.azs":{"source":"iana","extensions":["azs"]},"application/vnd.amadeus+json":{"source":"iana","compressible":true},"application/vnd.amazon.ebook":{"source":"apache","extensions":["azw"]},"application/vnd.amazon.mobi8-ebook":{"source":"iana"},"application/vnd.americandynamics.acc":{"source":"iana","extensions":["acc"]},"application/vnd.amiga.ami":{"source":"iana","extensions":["ami"]},"application/vnd.amundsen.maze+xml":{"source":"iana","compressible":true},"application/vnd.android.ota":{"source":"iana"},"application/vnd.android.package-archive":{"source":"apache","compressible":false,"extensions":["apk"]},"application/vnd.anki":{"source":"iana"},"application/vnd.anser-web-certificate-issue-initiation":{"source":"iana","extensions":["cii"]},"application/vnd.anser-web-funds-transfer-initiation":{"source":"apache","extensions":["fti"]},"application/vnd.antix.game-component":{"source":"iana","extensions":["atx"]},"application/vnd.apache.arrow.file":{"source":"iana"},"application/vnd.apache.arrow.stream":{"source":"iana"},"application/vnd.apache.thrift.binary":{"source":"iana"},"application/vnd.apache.thrift.compact":{"source":"iana"},"application/vnd.apache.thrift.json":{"source":"iana"},"application/vnd.api+json":{"source":"iana","compressible":true},"application/vnd.aplextor.warrp+json":{"source":"iana","compressible":true},"application/vnd.apothekende.reservation+json":{"source":"iana","compressible":true},"application/vnd.apple.installer+xml":{"source":"iana","compressible":true,"extensions":["mpkg"]},"application/vnd.apple.keynote":{"source":"iana","extensions":["key"]},"application/vnd.apple.mpegurl":{"source":"iana","extensions":["m3u8"]},"application/vnd.apple.numbers":{"source":"iana","extensions":["numbers"]},"application/vnd.apple.pages":{"source":"iana","extensions":["pages"]},"application/vnd.apple.pkpass":{"compressible":false,"extensions":["pkpass"]},"application/vnd.arastra.swi":{"source":"iana"},"application/vnd.aristanetworks.swi":{"source":"iana","extensions":["swi"]},"application/vnd.artisan+json":{"source":"iana","compressible":true},"application/vnd.artsquare":{"source":"iana"},"application/vnd.astraea-software.iota":{"source":"iana","extensions":["iota"]},"application/vnd.audiograph":{"source":"iana","extensions":["aep"]},"application/vnd.autopackage":{"source":"iana"},"application/vnd.avalon+json":{"source":"iana","compressible":true},"application/vnd.avistar+xml":{"source":"iana","compressible":true},"application/vnd.balsamiq.bmml+xml":{"source":"iana","compressible":true,"extensions":["bmml"]},"application/vnd.balsamiq.bmpr":{"source":"iana"},"application/vnd.banana-accounting":{"source":"iana"},"application/vnd.bbf.usp.error":{"source":"iana"},"application/vnd.bbf.usp.msg":{"source":"iana"},"application/vnd.bbf.usp.msg+json":{"source":"iana","compressible":true},"application/vnd.bekitzur-stech+json":{"source":"iana","compressible":true},"application/vnd.bint.med-content":{"source":"iana"},"application/vnd.biopax.rdf+xml":{"source":"iana","compressible":true},"application/vnd.blink-idb-value-wrapper":{"source":"iana"},"application/vnd.blueice.multipass":{"source":"iana","extensions":["mpm"]},"application/vnd.bluetooth.ep.oob":{"source":"iana"},"application/vnd.bluetooth.le.oob":{"source":"iana"},"application/vnd.bmi":{"source":"iana","extensions":["bmi"]},"application/vnd.bpf":{"source":"iana"},"application/vnd.bpf3":{"source":"iana"},"application/vnd.businessobjects":{"source":"iana","extensions":["rep"]},"application/vnd.byu.uapi+json":{"source":"iana","compressible":true},"application/vnd.cab-jscript":{"source":"iana"},"application/vnd.canon-cpdl":{"source":"iana"},"application/vnd.canon-lips":{"source":"iana"},"application/vnd.capasystems-pg+json":{"source":"iana","compressible":true},"application/vnd.cendio.thinlinc.clientconf":{"source":"iana"},"application/vnd.century-systems.tcp_stream":{"source":"iana"},"application/vnd.chemdraw+xml":{"source":"iana","compressible":true,"extensions":["cdxml"]},"application/vnd.chess-pgn":{"source":"iana"},"application/vnd.chipnuts.karaoke-mmd":{"source":"iana","extensions":["mmd"]},"application/vnd.ciedi":{"source":"iana"},"application/vnd.cinderella":{"source":"iana","extensions":["cdy"]},"application/vnd.cirpack.isdn-ext":{"source":"iana"},"application/vnd.citationstyles.style+xml":{"source":"iana","compressible":true,"extensions":["csl"]},"application/vnd.claymore":{"source":"iana","extensions":["cla"]},"application/vnd.cloanto.rp9":{"source":"iana","extensions":["rp9"]},"application/vnd.clonk.c4group":{"source":"iana","extensions":["c4g","c4d","c4f","c4p","c4u"]},"application/vnd.cluetrust.cartomobile-config":{"source":"iana","extensions":["c11amc"]},"application/vnd.cluetrust.cartomobile-config-pkg":{"source":"iana","extensions":["c11amz"]},"application/vnd.coffeescript":{"source":"iana"},"application/vnd.collabio.xodocuments.document":{"source":"iana"},"application/vnd.collabio.xodocuments.document-template":{"source":"iana"},"application/vnd.collabio.xodocuments.presentation":{"source":"iana"},"application/vnd.collabio.xodocuments.presentation-template":{"source":"iana"},"application/vnd.collabio.xodocuments.spreadsheet":{"source":"iana"},"application/vnd.collabio.xodocuments.spreadsheet-template":{"source":"iana"},"application/vnd.collection+json":{"source":"iana","compressible":true},"application/vnd.collection.doc+json":{"source":"iana","compressible":true},"application/vnd.collection.next+json":{"source":"iana","compressible":true},"application/vnd.comicbook+zip":{"source":"iana","compressible":false},"application/vnd.comicbook-rar":{"source":"iana"},"application/vnd.commerce-battelle":{"source":"iana"},"application/vnd.commonspace":{"source":"iana","extensions":["csp"]},"application/vnd.contact.cmsg":{"source":"iana","extensions":["cdbcmsg"]},"application/vnd.coreos.ignition+json":{"source":"iana","compressible":true},"application/vnd.cosmocaller":{"source":"iana","extensions":["cmc"]},"application/vnd.crick.clicker":{"source":"iana","extensions":["clkx"]},"application/vnd.crick.clicker.keyboard":{"source":"iana","extensions":["clkk"]},"application/vnd.crick.clicker.palette":{"source":"iana","extensions":["clkp"]},"application/vnd.crick.clicker.template":{"source":"iana","extensions":["clkt"]},"application/vnd.crick.clicker.wordbank":{"source":"iana","extensions":["clkw"]},"application/vnd.criticaltools.wbs+xml":{"source":"iana","compressible":true,"extensions":["wbs"]},"application/vnd.cryptii.pipe+json":{"source":"iana","compressible":true},"application/vnd.crypto-shade-file":{"source":"iana"},"application/vnd.cryptomator.encrypted":{"source":"iana"},"application/vnd.cryptomator.vault":{"source":"iana"},"application/vnd.ctc-posml":{"source":"iana","extensions":["pml"]},"application/vnd.ctct.ws+xml":{"source":"iana","compressible":true},"application/vnd.cups-pdf":{"source":"iana"},"application/vnd.cups-postscript":{"source":"iana"},"application/vnd.cups-ppd":{"source":"iana","extensions":["ppd"]},"application/vnd.cups-raster":{"source":"iana"},"application/vnd.cups-raw":{"source":"iana"},"application/vnd.curl":{"source":"iana"},"application/vnd.curl.car":{"source":"apache","extensions":["car"]},"application/vnd.curl.pcurl":{"source":"apache","extensions":["pcurl"]},"application/vnd.cyan.dean.root+xml":{"source":"iana","compressible":true},"application/vnd.cybank":{"source":"iana"},"application/vnd.cyclonedx+json":{"source":"iana","compressible":true},"application/vnd.cyclonedx+xml":{"source":"iana","compressible":true},"application/vnd.d2l.coursepackage1p0+zip":{"source":"iana","compressible":false},"application/vnd.d3m-dataset":{"source":"iana"},"application/vnd.d3m-problem":{"source":"iana"},"application/vnd.dart":{"source":"iana","compressible":true,"extensions":["dart"]},"application/vnd.data-vision.rdz":{"source":"iana","extensions":["rdz"]},"application/vnd.datapackage+json":{"source":"iana","compressible":true},"application/vnd.dataresource+json":{"source":"iana","compressible":true},"application/vnd.dbf":{"source":"iana","extensions":["dbf"]},"application/vnd.debian.binary-package":{"source":"iana"},"application/vnd.dece.data":{"source":"iana","extensions":["uvf","uvvf","uvd","uvvd"]},"application/vnd.dece.ttml+xml":{"source":"iana","compressible":true,"extensions":["uvt","uvvt"]},"application/vnd.dece.unspecified":{"source":"iana","extensions":["uvx","uvvx"]},"application/vnd.dece.zip":{"source":"iana","extensions":["uvz","uvvz"]},"application/vnd.denovo.fcselayout-link":{"source":"iana","extensions":["fe_launch"]},"application/vnd.desmume.movie":{"source":"iana"},"application/vnd.dir-bi.plate-dl-nosuffix":{"source":"iana"},"application/vnd.dm.delegation+xml":{"source":"iana","compressible":true},"application/vnd.dna":{"source":"iana","extensions":["dna"]},"application/vnd.document+json":{"source":"iana","compressible":true},"application/vnd.dolby.mlp":{"source":"apache","extensions":["mlp"]},"application/vnd.dolby.mobile.1":{"source":"iana"},"application/vnd.dolby.mobile.2":{"source":"iana"},"application/vnd.doremir.scorecloud-binary-document":{"source":"iana"},"application/vnd.dpgraph":{"source":"iana","extensions":["dpg"]},"application/vnd.dreamfactory":{"source":"iana","extensions":["dfac"]},"application/vnd.drive+json":{"source":"iana","compressible":true},"application/vnd.ds-keypoint":{"source":"apache","extensions":["kpxx"]},"application/vnd.dtg.local":{"source":"iana"},"application/vnd.dtg.local.flash":{"source":"iana"},"application/vnd.dtg.local.html":{"source":"iana"},"application/vnd.dvb.ait":{"source":"iana","extensions":["ait"]},"application/vnd.dvb.dvbisl+xml":{"source":"iana","compressible":true},"application/vnd.dvb.dvbj":{"source":"iana"},"application/vnd.dvb.esgcontainer":{"source":"iana"},"application/vnd.dvb.ipdcdftnotifaccess":{"source":"iana"},"application/vnd.dvb.ipdcesgaccess":{"source":"iana"},"application/vnd.dvb.ipdcesgaccess2":{"source":"iana"},"application/vnd.dvb.ipdcesgpdd":{"source":"iana"},"application/vnd.dvb.ipdcroaming":{"source":"iana"},"application/vnd.dvb.iptv.alfec-base":{"source":"iana"},"application/vnd.dvb.iptv.alfec-enhancement":{"source":"iana"},"application/vnd.dvb.notif-aggregate-root+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-container+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-generic+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-msglist+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-registration-request+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-registration-response+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-init+xml":{"source":"iana","compressible":true},"application/vnd.dvb.pfr":{"source":"iana"},"application/vnd.dvb.service":{"source":"iana","extensions":["svc"]},"application/vnd.dxr":{"source":"iana"},"application/vnd.dynageo":{"source":"iana","extensions":["geo"]},"application/vnd.dzr":{"source":"iana"},"application/vnd.easykaraoke.cdgdownload":{"source":"iana"},"application/vnd.ecdis-update":{"source":"iana"},"application/vnd.ecip.rlp":{"source":"iana"},"application/vnd.eclipse.ditto+json":{"source":"iana","compressible":true},"application/vnd.ecowin.chart":{"source":"iana","extensions":["mag"]},"application/vnd.ecowin.filerequest":{"source":"iana"},"application/vnd.ecowin.fileupdate":{"source":"iana"},"application/vnd.ecowin.series":{"source":"iana"},"application/vnd.ecowin.seriesrequest":{"source":"iana"},"application/vnd.ecowin.seriesupdate":{"source":"iana"},"application/vnd.efi.img":{"source":"iana"},"application/vnd.efi.iso":{"source":"iana"},"application/vnd.emclient.accessrequest+xml":{"source":"iana","compressible":true},"application/vnd.enliven":{"source":"iana","extensions":["nml"]},"application/vnd.enphase.envoy":{"source":"iana"},"application/vnd.eprints.data+xml":{"source":"iana","compressible":true},"application/vnd.epson.esf":{"source":"iana","extensions":["esf"]},"application/vnd.epson.msf":{"source":"iana","extensions":["msf"]},"application/vnd.epson.quickanime":{"source":"iana","extensions":["qam"]},"application/vnd.epson.salt":{"source":"iana","extensions":["slt"]},"application/vnd.epson.ssf":{"source":"iana","extensions":["ssf"]},"application/vnd.ericsson.quickcall":{"source":"iana"},"application/vnd.espass-espass+zip":{"source":"iana","compressible":false},"application/vnd.eszigno3+xml":{"source":"iana","compressible":true,"extensions":["es3","et3"]},"application/vnd.etsi.aoc+xml":{"source":"iana","compressible":true},"application/vnd.etsi.asic-e+zip":{"source":"iana","compressible":false},"application/vnd.etsi.asic-s+zip":{"source":"iana","compressible":false},"application/vnd.etsi.cug+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvcommand+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvdiscovery+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvprofile+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-bc+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-cod+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-npvr+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvservice+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsync+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvueprofile+xml":{"source":"iana","compressible":true},"application/vnd.etsi.mcid+xml":{"source":"iana","compressible":true},"application/vnd.etsi.mheg5":{"source":"iana"},"application/vnd.etsi.overload-control-policy-dataset+xml":{"source":"iana","compressible":true},"application/vnd.etsi.pstn+xml":{"source":"iana","compressible":true},"application/vnd.etsi.sci+xml":{"source":"iana","compressible":true},"application/vnd.etsi.simservs+xml":{"source":"iana","compressible":true},"application/vnd.etsi.timestamp-token":{"source":"iana"},"application/vnd.etsi.tsl+xml":{"source":"iana","compressible":true},"application/vnd.etsi.tsl.der":{"source":"iana"},"application/vnd.eu.kasparian.car+json":{"source":"iana","compressible":true},"application/vnd.eudora.data":{"source":"iana"},"application/vnd.evolv.ecig.profile":{"source":"iana"},"application/vnd.evolv.ecig.settings":{"source":"iana"},"application/vnd.evolv.ecig.theme":{"source":"iana"},"application/vnd.exstream-empower+zip":{"source":"iana","compressible":false},"application/vnd.exstream-package":{"source":"iana"},"application/vnd.ezpix-album":{"source":"iana","extensions":["ez2"]},"application/vnd.ezpix-package":{"source":"iana","extensions":["ez3"]},"application/vnd.f-secure.mobile":{"source":"iana"},"application/vnd.familysearch.gedcom+zip":{"source":"iana","compressible":false},"application/vnd.fastcopy-disk-image":{"source":"iana"},"application/vnd.fdf":{"source":"iana","extensions":["fdf"]},"application/vnd.fdsn.mseed":{"source":"iana","extensions":["mseed"]},"application/vnd.fdsn.seed":{"source":"iana","extensions":["seed","dataless"]},"application/vnd.ffsns":{"source":"iana"},"application/vnd.ficlab.flb+zip":{"source":"iana","compressible":false},"application/vnd.filmit.zfc":{"source":"iana"},"application/vnd.fints":{"source":"iana"},"application/vnd.firemonkeys.cloudcell":{"source":"iana"},"application/vnd.flographit":{"source":"iana","extensions":["gph"]},"application/vnd.fluxtime.clip":{"source":"iana","extensions":["ftc"]},"application/vnd.font-fontforge-sfd":{"source":"iana"},"application/vnd.framemaker":{"source":"iana","extensions":["fm","frame","maker","book"]},"application/vnd.frogans.fnc":{"source":"iana","extensions":["fnc"]},"application/vnd.frogans.ltf":{"source":"iana","extensions":["ltf"]},"application/vnd.fsc.weblaunch":{"source":"iana","extensions":["fsc"]},"application/vnd.fujifilm.fb.docuworks":{"source":"iana"},"application/vnd.fujifilm.fb.docuworks.binder":{"source":"iana"},"application/vnd.fujifilm.fb.docuworks.container":{"source":"iana"},"application/vnd.fujifilm.fb.jfi+xml":{"source":"iana","compressible":true},"application/vnd.fujitsu.oasys":{"source":"iana","extensions":["oas"]},"application/vnd.fujitsu.oasys2":{"source":"iana","extensions":["oa2"]},"application/vnd.fujitsu.oasys3":{"source":"iana","extensions":["oa3"]},"application/vnd.fujitsu.oasysgp":{"source":"iana","extensions":["fg5"]},"application/vnd.fujitsu.oasysprs":{"source":"iana","extensions":["bh2"]},"application/vnd.fujixerox.art-ex":{"source":"iana"},"application/vnd.fujixerox.art4":{"source":"iana"},"application/vnd.fujixerox.ddd":{"source":"iana","extensions":["ddd"]},"application/vnd.fujixerox.docuworks":{"source":"iana","extensions":["xdw"]},"application/vnd.fujixerox.docuworks.binder":{"source":"iana","extensions":["xbd"]},"application/vnd.fujixerox.docuworks.container":{"source":"iana"},"application/vnd.fujixerox.hbpl":{"source":"iana"},"application/vnd.fut-misnet":{"source":"iana"},"application/vnd.futoin+cbor":{"source":"iana"},"application/vnd.futoin+json":{"source":"iana","compressible":true},"application/vnd.fuzzysheet":{"source":"iana","extensions":["fzs"]},"application/vnd.genomatix.tuxedo":{"source":"iana","extensions":["txd"]},"application/vnd.gentics.grd+json":{"source":"iana","compressible":true},"application/vnd.geo+json":{"source":"iana","compressible":true},"application/vnd.geocube+xml":{"source":"iana","compressible":true},"application/vnd.geogebra.file":{"source":"iana","extensions":["ggb"]},"application/vnd.geogebra.slides":{"source":"iana"},"application/vnd.geogebra.tool":{"source":"iana","extensions":["ggt"]},"application/vnd.geometry-explorer":{"source":"iana","extensions":["gex","gre"]},"application/vnd.geonext":{"source":"iana","extensions":["gxt"]},"application/vnd.geoplan":{"source":"iana","extensions":["g2w"]},"application/vnd.geospace":{"source":"iana","extensions":["g3w"]},"application/vnd.gerber":{"source":"iana"},"application/vnd.globalplatform.card-content-mgt":{"source":"iana"},"application/vnd.globalplatform.card-content-mgt-response":{"source":"iana"},"application/vnd.gmx":{"source":"iana","extensions":["gmx"]},"application/vnd.google-apps.document":{"compressible":false,"extensions":["gdoc"]},"application/vnd.google-apps.presentation":{"compressible":false,"extensions":["gslides"]},"application/vnd.google-apps.spreadsheet":{"compressible":false,"extensions":["gsheet"]},"application/vnd.google-earth.kml+xml":{"source":"iana","compressible":true,"extensions":["kml"]},"application/vnd.google-earth.kmz":{"source":"iana","compressible":false,"extensions":["kmz"]},"application/vnd.gov.sk.e-form+xml":{"source":"iana","compressible":true},"application/vnd.gov.sk.e-form+zip":{"source":"iana","compressible":false},"application/vnd.gov.sk.xmldatacontainer+xml":{"source":"iana","compressible":true},"application/vnd.grafeq":{"source":"iana","extensions":["gqf","gqs"]},"application/vnd.gridmp":{"source":"iana"},"application/vnd.groove-account":{"source":"iana","extensions":["gac"]},"application/vnd.groove-help":{"source":"iana","extensions":["ghf"]},"application/vnd.groove-identity-message":{"source":"iana","extensions":["gim"]},"application/vnd.groove-injector":{"source":"iana","extensions":["grv"]},"application/vnd.groove-tool-message":{"source":"iana","extensions":["gtm"]},"application/vnd.groove-tool-template":{"source":"iana","extensions":["tpl"]},"application/vnd.groove-vcard":{"source":"iana","extensions":["vcg"]},"application/vnd.hal+json":{"source":"iana","compressible":true},"application/vnd.hal+xml":{"source":"iana","compressible":true,"extensions":["hal"]},"application/vnd.handheld-entertainment+xml":{"source":"iana","compressible":true,"extensions":["zmm"]},"application/vnd.hbci":{"source":"iana","extensions":["hbci"]},"application/vnd.hc+json":{"source":"iana","compressible":true},"application/vnd.hcl-bireports":{"source":"iana"},"application/vnd.hdt":{"source":"iana"},"application/vnd.heroku+json":{"source":"iana","compressible":true},"application/vnd.hhe.lesson-player":{"source":"iana","extensions":["les"]},"application/vnd.hl7cda+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.hl7v2+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.hp-hpgl":{"source":"iana","extensions":["hpgl"]},"application/vnd.hp-hpid":{"source":"iana","extensions":["hpid"]},"application/vnd.hp-hps":{"source":"iana","extensions":["hps"]},"application/vnd.hp-jlyt":{"source":"iana","extensions":["jlt"]},"application/vnd.hp-pcl":{"source":"iana","extensions":["pcl"]},"application/vnd.hp-pclxl":{"source":"iana","extensions":["pclxl"]},"application/vnd.httphone":{"source":"iana"},"application/vnd.hydrostatix.sof-data":{"source":"iana","extensions":["sfd-hdstx"]},"application/vnd.hyper+json":{"source":"iana","compressible":true},"application/vnd.hyper-item+json":{"source":"iana","compressible":true},"application/vnd.hyperdrive+json":{"source":"iana","compressible":true},"application/vnd.hzn-3d-crossword":{"source":"iana"},"application/vnd.ibm.afplinedata":{"source":"iana"},"application/vnd.ibm.electronic-media":{"source":"iana"},"application/vnd.ibm.minipay":{"source":"iana","extensions":["mpy"]},"application/vnd.ibm.modcap":{"source":"iana","extensions":["afp","listafp","list3820"]},"application/vnd.ibm.rights-management":{"source":"iana","extensions":["irm"]},"application/vnd.ibm.secure-container":{"source":"iana","extensions":["sc"]},"application/vnd.iccprofile":{"source":"iana","extensions":["icc","icm"]},"application/vnd.ieee.1905":{"source":"iana"},"application/vnd.igloader":{"source":"iana","extensions":["igl"]},"application/vnd.imagemeter.folder+zip":{"source":"iana","compressible":false},"application/vnd.imagemeter.image+zip":{"source":"iana","compressible":false},"application/vnd.immervision-ivp":{"source":"iana","extensions":["ivp"]},"application/vnd.immervision-ivu":{"source":"iana","extensions":["ivu"]},"application/vnd.ims.imsccv1p1":{"source":"iana"},"application/vnd.ims.imsccv1p2":{"source":"iana"},"application/vnd.ims.imsccv1p3":{"source":"iana"},"application/vnd.ims.lis.v2.result+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolconsumerprofile+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolproxy+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolproxy.id+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolsettings+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolsettings.simple+json":{"source":"iana","compressible":true},"application/vnd.informedcontrol.rms+xml":{"source":"iana","compressible":true},"application/vnd.informix-visionary":{"source":"iana"},"application/vnd.infotech.project":{"source":"iana"},"application/vnd.infotech.project+xml":{"source":"iana","compressible":true},"application/vnd.innopath.wamp.notification":{"source":"iana"},"application/vnd.insors.igm":{"source":"iana","extensions":["igm"]},"application/vnd.intercon.formnet":{"source":"iana","extensions":["xpw","xpx"]},"application/vnd.intergeo":{"source":"iana","extensions":["i2g"]},"application/vnd.intertrust.digibox":{"source":"iana"},"application/vnd.intertrust.nncp":{"source":"iana"},"application/vnd.intu.qbo":{"source":"iana","extensions":["qbo"]},"application/vnd.intu.qfx":{"source":"iana","extensions":["qfx"]},"application/vnd.iptc.g2.catalogitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.conceptitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.knowledgeitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.newsitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.newsmessage+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.packageitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.planningitem+xml":{"source":"iana","compressible":true},"application/vnd.ipunplugged.rcprofile":{"source":"iana","extensions":["rcprofile"]},"application/vnd.irepository.package+xml":{"source":"iana","compressible":true,"extensions":["irp"]},"application/vnd.is-xpr":{"source":"iana","extensions":["xpr"]},"application/vnd.isac.fcs":{"source":"iana","extensions":["fcs"]},"application/vnd.iso11783-10+zip":{"source":"iana","compressible":false},"application/vnd.jam":{"source":"iana","extensions":["jam"]},"application/vnd.japannet-directory-service":{"source":"iana"},"application/vnd.japannet-jpnstore-wakeup":{"source":"iana"},"application/vnd.japannet-payment-wakeup":{"source":"iana"},"application/vnd.japannet-registration":{"source":"iana"},"application/vnd.japannet-registration-wakeup":{"source":"iana"},"application/vnd.japannet-setstore-wakeup":{"source":"iana"},"application/vnd.japannet-verification":{"source":"iana"},"application/vnd.japannet-verification-wakeup":{"source":"iana"},"application/vnd.jcp.javame.midlet-rms":{"source":"iana","extensions":["rms"]},"application/vnd.jisp":{"source":"iana","extensions":["jisp"]},"application/vnd.joost.joda-archive":{"source":"iana","extensions":["joda"]},"application/vnd.jsk.isdn-ngn":{"source":"iana"},"application/vnd.kahootz":{"source":"iana","extensions":["ktz","ktr"]},"application/vnd.kde.karbon":{"source":"iana","extensions":["karbon"]},"application/vnd.kde.kchart":{"source":"iana","extensions":["chrt"]},"application/vnd.kde.kformula":{"source":"iana","extensions":["kfo"]},"application/vnd.kde.kivio":{"source":"iana","extensions":["flw"]},"application/vnd.kde.kontour":{"source":"iana","extensions":["kon"]},"application/vnd.kde.kpresenter":{"source":"iana","extensions":["kpr","kpt"]},"application/vnd.kde.kspread":{"source":"iana","extensions":["ksp"]},"application/vnd.kde.kword":{"source":"iana","extensions":["kwd","kwt"]},"application/vnd.kenameaapp":{"source":"iana","extensions":["htke"]},"application/vnd.kidspiration":{"source":"iana","extensions":["kia"]},"application/vnd.kinar":{"source":"iana","extensions":["kne","knp"]},"application/vnd.koan":{"source":"iana","extensions":["skp","skd","skt","skm"]},"application/vnd.kodak-descriptor":{"source":"iana","extensions":["sse"]},"application/vnd.las":{"source":"iana"},"application/vnd.las.las+json":{"source":"iana","compressible":true},"application/vnd.las.las+xml":{"source":"iana","compressible":true,"extensions":["lasxml"]},"application/vnd.laszip":{"source":"iana"},"application/vnd.leap+json":{"source":"iana","compressible":true},"application/vnd.liberty-request+xml":{"source":"iana","compressible":true},"application/vnd.llamagraphics.life-balance.desktop":{"source":"iana","extensions":["lbd"]},"application/vnd.llamagraphics.life-balance.exchange+xml":{"source":"iana","compressible":true,"extensions":["lbe"]},"application/vnd.logipipe.circuit+zip":{"source":"iana","compressible":false},"application/vnd.loom":{"source":"iana"},"application/vnd.lotus-1-2-3":{"source":"iana","extensions":["123"]},"application/vnd.lotus-approach":{"source":"iana","extensions":["apr"]},"application/vnd.lotus-freelance":{"source":"iana","extensions":["pre"]},"application/vnd.lotus-notes":{"source":"iana","extensions":["nsf"]},"application/vnd.lotus-organizer":{"source":"iana","extensions":["org"]},"application/vnd.lotus-screencam":{"source":"iana","extensions":["scm"]},"application/vnd.lotus-wordpro":{"source":"iana","extensions":["lwp"]},"application/vnd.macports.portpkg":{"source":"iana","extensions":["portpkg"]},"application/vnd.mapbox-vector-tile":{"source":"iana","extensions":["mvt"]},"application/vnd.marlin.drm.actiontoken+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.conftoken+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.license+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.mdcf":{"source":"iana"},"application/vnd.mason+json":{"source":"iana","compressible":true},"application/vnd.maxar.archive.3tz+zip":{"source":"iana","compressible":false},"application/vnd.maxmind.maxmind-db":{"source":"iana"},"application/vnd.mcd":{"source":"iana","extensions":["mcd"]},"application/vnd.medcalcdata":{"source":"iana","extensions":["mc1"]},"application/vnd.mediastation.cdkey":{"source":"iana","extensions":["cdkey"]},"application/vnd.meridian-slingshot":{"source":"iana"},"application/vnd.mfer":{"source":"iana","extensions":["mwf"]},"application/vnd.mfmp":{"source":"iana","extensions":["mfm"]},"application/vnd.micro+json":{"source":"iana","compressible":true},"application/vnd.micrografx.flo":{"source":"iana","extensions":["flo"]},"application/vnd.micrografx.igx":{"source":"iana","extensions":["igx"]},"application/vnd.microsoft.portable-executable":{"source":"iana"},"application/vnd.microsoft.windows.thumbnail-cache":{"source":"iana"},"application/vnd.miele+json":{"source":"iana","compressible":true},"application/vnd.mif":{"source":"iana","extensions":["mif"]},"application/vnd.minisoft-hp3000-save":{"source":"iana"},"application/vnd.mitsubishi.misty-guard.trustweb":{"source":"iana"},"application/vnd.mobius.daf":{"source":"iana","extensions":["daf"]},"application/vnd.mobius.dis":{"source":"iana","extensions":["dis"]},"application/vnd.mobius.mbk":{"source":"iana","extensions":["mbk"]},"application/vnd.mobius.mqy":{"source":"iana","extensions":["mqy"]},"application/vnd.mobius.msl":{"source":"iana","extensions":["msl"]},"application/vnd.mobius.plc":{"source":"iana","extensions":["plc"]},"application/vnd.mobius.txf":{"source":"iana","extensions":["txf"]},"application/vnd.mophun.application":{"source":"iana","extensions":["mpn"]},"application/vnd.mophun.certificate":{"source":"iana","extensions":["mpc"]},"application/vnd.motorola.flexsuite":{"source":"iana"},"application/vnd.motorola.flexsuite.adsi":{"source":"iana"},"application/vnd.motorola.flexsuite.fis":{"source":"iana"},"application/vnd.motorola.flexsuite.gotap":{"source":"iana"},"application/vnd.motorola.flexsuite.kmr":{"source":"iana"},"application/vnd.motorola.flexsuite.ttc":{"source":"iana"},"application/vnd.motorola.flexsuite.wem":{"source":"iana"},"application/vnd.motorola.iprm":{"source":"iana"},"application/vnd.mozilla.xul+xml":{"source":"iana","compressible":true,"extensions":["xul"]},"application/vnd.ms-3mfdocument":{"source":"iana"},"application/vnd.ms-artgalry":{"source":"iana","extensions":["cil"]},"application/vnd.ms-asf":{"source":"iana"},"application/vnd.ms-cab-compressed":{"source":"iana","extensions":["cab"]},"application/vnd.ms-color.iccprofile":{"source":"apache"},"application/vnd.ms-excel":{"source":"iana","compressible":false,"extensions":["xls","xlm","xla","xlc","xlt","xlw"]},"application/vnd.ms-excel.addin.macroenabled.12":{"source":"iana","extensions":["xlam"]},"application/vnd.ms-excel.sheet.binary.macroenabled.12":{"source":"iana","extensions":["xlsb"]},"application/vnd.ms-excel.sheet.macroenabled.12":{"source":"iana","extensions":["xlsm"]},"application/vnd.ms-excel.template.macroenabled.12":{"source":"iana","extensions":["xltm"]},"application/vnd.ms-fontobject":{"source":"iana","compressible":true,"extensions":["eot"]},"application/vnd.ms-htmlhelp":{"source":"iana","extensions":["chm"]},"application/vnd.ms-ims":{"source":"iana","extensions":["ims"]},"application/vnd.ms-lrm":{"source":"iana","extensions":["lrm"]},"application/vnd.ms-office.activex+xml":{"source":"iana","compressible":true},"application/vnd.ms-officetheme":{"source":"iana","extensions":["thmx"]},"application/vnd.ms-opentype":{"source":"apache","compressible":true},"application/vnd.ms-outlook":{"compressible":false,"extensions":["msg"]},"application/vnd.ms-package.obfuscated-opentype":{"source":"apache"},"application/vnd.ms-pki.seccat":{"source":"apache","extensions":["cat"]},"application/vnd.ms-pki.stl":{"source":"apache","extensions":["stl"]},"application/vnd.ms-playready.initiator+xml":{"source":"iana","compressible":true},"application/vnd.ms-powerpoint":{"source":"iana","compressible":false,"extensions":["ppt","pps","pot"]},"application/vnd.ms-powerpoint.addin.macroenabled.12":{"source":"iana","extensions":["ppam"]},"application/vnd.ms-powerpoint.presentation.macroenabled.12":{"source":"iana","extensions":["pptm"]},"application/vnd.ms-powerpoint.slide.macroenabled.12":{"source":"iana","extensions":["sldm"]},"application/vnd.ms-powerpoint.slideshow.macroenabled.12":{"source":"iana","extensions":["ppsm"]},"application/vnd.ms-powerpoint.template.macroenabled.12":{"source":"iana","extensions":["potm"]},"application/vnd.ms-printdevicecapabilities+xml":{"source":"iana","compressible":true},"application/vnd.ms-printing.printticket+xml":{"source":"apache","compressible":true},"application/vnd.ms-printschematicket+xml":{"source":"iana","compressible":true},"application/vnd.ms-project":{"source":"iana","extensions":["mpp","mpt"]},"application/vnd.ms-tnef":{"source":"iana"},"application/vnd.ms-windows.devicepairing":{"source":"iana"},"application/vnd.ms-windows.nwprinting.oob":{"source":"iana"},"application/vnd.ms-windows.printerpairing":{"source":"iana"},"application/vnd.ms-windows.wsd.oob":{"source":"iana"},"application/vnd.ms-wmdrm.lic-chlg-req":{"source":"iana"},"application/vnd.ms-wmdrm.lic-resp":{"source":"iana"},"application/vnd.ms-wmdrm.meter-chlg-req":{"source":"iana"},"application/vnd.ms-wmdrm.meter-resp":{"source":"iana"},"application/vnd.ms-word.document.macroenabled.12":{"source":"iana","extensions":["docm"]},"application/vnd.ms-word.template.macroenabled.12":{"source":"iana","extensions":["dotm"]},"application/vnd.ms-works":{"source":"iana","extensions":["wps","wks","wcm","wdb"]},"application/vnd.ms-wpl":{"source":"iana","extensions":["wpl"]},"application/vnd.ms-xpsdocument":{"source":"iana","compressible":false,"extensions":["xps"]},"application/vnd.msa-disk-image":{"source":"iana"},"application/vnd.mseq":{"source":"iana","extensions":["mseq"]},"application/vnd.msign":{"source":"iana"},"application/vnd.multiad.creator":{"source":"iana"},"application/vnd.multiad.creator.cif":{"source":"iana"},"application/vnd.music-niff":{"source":"iana"},"application/vnd.musician":{"source":"iana","extensions":["mus"]},"application/vnd.muvee.style":{"source":"iana","extensions":["msty"]},"application/vnd.mynfc":{"source":"iana","extensions":["taglet"]},"application/vnd.nacamar.ybrid+json":{"source":"iana","compressible":true},"application/vnd.ncd.control":{"source":"iana"},"application/vnd.ncd.reference":{"source":"iana"},"application/vnd.nearst.inv+json":{"source":"iana","compressible":true},"application/vnd.nebumind.line":{"source":"iana"},"application/vnd.nervana":{"source":"iana"},"application/vnd.netfpx":{"source":"iana"},"application/vnd.neurolanguage.nlu":{"source":"iana","extensions":["nlu"]},"application/vnd.nimn":{"source":"iana"},"application/vnd.nintendo.nitro.rom":{"source":"iana"},"application/vnd.nintendo.snes.rom":{"source":"iana"},"application/vnd.nitf":{"source":"iana","extensions":["ntf","nitf"]},"application/vnd.noblenet-directory":{"source":"iana","extensions":["nnd"]},"application/vnd.noblenet-sealer":{"source":"iana","extensions":["nns"]},"application/vnd.noblenet-web":{"source":"iana","extensions":["nnw"]},"application/vnd.nokia.catalogs":{"source":"iana"},"application/vnd.nokia.conml+wbxml":{"source":"iana"},"application/vnd.nokia.conml+xml":{"source":"iana","compressible":true},"application/vnd.nokia.iptv.config+xml":{"source":"iana","compressible":true},"application/vnd.nokia.isds-radio-presets":{"source":"iana"},"application/vnd.nokia.landmark+wbxml":{"source":"iana"},"application/vnd.nokia.landmark+xml":{"source":"iana","compressible":true},"application/vnd.nokia.landmarkcollection+xml":{"source":"iana","compressible":true},"application/vnd.nokia.n-gage.ac+xml":{"source":"iana","compressible":true,"extensions":["ac"]},"application/vnd.nokia.n-gage.data":{"source":"iana","extensions":["ngdat"]},"application/vnd.nokia.n-gage.symbian.install":{"source":"iana","extensions":["n-gage"]},"application/vnd.nokia.ncd":{"source":"iana"},"application/vnd.nokia.pcd+wbxml":{"source":"iana"},"application/vnd.nokia.pcd+xml":{"source":"iana","compressible":true},"application/vnd.nokia.radio-preset":{"source":"iana","extensions":["rpst"]},"application/vnd.nokia.radio-presets":{"source":"iana","extensions":["rpss"]},"application/vnd.novadigm.edm":{"source":"iana","extensions":["edm"]},"application/vnd.novadigm.edx":{"source":"iana","extensions":["edx"]},"application/vnd.novadigm.ext":{"source":"iana","extensions":["ext"]},"application/vnd.ntt-local.content-share":{"source":"iana"},"application/vnd.ntt-local.file-transfer":{"source":"iana"},"application/vnd.ntt-local.ogw_remote-access":{"source":"iana"},"application/vnd.ntt-local.sip-ta_remote":{"source":"iana"},"application/vnd.ntt-local.sip-ta_tcp_stream":{"source":"iana"},"application/vnd.oasis.opendocument.chart":{"source":"iana","extensions":["odc"]},"application/vnd.oasis.opendocument.chart-template":{"source":"iana","extensions":["otc"]},"application/vnd.oasis.opendocument.database":{"source":"iana","extensions":["odb"]},"application/vnd.oasis.opendocument.formula":{"source":"iana","extensions":["odf"]},"application/vnd.oasis.opendocument.formula-template":{"source":"iana","extensions":["odft"]},"application/vnd.oasis.opendocument.graphics":{"source":"iana","compressible":false,"extensions":["odg"]},"application/vnd.oasis.opendocument.graphics-template":{"source":"iana","extensions":["otg"]},"application/vnd.oasis.opendocument.image":{"source":"iana","extensions":["odi"]},"application/vnd.oasis.opendocument.image-template":{"source":"iana","extensions":["oti"]},"application/vnd.oasis.opendocument.presentation":{"source":"iana","compressible":false,"extensions":["odp"]},"application/vnd.oasis.opendocument.presentation-template":{"source":"iana","extensions":["otp"]},"application/vnd.oasis.opendocument.spreadsheet":{"source":"iana","compressible":false,"extensions":["ods"]},"application/vnd.oasis.opendocument.spreadsheet-template":{"source":"iana","extensions":["ots"]},"application/vnd.oasis.opendocument.text":{"source":"iana","compressible":false,"extensions":["odt"]},"application/vnd.oasis.opendocument.text-master":{"source":"iana","extensions":["odm"]},"application/vnd.oasis.opendocument.text-template":{"source":"iana","extensions":["ott"]},"application/vnd.oasis.opendocument.text-web":{"source":"iana","extensions":["oth"]},"application/vnd.obn":{"source":"iana"},"application/vnd.ocf+cbor":{"source":"iana"},"application/vnd.oci.image.manifest.v1+json":{"source":"iana","compressible":true},"application/vnd.oftn.l10n+json":{"source":"iana","compressible":true},"application/vnd.oipf.contentaccessdownload+xml":{"source":"iana","compressible":true},"application/vnd.oipf.contentaccessstreaming+xml":{"source":"iana","compressible":true},"application/vnd.oipf.cspg-hexbinary":{"source":"iana"},"application/vnd.oipf.dae.svg+xml":{"source":"iana","compressible":true},"application/vnd.oipf.dae.xhtml+xml":{"source":"iana","compressible":true},"application/vnd.oipf.mippvcontrolmessage+xml":{"source":"iana","compressible":true},"application/vnd.oipf.pae.gem":{"source":"iana"},"application/vnd.oipf.spdiscovery+xml":{"source":"iana","compressible":true},"application/vnd.oipf.spdlist+xml":{"source":"iana","compressible":true},"application/vnd.oipf.ueprofile+xml":{"source":"iana","compressible":true},"application/vnd.oipf.userprofile+xml":{"source":"iana","compressible":true},"application/vnd.olpc-sugar":{"source":"iana","extensions":["xo"]},"application/vnd.oma-scws-config":{"source":"iana"},"application/vnd.oma-scws-http-request":{"source":"iana"},"application/vnd.oma-scws-http-response":{"source":"iana"},"application/vnd.oma.bcast.associated-procedure-parameter+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.drm-trigger+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.imd+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.ltkm":{"source":"iana"},"application/vnd.oma.bcast.notification+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.provisioningtrigger":{"source":"iana"},"application/vnd.oma.bcast.sgboot":{"source":"iana"},"application/vnd.oma.bcast.sgdd+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.sgdu":{"source":"iana"},"application/vnd.oma.bcast.simple-symbol-container":{"source":"iana"},"application/vnd.oma.bcast.smartcard-trigger+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.sprov+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.stkm":{"source":"iana"},"application/vnd.oma.cab-address-book+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-feature-handler+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-pcc+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-subs-invite+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-user-prefs+xml":{"source":"iana","compressible":true},"application/vnd.oma.dcd":{"source":"iana"},"application/vnd.oma.dcdc":{"source":"iana"},"application/vnd.oma.dd2+xml":{"source":"iana","compressible":true,"extensions":["dd2"]},"application/vnd.oma.drm.risd+xml":{"source":"iana","compressible":true},"application/vnd.oma.group-usage-list+xml":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+cbor":{"source":"iana"},"application/vnd.oma.lwm2m+json":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+tlv":{"source":"iana"},"application/vnd.oma.pal+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.detailed-progress-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.final-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.groups+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.invocation-descriptor+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.optimized-progress-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.push":{"source":"iana"},"application/vnd.oma.scidm.messages+xml":{"source":"iana","compressible":true},"application/vnd.oma.xcap-directory+xml":{"source":"iana","compressible":true},"application/vnd.omads-email+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omads-file+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omads-folder+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omaloc-supl-init":{"source":"iana"},"application/vnd.onepager":{"source":"iana"},"application/vnd.onepagertamp":{"source":"iana"},"application/vnd.onepagertamx":{"source":"iana"},"application/vnd.onepagertat":{"source":"iana"},"application/vnd.onepagertatp":{"source":"iana"},"application/vnd.onepagertatx":{"source":"iana"},"application/vnd.openblox.game+xml":{"source":"iana","compressible":true,"extensions":["obgx"]},"application/vnd.openblox.game-binary":{"source":"iana"},"application/vnd.openeye.oeb":{"source":"iana"},"application/vnd.openofficeorg.extension":{"source":"apache","extensions":["oxt"]},"application/vnd.openstreetmap.data+xml":{"source":"iana","compressible":true,"extensions":["osm"]},"application/vnd.opentimestamps.ots":{"source":"iana"},"application/vnd.openxmlformats-officedocument.custom-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.customxmlproperties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawing+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.chart+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.extended-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.presentation":{"source":"iana","compressible":false,"extensions":["pptx"]},"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.presprops+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slide":{"source":"iana","extensions":["sldx"]},"application/vnd.openxmlformats-officedocument.presentationml.slide+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slideshow":{"source":"iana","extensions":["ppsx"]},"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.tags+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.template":{"source":"iana","extensions":["potx"]},"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"source":"iana","compressible":false,"extensions":["xlsx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.template":{"source":"iana","extensions":["xltx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.theme+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.themeoverride+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.vmldrawing":{"source":"iana"},"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{"source":"iana","compressible":false,"extensions":["docx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.template":{"source":"iana","extensions":["dotx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.core-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.relationships+xml":{"source":"iana","compressible":true},"application/vnd.oracle.resource+json":{"source":"iana","compressible":true},"application/vnd.orange.indata":{"source":"iana"},"application/vnd.osa.netdeploy":{"source":"iana"},"application/vnd.osgeo.mapguide.package":{"source":"iana","extensions":["mgp"]},"application/vnd.osgi.bundle":{"source":"iana"},"application/vnd.osgi.dp":{"source":"iana","extensions":["dp"]},"application/vnd.osgi.subsystem":{"source":"iana","extensions":["esa"]},"application/vnd.otps.ct-kip+xml":{"source":"iana","compressible":true},"application/vnd.oxli.countgraph":{"source":"iana"},"application/vnd.pagerduty+json":{"source":"iana","compressible":true},"application/vnd.palm":{"source":"iana","extensions":["pdb","pqa","oprc"]},"application/vnd.panoply":{"source":"iana"},"application/vnd.paos.xml":{"source":"iana"},"application/vnd.patentdive":{"source":"iana"},"application/vnd.patientecommsdoc":{"source":"iana"},"application/vnd.pawaafile":{"source":"iana","extensions":["paw"]},"application/vnd.pcos":{"source":"iana"},"application/vnd.pg.format":{"source":"iana","extensions":["str"]},"application/vnd.pg.osasli":{"source":"iana","extensions":["ei6"]},"application/vnd.piaccess.application-licence":{"source":"iana"},"application/vnd.picsel":{"source":"iana","extensions":["efif"]},"application/vnd.pmi.widget":{"source":"iana","extensions":["wg"]},"application/vnd.poc.group-advertisement+xml":{"source":"iana","compressible":true},"application/vnd.pocketlearn":{"source":"iana","extensions":["plf"]},"application/vnd.powerbuilder6":{"source":"iana","extensions":["pbd"]},"application/vnd.powerbuilder6-s":{"source":"iana"},"application/vnd.powerbuilder7":{"source":"iana"},"application/vnd.powerbuilder7-s":{"source":"iana"},"application/vnd.powerbuilder75":{"source":"iana"},"application/vnd.powerbuilder75-s":{"source":"iana"},"application/vnd.preminet":{"source":"iana"},"application/vnd.previewsystems.box":{"source":"iana","extensions":["box"]},"application/vnd.proteus.magazine":{"source":"iana","extensions":["mgz"]},"application/vnd.psfs":{"source":"iana"},"application/vnd.publishare-delta-tree":{"source":"iana","extensions":["qps"]},"application/vnd.pvi.ptid1":{"source":"iana","extensions":["ptid"]},"application/vnd.pwg-multiplexed":{"source":"iana"},"application/vnd.pwg-xhtml-print+xml":{"source":"iana","compressible":true},"application/vnd.qualcomm.brew-app-res":{"source":"iana"},"application/vnd.quarantainenet":{"source":"iana"},"application/vnd.quark.quarkxpress":{"source":"iana","extensions":["qxd","qxt","qwd","qwt","qxl","qxb"]},"application/vnd.quobject-quoxdocument":{"source":"iana"},"application/vnd.radisys.moml+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-conf+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-conn+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-dialog+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-stream+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-conf+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-base+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-fax-detect+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-fax-sendrecv+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-group+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-speech+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-transform+xml":{"source":"iana","compressible":true},"application/vnd.rainstor.data":{"source":"iana"},"application/vnd.rapid":{"source":"iana"},"application/vnd.rar":{"source":"iana","extensions":["rar"]},"application/vnd.realvnc.bed":{"source":"iana","extensions":["bed"]},"application/vnd.recordare.musicxml":{"source":"iana","extensions":["mxl"]},"application/vnd.recordare.musicxml+xml":{"source":"iana","compressible":true,"extensions":["musicxml"]},"application/vnd.renlearn.rlprint":{"source":"iana"},"application/vnd.resilient.logic":{"source":"iana"},"application/vnd.restful+json":{"source":"iana","compressible":true},"application/vnd.rig.cryptonote":{"source":"iana","extensions":["cryptonote"]},"application/vnd.rim.cod":{"source":"apache","extensions":["cod"]},"application/vnd.rn-realmedia":{"source":"apache","extensions":["rm"]},"application/vnd.rn-realmedia-vbr":{"source":"apache","extensions":["rmvb"]},"application/vnd.route66.link66+xml":{"source":"iana","compressible":true,"extensions":["link66"]},"application/vnd.rs-274x":{"source":"iana"},"application/vnd.ruckus.download":{"source":"iana"},"application/vnd.s3sms":{"source":"iana"},"application/vnd.sailingtracker.track":{"source":"iana","extensions":["st"]},"application/vnd.sar":{"source":"iana"},"application/vnd.sbm.cid":{"source":"iana"},"application/vnd.sbm.mid2":{"source":"iana"},"application/vnd.scribus":{"source":"iana"},"application/vnd.sealed.3df":{"source":"iana"},"application/vnd.sealed.csf":{"source":"iana"},"application/vnd.sealed.doc":{"source":"iana"},"application/vnd.sealed.eml":{"source":"iana"},"application/vnd.sealed.mht":{"source":"iana"},"application/vnd.sealed.net":{"source":"iana"},"application/vnd.sealed.ppt":{"source":"iana"},"application/vnd.sealed.tiff":{"source":"iana"},"application/vnd.sealed.xls":{"source":"iana"},"application/vnd.sealedmedia.softseal.html":{"source":"iana"},"application/vnd.sealedmedia.softseal.pdf":{"source":"iana"},"application/vnd.seemail":{"source":"iana","extensions":["see"]},"application/vnd.seis+json":{"source":"iana","compressible":true},"application/vnd.sema":{"source":"iana","extensions":["sema"]},"application/vnd.semd":{"source":"iana","extensions":["semd"]},"application/vnd.semf":{"source":"iana","extensions":["semf"]},"application/vnd.shade-save-file":{"source":"iana"},"application/vnd.shana.informed.formdata":{"source":"iana","extensions":["ifm"]},"application/vnd.shana.informed.formtemplate":{"source":"iana","extensions":["itp"]},"application/vnd.shana.informed.interchange":{"source":"iana","extensions":["iif"]},"application/vnd.shana.informed.package":{"source":"iana","extensions":["ipk"]},"application/vnd.shootproof+json":{"source":"iana","compressible":true},"application/vnd.shopkick+json":{"source":"iana","compressible":true},"application/vnd.shp":{"source":"iana"},"application/vnd.shx":{"source":"iana"},"application/vnd.sigrok.session":{"source":"iana"},"application/vnd.simtech-mindmapper":{"source":"iana","extensions":["twd","twds"]},"application/vnd.siren+json":{"source":"iana","compressible":true},"application/vnd.smaf":{"source":"iana","extensions":["mmf"]},"application/vnd.smart.notebook":{"source":"iana"},"application/vnd.smart.teacher":{"source":"iana","extensions":["teacher"]},"application/vnd.snesdev-page-table":{"source":"iana"},"application/vnd.software602.filler.form+xml":{"source":"iana","compressible":true,"extensions":["fo"]},"application/vnd.software602.filler.form-xml-zip":{"source":"iana"},"application/vnd.solent.sdkm+xml":{"source":"iana","compressible":true,"extensions":["sdkm","sdkd"]},"application/vnd.spotfire.dxp":{"source":"iana","extensions":["dxp"]},"application/vnd.spotfire.sfs":{"source":"iana","extensions":["sfs"]},"application/vnd.sqlite3":{"source":"iana"},"application/vnd.sss-cod":{"source":"iana"},"application/vnd.sss-dtf":{"source":"iana"},"application/vnd.sss-ntf":{"source":"iana"},"application/vnd.stardivision.calc":{"source":"apache","extensions":["sdc"]},"application/vnd.stardivision.draw":{"source":"apache","extensions":["sda"]},"application/vnd.stardivision.impress":{"source":"apache","extensions":["sdd"]},"application/vnd.stardivision.math":{"source":"apache","extensions":["smf"]},"application/vnd.stardivision.writer":{"source":"apache","extensions":["sdw","vor"]},"application/vnd.stardivision.writer-global":{"source":"apache","extensions":["sgl"]},"application/vnd.stepmania.package":{"source":"iana","extensions":["smzip"]},"application/vnd.stepmania.stepchart":{"source":"iana","extensions":["sm"]},"application/vnd.street-stream":{"source":"iana"},"application/vnd.sun.wadl+xml":{"source":"iana","compressible":true,"extensions":["wadl"]},"application/vnd.sun.xml.calc":{"source":"apache","extensions":["sxc"]},"application/vnd.sun.xml.calc.template":{"source":"apache","extensions":["stc"]},"application/vnd.sun.xml.draw":{"source":"apache","extensions":["sxd"]},"application/vnd.sun.xml.draw.template":{"source":"apache","extensions":["std"]},"application/vnd.sun.xml.impress":{"source":"apache","extensions":["sxi"]},"application/vnd.sun.xml.impress.template":{"source":"apache","extensions":["sti"]},"application/vnd.sun.xml.math":{"source":"apache","extensions":["sxm"]},"application/vnd.sun.xml.writer":{"source":"apache","extensions":["sxw"]},"application/vnd.sun.xml.writer.global":{"source":"apache","extensions":["sxg"]},"application/vnd.sun.xml.writer.template":{"source":"apache","extensions":["stw"]},"application/vnd.sus-calendar":{"source":"iana","extensions":["sus","susp"]},"application/vnd.svd":{"source":"iana","extensions":["svd"]},"application/vnd.swiftview-ics":{"source":"iana"},"application/vnd.sycle+xml":{"source":"iana","compressible":true},"application/vnd.syft+json":{"source":"iana","compressible":true},"application/vnd.symbian.install":{"source":"apache","extensions":["sis","sisx"]},"application/vnd.syncml+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xsm"]},"application/vnd.syncml.dm+wbxml":{"source":"iana","charset":"UTF-8","extensions":["bdm"]},"application/vnd.syncml.dm+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xdm"]},"application/vnd.syncml.dm.notification":{"source":"iana"},"application/vnd.syncml.dmddf+wbxml":{"source":"iana"},"application/vnd.syncml.dmddf+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["ddf"]},"application/vnd.syncml.dmtnds+wbxml":{"source":"iana"},"application/vnd.syncml.dmtnds+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.syncml.ds.notification":{"source":"iana"},"application/vnd.tableschema+json":{"source":"iana","compressible":true},"application/vnd.tao.intent-module-archive":{"source":"iana","extensions":["tao"]},"application/vnd.tcpdump.pcap":{"source":"iana","extensions":["pcap","cap","dmp"]},"application/vnd.think-cell.ppttc+json":{"source":"iana","compressible":true},"application/vnd.tmd.mediaflex.api+xml":{"source":"iana","compressible":true},"application/vnd.tml":{"source":"iana"},"application/vnd.tmobile-livetv":{"source":"iana","extensions":["tmo"]},"application/vnd.tri.onesource":{"source":"iana"},"application/vnd.trid.tpt":{"source":"iana","extensions":["tpt"]},"application/vnd.triscape.mxs":{"source":"iana","extensions":["mxs"]},"application/vnd.trueapp":{"source":"iana","extensions":["tra"]},"application/vnd.truedoc":{"source":"iana"},"application/vnd.ubisoft.webplayer":{"source":"iana"},"application/vnd.ufdl":{"source":"iana","extensions":["ufd","ufdl"]},"application/vnd.uiq.theme":{"source":"iana","extensions":["utz"]},"application/vnd.umajin":{"source":"iana","extensions":["umj"]},"application/vnd.unity":{"source":"iana","extensions":["unityweb"]},"application/vnd.uoml+xml":{"source":"iana","compressible":true,"extensions":["uoml"]},"application/vnd.uplanet.alert":{"source":"iana"},"application/vnd.uplanet.alert-wbxml":{"source":"iana"},"application/vnd.uplanet.bearer-choice":{"source":"iana"},"application/vnd.uplanet.bearer-choice-wbxml":{"source":"iana"},"application/vnd.uplanet.cacheop":{"source":"iana"},"application/vnd.uplanet.cacheop-wbxml":{"source":"iana"},"application/vnd.uplanet.channel":{"source":"iana"},"application/vnd.uplanet.channel-wbxml":{"source":"iana"},"application/vnd.uplanet.list":{"source":"iana"},"application/vnd.uplanet.list-wbxml":{"source":"iana"},"application/vnd.uplanet.listcmd":{"source":"iana"},"application/vnd.uplanet.listcmd-wbxml":{"source":"iana"},"application/vnd.uplanet.signal":{"source":"iana"},"application/vnd.uri-map":{"source":"iana"},"application/vnd.valve.source.material":{"source":"iana"},"application/vnd.vcx":{"source":"iana","extensions":["vcx"]},"application/vnd.vd-study":{"source":"iana"},"application/vnd.vectorworks":{"source":"iana"},"application/vnd.vel+json":{"source":"iana","compressible":true},"application/vnd.verimatrix.vcas":{"source":"iana"},"application/vnd.veritone.aion+json":{"source":"iana","compressible":true},"application/vnd.veryant.thin":{"source":"iana"},"application/vnd.ves.encrypted":{"source":"iana"},"application/vnd.vidsoft.vidconference":{"source":"iana"},"application/vnd.visio":{"source":"iana","extensions":["vsd","vst","vss","vsw"]},"application/vnd.visionary":{"source":"iana","extensions":["vis"]},"application/vnd.vividence.scriptfile":{"source":"iana"},"application/vnd.vsf":{"source":"iana","extensions":["vsf"]},"application/vnd.wap.sic":{"source":"iana"},"application/vnd.wap.slc":{"source":"iana"},"application/vnd.wap.wbxml":{"source":"iana","charset":"UTF-8","extensions":["wbxml"]},"application/vnd.wap.wmlc":{"source":"iana","extensions":["wmlc"]},"application/vnd.wap.wmlscriptc":{"source":"iana","extensions":["wmlsc"]},"application/vnd.webturbo":{"source":"iana","extensions":["wtb"]},"application/vnd.wfa.dpp":{"source":"iana"},"application/vnd.wfa.p2p":{"source":"iana"},"application/vnd.wfa.wsc":{"source":"iana"},"application/vnd.windows.devicepairing":{"source":"iana"},"application/vnd.wmc":{"source":"iana"},"application/vnd.wmf.bootstrap":{"source":"iana"},"application/vnd.wolfram.mathematica":{"source":"iana"},"application/vnd.wolfram.mathematica.package":{"source":"iana"},"application/vnd.wolfram.player":{"source":"iana","extensions":["nbp"]},"application/vnd.wordperfect":{"source":"iana","extensions":["wpd"]},"application/vnd.wqd":{"source":"iana","extensions":["wqd"]},"application/vnd.wrq-hp3000-labelled":{"source":"iana"},"application/vnd.wt.stf":{"source":"iana","extensions":["stf"]},"application/vnd.wv.csp+wbxml":{"source":"iana"},"application/vnd.wv.csp+xml":{"source":"iana","compressible":true},"application/vnd.wv.ssp+xml":{"source":"iana","compressible":true},"application/vnd.xacml+json":{"source":"iana","compressible":true},"application/vnd.xara":{"source":"iana","extensions":["xar"]},"application/vnd.xfdl":{"source":"iana","extensions":["xfdl"]},"application/vnd.xfdl.webform":{"source":"iana"},"application/vnd.xmi+xml":{"source":"iana","compressible":true},"application/vnd.xmpie.cpkg":{"source":"iana"},"application/vnd.xmpie.dpkg":{"source":"iana"},"application/vnd.xmpie.plan":{"source":"iana"},"application/vnd.xmpie.ppkg":{"source":"iana"},"application/vnd.xmpie.xlim":{"source":"iana"},"application/vnd.yamaha.hv-dic":{"source":"iana","extensions":["hvd"]},"application/vnd.yamaha.hv-script":{"source":"iana","extensions":["hvs"]},"application/vnd.yamaha.hv-voice":{"source":"iana","extensions":["hvp"]},"application/vnd.yamaha.openscoreformat":{"source":"iana","extensions":["osf"]},"application/vnd.yamaha.openscoreformat.osfpvg+xml":{"source":"iana","compressible":true,"extensions":["osfpvg"]},"application/vnd.yamaha.remote-setup":{"source":"iana"},"application/vnd.yamaha.smaf-audio":{"source":"iana","extensions":["saf"]},"application/vnd.yamaha.smaf-phrase":{"source":"iana","extensions":["spf"]},"application/vnd.yamaha.through-ngn":{"source":"iana"},"application/vnd.yamaha.tunnel-udpencap":{"source":"iana"},"application/vnd.yaoweme":{"source":"iana"},"application/vnd.yellowriver-custom-menu":{"source":"iana","extensions":["cmp"]},"application/vnd.youtube.yt":{"source":"iana"},"application/vnd.zul":{"source":"iana","extensions":["zir","zirz"]},"application/vnd.zzazz.deck+xml":{"source":"iana","compressible":true,"extensions":["zaz"]},"application/voicexml+xml":{"source":"iana","compressible":true,"extensions":["vxml"]},"application/voucher-cms+json":{"source":"iana","compressible":true},"application/vq-rtcpxr":{"source":"iana"},"application/wasm":{"source":"iana","compressible":true,"extensions":["wasm"]},"application/watcherinfo+xml":{"source":"iana","compressible":true,"extensions":["wif"]},"application/webpush-options+json":{"source":"iana","compressible":true},"application/whoispp-query":{"source":"iana"},"application/whoispp-response":{"source":"iana"},"application/widget":{"source":"iana","extensions":["wgt"]},"application/winhlp":{"source":"apache","extensions":["hlp"]},"application/wita":{"source":"iana"},"application/wordperfect5.1":{"source":"iana"},"application/wsdl+xml":{"source":"iana","compressible":true,"extensions":["wsdl"]},"application/wspolicy+xml":{"source":"iana","compressible":true,"extensions":["wspolicy"]},"application/x-7z-compressed":{"source":"apache","compressible":false,"extensions":["7z"]},"application/x-abiword":{"source":"apache","extensions":["abw"]},"application/x-ace-compressed":{"source":"apache","extensions":["ace"]},"application/x-amf":{"source":"apache"},"application/x-apple-diskimage":{"source":"apache","extensions":["dmg"]},"application/x-arj":{"compressible":false,"extensions":["arj"]},"application/x-authorware-bin":{"source":"apache","extensions":["aab","x32","u32","vox"]},"application/x-authorware-map":{"source":"apache","extensions":["aam"]},"application/x-authorware-seg":{"source":"apache","extensions":["aas"]},"application/x-bcpio":{"source":"apache","extensions":["bcpio"]},"application/x-bdoc":{"compressible":false,"extensions":["bdoc"]},"application/x-bittorrent":{"source":"apache","extensions":["torrent"]},"application/x-blorb":{"source":"apache","extensions":["blb","blorb"]},"application/x-bzip":{"source":"apache","compressible":false,"extensions":["bz"]},"application/x-bzip2":{"source":"apache","compressible":false,"extensions":["bz2","boz"]},"application/x-cbr":{"source":"apache","extensions":["cbr","cba","cbt","cbz","cb7"]},"application/x-cdlink":{"source":"apache","extensions":["vcd"]},"application/x-cfs-compressed":{"source":"apache","extensions":["cfs"]},"application/x-chat":{"source":"apache","extensions":["chat"]},"application/x-chess-pgn":{"source":"apache","extensions":["pgn"]},"application/x-chrome-extension":{"extensions":["crx"]},"application/x-cocoa":{"source":"nginx","extensions":["cco"]},"application/x-compress":{"source":"apache"},"application/x-conference":{"source":"apache","extensions":["nsc"]},"application/x-cpio":{"source":"apache","extensions":["cpio"]},"application/x-csh":{"source":"apache","extensions":["csh"]},"application/x-deb":{"compressible":false},"application/x-debian-package":{"source":"apache","extensions":["deb","udeb"]},"application/x-dgc-compressed":{"source":"apache","extensions":["dgc"]},"application/x-director":{"source":"apache","extensions":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]},"application/x-doom":{"source":"apache","extensions":["wad"]},"application/x-dtbncx+xml":{"source":"apache","compressible":true,"extensions":["ncx"]},"application/x-dtbook+xml":{"source":"apache","compressible":true,"extensions":["dtb"]},"application/x-dtbresource+xml":{"source":"apache","compressible":true,"extensions":["res"]},"application/x-dvi":{"source":"apache","compressible":false,"extensions":["dvi"]},"application/x-envoy":{"source":"apache","extensions":["evy"]},"application/x-eva":{"source":"apache","extensions":["eva"]},"application/x-font-bdf":{"source":"apache","extensions":["bdf"]},"application/x-font-dos":{"source":"apache"},"application/x-font-framemaker":{"source":"apache"},"application/x-font-ghostscript":{"source":"apache","extensions":["gsf"]},"application/x-font-libgrx":{"source":"apache"},"application/x-font-linux-psf":{"source":"apache","extensions":["psf"]},"application/x-font-pcf":{"source":"apache","extensions":["pcf"]},"application/x-font-snf":{"source":"apache","extensions":["snf"]},"application/x-font-speedo":{"source":"apache"},"application/x-font-sunos-news":{"source":"apache"},"application/x-font-type1":{"source":"apache","extensions":["pfa","pfb","pfm","afm"]},"application/x-font-vfont":{"source":"apache"},"application/x-freearc":{"source":"apache","extensions":["arc"]},"application/x-futuresplash":{"source":"apache","extensions":["spl"]},"application/x-gca-compressed":{"source":"apache","extensions":["gca"]},"application/x-glulx":{"source":"apache","extensions":["ulx"]},"application/x-gnumeric":{"source":"apache","extensions":["gnumeric"]},"application/x-gramps-xml":{"source":"apache","extensions":["gramps"]},"application/x-gtar":{"source":"apache","extensions":["gtar"]},"application/x-gzip":{"source":"apache"},"application/x-hdf":{"source":"apache","extensions":["hdf"]},"application/x-httpd-php":{"compressible":true,"extensions":["php"]},"application/x-install-instructions":{"source":"apache","extensions":["install"]},"application/x-iso9660-image":{"source":"apache","extensions":["iso"]},"application/x-iwork-keynote-sffkey":{"extensions":["key"]},"application/x-iwork-numbers-sffnumbers":{"extensions":["numbers"]},"application/x-iwork-pages-sffpages":{"extensions":["pages"]},"application/x-java-archive-diff":{"source":"nginx","extensions":["jardiff"]},"application/x-java-jnlp-file":{"source":"apache","compressible":false,"extensions":["jnlp"]},"application/x-javascript":{"compressible":true},"application/x-keepass2":{"extensions":["kdbx"]},"application/x-latex":{"source":"apache","compressible":false,"extensions":["latex"]},"application/x-lua-bytecode":{"extensions":["luac"]},"application/x-lzh-compressed":{"source":"apache","extensions":["lzh","lha"]},"application/x-makeself":{"source":"nginx","extensions":["run"]},"application/x-mie":{"source":"apache","extensions":["mie"]},"application/x-mobipocket-ebook":{"source":"apache","extensions":["prc","mobi"]},"application/x-mpegurl":{"compressible":false},"application/x-ms-application":{"source":"apache","extensions":["application"]},"application/x-ms-shortcut":{"source":"apache","extensions":["lnk"]},"application/x-ms-wmd":{"source":"apache","extensions":["wmd"]},"application/x-ms-wmz":{"source":"apache","extensions":["wmz"]},"application/x-ms-xbap":{"source":"apache","extensions":["xbap"]},"application/x-msaccess":{"source":"apache","extensions":["mdb"]},"application/x-msbinder":{"source":"apache","extensions":["obd"]},"application/x-mscardfile":{"source":"apache","extensions":["crd"]},"application/x-msclip":{"source":"apache","extensions":["clp"]},"application/x-msdos-program":{"extensions":["exe"]},"application/x-msdownload":{"source":"apache","extensions":["exe","dll","com","bat","msi"]},"application/x-msmediaview":{"source":"apache","extensions":["mvb","m13","m14"]},"application/x-msmetafile":{"source":"apache","extensions":["wmf","wmz","emf","emz"]},"application/x-msmoney":{"source":"apache","extensions":["mny"]},"application/x-mspublisher":{"source":"apache","extensions":["pub"]},"application/x-msschedule":{"source":"apache","extensions":["scd"]},"application/x-msterminal":{"source":"apache","extensions":["trm"]},"application/x-mswrite":{"source":"apache","extensions":["wri"]},"application/x-netcdf":{"source":"apache","extensions":["nc","cdf"]},"application/x-ns-proxy-autoconfig":{"compressible":true,"extensions":["pac"]},"application/x-nzb":{"source":"apache","extensions":["nzb"]},"application/x-perl":{"source":"nginx","extensions":["pl","pm"]},"application/x-pilot":{"source":"nginx","extensions":["prc","pdb"]},"application/x-pkcs12":{"source":"apache","compressible":false,"extensions":["p12","pfx"]},"application/x-pkcs7-certificates":{"source":"apache","extensions":["p7b","spc"]},"application/x-pkcs7-certreqresp":{"source":"apache","extensions":["p7r"]},"application/x-pki-message":{"source":"iana"},"application/x-rar-compressed":{"source":"apache","compressible":false,"extensions":["rar"]},"application/x-redhat-package-manager":{"source":"nginx","extensions":["rpm"]},"application/x-research-info-systems":{"source":"apache","extensions":["ris"]},"application/x-sea":{"source":"nginx","extensions":["sea"]},"application/x-sh":{"source":"apache","compressible":true,"extensions":["sh"]},"application/x-shar":{"source":"apache","extensions":["shar"]},"application/x-shockwave-flash":{"source":"apache","compressible":false,"extensions":["swf"]},"application/x-silverlight-app":{"source":"apache","extensions":["xap"]},"application/x-sql":{"source":"apache","extensions":["sql"]},"application/x-stuffit":{"source":"apache","compressible":false,"extensions":["sit"]},"application/x-stuffitx":{"source":"apache","extensions":["sitx"]},"application/x-subrip":{"source":"apache","extensions":["srt"]},"application/x-sv4cpio":{"source":"apache","extensions":["sv4cpio"]},"application/x-sv4crc":{"source":"apache","extensions":["sv4crc"]},"application/x-t3vm-image":{"source":"apache","extensions":["t3"]},"application/x-tads":{"source":"apache","extensions":["gam"]},"application/x-tar":{"source":"apache","compressible":true,"extensions":["tar"]},"application/x-tcl":{"source":"apache","extensions":["tcl","tk"]},"application/x-tex":{"source":"apache","extensions":["tex"]},"application/x-tex-tfm":{"source":"apache","extensions":["tfm"]},"application/x-texinfo":{"source":"apache","extensions":["texinfo","texi"]},"application/x-tgif":{"source":"apache","extensions":["obj"]},"application/x-ustar":{"source":"apache","extensions":["ustar"]},"application/x-virtualbox-hdd":{"compressible":true,"extensions":["hdd"]},"application/x-virtualbox-ova":{"compressible":true,"extensions":["ova"]},"application/x-virtualbox-ovf":{"compressible":true,"extensions":["ovf"]},"application/x-virtualbox-vbox":{"compressible":true,"extensions":["vbox"]},"application/x-virtualbox-vbox-extpack":{"compressible":false,"extensions":["vbox-extpack"]},"application/x-virtualbox-vdi":{"compressible":true,"extensions":["vdi"]},"application/x-virtualbox-vhd":{"compressible":true,"extensions":["vhd"]},"application/x-virtualbox-vmdk":{"compressible":true,"extensions":["vmdk"]},"application/x-wais-source":{"source":"apache","extensions":["src"]},"application/x-web-app-manifest+json":{"compressible":true,"extensions":["webapp"]},"application/x-www-form-urlencoded":{"source":"iana","compressible":true},"application/x-x509-ca-cert":{"source":"iana","extensions":["der","crt","pem"]},"application/x-x509-ca-ra-cert":{"source":"iana"},"application/x-x509-next-ca-cert":{"source":"iana"},"application/x-xfig":{"source":"apache","extensions":["fig"]},"application/x-xliff+xml":{"source":"apache","compressible":true,"extensions":["xlf"]},"application/x-xpinstall":{"source":"apache","compressible":false,"extensions":["xpi"]},"application/x-xz":{"source":"apache","extensions":["xz"]},"application/x-zmachine":{"source":"apache","extensions":["z1","z2","z3","z4","z5","z6","z7","z8"]},"application/x400-bp":{"source":"iana"},"application/xacml+xml":{"source":"iana","compressible":true},"application/xaml+xml":{"source":"apache","compressible":true,"extensions":["xaml"]},"application/xcap-att+xml":{"source":"iana","compressible":true,"extensions":["xav"]},"application/xcap-caps+xml":{"source":"iana","compressible":true,"extensions":["xca"]},"application/xcap-diff+xml":{"source":"iana","compressible":true,"extensions":["xdf"]},"application/xcap-el+xml":{"source":"iana","compressible":true,"extensions":["xel"]},"application/xcap-error+xml":{"source":"iana","compressible":true},"application/xcap-ns+xml":{"source":"iana","compressible":true,"extensions":["xns"]},"application/xcon-conference-info+xml":{"source":"iana","compressible":true},"application/xcon-conference-info-diff+xml":{"source":"iana","compressible":true},"application/xenc+xml":{"source":"iana","compressible":true,"extensions":["xenc"]},"application/xhtml+xml":{"source":"iana","compressible":true,"extensions":["xhtml","xht"]},"application/xhtml-voice+xml":{"source":"apache","compressible":true},"application/xliff+xml":{"source":"iana","compressible":true,"extensions":["xlf"]},"application/xml":{"source":"iana","compressible":true,"extensions":["xml","xsl","xsd","rng"]},"application/xml-dtd":{"source":"iana","compressible":true,"extensions":["dtd"]},"application/xml-external-parsed-entity":{"source":"iana"},"application/xml-patch+xml":{"source":"iana","compressible":true},"application/xmpp+xml":{"source":"iana","compressible":true},"application/xop+xml":{"source":"iana","compressible":true,"extensions":["xop"]},"application/xproc+xml":{"source":"apache","compressible":true,"extensions":["xpl"]},"application/xslt+xml":{"source":"iana","compressible":true,"extensions":["xsl","xslt"]},"application/xspf+xml":{"source":"apache","compressible":true,"extensions":["xspf"]},"application/xv+xml":{"source":"iana","compressible":true,"extensions":["mxml","xhvml","xvml","xvm"]},"application/yang":{"source":"iana","extensions":["yang"]},"application/yang-data+json":{"source":"iana","compressible":true},"application/yang-data+xml":{"source":"iana","compressible":true},"application/yang-patch+json":{"source":"iana","compressible":true},"application/yang-patch+xml":{"source":"iana","compressible":true},"application/yin+xml":{"source":"iana","compressible":true,"extensions":["yin"]},"application/zip":{"source":"iana","compressible":false,"extensions":["zip"]},"application/zlib":{"source":"iana"},"application/zstd":{"source":"iana"},"audio/1d-interleaved-parityfec":{"source":"iana"},"audio/32kadpcm":{"source":"iana"},"audio/3gpp":{"source":"iana","compressible":false,"extensions":["3gpp"]},"audio/3gpp2":{"source":"iana"},"audio/aac":{"source":"iana"},"audio/ac3":{"source":"iana"},"audio/adpcm":{"source":"apache","extensions":["adp"]},"audio/amr":{"source":"iana","extensions":["amr"]},"audio/amr-wb":{"source":"iana"},"audio/amr-wb+":{"source":"iana"},"audio/aptx":{"source":"iana"},"audio/asc":{"source":"iana"},"audio/atrac-advanced-lossless":{"source":"iana"},"audio/atrac-x":{"source":"iana"},"audio/atrac3":{"source":"iana"},"audio/basic":{"source":"iana","compressible":false,"extensions":["au","snd"]},"audio/bv16":{"source":"iana"},"audio/bv32":{"source":"iana"},"audio/clearmode":{"source":"iana"},"audio/cn":{"source":"iana"},"audio/dat12":{"source":"iana"},"audio/dls":{"source":"iana"},"audio/dsr-es201108":{"source":"iana"},"audio/dsr-es202050":{"source":"iana"},"audio/dsr-es202211":{"source":"iana"},"audio/dsr-es202212":{"source":"iana"},"audio/dv":{"source":"iana"},"audio/dvi4":{"source":"iana"},"audio/eac3":{"source":"iana"},"audio/encaprtp":{"source":"iana"},"audio/evrc":{"source":"iana"},"audio/evrc-qcp":{"source":"iana"},"audio/evrc0":{"source":"iana"},"audio/evrc1":{"source":"iana"},"audio/evrcb":{"source":"iana"},"audio/evrcb0":{"source":"iana"},"audio/evrcb1":{"source":"iana"},"audio/evrcnw":{"source":"iana"},"audio/evrcnw0":{"source":"iana"},"audio/evrcnw1":{"source":"iana"},"audio/evrcwb":{"source":"iana"},"audio/evrcwb0":{"source":"iana"},"audio/evrcwb1":{"source":"iana"},"audio/evs":{"source":"iana"},"audio/flexfec":{"source":"iana"},"audio/fwdred":{"source":"iana"},"audio/g711-0":{"source":"iana"},"audio/g719":{"source":"iana"},"audio/g722":{"source":"iana"},"audio/g7221":{"source":"iana"},"audio/g723":{"source":"iana"},"audio/g726-16":{"source":"iana"},"audio/g726-24":{"source":"iana"},"audio/g726-32":{"source":"iana"},"audio/g726-40":{"source":"iana"},"audio/g728":{"source":"iana"},"audio/g729":{"source":"iana"},"audio/g7291":{"source":"iana"},"audio/g729d":{"source":"iana"},"audio/g729e":{"source":"iana"},"audio/gsm":{"source":"iana"},"audio/gsm-efr":{"source":"iana"},"audio/gsm-hr-08":{"source":"iana"},"audio/ilbc":{"source":"iana"},"audio/ip-mr_v2.5":{"source":"iana"},"audio/isac":{"source":"apache"},"audio/l16":{"source":"iana"},"audio/l20":{"source":"iana"},"audio/l24":{"source":"iana","compressible":false},"audio/l8":{"source":"iana"},"audio/lpc":{"source":"iana"},"audio/melp":{"source":"iana"},"audio/melp1200":{"source":"iana"},"audio/melp2400":{"source":"iana"},"audio/melp600":{"source":"iana"},"audio/mhas":{"source":"iana"},"audio/midi":{"source":"apache","extensions":["mid","midi","kar","rmi"]},"audio/mobile-xmf":{"source":"iana","extensions":["mxmf"]},"audio/mp3":{"compressible":false,"extensions":["mp3"]},"audio/mp4":{"source":"iana","compressible":false,"extensions":["m4a","mp4a"]},"audio/mp4a-latm":{"source":"iana"},"audio/mpa":{"source":"iana"},"audio/mpa-robust":{"source":"iana"},"audio/mpeg":{"source":"iana","compressible":false,"extensions":["mpga","mp2","mp2a","mp3","m2a","m3a"]},"audio/mpeg4-generic":{"source":"iana"},"audio/musepack":{"source":"apache"},"audio/ogg":{"source":"iana","compressible":false,"extensions":["oga","ogg","spx","opus"]},"audio/opus":{"source":"iana"},"audio/parityfec":{"source":"iana"},"audio/pcma":{"source":"iana"},"audio/pcma-wb":{"source":"iana"},"audio/pcmu":{"source":"iana"},"audio/pcmu-wb":{"source":"iana"},"audio/prs.sid":{"source":"iana"},"audio/qcelp":{"source":"iana"},"audio/raptorfec":{"source":"iana"},"audio/red":{"source":"iana"},"audio/rtp-enc-aescm128":{"source":"iana"},"audio/rtp-midi":{"source":"iana"},"audio/rtploopback":{"source":"iana"},"audio/rtx":{"source":"iana"},"audio/s3m":{"source":"apache","extensions":["s3m"]},"audio/scip":{"source":"iana"},"audio/silk":{"source":"apache","extensions":["sil"]},"audio/smv":{"source":"iana"},"audio/smv-qcp":{"source":"iana"},"audio/smv0":{"source":"iana"},"audio/sofa":{"source":"iana"},"audio/sp-midi":{"source":"iana"},"audio/speex":{"source":"iana"},"audio/t140c":{"source":"iana"},"audio/t38":{"source":"iana"},"audio/telephone-event":{"source":"iana"},"audio/tetra_acelp":{"source":"iana"},"audio/tetra_acelp_bb":{"source":"iana"},"audio/tone":{"source":"iana"},"audio/tsvcis":{"source":"iana"},"audio/uemclip":{"source":"iana"},"audio/ulpfec":{"source":"iana"},"audio/usac":{"source":"iana"},"audio/vdvi":{"source":"iana"},"audio/vmr-wb":{"source":"iana"},"audio/vnd.3gpp.iufp":{"source":"iana"},"audio/vnd.4sb":{"source":"iana"},"audio/vnd.audiokoz":{"source":"iana"},"audio/vnd.celp":{"source":"iana"},"audio/vnd.cisco.nse":{"source":"iana"},"audio/vnd.cmles.radio-events":{"source":"iana"},"audio/vnd.cns.anp1":{"source":"iana"},"audio/vnd.cns.inf1":{"source":"iana"},"audio/vnd.dece.audio":{"source":"iana","extensions":["uva","uvva"]},"audio/vnd.digital-winds":{"source":"iana","extensions":["eol"]},"audio/vnd.dlna.adts":{"source":"iana"},"audio/vnd.dolby.heaac.1":{"source":"iana"},"audio/vnd.dolby.heaac.2":{"source":"iana"},"audio/vnd.dolby.mlp":{"source":"iana"},"audio/vnd.dolby.mps":{"source":"iana"},"audio/vnd.dolby.pl2":{"source":"iana"},"audio/vnd.dolby.pl2x":{"source":"iana"},"audio/vnd.dolby.pl2z":{"source":"iana"},"audio/vnd.dolby.pulse.1":{"source":"iana"},"audio/vnd.dra":{"source":"iana","extensions":["dra"]},"audio/vnd.dts":{"source":"iana","extensions":["dts"]},"audio/vnd.dts.hd":{"source":"iana","extensions":["dtshd"]},"audio/vnd.dts.uhd":{"source":"iana"},"audio/vnd.dvb.file":{"source":"iana"},"audio/vnd.everad.plj":{"source":"iana"},"audio/vnd.hns.audio":{"source":"iana"},"audio/vnd.lucent.voice":{"source":"iana","extensions":["lvp"]},"audio/vnd.ms-playready.media.pya":{"source":"iana","extensions":["pya"]},"audio/vnd.nokia.mobile-xmf":{"source":"iana"},"audio/vnd.nortel.vbk":{"source":"iana"},"audio/vnd.nuera.ecelp4800":{"source":"iana","extensions":["ecelp4800"]},"audio/vnd.nuera.ecelp7470":{"source":"iana","extensions":["ecelp7470"]},"audio/vnd.nuera.ecelp9600":{"source":"iana","extensions":["ecelp9600"]},"audio/vnd.octel.sbc":{"source":"iana"},"audio/vnd.presonus.multitrack":{"source":"iana"},"audio/vnd.qcelp":{"source":"iana"},"audio/vnd.rhetorex.32kadpcm":{"source":"iana"},"audio/vnd.rip":{"source":"iana","extensions":["rip"]},"audio/vnd.rn-realaudio":{"compressible":false},"audio/vnd.sealedmedia.softseal.mpeg":{"source":"iana"},"audio/vnd.vmx.cvsd":{"source":"iana"},"audio/vnd.wave":{"compressible":false},"audio/vorbis":{"source":"iana","compressible":false},"audio/vorbis-config":{"source":"iana"},"audio/wav":{"compressible":false,"extensions":["wav"]},"audio/wave":{"compressible":false,"extensions":["wav"]},"audio/webm":{"source":"apache","compressible":false,"extensions":["weba"]},"audio/x-aac":{"source":"apache","compressible":false,"extensions":["aac"]},"audio/x-aiff":{"source":"apache","extensions":["aif","aiff","aifc"]},"audio/x-caf":{"source":"apache","compressible":false,"extensions":["caf"]},"audio/x-flac":{"source":"apache","extensions":["flac"]},"audio/x-m4a":{"source":"nginx","extensions":["m4a"]},"audio/x-matroska":{"source":"apache","extensions":["mka"]},"audio/x-mpegurl":{"source":"apache","extensions":["m3u"]},"audio/x-ms-wax":{"source":"apache","extensions":["wax"]},"audio/x-ms-wma":{"source":"apache","extensions":["wma"]},"audio/x-pn-realaudio":{"source":"apache","extensions":["ram","ra"]},"audio/x-pn-realaudio-plugin":{"source":"apache","extensions":["rmp"]},"audio/x-realaudio":{"source":"nginx","extensions":["ra"]},"audio/x-tta":{"source":"apache"},"audio/x-wav":{"source":"apache","extensions":["wav"]},"audio/xm":{"source":"apache","extensions":["xm"]},"chemical/x-cdx":{"source":"apache","extensions":["cdx"]},"chemical/x-cif":{"source":"apache","extensions":["cif"]},"chemical/x-cmdf":{"source":"apache","extensions":["cmdf"]},"chemical/x-cml":{"source":"apache","extensions":["cml"]},"chemical/x-csml":{"source":"apache","extensions":["csml"]},"chemical/x-pdb":{"source":"apache"},"chemical/x-xyz":{"source":"apache","extensions":["xyz"]},"font/collection":{"source":"iana","extensions":["ttc"]},"font/otf":{"source":"iana","compressible":true,"extensions":["otf"]},"font/sfnt":{"source":"iana"},"font/ttf":{"source":"iana","compressible":true,"extensions":["ttf"]},"font/woff":{"source":"iana","extensions":["woff"]},"font/woff2":{"source":"iana","extensions":["woff2"]},"image/aces":{"source":"iana","extensions":["exr"]},"image/apng":{"compressible":false,"extensions":["apng"]},"image/avci":{"source":"iana","extensions":["avci"]},"image/avcs":{"source":"iana","extensions":["avcs"]},"image/avif":{"source":"iana","compressible":false,"extensions":["avif"]},"image/bmp":{"source":"iana","compressible":true,"extensions":["bmp"]},"image/cgm":{"source":"iana","extensions":["cgm"]},"image/dicom-rle":{"source":"iana","extensions":["drle"]},"image/emf":{"source":"iana","extensions":["emf"]},"image/fits":{"source":"iana","extensions":["fits"]},"image/g3fax":{"source":"iana","extensions":["g3"]},"image/gif":{"source":"iana","compressible":false,"extensions":["gif"]},"image/heic":{"source":"iana","extensions":["heic"]},"image/heic-sequence":{"source":"iana","extensions":["heics"]},"image/heif":{"source":"iana","extensions":["heif"]},"image/heif-sequence":{"source":"iana","extensions":["heifs"]},"image/hej2k":{"source":"iana","extensions":["hej2"]},"image/hsj2":{"source":"iana","extensions":["hsj2"]},"image/ief":{"source":"iana","extensions":["ief"]},"image/jls":{"source":"iana","extensions":["jls"]},"image/jp2":{"source":"iana","compressible":false,"extensions":["jp2","jpg2"]},"image/jpeg":{"source":"iana","compressible":false,"extensions":["jpeg","jpg","jpe"]},"image/jph":{"source":"iana","extensions":["jph"]},"image/jphc":{"source":"iana","extensions":["jhc"]},"image/jpm":{"source":"iana","compressible":false,"extensions":["jpm"]},"image/jpx":{"source":"iana","compressible":false,"extensions":["jpx","jpf"]},"image/jxr":{"source":"iana","extensions":["jxr"]},"image/jxra":{"source":"iana","extensions":["jxra"]},"image/jxrs":{"source":"iana","extensions":["jxrs"]},"image/jxs":{"source":"iana","extensions":["jxs"]},"image/jxsc":{"source":"iana","extensions":["jxsc"]},"image/jxsi":{"source":"iana","extensions":["jxsi"]},"image/jxss":{"source":"iana","extensions":["jxss"]},"image/ktx":{"source":"iana","extensions":["ktx"]},"image/ktx2":{"source":"iana","extensions":["ktx2"]},"image/naplps":{"source":"iana"},"image/pjpeg":{"compressible":false},"image/png":{"source":"iana","compressible":false,"extensions":["png"]},"image/prs.btif":{"source":"iana","extensions":["btif"]},"image/prs.pti":{"source":"iana","extensions":["pti"]},"image/pwg-raster":{"source":"iana"},"image/sgi":{"source":"apache","extensions":["sgi"]},"image/svg+xml":{"source":"iana","compressible":true,"extensions":["svg","svgz"]},"image/t38":{"source":"iana","extensions":["t38"]},"image/tiff":{"source":"iana","compressible":false,"extensions":["tif","tiff"]},"image/tiff-fx":{"source":"iana","extensions":["tfx"]},"image/vnd.adobe.photoshop":{"source":"iana","compressible":true,"extensions":["psd"]},"image/vnd.airzip.accelerator.azv":{"source":"iana","extensions":["azv"]},"image/vnd.cns.inf2":{"source":"iana"},"image/vnd.dece.graphic":{"source":"iana","extensions":["uvi","uvvi","uvg","uvvg"]},"image/vnd.djvu":{"source":"iana","extensions":["djvu","djv"]},"image/vnd.dvb.subtitle":{"source":"iana","extensions":["sub"]},"image/vnd.dwg":{"source":"iana","extensions":["dwg"]},"image/vnd.dxf":{"source":"iana","extensions":["dxf"]},"image/vnd.fastbidsheet":{"source":"iana","extensions":["fbs"]},"image/vnd.fpx":{"source":"iana","extensions":["fpx"]},"image/vnd.fst":{"source":"iana","extensions":["fst"]},"image/vnd.fujixerox.edmics-mmr":{"source":"iana","extensions":["mmr"]},"image/vnd.fujixerox.edmics-rlc":{"source":"iana","extensions":["rlc"]},"image/vnd.globalgraphics.pgb":{"source":"iana"},"image/vnd.microsoft.icon":{"source":"iana","compressible":true,"extensions":["ico"]},"image/vnd.mix":{"source":"iana"},"image/vnd.mozilla.apng":{"source":"iana"},"image/vnd.ms-dds":{"compressible":true,"extensions":["dds"]},"image/vnd.ms-modi":{"source":"iana","extensions":["mdi"]},"image/vnd.ms-photo":{"source":"apache","extensions":["wdp"]},"image/vnd.net-fpx":{"source":"iana","extensions":["npx"]},"image/vnd.pco.b16":{"source":"iana","extensions":["b16"]},"image/vnd.radiance":{"source":"iana"},"image/vnd.sealed.png":{"source":"iana"},"image/vnd.sealedmedia.softseal.gif":{"source":"iana"},"image/vnd.sealedmedia.softseal.jpg":{"source":"iana"},"image/vnd.svf":{"source":"iana"},"image/vnd.tencent.tap":{"source":"iana","extensions":["tap"]},"image/vnd.valve.source.texture":{"source":"iana","extensions":["vtf"]},"image/vnd.wap.wbmp":{"source":"iana","extensions":["wbmp"]},"image/vnd.xiff":{"source":"iana","extensions":["xif"]},"image/vnd.zbrush.pcx":{"source":"iana","extensions":["pcx"]},"image/webp":{"source":"apache","extensions":["webp"]},"image/wmf":{"source":"iana","extensions":["wmf"]},"image/x-3ds":{"source":"apache","extensions":["3ds"]},"image/x-cmu-raster":{"source":"apache","extensions":["ras"]},"image/x-cmx":{"source":"apache","extensions":["cmx"]},"image/x-freehand":{"source":"apache","extensions":["fh","fhc","fh4","fh5","fh7"]},"image/x-icon":{"source":"apache","compressible":true,"extensions":["ico"]},"image/x-jng":{"source":"nginx","extensions":["jng"]},"image/x-mrsid-image":{"source":"apache","extensions":["sid"]},"image/x-ms-bmp":{"source":"nginx","compressible":true,"extensions":["bmp"]},"image/x-pcx":{"source":"apache","extensions":["pcx"]},"image/x-pict":{"source":"apache","extensions":["pic","pct"]},"image/x-portable-anymap":{"source":"apache","extensions":["pnm"]},"image/x-portable-bitmap":{"source":"apache","extensions":["pbm"]},"image/x-portable-graymap":{"source":"apache","extensions":["pgm"]},"image/x-portable-pixmap":{"source":"apache","extensions":["ppm"]},"image/x-rgb":{"source":"apache","extensions":["rgb"]},"image/x-tga":{"source":"apache","extensions":["tga"]},"image/x-xbitmap":{"source":"apache","extensions":["xbm"]},"image/x-xcf":{"compressible":false},"image/x-xpixmap":{"source":"apache","extensions":["xpm"]},"image/x-xwindowdump":{"source":"apache","extensions":["xwd"]},"message/cpim":{"source":"iana"},"message/delivery-status":{"source":"iana"},"message/disposition-notification":{"source":"iana","extensions":["disposition-notification"]},"message/external-body":{"source":"iana"},"message/feedback-report":{"source":"iana"},"message/global":{"source":"iana","extensions":["u8msg"]},"message/global-delivery-status":{"source":"iana","extensions":["u8dsn"]},"message/global-disposition-notification":{"source":"iana","extensions":["u8mdn"]},"message/global-headers":{"source":"iana","extensions":["u8hdr"]},"message/http":{"source":"iana","compressible":false},"message/imdn+xml":{"source":"iana","compressible":true},"message/news":{"source":"iana"},"message/partial":{"source":"iana","compressible":false},"message/rfc822":{"source":"iana","compressible":true,"extensions":["eml","mime"]},"message/s-http":{"source":"iana"},"message/sip":{"source":"iana"},"message/sipfrag":{"source":"iana"},"message/tracking-status":{"source":"iana"},"message/vnd.si.simp":{"source":"iana"},"message/vnd.wfa.wsc":{"source":"iana","extensions":["wsc"]},"model/3mf":{"source":"iana","extensions":["3mf"]},"model/e57":{"source":"iana"},"model/gltf+json":{"source":"iana","compressible":true,"extensions":["gltf"]},"model/gltf-binary":{"source":"iana","compressible":true,"extensions":["glb"]},"model/iges":{"source":"iana","compressible":false,"extensions":["igs","iges"]},"model/mesh":{"source":"iana","compressible":false,"extensions":["msh","mesh","silo"]},"model/mtl":{"source":"iana","extensions":["mtl"]},"model/obj":{"source":"iana","extensions":["obj"]},"model/step":{"source":"iana"},"model/step+xml":{"source":"iana","compressible":true,"extensions":["stpx"]},"model/step+zip":{"source":"iana","compressible":false,"extensions":["stpz"]},"model/step-xml+zip":{"source":"iana","compressible":false,"extensions":["stpxz"]},"model/stl":{"source":"iana","extensions":["stl"]},"model/vnd.collada+xml":{"source":"iana","compressible":true,"extensions":["dae"]},"model/vnd.dwf":{"source":"iana","extensions":["dwf"]},"model/vnd.flatland.3dml":{"source":"iana"},"model/vnd.gdl":{"source":"iana","extensions":["gdl"]},"model/vnd.gs-gdl":{"source":"apache"},"model/vnd.gs.gdl":{"source":"iana"},"model/vnd.gtw":{"source":"iana","extensions":["gtw"]},"model/vnd.moml+xml":{"source":"iana","compressible":true},"model/vnd.mts":{"source":"iana","extensions":["mts"]},"model/vnd.opengex":{"source":"iana","extensions":["ogex"]},"model/vnd.parasolid.transmit.binary":{"source":"iana","extensions":["x_b"]},"model/vnd.parasolid.transmit.text":{"source":"iana","extensions":["x_t"]},"model/vnd.pytha.pyox":{"source":"iana"},"model/vnd.rosette.annotated-data-model":{"source":"iana"},"model/vnd.sap.vds":{"source":"iana","extensions":["vds"]},"model/vnd.usdz+zip":{"source":"iana","compressible":false,"extensions":["usdz"]},"model/vnd.valve.source.compiled-map":{"source":"iana","extensions":["bsp"]},"model/vnd.vtu":{"source":"iana","extensions":["vtu"]},"model/vrml":{"source":"iana","compressible":false,"extensions":["wrl","vrml"]},"model/x3d+binary":{"source":"apache","compressible":false,"extensions":["x3db","x3dbz"]},"model/x3d+fastinfoset":{"source":"iana","extensions":["x3db"]},"model/x3d+vrml":{"source":"apache","compressible":false,"extensions":["x3dv","x3dvz"]},"model/x3d+xml":{"source":"iana","compressible":true,"extensions":["x3d","x3dz"]},"model/x3d-vrml":{"source":"iana","extensions":["x3dv"]},"multipart/alternative":{"source":"iana","compressible":false},"multipart/appledouble":{"source":"iana"},"multipart/byteranges":{"source":"iana"},"multipart/digest":{"source":"iana"},"multipart/encrypted":{"source":"iana","compressible":false},"multipart/form-data":{"source":"iana","compressible":false},"multipart/header-set":{"source":"iana"},"multipart/mixed":{"source":"iana"},"multipart/multilingual":{"source":"iana"},"multipart/parallel":{"source":"iana"},"multipart/related":{"source":"iana","compressible":false},"multipart/report":{"source":"iana"},"multipart/signed":{"source":"iana","compressible":false},"multipart/vnd.bint.med-plus":{"source":"iana"},"multipart/voice-message":{"source":"iana"},"multipart/x-mixed-replace":{"source":"iana"},"text/1d-interleaved-parityfec":{"source":"iana"},"text/cache-manifest":{"source":"iana","compressible":true,"extensions":["appcache","manifest"]},"text/calendar":{"source":"iana","extensions":["ics","ifb"]},"text/calender":{"compressible":true},"text/cmd":{"compressible":true},"text/coffeescript":{"extensions":["coffee","litcoffee"]},"text/cql":{"source":"iana"},"text/cql-expression":{"source":"iana"},"text/cql-identifier":{"source":"iana"},"text/css":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["css"]},"text/csv":{"source":"iana","compressible":true,"extensions":["csv"]},"text/csv-schema":{"source":"iana"},"text/directory":{"source":"iana"},"text/dns":{"source":"iana"},"text/ecmascript":{"source":"iana"},"text/encaprtp":{"source":"iana"},"text/enriched":{"source":"iana"},"text/fhirpath":{"source":"iana"},"text/flexfec":{"source":"iana"},"text/fwdred":{"source":"iana"},"text/gff3":{"source":"iana"},"text/grammar-ref-list":{"source":"iana"},"text/html":{"source":"iana","compressible":true,"extensions":["html","htm","shtml"]},"text/jade":{"extensions":["jade"]},"text/javascript":{"source":"iana","compressible":true},"text/jcr-cnd":{"source":"iana"},"text/jsx":{"compressible":true,"extensions":["jsx"]},"text/less":{"compressible":true,"extensions":["less"]},"text/markdown":{"source":"iana","compressible":true,"extensions":["markdown","md"]},"text/mathml":{"source":"nginx","extensions":["mml"]},"text/mdx":{"compressible":true,"extensions":["mdx"]},"text/mizar":{"source":"iana"},"text/n3":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["n3"]},"text/parameters":{"source":"iana","charset":"UTF-8"},"text/parityfec":{"source":"iana"},"text/plain":{"source":"iana","compressible":true,"extensions":["txt","text","conf","def","list","log","in","ini"]},"text/provenance-notation":{"source":"iana","charset":"UTF-8"},"text/prs.fallenstein.rst":{"source":"iana"},"text/prs.lines.tag":{"source":"iana","extensions":["dsc"]},"text/prs.prop.logic":{"source":"iana"},"text/raptorfec":{"source":"iana"},"text/red":{"source":"iana"},"text/rfc822-headers":{"source":"iana"},"text/richtext":{"source":"iana","compressible":true,"extensions":["rtx"]},"text/rtf":{"source":"iana","compressible":true,"extensions":["rtf"]},"text/rtp-enc-aescm128":{"source":"iana"},"text/rtploopback":{"source":"iana"},"text/rtx":{"source":"iana"},"text/sgml":{"source":"iana","extensions":["sgml","sgm"]},"text/shaclc":{"source":"iana"},"text/shex":{"source":"iana","extensions":["shex"]},"text/slim":{"extensions":["slim","slm"]},"text/spdx":{"source":"iana","extensions":["spdx"]},"text/strings":{"source":"iana"},"text/stylus":{"extensions":["stylus","styl"]},"text/t140":{"source":"iana"},"text/tab-separated-values":{"source":"iana","compressible":true,"extensions":["tsv"]},"text/troff":{"source":"iana","extensions":["t","tr","roff","man","me","ms"]},"text/turtle":{"source":"iana","charset":"UTF-8","extensions":["ttl"]},"text/ulpfec":{"source":"iana"},"text/uri-list":{"source":"iana","compressible":true,"extensions":["uri","uris","urls"]},"text/vcard":{"source":"iana","compressible":true,"extensions":["vcard"]},"text/vnd.a":{"source":"iana"},"text/vnd.abc":{"source":"iana"},"text/vnd.ascii-art":{"source":"iana"},"text/vnd.curl":{"source":"iana","extensions":["curl"]},"text/vnd.curl.dcurl":{"source":"apache","extensions":["dcurl"]},"text/vnd.curl.mcurl":{"source":"apache","extensions":["mcurl"]},"text/vnd.curl.scurl":{"source":"apache","extensions":["scurl"]},"text/vnd.debian.copyright":{"source":"iana","charset":"UTF-8"},"text/vnd.dmclientscript":{"source":"iana"},"text/vnd.dvb.subtitle":{"source":"iana","extensions":["sub"]},"text/vnd.esmertec.theme-descriptor":{"source":"iana","charset":"UTF-8"},"text/vnd.familysearch.gedcom":{"source":"iana","extensions":["ged"]},"text/vnd.ficlab.flt":{"source":"iana"},"text/vnd.fly":{"source":"iana","extensions":["fly"]},"text/vnd.fmi.flexstor":{"source":"iana","extensions":["flx"]},"text/vnd.gml":{"source":"iana"},"text/vnd.graphviz":{"source":"iana","extensions":["gv"]},"text/vnd.hans":{"source":"iana"},"text/vnd.hgl":{"source":"iana"},"text/vnd.in3d.3dml":{"source":"iana","extensions":["3dml"]},"text/vnd.in3d.spot":{"source":"iana","extensions":["spot"]},"text/vnd.iptc.newsml":{"source":"iana"},"text/vnd.iptc.nitf":{"source":"iana"},"text/vnd.latex-z":{"source":"iana"},"text/vnd.motorola.reflex":{"source":"iana"},"text/vnd.ms-mediapackage":{"source":"iana"},"text/vnd.net2phone.commcenter.command":{"source":"iana"},"text/vnd.radisys.msml-basic-layout":{"source":"iana"},"text/vnd.senx.warpscript":{"source":"iana"},"text/vnd.si.uricatalogue":{"source":"iana"},"text/vnd.sosi":{"source":"iana"},"text/vnd.sun.j2me.app-descriptor":{"source":"iana","charset":"UTF-8","extensions":["jad"]},"text/vnd.trolltech.linguist":{"source":"iana","charset":"UTF-8"},"text/vnd.wap.si":{"source":"iana"},"text/vnd.wap.sl":{"source":"iana"},"text/vnd.wap.wml":{"source":"iana","extensions":["wml"]},"text/vnd.wap.wmlscript":{"source":"iana","extensions":["wmls"]},"text/vtt":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["vtt"]},"text/x-asm":{"source":"apache","extensions":["s","asm"]},"text/x-c":{"source":"apache","extensions":["c","cc","cxx","cpp","h","hh","dic"]},"text/x-component":{"source":"nginx","extensions":["htc"]},"text/x-fortran":{"source":"apache","extensions":["f","for","f77","f90"]},"text/x-gwt-rpc":{"compressible":true},"text/x-handlebars-template":{"extensions":["hbs"]},"text/x-java-source":{"source":"apache","extensions":["java"]},"text/x-jquery-tmpl":{"compressible":true},"text/x-lua":{"extensions":["lua"]},"text/x-markdown":{"compressible":true,"extensions":["mkd"]},"text/x-nfo":{"source":"apache","extensions":["nfo"]},"text/x-opml":{"source":"apache","extensions":["opml"]},"text/x-org":{"compressible":true,"extensions":["org"]},"text/x-pascal":{"source":"apache","extensions":["p","pas"]},"text/x-processing":{"compressible":true,"extensions":["pde"]},"text/x-sass":{"extensions":["sass"]},"text/x-scss":{"extensions":["scss"]},"text/x-setext":{"source":"apache","extensions":["etx"]},"text/x-sfv":{"source":"apache","extensions":["sfv"]},"text/x-suse-ymp":{"compressible":true,"extensions":["ymp"]},"text/x-uuencode":{"source":"apache","extensions":["uu"]},"text/x-vcalendar":{"source":"apache","extensions":["vcs"]},"text/x-vcard":{"source":"apache","extensions":["vcf"]},"text/xml":{"source":"iana","compressible":true,"extensions":["xml"]},"text/xml-external-parsed-entity":{"source":"iana"},"text/yaml":{"compressible":true,"extensions":["yaml","yml"]},"video/1d-interleaved-parityfec":{"source":"iana"},"video/3gpp":{"source":"iana","extensions":["3gp","3gpp"]},"video/3gpp-tt":{"source":"iana"},"video/3gpp2":{"source":"iana","extensions":["3g2"]},"video/av1":{"source":"iana"},"video/bmpeg":{"source":"iana"},"video/bt656":{"source":"iana"},"video/celb":{"source":"iana"},"video/dv":{"source":"iana"},"video/encaprtp":{"source":"iana"},"video/ffv1":{"source":"iana"},"video/flexfec":{"source":"iana"},"video/h261":{"source":"iana","extensions":["h261"]},"video/h263":{"source":"iana","extensions":["h263"]},"video/h263-1998":{"source":"iana"},"video/h263-2000":{"source":"iana"},"video/h264":{"source":"iana","extensions":["h264"]},"video/h264-rcdo":{"source":"iana"},"video/h264-svc":{"source":"iana"},"video/h265":{"source":"iana"},"video/iso.segment":{"source":"iana","extensions":["m4s"]},"video/jpeg":{"source":"iana","extensions":["jpgv"]},"video/jpeg2000":{"source":"iana"},"video/jpm":{"source":"apache","extensions":["jpm","jpgm"]},"video/jxsv":{"source":"iana"},"video/mj2":{"source":"iana","extensions":["mj2","mjp2"]},"video/mp1s":{"source":"iana"},"video/mp2p":{"source":"iana"},"video/mp2t":{"source":"iana","extensions":["ts"]},"video/mp4":{"source":"iana","compressible":false,"extensions":["mp4","mp4v","mpg4"]},"video/mp4v-es":{"source":"iana"},"video/mpeg":{"source":"iana","compressible":false,"extensions":["mpeg","mpg","mpe","m1v","m2v"]},"video/mpeg4-generic":{"source":"iana"},"video/mpv":{"source":"iana"},"video/nv":{"source":"iana"},"video/ogg":{"source":"iana","compressible":false,"extensions":["ogv"]},"video/parityfec":{"source":"iana"},"video/pointer":{"source":"iana"},"video/quicktime":{"source":"iana","compressible":false,"extensions":["qt","mov"]},"video/raptorfec":{"source":"iana"},"video/raw":{"source":"iana"},"video/rtp-enc-aescm128":{"source":"iana"},"video/rtploopback":{"source":"iana"},"video/rtx":{"source":"iana"},"video/scip":{"source":"iana"},"video/smpte291":{"source":"iana"},"video/smpte292m":{"source":"iana"},"video/ulpfec":{"source":"iana"},"video/vc1":{"source":"iana"},"video/vc2":{"source":"iana"},"video/vnd.cctv":{"source":"iana"},"video/vnd.dece.hd":{"source":"iana","extensions":["uvh","uvvh"]},"video/vnd.dece.mobile":{"source":"iana","extensions":["uvm","uvvm"]},"video/vnd.dece.mp4":{"source":"iana"},"video/vnd.dece.pd":{"source":"iana","extensions":["uvp","uvvp"]},"video/vnd.dece.sd":{"source":"iana","extensions":["uvs","uvvs"]},"video/vnd.dece.video":{"source":"iana","extensions":["uvv","uvvv"]},"video/vnd.directv.mpeg":{"source":"iana"},"video/vnd.directv.mpeg-tts":{"source":"iana"},"video/vnd.dlna.mpeg-tts":{"source":"iana"},"video/vnd.dvb.file":{"source":"iana","extensions":["dvb"]},"video/vnd.fvt":{"source":"iana","extensions":["fvt"]},"video/vnd.hns.video":{"source":"iana"},"video/vnd.iptvforum.1dparityfec-1010":{"source":"iana"},"video/vnd.iptvforum.1dparityfec-2005":{"source":"iana"},"video/vnd.iptvforum.2dparityfec-1010":{"source":"iana"},"video/vnd.iptvforum.2dparityfec-2005":{"source":"iana"},"video/vnd.iptvforum.ttsavc":{"source":"iana"},"video/vnd.iptvforum.ttsmpeg2":{"source":"iana"},"video/vnd.motorola.video":{"source":"iana"},"video/vnd.motorola.videop":{"source":"iana"},"video/vnd.mpegurl":{"source":"iana","extensions":["mxu","m4u"]},"video/vnd.ms-playready.media.pyv":{"source":"iana","extensions":["pyv"]},"video/vnd.nokia.interleaved-multimedia":{"source":"iana"},"video/vnd.nokia.mp4vr":{"source":"iana"},"video/vnd.nokia.videovoip":{"source":"iana"},"video/vnd.objectvideo":{"source":"iana"},"video/vnd.radgamettools.bink":{"source":"iana"},"video/vnd.radgamettools.smacker":{"source":"iana"},"video/vnd.sealed.mpeg1":{"source":"iana"},"video/vnd.sealed.mpeg4":{"source":"iana"},"video/vnd.sealed.swf":{"source":"iana"},"video/vnd.sealedmedia.softseal.mov":{"source":"iana"},"video/vnd.uvvu.mp4":{"source":"iana","extensions":["uvu","uvvu"]},"video/vnd.vivo":{"source":"iana","extensions":["viv"]},"video/vnd.youtube.yt":{"source":"iana"},"video/vp8":{"source":"iana"},"video/vp9":{"source":"iana"},"video/webm":{"source":"apache","compressible":false,"extensions":["webm"]},"video/x-f4v":{"source":"apache","extensions":["f4v"]},"video/x-fli":{"source":"apache","extensions":["fli"]},"video/x-flv":{"source":"apache","compressible":false,"extensions":["flv"]},"video/x-m4v":{"source":"apache","extensions":["m4v"]},"video/x-matroska":{"source":"apache","compressible":false,"extensions":["mkv","mk3d","mks"]},"video/x-mng":{"source":"apache","extensions":["mng"]},"video/x-ms-asf":{"source":"apache","extensions":["asf","asx"]},"video/x-ms-vob":{"source":"apache","extensions":["vob"]},"video/x-ms-wm":{"source":"apache","extensions":["wm"]},"video/x-ms-wmv":{"source":"apache","compressible":false,"extensions":["wmv"]},"video/x-ms-wmx":{"source":"apache","extensions":["wmx"]},"video/x-ms-wvx":{"source":"apache","extensions":["wvx"]},"video/x-msvideo":{"source":"apache","extensions":["avi"]},"video/x-sgi-movie":{"source":"apache","extensions":["movie"]},"video/x-smv":{"source":"apache","extensions":["smv"]},"x-conference/x-cooltalk":{"source":"apache","extensions":["ice"]},"x-shader/x-fragment":{"compressible":true},"x-shader/x-vertex":{"compressible":true}}'); -// API -module.exports = async; +/***/ }) -/** - * Runs provided callback asynchronously - * even if callback itself is not +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __nccwpck_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ var threw = true; +/******/ try { +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __nccwpck_require__); +/******/ threw = false; +/******/ } finally { +/******/ if(threw) delete __webpack_module_cache__[moduleId]; +/******/ } +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/compat */ +/******/ +/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/"; +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { +/*! + * Copyright 2021 Google Inc. * - * @param {function} callback - callback to invoke - * @returns {function} - augmented callback + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ -function async(callback) -{ - var isAsync = false; - // check if async happened - defer(function() { isAsync = true; }); +const core = __nccwpck_require__(2186); +const formData = __nccwpck_require__(5685); +const Mailgun = __nccwpck_require__(5046); - return function async_callback(err, result) - { - if (isAsync) - { - callback(err, result); - } - else - { - defer(function nextTick_callback() - { - callback(err, result); - }); +const mailgun = new Mailgun(formData); +const optionalFields = ['cc', 'text', 'html']; + +function loadConfig() { + return { + apiKey: core.getInput('api-key'), + domain: core.getInput('domain'), + to: core.getInput('to'), + from: core.getInput('from'), + cc: core.getInput('cc'), + subject: core.getInput('subject'), + text: core.getInput('text'), + html: core.getInput('html'), + } +} + +function validate(config) { + for (param in config) { + if (optionalFields.includes(param)) { + continue; } - }; + validateRequiredParameter(config[param], `'${param}'`); + } } +function validateRequiredParameter(value, name) { + if (!isNonEmptyString(value)) { + throw new Error(`${name} must be a non-empty string.`); + } +} -/***/ }), +function sendEmail(config) { + const mg = mailgun.client({ + username: 'api', + key: config.apiKey, + }); -/***/ 835: -/***/ (function(module) { + return mg.messages + .create(config.domain, { + from: config.from, + to: config.to, + cc: config.cc, + subject: config.subject, + text: config.text, + html: config.html, + }) + .then((resp) => { + core.setOutput('response', resp.message); + return; + }) + .catch((err) => { + core.setFailed(err.message); + }); +} -module.exports = require("url"); +function isNonEmptyString(value) { + return typeof value === 'string' && value !== ''; +} -/***/ }) +const config = loadConfig(); +validate(config); +sendEmail(config); + +})(); -/******/ }); \ No newline at end of file +module.exports = __webpack_exports__; +/******/ })() +; \ No newline at end of file diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 7c585c79c0..3efe8ace25 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -1,109 +1,299 @@ { "name": "send-email", - "version": "1.0.0", - "lockfileVersion": 1, + "version": "1.0.1", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@actions/core": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", - "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", - "requires": { + "packages": { + "": { + "name": "send-email", + "version": "1.0.1", + "license": "Apache-2.0", + "dependencies": { + "@actions/core": "^1.10.1", + "mailgun.js": "^3.3.0" + }, + "devDependencies": { + "@vercel/ncc": "^0.38.1" + } + }, + "node_modules/@actions/core": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.1.tgz", + "integrity": "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==", + "dependencies": { "@actions/http-client": "^2.0.1", "uuid": "^8.3.2" } }, - "@actions/http-client": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz", - "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==", - "requires": { - "tunnel": "^0.0.6" + "node_modules/@actions/http-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz", + "integrity": "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==", + "dependencies": { + "tunnel": "^0.0.6", + "undici": "^5.25.4" } }, - "@zeit/ncc": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@zeit/ncc/-/ncc-0.21.1.tgz", - "integrity": "sha512-M9WzgquSOt2nsjRkYM9LRylBLmmlwNCwYbm3Up3PDEshfvdmIfqpFNSK8EJvR18NwZjGHE5z2avlDtYQx2JQnw==", - "dev": true + "node_modules/@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@vercel/ncc": { + "version": "0.38.1", + "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.1.tgz", + "integrity": "sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==", + "dev": true, + "bin": { + "ncc": "dist/ncc/cli.js" + } }, - "abort-controller": { + "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { + "dependencies": { "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" } }, - "bluebird": { + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" + }, + "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "btoa": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", - "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "clone-deep": { + "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { + "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "event-target-shim": { + "node_modules/data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } }, - "fetch-blob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.1.tgz", - "integrity": "sha512-Uf+gxPCe1hTOFXwkxYyckn8iUSk6CFXGy5VENZKifovUTZC9eUODWSBhOBS7zICGrAetKzdwLMr85KhIcePMAQ==" + "node_modules/fetch-blob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", + "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==", + "engines": { + "node": "^10.17.0 || >=12.3.0" + }, + "peerDependenciesMeta": { + "domexception": { + "optional": true + } + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-plain-object": { + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { + "dependencies": { "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "isobject": { + "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } }, - "kind-of": { + "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } }, - "ky": { + "node_modules/ky": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/ky/-/ky-0.25.1.tgz", - "integrity": "sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA==" + "integrity": "sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } }, - "ky-universal": { + "node_modules/ky-universal": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.8.2.tgz", "integrity": "sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ==", - "requires": { + "dependencies": { "abort-controller": "^3.0.0", "node-fetch": "3.0.0-beta.9" + }, + "engines": { + "node": ">=10.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky-universal?sponsor=1" + }, + "peerDependencies": { + "ky": ">=0.17.0", + "web-streams-polyfill": ">=2.0.0" + }, + "peerDependenciesMeta": { + "web-streams-polyfill": { + "optional": true + } } }, - "mailgun.js": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-3.3.0.tgz", - "integrity": "sha512-Ikcl9Lp18oXu8/ht6Ow3b2yRYBEa4S70YvquOM2O4FA4NDboa8btZIMEQRRFAmBEfEbWOPrl/Z6E8kL8vnyonQ==", - "requires": { + "node_modules/mailgun.js": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-3.7.3.tgz", + "integrity": "sha512-DHP9v6dNPRM2puOx4HVJVjQKWzgzpQ5Fh1ICW632qaDVgd/QqGRhOjCoHe12JJqrFkhgDvXBhENYeZDHYdkJHQ==", + "dependencies": { + "base-64": "^1.0.0", "bluebird": "^3.7.2", - "btoa": "^1.1.2", "ky": "^0.25.1", "ky-universal": "^0.8.2", "url": "^0.11.0", @@ -112,84 +302,153 @@ "webpack-merge": "^5.4.0" } }, - "node-fetch": { + "node_modules/node-fetch": { "version": "3.0.0-beta.9", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0-beta.9.tgz", "integrity": "sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==", - "requires": { + "dependencies": { "data-uri-to-buffer": "^3.0.1", "fetch-blob": "^2.1.1" }, + "engines": { + "node": "^10.17 || >=12.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", "dependencies": { - "data-uri-to-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", - "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==" - } + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } }, - "shallow-clone": { + "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { + "dependencies": { "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "tunnel": { + "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" + "node_modules/undici": { + "version": "5.28.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", + "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==", + "dependencies": { + "@fastify/busboy": "^2.0.0" }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } + "punycode": "^1.4.1", + "qs": "^6.11.2" } }, - "url-join": { + "node_modules/url-join": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", - "integrity": "sha1-HbSK1CLTQCRpqH99l73r/k+x48g=" + "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==" }, - "uuid": { + "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "web-streams-polyfill": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.0.2.tgz", - "integrity": "sha512-JTNkNbAKoSo8NKiqu2UUaqRFCDWWZaCOsXuJEsToWopikTA0YHKKUf91GNkS/SnD8JixOkJjVsiacNlrFnRECA==" - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "requires": { + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", + "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dependencies": { "clone-deep": "^4.0.1", + "flat": "^5.0.2", "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" } }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" } } } diff --git a/.github/actions/send-email/package.json b/.github/actions/send-email/package.json index e35ba448a1..088f74f9ea 100644 --- a/.github/actions/send-email/package.json +++ b/.github/actions/send-email/package.json @@ -1,6 +1,6 @@ { "name": "send-email", - "version": "1.0.0", + "version": "1.0.1", "description": "Send Emails from GitHub Actions workflows using Mailgun.", "main": "index.js", "scripts": { @@ -14,10 +14,10 @@ "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", "dependencies": { - "@actions/core": "^1.9.1", + "@actions/core": "^1.10.1", "mailgun.js": "^3.3.0" }, "devDependencies": { - "@zeit/ncc": "^0.21.1" + "@vercel/ncc": "^0.38.1" } } From 4f585dd6b8bf8766ba4f3ba8a308b494d147683d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 11:37:46 -0500 Subject: [PATCH 054/323] build(deps-dev): bump @types/sinon from 17.0.2 to 17.0.3 (#2442) Bumps [@types/sinon](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon) from 17.0.2 to 17.0.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/sinon) --- updated-dependencies: - dependency-name: "@types/sinon" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61fd1e6231..467700cef8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1479,9 +1479,9 @@ } }, "@types/sinon": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.2.tgz", - "integrity": "sha512-Zt6heIGsdqERkxctIpvN5Pv3edgBrhoeb3yHyxffd4InN0AX2SVNKSrhdDZKGQICVOxWP/q4DyhpfPNMSrpIiA==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" From 4dc035bf38551773397f91e129acce5b1eb20024 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 16:43:32 +0000 Subject: [PATCH 055/323] build(deps-dev): bump @firebase/app-compat from 0.2.25 to 0.2.27 (#2443) --- package-lock.json | 64 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 467700cef8..1599ff4ddf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -477,16 +477,37 @@ } }, "@firebase/app": { - "version": "0.9.25", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.25.tgz", - "integrity": "sha512-fX22gL5USXhOK21Hlh3oTeOzQZ6th6S2JrjXNEpBARmwzuUkqmVGVdsOCIFYIsLpK0dQE3o8xZnLrRg5wnzZ/g==", + "version": "0.9.27", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.27.tgz", + "integrity": "sha512-p2Dvl1ge4kRsyK5+wWcmdAIE9MSwZ0pDKAYB51LZgZuz6wciUZk4E1yAEdkfQlRxuHehn+Ol9WP5Qk2XQZiHGg==", "dev": true, "requires": { - "@firebase/component": "0.6.4", + "@firebase/component": "0.6.5", "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.3", + "@firebase/util": "1.9.4", "idb": "7.1.1", "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/component": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz", + "integrity": "sha512-2tVDk1ixi12sbDmmfITK8lxSjmcb73BMF6Qwc3U44hN/J1Fi1QY/Hnnb6klFlbB9/G16a3J3d4nXykye2EADTw==", + "dev": true, + "requires": { + "@firebase/util": "1.9.4", + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", + "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } } }, "@firebase/app-check-interop-types": { @@ -495,16 +516,37 @@ "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" }, "@firebase/app-compat": { - "version": "0.2.25", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.25.tgz", - "integrity": "sha512-B/JtCp1FsTuzlh1tIGQpYM2AXps21/zlzpFsk5LRsROOTRhBcR2N45AyaONPFD06C0yS0Tw19foxADzHyOSC3A==", + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.27.tgz", + "integrity": "sha512-SYlqocfUDKPHR6MSFC8hree0BTiWFu5o8wbf6zFlYXyG41w7TcHp4wJi4H/EL5V6cM4kxwruXTJtqXX/fRAZtw==", "dev": true, "requires": { - "@firebase/app": "0.9.25", - "@firebase/component": "0.6.4", + "@firebase/app": "0.9.27", + "@firebase/component": "0.6.5", "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.3", + "@firebase/util": "1.9.4", "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/component": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz", + "integrity": "sha512-2tVDk1ixi12sbDmmfITK8lxSjmcb73BMF6Qwc3U44hN/J1Fi1QY/Hnnb6klFlbB9/G16a3J3d4nXykye2EADTw==", + "dev": true, + "requires": { + "@firebase/util": "1.9.4", + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", + "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } } }, "@firebase/app-types": { From 2536e2f4786a34dde9d0c5103c35d08328efb1d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 17:17:19 +0000 Subject: [PATCH 056/323] build(deps-dev): bump @types/uuid from 9.0.7 to 9.0.8 (#2445) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1599ff4ddf..f5096e7279 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1551,9 +1551,9 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" }, "@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", "dev": true }, "@typescript-eslint/eslint-plugin": { From 910460d213f276df955442119ac90083e2836c6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 17:22:04 +0000 Subject: [PATCH 057/323] build(deps): bump @google-cloud/firestore from 7.1.0 to 7.3.0 (#2446) --- package-lock.json | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5096e7279..5fe3a93dae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ } }, "@google-cloud/firestore": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.1.0.tgz", - "integrity": "sha512-kkTC0Sb9r2lONuFF8Tr2wFfBfk0DT1/EKcTKOhsuoXUVClv3jCqGYVPtHgQsHFjdOsubS+tx9G5D5WG+obB2DA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.3.0.tgz", + "integrity": "sha512-2IftQLAbCuVp0nTd3neeu+d3OYIegJpV/V9R4USQj51LzJcXPe8h8jZ7j3+svSNhJVGy6JsN0T1QqlJdMDhTwg==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -743,9 +743,9 @@ } }, "@grpc/grpc-js": { - "version": "1.9.12", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.12.tgz", - "integrity": "sha512-Um5MBuge32TS3lAKX02PGCnFM4xPT996yLgZNb5H03pn6NyJ4Iwn5YcPq6Jj9yxGRk7WOgaZFtVRH5iTdYBeUg==", + "version": "1.9.14", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.14.tgz", + "integrity": "sha512-nOpuzZ2G3IuMFN+UPPpKrC6NsLmWsTqSsm66IRfnBt1D4pwTqE27lmbpcPM+l2Ua4gE7PfjRHI6uedAy7hoXUw==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.8", @@ -4564,9 +4564,9 @@ } }, "google-gax": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.0.5.tgz", - "integrity": "sha512-yLoYtp4zE+8OQA74oBEbNkbzI6c95W01JSL7RqC8XERKpRvj3ytZp1dgnbA6G9aRsc8pZB25xWYBcCmrbYOEhA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.0.tgz", + "integrity": "sha512-SWHX72gbccNfpPoeTkNmZJxmLyKWeLr0+5Ch6qtrf4oAN8KFXnyXe5EixatILnJWufM3L59MRZ4hSJWVJ3IQqw==", "optional": true, "requires": { "@grpc/grpc-js": "~1.9.6", @@ -4578,8 +4578,9 @@ "node-fetch": "^2.6.1", "object-hash": "^3.0.0", "proto3-json-serializer": "^2.0.0", - "protobufjs": "7.2.5", - "retry-request": "^7.0.0" + "protobufjs": "7.2.6", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" } }, "gopd": { @@ -7702,18 +7703,18 @@ "dev": true }, "proto3-json-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.0.tgz", - "integrity": "sha512-FB/YaNrpiPkyQNSNPilpn8qn0KdEfkgmJ9JP93PQyF/U4bAiXY5BiUdDhiDO4S48uSQ6AesklgVlrKiqZPzegw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz", + "integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==", "optional": true, "requires": { - "protobufjs": "^7.0.0" + "protobufjs": "^7.2.5" } }, "protobufjs": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", - "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", "optional": true, "requires": { "@protobufjs/aspromise": "^1.1.2", From 4d966837eed11ce85175c490bfeda1786da00468 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 8 Feb 2024 08:45:57 -0500 Subject: [PATCH 058/323] [chore] Bump `mailgun.js` to `v10.1.0` (#2451) * Test mailgun update * remove send-email, used for verifying, from ci --- .github/actions/send-email/dist/index.js | 38592 +++++++++-------- .github/actions/send-email/package-lock.json | 395 +- .github/actions/send-email/package.json | 2 +- 3 files changed, 19378 insertions(+), 19611 deletions(-) diff --git a/.github/actions/send-email/dist/index.js b/.github/actions/send-email/dist/index.js index 410dda0a18..c7529cc1dd 100644 --- a/.github/actions/send-email/dist/index.js +++ b/.github/actions/send-email/dist/index.js @@ -1834,24372 +1834,24390 @@ function isLoopbackAddress(host) { /***/ }), -/***/ 5046: -/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) { - -/*! For license information please see mailgun.node.js.LICENSE.txt */ -!function(e,t){ true?module.exports=t():0}(this,(function(){return(()=>{var e={271:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=r(185);class AbortSignal extends o.EventTarget{constructor(){throw super(),new TypeError("AbortSignal cannot be constructed directly")}get aborted(){const e=n.get(this);if("boolean"!=typeof e)throw new TypeError("Expected 'this' to be an 'AbortSignal' object, but got "+(null===this?"null":typeof this));return e}}o.defineEventAttribute(AbortSignal.prototype,"abort");const n=new WeakMap;Object.defineProperties(AbortSignal.prototype,{aborted:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(AbortSignal.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortSignal"});class AbortController{constructor(){s.set(this,function(){const e=Object.create(AbortSignal.prototype);return o.EventTarget.call(e),n.set(e,!1),e}())}get signal(){return i(this)}abort(){var e;e=i(this),!1===n.get(e)&&(n.set(e,!0),e.dispatchEvent({type:"abort"}))}}const s=new WeakMap;function i(e){const t=s.get(e);if(null==t)throw new TypeError("Expected 'this' to be an 'AbortController' object, but got "+(null===e?"null":typeof e));return t}Object.defineProperties(AbortController.prototype,{signal:{enumerable:!0},abort:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(AbortController.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortController"}),t.AbortController=AbortController,t.AbortSignal=AbortSignal,t.default=AbortController,e.exports=AbortController,e.exports.AbortController=e.exports.default=AbortController,e.exports.AbortSignal=AbortSignal},48:function(e,t,r){"use strict";var o=(this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}})(r(475)),n=function(){function e(e){this.formData=e}return e.prototype.client=function(e){return new o.default(e,this.formData)},e}();e.exports=n},475:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){var t=this;return this.request.get("/v1/ip_pools",e).then((function(e){return t.parseIpPoolsResponse(e)}))},e.prototype.create=function(e){return this.request.post("/v1/ip_pools",e).then((function(e){return null==e?void 0:e.body}))},e.prototype.update=function(e,t){return this.request.patch("/v1/ip_pools/"+e,t).then((function(e){return null==e?void 0:e.body}))},e.prototype.delete=function(e,t){return this.request.delete("/v1/ip_pools/"+e,t).then((function(e){return null==e?void 0:e.body}))},e.prototype.parseIpPoolsResponse=function(e){return e.body.ip_pools},e}();t.default=r},345:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){var t=this;return this.request.get("/v3/ips",e).then((function(e){return t.parseIpsResponse(e)}))},e.prototype.get=function(e){var t=this;return this.request.get("/v3/ips/"+e).then((function(e){return t.parseIpsResponse(e)}))},e.prototype.parseIpsResponse=function(e){return e.body},e}();t.default=r},126:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){this.request=e,this.baseRoute="/v3/lists",this.members=t}return e.prototype.list=function(e){return this.request.get(this.baseRoute+"/pages",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get(this.baseRoute+"/"+e).then((function(e){return e.body.list}))},e.prototype.create=function(e){return this.request.postWithFD(this.baseRoute,e).then((function(e){return e.body.list}))},e.prototype.update=function(e,t){return this.request.putWithFD(this.baseRoute+"/"+e,t).then((function(e){return e.body.list}))},e.prototype.destroy=function(e){return this.request.delete(this.baseRoute+"/"+e).then((function(e){return e.body}))},e}();t.default=r},135:function(e,t){"use strict";var r=this&&this.__assign||function(){return r=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype._parseResponse=function(e){return e.body?e.body:e},e.prototype.create=function(e,t){return t.message?this.request.postWithFD("/v3/"+e+"/messages.mime",t).then(this._parseResponse):this.request.postWithFD("/v3/"+e+"/messages",t).then(this._parseResponse)},e}();t.default=r},826:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.get=function(e,t){var r={};return Array.isArray(e)?r.addresses=e.join(","):r.addresses=e,t&&(r.syntax_only=!1),this.request.get("/v3/address/parse",r).then((function(e){return e.body}))},e}();t.default=r},438:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r0&&n[n.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!n||s[1]>n[0]&&s[1]0&&(p.searchParams=n.query,delete p.query),[4,(0,l.default)((0,u.default)(this.url,t),o({method:e.toLocaleUpperCase(),headers:f,throwHttpErrors:!1,timeout:this.timeout},p))];case 1:return(null==(h=s.sent())?void 0:h.ok)?[3,6]:(null==h?void 0:h.body)&&d(h.body)?[4,(_=h.body,g=[],new Promise((function(e,t){_.on("data",(function(e){return g.push(e)})),_.on("error",t),_.on("end",(function(){return e(Buffer.concat(g).toString("utf8"))}))})))]:[3,3];case 2:return y=s.sent(),[3,5];case 3:return[4,null==h?void 0:h.json()];case 4:y=s.sent(),s.label=5;case 5:throw b=y,new c.default({status:null==h?void 0:h.status,statusText:null==h?void 0:h.statusText,body:{message:b}});case 6:return m={},[4,null==h?void 0:h.json()];case 7:return[2,(m.body=s.sent(),m.status=null==h?void 0:h.status,m)]}var _,g}))}))},e.prototype.query=function(e,t,r,n){return this.request(e,t,o({query:r},n))},e.prototype.command=function(e,t,r,n){return this.request(e,t,o({headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r},n))},e.prototype.get=function(e,t,r){return this.query("get",e,t,r)},e.prototype.head=function(e,t,r){return this.query("head",e,t,r)},e.prototype.options=function(e,t,r){return this.query("options",e,t,r)},e.prototype.post=function(e,t,r){return this.command("post",e,t,r)},e.prototype.postWithFD=function(e,t){var r=this.createFormData(t);return this.command("post",e,r,{headers:{"Content-Type":null}})},e.prototype.putWithFD=function(e,t){var r=this.createFormData(t);return this.command("put",e,r,{headers:{"Content-Type":null}})},e.prototype.createFormData=function(e){var t=function(e,t,r){var n=d(t)?t:t.data,s=function(e){if("object"!=typeof e||d(e))return{};var t=e.filename,r=e.contentType,n=e.knownLength;return o(o(o({},t?{filename:t}:{filename:"file"}),r&&{contentType:r}),n&&{knownLength:n})}(t);!function(e){return void 0!==e.getHeaders}(r)?r.append(e,n,s.filename):r.append(e,n,s)};return Object.keys(e).filter((function(t){return e[t]})).reduce((function(r,o){if("attachment"===o||"inline"===o){var n=e[o];return Array.isArray(n)?n.forEach((function(e){t(o,e,r)})):t(o,n,r),r}return Array.isArray(e[o])?e[o].forEach((function(e){r.append(o,e)})):null!=e[o]&&r.append(o,e[o]),r}),new this.formData)},e.prototype.put=function(e,t,r){return this.command("put",e,t,r)},e.prototype.patch=function(e,t,r){return this.command("patch",e,t,r)},e.prototype.delete=function(e,t,r){return this.command("delete",e,t,r)},e}();t.default=f},277:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.list=function(e){return this.request.get("/v3/routes",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get("/v3/routes/"+e).then((function(e){return e.body.route}))},e.prototype.create=function(e){return this.request.postWithFD("/v3/routes",e).then((function(e){return e.body.route}))},e.prototype.update=function(e,t){return this.request.putWithFD("/v3/routes/"+e,t).then((function(e){return e.body}))},e.prototype.destroy=function(e){return this.request.delete("/v3/routes/"+e).then((function(e){return e.body}))},e}();t.default=r},747:function(e,t,r){"use strict";var o=this&&this.__assign||function(){return o=Object.assign||function(e){for(var t,r=1,o=arguments.length;r{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e){this.request=e}return e.prototype.get=function(e){return this.request.get("/v3/address/validate",{address:e}).then((function(e){return e.body}))},e}();t.default=r},750:function(e,t,r){"use strict";var o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var n=o(r(78)),s=function(e,t){this.id=e,this.url=t},i=function(){function e(e){this.request=e}return e.prototype._parseWebhookList=function(e){return e.body.webhooks},e.prototype._parseWebhookWithID=function(e){return function(t){var r,o=null===(r=null==t?void 0:t.body)||void 0===r?void 0:r.webhook,n=null==o?void 0:o.url;return n||(n=(null==o?void 0:o.urls)&&o.urls.length?o.urls[0]:null),new s(e,n)}},e.prototype._parseWebhookTest=function(e){return{code:e.body.code,message:e.body.message}},e.prototype.list=function(e,t){return this.request.get((0,n.default)("/v2/domains",e,"webhooks"),t).then(this._parseWebhookList)},e.prototype.get=function(e,t){return this.request.get((0,n.default)("/v2/domains",e,"webhooks",t)).then(this._parseWebhookWithID(t))},e.prototype.create=function(e,t,r,o){return void 0===o&&(o=!1),o?this.request.putWithFD((0,n.default)("/v2/domains",e,"webhooks",t,"test"),{url:r}).then(this._parseWebhookTest):this.request.postWithFD((0,n.default)("/v2/domains",e,"webhooks"),{id:t,url:r}).then(this._parseWebhookWithID(t))},e.prototype.update=function(e,t,r){return this.request.putWithFD((0,n.default)("/v2/domains",e,"webhooks",t),{url:r}).then(this._parseWebhookWithID(t))},e.prototype.destroy=function(e,t){return this.request.delete((0,n.default)("/v2/domains",e,"webhooks",t)).then(this._parseWebhookWithID(t))},e}();t.default=i},501:function(e,t,r){var o;e=r.nmd(e),function(n){var s=t,i=(e&&e.exports,"object"==typeof global&&global);i.global!==i&&i.window;var a=function(e){this.message=e};(a.prototype=new Error).name="InvalidCharacterError";var u=function(e){throw new a(e)},l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=/[\t\n\f\r ]/g,d={encode:function(e){e=String(e),/[^\0-\xFF]/.test(e)&&u("The string to be encoded contains characters outside of the Latin1 range.");for(var t,r,o,n,s=e.length%3,i="",a=-1,c=e.length-s;++a>18&63)+l.charAt(n>>12&63)+l.charAt(n>>6&63)+l.charAt(63&n);return 2==s?(t=e.charCodeAt(a)<<8,r=e.charCodeAt(++a),i+=l.charAt((n=t+r)>>10)+l.charAt(n>>4&63)+l.charAt(n<<2&63)+"="):1==s&&(n=e.charCodeAt(a),i+=l.charAt(n>>2)+l.charAt(n<<4&63)+"=="),i},decode:function(e){var t=(e=String(e).replace(c,"")).length;t%4==0&&(t=(e=e.replace(/==?$/,"")).length),(t%4==1||/[^+a-zA-Z0-9/]/.test(e))&&u("Invalid character: the string to be decoded is not correctly encoded.");for(var r,o,n=0,s="",i=-1;++i>(-2*n&6)));return s},version:"1.0.0"};void 0===(o=function(){return d}.call(t,r,t,e))||(e.exports=o)}()},175:e=>{"use strict";e.exports=function(e){if(!/^data:/i.test(e))throw new TypeError('`uri` does not appear to be a Data URI (must begin with "data:")');const t=(e=e.replace(/\r?\n/g,"")).indexOf(",");if(-1===t||t<=4)throw new TypeError("malformed data: URI");const r=e.substring(5,t).split(";");let o="",n=!1;const s=r[0]||"text/plain";let i=s;for(let e=1;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=new WeakMap,o=new WeakMap;function n(e){const t=r.get(e);return console.assert(null!=t,"'this' is expected an Event object, but got",e),t}function s(e){null==e.passiveListener?e.event.cancelable&&(e.canceled=!0,"function"==typeof e.event.preventDefault&&e.event.preventDefault()):"undefined"!=typeof console&&"function"==typeof console.error&&console.error("Unable to preventDefault inside passive event listener invocation.",e.passiveListener)}function i(e,t){r.set(this,{eventTarget:e,event:t,eventPhase:2,currentTarget:e,canceled:!1,stopped:!1,immediateStopped:!1,passiveListener:null,timeStamp:t.timeStamp||Date.now()}),Object.defineProperty(this,"isTrusted",{value:!1,enumerable:!0});const o=Object.keys(t);for(let e=0;e0){const e=new Array(arguments.length);for(let t=0;t{const{Readable:o}=r(781),n=new WeakMap;class Blob{constructor(e=[],t={}){let r=0;const o=e.map((e=>{let t;return t=e instanceof Buffer?e:ArrayBuffer.isView(e)?Buffer.from(e.buffer,e.byteOffset,e.byteLength):e instanceof ArrayBuffer?Buffer.from(e):e instanceof Blob?e:Buffer.from("string"==typeof e?e:String(e)),r+=t.length||t.size||0,t})),s=void 0===t.type?"":String(t.type).toLowerCase();n.set(this,{type:/[^\u0020-\u007E]/.test(s)?"":s,size:r,parts:o})}get size(){return n.get(this).size}get type(){return n.get(this).type}async text(){return Buffer.from(await this.arrayBuffer()).toString()}async arrayBuffer(){const e=new Uint8Array(this.size);let t=0;for await(const r of this.stream())e.set(r,t),t+=r.length;return e.buffer}stream(){return o.from(async function*(e){for(const t of e)"stream"in t?yield*t.stream():yield t}(n.get(this).parts))}slice(e=0,t=this.size,r=""){const{size:o}=this;let s=e<0?Math.max(o+e,0):Math.min(e,o),i=t<0?Math.max(o+t,0):Math.min(t,o);const a=Math.max(i-s,0),u=n.get(this).parts.values(),l=[];let c=0;for(const e of u){const t=ArrayBuffer.isView(e)?e.byteLength:e.size;if(s&&t<=s)s-=t,i-=t;else{const r=e.slice(s,Math.min(t,i));if(l.push(r),c+=ArrayBuffer.isView(r)?r.byteLength:r.size,s=0,c>=a)break}}const d=new Blob([],{type:String(r).toLowerCase()});return Object.assign(n.get(d),{size:a,parts:l}),d}get[Symbol.toStringTag](){return"Blob"}static[Symbol.hasInstance](e){return e&&"object"==typeof e&&"function"==typeof e.stream&&0===e.stream.length&&"function"==typeof e.constructor&&/^(Blob|File)$/.test(e[Symbol.toStringTag])}}Object.defineProperties(Blob.prototype,{size:{enumerable:!0},type:{enumerable:!0},slice:{enumerable:!0}}),e.exports=Blob},556:(e,t,r)=>{"use strict";const o=r(594),n=r(271);if(global.fetch||(global.fetch=(e,t)=>o(e,{highWaterMark:1e7,...t})),global.Headers||(global.Headers=o.Headers),global.Request||(global.Request=o.Request),global.Response||(global.Response=o.Response),global.AbortController||(global.AbortController=n),!global.ReadableStream)try{global.ReadableStream=r(902)}catch(e){}e.exports=r(721)},721:function(e){var t;t=function(){"use strict";const e={},t=e=>"undefined"!=typeof self&&self&&e in self?self:"undefined"!=typeof window&&window&&e in window?window:"undefined"!=typeof global&&global&&e in global?global:"undefined"!=typeof globalThis&&globalThis?globalThis:void 0,r=["Headers","Request","Response","ReadableStream","fetch","AbortController","FormData"];for(const o of r)Object.defineProperty(e,o,{get(){const e=t(o),r=e&&e[o];return"function"==typeof r?r.bind(e):r}});const o=e=>null!==e&&"object"==typeof e,n="function"==typeof e.AbortController,s="function"==typeof e.ReadableStream,i="function"==typeof e.FormData,a=(t,r)=>{const o=new e.Headers(t||{}),n=r instanceof e.Headers,s=new e.Headers(r||{});for(const[e,t]of s)n&&"undefined"===t||void 0===t?o.delete(e):o.set(e,t);return o},u=(...e)=>{let t={},r={};for(const n of e){if(Array.isArray(n))Array.isArray(t)||(t=[]),t=[...t,...n];else if(o(n)){for(let[e,r]of Object.entries(n))o(r)&&e in t&&(r=u(t[e],r)),t={...t,[e]:r};o(n.headers)&&(r=a(r,n.headers))}t.headers=r}return t},l=["get","post","put","patch","head","delete"],c={json:"application/json",text:"text/*",formData:"multipart/form-data",arrayBuffer:"*/*",blob:"*/*"},d=[413,429,503],f=Symbol("stop");class HTTPError extends Error{constructor(e){super(e.statusText||String(0===e.status||e.status?e.status:"Unknown response error")),this.name="HTTPError",this.response=e}}class TimeoutError extends Error{constructor(e){super("Request timed out"),this.name="TimeoutError",this.request=e}}const p=e=>new Promise((t=>setTimeout(t,e))),h=e=>l.includes(e)?e.toUpperCase():e,b={limit:2,methods:["get","put","head","delete","options","trace"],statusCodes:[408,413,429,500,502,503,504],afterStatusCodes:d},y=(e={})=>{if("number"==typeof e)return{...b,limit:e};if(e.methods&&!Array.isArray(e.methods))throw new Error("retry.methods must be an array");if(e.statusCodes&&!Array.isArray(e.statusCodes))throw new Error("retry.statusCodes must be an array");return{...b,...e,afterStatusCodes:d}},m=2147483647;class Ky{constructor(t,r={}){if(this._retryCount=0,this._input=t,this._options={credentials:this._input.credentials||"same-origin",...r,headers:a(this._input.headers,r.headers),hooks:u({beforeRequest:[],beforeRetry:[],afterResponse:[]},r.hooks),method:h(r.method||this._input.method),prefixUrl:String(r.prefixUrl||""),retry:y(r.retry),throwHttpErrors:!1!==r.throwHttpErrors,timeout:void 0===r.timeout?1e4:r.timeout,fetch:r.fetch||e.fetch},"string"!=typeof this._input&&!(this._input instanceof URL||this._input instanceof e.Request))throw new TypeError("`input` must be a string, URL, or Request");if(this._options.prefixUrl&&"string"==typeof this._input){if(this._input.startsWith("/"))throw new Error("`input` must not begin with a slash when using `prefixUrl`");this._options.prefixUrl.endsWith("/")||(this._options.prefixUrl+="/"),this._input=this._options.prefixUrl+this._input}if(n&&(this.abortController=new e.AbortController,this._options.signal&&this._options.signal.addEventListener("abort",(()=>{this.abortController.abort()})),this._options.signal=this.abortController.signal),this.request=new e.Request(this._input,this._options),this._options.searchParams){const t="?"+new URLSearchParams(this._options.searchParams).toString(),r=this.request.url.replace(/(?:\?.*?)?(?=#|$)/,t);!(i&&this._options.body instanceof e.FormData||this._options.body instanceof URLSearchParams)||this._options.headers&&this._options.headers["content-type"]||this.request.headers.delete("content-type"),this.request=new e.Request(new e.Request(r,this.request),this._options)}void 0!==this._options.json&&(this._options.body=JSON.stringify(this._options.json),this.request.headers.set("content-type","application/json"),this.request=new e.Request(this.request,{body:this._options.body}));const o=async()=>{if(this._options.timeout>m)throw new RangeError("The `timeout` option cannot be greater than 2147483647");await p(1);let t=await this._fetch();for(const r of this._options.hooks.afterResponse){const o=await r(this.request,this._options,this._decorateResponse(t.clone()));o instanceof e.Response&&(t=o)}if(this._decorateResponse(t),!t.ok&&this._options.throwHttpErrors)throw new HTTPError(t);if(this._options.onDownloadProgress){if("function"!=typeof this._options.onDownloadProgress)throw new TypeError("The `onDownloadProgress` option must be a function");if(!s)throw new Error("Streams are not supported in your environment. `ReadableStream` is missing.");return this._stream(t.clone(),this._options.onDownloadProgress)}return t},l=this._options.retry.methods.includes(this.request.method.toLowerCase())?this._retry(o):o();for(const[e,t]of Object.entries(c))l[e]=async()=>{this.request.headers.set("accept",this.request.headers.get("accept")||t);const o=(await l).clone();if("json"===e){if(204===o.status)return"";if(r.parseJson)return r.parseJson(await o.text())}return o[e]()};return l}_calculateRetryDelay(e){if(this._retryCount++,this._retryCountthis._options.retry.maxRetryAfter?0:e}if(413===e.response.status)return 0}return.3*2**(this._retryCount-1)*1e3}return 0}_decorateResponse(e){return this._options.parseJson&&(e.json=async()=>this._options.parseJson(await e.text())),e}async _retry(e){try{return await e()}catch(t){const r=Math.min(this._calculateRetryDelay(t),m);if(0!==r&&this._retryCount>0){await p(r);for(const e of this._options.hooks.beforeRetry)if(await e({request:this.request,options:this._options,error:t,retryCount:this._retryCount})===f)return;return this._retry(e)}if(this._options.throwHttpErrors)throw t}}async _fetch(){for(const e of this._options.hooks.beforeRequest){const t=await e(this.request,this._options);if(t instanceof Request){this.request=t;break}if(t instanceof Response)return t}return!1===this._options.timeout?this._options.fetch(this.request.clone()):(e=this.request.clone(),t=this.abortController,r=this._options,new Promise(((o,n)=>{const s=setTimeout((()=>{t&&t.abort(),n(new TimeoutError(e))}),r.timeout);r.fetch(e).then(o).catch(n).then((()=>{clearTimeout(s)}))})));var e,t,r}_stream(t,r){const o=Number(t.headers.get("content-length"))||0;let n=0;return new e.Response(new e.ReadableStream({start(e){const s=t.body.getReader();r&&r({percent:0,transferredBytes:0,totalBytes:o},new Uint8Array),async function t(){const{done:i,value:a}=await s.read();i?e.close():(r&&(n+=a.byteLength,r({percent:0===o?0:n/o,transferredBytes:n,totalBytes:o},a)),e.enqueue(a),t())}()}}))}}const _=(...e)=>{for(const t of e)if((!o(t)||Array.isArray(t))&&void 0!==t)throw new TypeError("The `options` argument must be an object");return u({},...e)},g=e=>{const t=(t,r)=>new Ky(t,_(e,r));for(const r of l)t[r]=(t,o)=>new Ky(t,_(e,o,{method:r}));return t.HTTPError=HTTPError,t.TimeoutError=TimeoutError,t.create=e=>g(_(e)),t.extend=t=>g(_(e,t)),t.stop=f,t};return g()},e.exports=t()},78:e=>{function t(e){return e.replace(/[\/]+/g,"/").replace(/\/\?/g,"?").replace(/\/\#/g,"#").replace(/\:\//g,"://")}e.exports=function(){var e=[].slice.call(arguments,0).join("/");return t(e)}},113:e=>{"use strict";e.exports=__nccwpck_require__(6113)},685:e=>{"use strict";e.exports=__nccwpck_require__(3685)},687:e=>{"use strict";e.exports=__nccwpck_require__(5687)},781:e=>{"use strict";e.exports=__nccwpck_require__(2781)},310:e=>{"use strict";e.exports=__nccwpck_require__(7310)},837:e=>{"use strict";e.exports=__nccwpck_require__(3837)},796:e=>{"use strict";e.exports=__nccwpck_require__(9796)},594:(e,t,r)=>{"use strict";t=e.exports=W;const o=r(685),n=r(687),s=r(796),i=r(781),a=r(175),u=r(837),l=r(30),c=r(113),d=r(310);class FetchBaseError extends Error{constructor(e,t){super(e),Error.captureStackTrace(this,this.constructor),this.type=t}get name(){return this.constructor.name}get[Symbol.toStringTag](){return this.constructor.name}}class FetchError extends FetchBaseError{constructor(e,t,r){super(e,t),r&&(this.code=this.errno=r.code,this.erroredSysCall=r.syscall)}}const f=Symbol.toStringTag,p=e=>"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.delete&&"function"==typeof e.get&&"function"==typeof e.getAll&&"function"==typeof e.has&&"function"==typeof e.set&&"function"==typeof e.sort&&"URLSearchParams"===e[f],h=e=>"object"==typeof e&&"function"==typeof e.arrayBuffer&&"string"==typeof e.type&&"function"==typeof e.stream&&"function"==typeof e.constructor&&/^(Blob|File)$/.test(e[f]);function b(e){return"object"==typeof e&&"function"==typeof e.append&&"function"==typeof e.set&&"function"==typeof e.get&&"function"==typeof e.getAll&&"function"==typeof e.delete&&"function"==typeof e.keys&&"function"==typeof e.values&&"function"==typeof e.entries&&"function"==typeof e.constructor&&"FormData"===e[f]}const y="\r\n",m="-".repeat(2),_=Buffer.byteLength(y),g=e=>`${m}${e}${m}${y.repeat(2)}`;function v(e,t,r){let o="";return o+=`${m}${e}\r\n`,o+=`Content-Disposition: form-data; name="${t}"`,h(r)&&(o+=`; filename="${r.name}"\r\n`,o+=`Content-Type: ${r.type||"application/octet-stream"}`),`${o}${y.repeat(2)}`}const w=Symbol("Body internals");class Body{constructor(e,{size:t=0}={}){let r=null;null===e?e=null:p(e)?e=Buffer.from(e.toString()):h(e)||Buffer.isBuffer(e)||(u.types.isAnyArrayBuffer(e)?e=Buffer.from(e):ArrayBuffer.isView(e)?e=Buffer.from(e.buffer,e.byteOffset,e.byteLength):e instanceof i||(b(e)?(r=`NodeFetchFormDataBoundary${c.randomBytes(8).toString("hex")}`,e=i.Readable.from(async function*(e,t){for(const[r,o]of e)yield v(t,r,o),h(o)?yield*o.stream():yield o,yield y;yield g(t)}(e,r))):e=Buffer.from(String(e)))),this[w]={body:e,boundary:r,disturbed:!1,error:null},this.size=t,e instanceof i&&e.on("error",(e=>{const t=e instanceof FetchBaseError?e:new FetchError(`Invalid response body while trying to fetch ${this.url}: ${e.message}`,"system",e);this[w].error=t}))}get body(){return this[w].body}get bodyUsed(){return this[w].disturbed}async arrayBuffer(){const{buffer:e,byteOffset:t,byteLength:r}=await S(this);return e.slice(t,t+r)}async blob(){const e=this.headers&&this.headers.get("content-type")||this[w].body&&this[w].body.type||"",t=await this.buffer();return new l([t],{type:e})}async json(){const e=await S(this);return JSON.parse(e.toString())}async text(){return(await S(this)).toString()}buffer(){return S(this)}}async function S(e){if(e[w].disturbed)throw new TypeError(`body used already for: ${e.url}`);if(e[w].disturbed=!0,e[w].error)throw e[w].error;let{body:t}=e;if(null===t)return Buffer.alloc(0);if(h(t)&&(t=t.stream()),Buffer.isBuffer(t))return t;if(!(t instanceof i))return Buffer.alloc(0);const r=[];let o=0;try{for await(const n of t){if(e.size>0&&o+n.length>e.size){const r=new FetchError(`content size at ${e.url} over limit: ${e.size}`,"max-size");throw t.destroy(r),r}o+=n.length,r.push(n)}}catch(t){throw t instanceof FetchBaseError?t:new FetchError(`Invalid response body while trying to fetch ${e.url}: ${t.message}`,"system",t)}if(!0!==t.readableEnded&&!0!==t._readableState.ended)throw new FetchError(`Premature close of server response while trying to fetch ${e.url}`);try{return r.every((e=>"string"==typeof e))?Buffer.from(r.join("")):Buffer.concat(r,o)}catch(t){throw new FetchError(`Could not create Buffer from response body for ${e.url}: ${t.message}`,"system",t)}}Object.defineProperties(Body.prototype,{body:{enumerable:!0},bodyUsed:{enumerable:!0},arrayBuffer:{enumerable:!0},blob:{enumerable:!0},json:{enumerable:!0},text:{enumerable:!0}});const R=(e,t)=>{let r,o,{body:n}=e;if(e.bodyUsed)throw new Error("cannot clone body after it is used");return n instanceof i&&"function"!=typeof n.getBoundary&&(r=new i.PassThrough({highWaterMark:t}),o=new i.PassThrough({highWaterMark:t}),n.pipe(r),n.pipe(o),e[w].body=r,n=o),n},T=(e,t)=>null===e?null:"string"==typeof e?"text/plain;charset=UTF-8":p(e)?"application/x-www-form-urlencoded;charset=UTF-8":h(e)?e.type||null:Buffer.isBuffer(e)||u.types.isAnyArrayBuffer(e)||ArrayBuffer.isView(e)?null:e&&"function"==typeof e.getBoundary?`multipart/form-data;boundary=${e.getBoundary()}`:b(e)?`multipart/form-data; boundary=${t[w].boundary}`:e instanceof i?null:"text/plain;charset=UTF-8",q=e=>{const{body:t}=e;return null===t?0:h(t)?t.size:Buffer.isBuffer(t)?t.length:t&&"function"==typeof t.getLengthSync?t.hasKnownLength&&t.hasKnownLength()?t.getLengthSync():null:b(t)?function(e,t){let r=0;for(const[o,n]of e)r+=Buffer.byteLength(v(t,o,n)),h(n)?r+=n.size:r+=Buffer.byteLength(String(n)),r+=_;return r+=Buffer.byteLength(g(t)),r}(e[w].boundary):null},P="function"==typeof o.validateHeaderName?o.validateHeaderName:e=>{if(!/^[\^`\-\w!#$%&'*+.|~]+$/.test(e)){const t=new TypeError(`Header name must be a valid HTTP token [${e}]`);throw Object.defineProperty(t,"code",{value:"ERR_INVALID_HTTP_TOKEN"}),t}},E="function"==typeof o.validateHeaderValue?o.validateHeaderValue:(e,t)=>{if(/[^\t\u0020-\u007E\u0080-\u00FF]/.test(t)){const t=new TypeError(`Invalid character in header content ["${e}"]`);throw Object.defineProperty(t,"code",{value:"ERR_INVALID_CHAR"}),t}};class Headers extends URLSearchParams{constructor(e){let t=[];if(e instanceof Headers){const r=e.raw();for(const[e,o]of Object.entries(r))t.push(...o.map((t=>[e,t])))}else if(null==e);else{if("object"!=typeof e||u.types.isBoxedPrimitive(e))throw new TypeError("Failed to construct 'Headers': The provided value is not of type '(sequence> or record)");{const r=e[Symbol.iterator];if(null==r)t.push(...Object.entries(e));else{if("function"!=typeof r)throw new TypeError("Header pairs must be iterable");t=[...e].map((e=>{if("object"!=typeof e||u.types.isBoxedPrimitive(e))throw new TypeError("Each header pair must be an iterable object");return[...e]})).map((e=>{if(2!==e.length)throw new TypeError("Each header pair must be a name/value tuple");return[...e]}))}}}return t=t.length>0?t.map((([e,t])=>(P(e),E(e,String(t)),[String(e).toLowerCase(),String(t)]))):void 0,super(t),new Proxy(this,{get(e,t,r){switch(t){case"append":case"set":return(e,o)=>(P(e),E(e,String(o)),URLSearchParams.prototype[t].call(r,String(e).toLowerCase(),String(o)));case"delete":case"has":case"getAll":return e=>(P(e),URLSearchParams.prototype[t].call(r,String(e).toLowerCase()));case"keys":return()=>(e.sort(),new Set(URLSearchParams.prototype.keys.call(e)).keys());default:return Reflect.get(e,t,r)}}})}get[Symbol.toStringTag](){return this.constructor.name}toString(){return Object.prototype.toString.call(this)}get(e){const t=this.getAll(e);if(0===t.length)return null;let r=t.join(", ");return/^content-encoding$/i.test(e)&&(r=r.toLowerCase()),r}forEach(e){for(const t of this.keys())e(this.get(t),t)}*values(){for(const e of this.keys())yield this.get(e)}*entries(){for(const e of this.keys())yield[e,this.get(e)]}[Symbol.iterator](){return this.entries()}raw(){return[...this.keys()].reduce(((e,t)=>(e[t]=this.getAll(t),e)),{})}[Symbol.for("nodejs.util.inspect.custom")](){return[...this.keys()].reduce(((e,t)=>{const r=this.getAll(t);return e[t]="host"===t?r[0]:r.length>1?r:r[0],e}),{})}}Object.defineProperties(Headers.prototype,["get","entries","forEach","values"].reduce(((e,t)=>(e[t]={enumerable:!0},e)),{}));const C=new Set([301,302,303,307,308]),O=e=>C.has(e),A=Symbol("Response internals");class Response extends Body{constructor(e=null,t={}){super(e,t);const r=t.status||200,o=new Headers(t.headers);if(null!==e&&!o.has("Content-Type")){const t=T(e);t&&o.append("Content-Type",t)}this[A]={url:t.url,status:r,statusText:t.statusText||"",headers:o,counter:t.counter,highWaterMark:t.highWaterMark}}get url(){return this[A].url||""}get status(){return this[A].status}get ok(){return this[A].status>=200&&this[A].status<300}get redirected(){return this[A].counter>0}get statusText(){return this[A].statusText}get headers(){return this[A].headers}get highWaterMark(){return this[A].highWaterMark}clone(){return new Response(R(this,this.highWaterMark),{url:this.url,status:this.status,statusText:this.statusText,headers:this.headers,ok:this.ok,redirected:this.redirected,size:this.size})}static redirect(e,t=302){if(!O(t))throw new RangeError('Failed to execute "redirect" on "response": Invalid status code');return new Response(null,{headers:{location:new URL(e).toString()},status:t})}get[Symbol.toStringTag](){return"Response"}}Object.defineProperties(Response.prototype,{url:{enumerable:!0},status:{enumerable:!0},ok:{enumerable:!0},redirected:{enumerable:!0},statusText:{enumerable:!0},headers:{enumerable:!0},clone:{enumerable:!0}});const j=Symbol("Request internals"),k=e=>"object"==typeof e&&"object"==typeof e[j];class Request extends Body{constructor(e,t={}){let r;k(e)?r=new URL(e.url):(r=new URL(e),e={});let o=t.method||e.method||"GET";if(o=o.toUpperCase(),(null!=t.body||k(e))&&null!==e.body&&("GET"===o||"HEAD"===o))throw new TypeError("Request with GET/HEAD method cannot have body");const n=t.body?t.body:k(e)&&null!==e.body?R(e):null;super(n,{size:t.size||e.size||0});const s=new Headers(t.headers||e.headers||{});if(null!==n&&!s.has("Content-Type")){const e=T(n,this);e&&s.append("Content-Type",e)}let i=k(e)?e.signal:null;if("signal"in t&&(i=t.signal),null!==i&&("object"!=typeof(a=i)||"AbortSignal"!==a[f]))throw new TypeError("Expected signal to be an instanceof AbortSignal");var a;this[j]={method:o,redirect:t.redirect||e.redirect||"follow",headers:s,parsedURL:r,signal:i},this.follow=void 0===t.follow?void 0===e.follow?20:e.follow:t.follow,this.compress=void 0===t.compress?void 0===e.compress||e.compress:t.compress,this.counter=t.counter||e.counter||0,this.agent=t.agent||e.agent,this.highWaterMark=t.highWaterMark||e.highWaterMark||16384,this.insecureHTTPParser=t.insecureHTTPParser||e.insecureHTTPParser||!1}get method(){return this[j].method}get url(){return d.format(this[j].parsedURL)}get headers(){return this[j].headers}get redirect(){return this[j].redirect}get signal(){return this[j].signal}clone(){return new Request(this)}get[Symbol.toStringTag](){return"Request"}}Object.defineProperties(Request.prototype,{method:{enumerable:!0},url:{enumerable:!0},headers:{enumerable:!0},redirect:{enumerable:!0},clone:{enumerable:!0},signal:{enumerable:!0}});class AbortError extends FetchBaseError{constructor(e,t="aborted"){super(e,t)}}const B=new Set(["data:","http:","https:"]);async function W(e,t){return new Promise(((r,u)=>{const l=new Request(e,t),c=(e=>{const{parsedURL:t}=e[j],r=new Headers(e[j].headers);r.has("Accept")||r.set("Accept","*/*");let o=null;if(null===e.body&&/^(post|put)$/i.test(e.method)&&(o="0"),null!==e.body){const t=q(e);"number"!=typeof t||Number.isNaN(t)||(o=String(t))}o&&r.set("Content-Length",o),r.has("User-Agent")||r.set("User-Agent","node-fetch"),e.compress&&!r.has("Accept-Encoding")&&r.set("Accept-Encoding","gzip,deflate,br");let{agent:n}=e;"function"==typeof n&&(n=n(t)),r.has("Connection")||n||r.set("Connection","close");const s=(e=>{if(e.search)return e.search;const t=e.href.length-1,r=e.hash||("#"===e.href[t]?"#":"");return"?"===e.href[t-r.length]?"?":""})(t);return{path:t.pathname+s,pathname:t.pathname,hostname:t.hostname,protocol:t.protocol,port:t.port,hash:t.hash,search:t.search,query:t.query,href:t.href,method:e.method,headers:r[Symbol.for("nodejs.util.inspect.custom")](),insecureHTTPParser:e.insecureHTTPParser,agent:n}})(l);if(!B.has(c.protocol))throw new TypeError(`node-fetch cannot load ${e}. URL scheme "${c.protocol.replace(/:$/,"")}" is not supported.`);if("data:"===c.protocol){const e=a(l.url),t=new Response(e,{headers:{"Content-Type":e.typeFull}});return void r(t)}const d=("https:"===c.protocol?n:o).request,{signal:f}=l;let p=null;const b=()=>{const e=new AbortError("The operation was aborted.");u(e),l.body&&l.body instanceof i.Readable&&l.body.destroy(e),p&&p.body&&p.body.emit("error",e)};if(f&&f.aborted)return void b();const y=()=>{b(),_()},m=d(c);f&&f.addEventListener("abort",y);const _=()=>{m.abort(),f&&f.removeEventListener("abort",y)};m.on("error",(e=>{u(new FetchError(`request to ${l.url} failed, reason: ${e.message}`,"system",e)),_()})),m.on("response",(e=>{m.setTimeout(0);const o=function(e=[]){return new Headers(e.reduce(((e,t,r,o)=>(r%2==0&&e.push(o.slice(r,r+2)),e)),[]).filter((([e,t])=>{try{return P(e),E(e,String(t)),!0}catch{return!1}})))}(e.rawHeaders);if(O(e.statusCode)){const n=o.get("Location"),s=null===n?null:new URL(n,l.url);switch(l.redirect){case"error":return u(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${l.url}`,"no-redirect")),void _();case"manual":if(null!==s)try{o.set("Location",s)}catch(e){u(e)}break;case"follow":{if(null===s)break;if(l.counter>=l.follow)return u(new FetchError(`maximum redirect reached at: ${l.url}`,"max-redirect")),void _();const o={headers:new Headers(l.headers),follow:l.follow,counter:l.counter+1,agent:l.agent,compress:l.compress,method:l.method,body:l.body,signal:l.signal,size:l.size};return 303!==e.statusCode&&l.body&&t.body instanceof i.Readable?(u(new FetchError("Cannot follow redirect with body being a readable stream","unsupported-redirect")),void _()):(303!==e.statusCode&&(301!==e.statusCode&&302!==e.statusCode||"POST"!==l.method)||(o.method="GET",o.body=void 0,o.headers.delete("content-length")),r(W(new Request(s,o))),void _())}}}e.once("end",(()=>{f&&f.removeEventListener("abort",y)}));let n=i.pipeline(e,new i.PassThrough,(e=>{u(e)}));process.version<"v12.10"&&e.on("aborted",y);const a={url:l.url,status:e.statusCode,statusText:e.statusMessage,headers:o,size:l.size,counter:l.counter,highWaterMark:l.highWaterMark},c=o.get("Content-Encoding");if(!l.compress||"HEAD"===l.method||null===c||204===e.statusCode||304===e.statusCode)return p=new Response(n,a),void r(p);const d={flush:s.Z_SYNC_FLUSH,finishFlush:s.Z_SYNC_FLUSH};if("gzip"===c||"x-gzip"===c)return n=i.pipeline(n,s.createGunzip(d),(e=>{u(e)})),p=new Response(n,a),void r(p);if("deflate"!==c&&"x-deflate"!==c){if("br"===c)return n=i.pipeline(n,s.createBrotliDecompress(),(e=>{u(e)})),p=new Response(n,a),void r(p);p=new Response(n,a),r(p)}else{i.pipeline(e,new i.PassThrough,(e=>{u(e)})).once("data",(e=>{n=8==(15&e[0])?i.pipeline(n,s.createInflate(),(e=>{u(e)})):i.pipeline(n,s.createInflateRaw(),(e=>{u(e)})),p=new Response(n,a),r(p)}))}})),((e,{body:t})=>{null===t?e.end():h(t)?t.stream().pipe(e):Buffer.isBuffer(t)?(e.write(t),e.end()):t.pipe(e)})(m,l)}))}t.AbortError=AbortError,t.FetchError=FetchError,t.Headers=Headers,t.Request=Request,t.Response=Response,t.default=W,t.isRedirect=O},902:(e,t,r)=>{"use strict";r.r(t),r.d(t,{ByteLengthQueuingStrategy:()=>ByteLengthQueuingStrategy,CountQueuingStrategy:()=>CountQueuingStrategy,ReadableByteStreamController:()=>ReadableByteStreamController,ReadableStream:()=>ReadableStream,ReadableStreamBYOBReader:()=>ReadableStreamBYOBReader,ReadableStreamBYOBRequest:()=>ReadableStreamBYOBRequest,ReadableStreamDefaultController:()=>ReadableStreamDefaultController,ReadableStreamDefaultReader:()=>ReadableStreamDefaultReader,TransformStream:()=>TransformStream,TransformStreamDefaultController:()=>TransformStreamDefaultController,WritableStream:()=>WritableStream,WritableStreamDefaultController:()=>WritableStreamDefaultController,WritableStreamDefaultWriter:()=>WritableStreamDefaultWriter});const o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol:e=>`Symbol(${e})`;function n(){}const s="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0;function i(e){return"object"==typeof e&&null!==e||"function"==typeof e}const a=n,u=Promise,l=Promise.prototype.then,c=Promise.resolve.bind(u),d=Promise.reject.bind(u);function f(e){return new u(e)}function p(e){return c(e)}function h(e){return d(e)}function b(e,t,r){return l.call(e,t,r)}function y(e,t,r){b(b(e,t,r),void 0,a)}function m(e,t){y(e,t)}function _(e,t){y(e,void 0,t)}function g(e,t,r){return b(e,t,r)}function v(e){b(e,void 0,a)}const w=(()=>{const e=s&&s.queueMicrotask;if("function"==typeof e)return e;const t=p(void 0);return e=>b(t,e)})();function S(e,t,r){if("function"!=typeof e)throw new TypeError("Argument is not a function");return Function.prototype.apply.call(e,t,r)}function R(e,t,r){try{return p(S(e,t,r))}catch(e){return h(e)}}class SimpleQueue{constructor(){this._cursor=0,this._size=0,this._front={_elements:[],_next:void 0},this._back=this._front,this._cursor=0,this._size=0}get length(){return this._size}push(e){const t=this._back;let r=t;16383===t._elements.length&&(r={_elements:[],_next:void 0}),t._elements.push(e),r!==t&&(this._back=r,t._next=r),++this._size}shift(){const e=this._front;let t=e;const r=this._cursor;let o=r+1;const n=e._elements,s=n[r];return 16384===o&&(t=e._next,o=0),--this._size,this._cursor=o,e!==t&&(this._front=t),n[r]=void 0,s}forEach(e){let t=this._cursor,r=this._front,o=r._elements;for(;!(t===o.length&&void 0===r._next||t===o.length&&(r=r._next,o=r._elements,t=0,0===o.length));)e(o[t]),++t}peek(){const e=this._front,t=this._cursor;return e._elements[t]}}function T(e,t){e._ownerReadableStream=t,t._reader=e,"readable"===t._state?C(e):"closed"===t._state?function(e){C(e),j(e)}(e):O(e,t._storedError)}function q(e,t){return pr(e._ownerReadableStream,t)}function P(e){"readable"===e._ownerReadableStream._state?A(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness")):function(e,t){O(e,t)}(e,new TypeError("Reader was released and can no longer be used to monitor the stream's closedness")),e._ownerReadableStream._reader=void 0,e._ownerReadableStream=void 0}function E(e){return new TypeError("Cannot "+e+" a stream using a released reader")}function C(e){e._closedPromise=f(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r}))}function O(e,t){C(e),A(e,t)}function A(e,t){void 0!==e._closedPromise_reject&&(v(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}function j(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0)}const k=o("[[AbortSteps]]"),B=o("[[ErrorSteps]]"),W=o("[[CancelSteps]]"),x=o("[[PullSteps]]"),D=Number.isFinite||function(e){return"number"==typeof e&&isFinite(e)},L=Math.trunc||function(e){return e<0?Math.ceil(e):Math.floor(e)};function F(e,t){if(void 0!==e&&("object"!=typeof(r=e)&&"function"!=typeof r))throw new TypeError(`${t} is not an object.`);var r}function z(e,t){if("function"!=typeof e)throw new TypeError(`${t} is not a function.`)}function I(e,t){if(!function(e){return"object"==typeof e&&null!==e||"function"==typeof e}(e))throw new TypeError(`${t} is not an object.`)}function M(e,t,r){if(void 0===e)throw new TypeError(`Parameter ${t} is required in '${r}'.`)}function $(e,t,r){if(void 0===e)throw new TypeError(`${t} is required in '${r}'.`)}function H(e){return Number(e)}function U(e){return 0===e?0:e}function N(e,t){const r=Number.MAX_SAFE_INTEGER;let o=Number(e);if(o=U(o),!D(o))throw new TypeError(`${t} is not a finite number`);if(o=function(e){return U(L(e))}(o),o<0||o>r)throw new TypeError(`${t} is outside the accepted range of 0 to ${r}, inclusive`);return D(o)&&0!==o?o:0}function Q(e,t){if(!dr(e))throw new TypeError(`${t} is not a ReadableStream.`)}function Y(e){return new ReadableStreamDefaultReader(e)}function V(e,t){e._reader._readRequests.push(t)}function G(e,t,r){const o=e._reader._readRequests.shift();r?o._closeSteps():o._chunkSteps(t)}function J(e){return e._reader._readRequests.length}function K(e){const t=e._reader;return void 0!==t&&!!Z(t)}class ReadableStreamDefaultReader{constructor(e){if(M(e,1,"ReadableStreamDefaultReader"),Q(e,"First parameter"),fr(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");T(this,e),this._readRequests=new SimpleQueue}get closed(){return Z(this)?this._closedPromise:h(ee("closed"))}cancel(e){return Z(this)?void 0===this._ownerReadableStream?h(E("cancel")):q(this,e):h(ee("cancel"))}read(){if(!Z(this))return h(ee("read"));if(void 0===this._ownerReadableStream)return h(E("read from"));let e,t;const r=f(((r,o)=>{e=r,t=o}));return X(this,{_chunkSteps:t=>e({value:t,done:!1}),_closeSteps:()=>e({value:void 0,done:!0}),_errorSteps:e=>t(e)}),r}releaseLock(){if(!Z(this))throw ee("releaseLock");if(void 0!==this._ownerReadableStream){if(this._readRequests.length>0)throw new TypeError("Tried to release a reader lock when that reader has pending read() calls un-settled");P(this)}}}function Z(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readRequests")&&e instanceof ReadableStreamDefaultReader)}function X(e,t){const r=e._ownerReadableStream;r._disturbed=!0,"closed"===r._state?t._closeSteps():"errored"===r._state?t._errorSteps(r._storedError):r._readableStreamController[x](t)}function ee(e){return new TypeError(`ReadableStreamDefaultReader.prototype.${e} can only be used on a ReadableStreamDefaultReader`)}Object.defineProperties(ReadableStreamDefaultReader.prototype,{cancel:{enumerable:!0},read:{enumerable:!0},releaseLock:{enumerable:!0},closed:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamDefaultReader.prototype,o.toStringTag,{value:"ReadableStreamDefaultReader",configurable:!0});const te=Object.getPrototypeOf(Object.getPrototypeOf((async function*(){})).prototype);class ReadableStreamAsyncIteratorImpl{constructor(e,t){this._ongoingPromise=void 0,this._isFinished=!1,this._reader=e,this._preventCancel=t}next(){const e=()=>this._nextSteps();return this._ongoingPromise=this._ongoingPromise?g(this._ongoingPromise,e,e):e(),this._ongoingPromise}return(e){const t=()=>this._returnSteps(e);return this._ongoingPromise?g(this._ongoingPromise,t,t):t()}_nextSteps(){if(this._isFinished)return Promise.resolve({value:void 0,done:!0});const e=this._reader;if(void 0===e._ownerReadableStream)return h(E("iterate"));let t,r;const o=f(((e,o)=>{t=e,r=o}));return X(e,{_chunkSteps:e=>{this._ongoingPromise=void 0,w((()=>t({value:e,done:!1})))},_closeSteps:()=>{this._ongoingPromise=void 0,this._isFinished=!0,P(e),t({value:void 0,done:!0})},_errorSteps:t=>{this._ongoingPromise=void 0,this._isFinished=!0,P(e),r(t)}}),o}_returnSteps(e){if(this._isFinished)return Promise.resolve({value:e,done:!0});this._isFinished=!0;const t=this._reader;if(void 0===t._ownerReadableStream)return h(E("finish iterating"));if(!this._preventCancel){const r=q(t,e);return P(t),g(r,(()=>({value:e,done:!0})))}return P(t),p({value:e,done:!0})}}const re={next(){return oe(this)?this._asyncIteratorImpl.next():h(ne("next"))},return(e){return oe(this)?this._asyncIteratorImpl.return(e):h(ne("return"))}};function oe(e){if(!i(e))return!1;if(!Object.prototype.hasOwnProperty.call(e,"_asyncIteratorImpl"))return!1;try{return e._asyncIteratorImpl instanceof ReadableStreamAsyncIteratorImpl}catch(e){return!1}}function ne(e){return new TypeError(`ReadableStreamAsyncIterator.${e} can only be used on a ReadableSteamAsyncIterator`)}void 0!==te&&Object.setPrototypeOf(re,te);const se=Number.isNaN||function(e){return e!=e};function ie(e){return e.slice()}function ae(e,t,r,o,n){new Uint8Array(e).set(new Uint8Array(r,o,n),t)}function ue(e,t,r){if(e.slice)return e.slice(t,r);const o=r-t,n=new ArrayBuffer(o);return ae(n,0,e,t,o),n}function le(e){const t=ue(e.buffer,e.byteOffset,e.byteOffset+e.byteLength);return new Uint8Array(t)}function ce(e){const t=e._queue.shift();return e._queueTotalSize-=t.size,e._queueTotalSize<0&&(e._queueTotalSize=0),t.value}function de(e,t,r){if("number"!=typeof(o=r)||se(o)||o<0||r===1/0)throw new RangeError("Size must be a finite, non-NaN, non-negative number.");var o;e._queue.push({value:t,size:r}),e._queueTotalSize+=r}function fe(e){e._queue=new SimpleQueue,e._queueTotalSize=0}class ReadableStreamBYOBRequest{constructor(){throw new TypeError("Illegal constructor")}get view(){if(!he(this))throw De("view");return this._view}respond(e){if(!he(this))throw De("respond");if(M(e,1,"respond"),e=N(e,"First parameter"),void 0===this._associatedReadableByteStreamController)throw new TypeError("This BYOB request has been invalidated");this._view.buffer,Be(this._associatedReadableByteStreamController,e)}respondWithNewView(e){if(!he(this))throw De("respondWithNewView");if(M(e,1,"respondWithNewView"),!ArrayBuffer.isView(e))throw new TypeError("You can only respond with array buffer views");if(void 0===this._associatedReadableByteStreamController)throw new TypeError("This BYOB request has been invalidated");e.buffer,We(this._associatedReadableByteStreamController,e)}}Object.defineProperties(ReadableStreamBYOBRequest.prototype,{respond:{enumerable:!0},respondWithNewView:{enumerable:!0},view:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamBYOBRequest.prototype,o.toStringTag,{value:"ReadableStreamBYOBRequest",configurable:!0});class ReadableByteStreamController{constructor(){throw new TypeError("Illegal constructor")}get byobRequest(){if(!pe(this))throw Le("byobRequest");return je(this)}get desiredSize(){if(!pe(this))throw Le("desiredSize");return ke(this)}close(){if(!pe(this))throw Le("close");if(this._closeRequested)throw new TypeError("The stream has already been closed; do not close it again!");const e=this._controlledReadableByteStream._state;if("readable"!==e)throw new TypeError(`The stream (in ${e} state) is not in the readable state and cannot be closed`);Ce(this)}enqueue(e){if(!pe(this))throw Le("enqueue");if(M(e,1,"enqueue"),!ArrayBuffer.isView(e))throw new TypeError("chunk must be an array buffer view");if(0===e.byteLength)throw new TypeError("chunk must have non-zero byteLength");if(0===e.buffer.byteLength)throw new TypeError("chunk's buffer must have non-zero byteLength");if(this._closeRequested)throw new TypeError("stream is closed or draining");const t=this._controlledReadableByteStream._state;if("readable"!==t)throw new TypeError(`The stream (in ${t} state) is not in the readable state and cannot be enqueued to`);Oe(this,e)}error(e){if(!pe(this))throw Le("error");Ae(this,e)}[W](e){ye(this),fe(this);const t=this._cancelAlgorithm(e);return Ee(this),t}[x](e){const t=this._controlledReadableByteStream;if(this._queueTotalSize>0){const t=this._queue.shift();this._queueTotalSize-=t.byteLength,Se(this);const r=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return void e._chunkSteps(r)}const r=this._autoAllocateChunkSize;if(void 0!==r){let t;try{t=new ArrayBuffer(r)}catch(t){return void e._errorSteps(t)}const o={buffer:t,bufferByteLength:r,byteOffset:0,byteLength:r,bytesFilled:0,elementSize:1,viewConstructor:Uint8Array,readerType:"default"};this._pendingPullIntos.push(o)}V(t,e),be(this)}}function pe(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledReadableByteStream")&&e instanceof ReadableByteStreamController)}function he(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_associatedReadableByteStreamController")&&e instanceof ReadableStreamBYOBRequest)}function be(e){const t=function(e){const t=e._controlledReadableByteStream;if("readable"!==t._state)return!1;if(e._closeRequested)return!1;if(!e._started)return!1;if(K(t)&&J(t)>0)return!0;if(Me(t)&&Ie(t)>0)return!0;if(ke(e)>0)return!0;return!1}(e);if(!t)return;if(e._pulling)return void(e._pullAgain=!0);e._pulling=!0;y(e._pullAlgorithm(),(()=>{e._pulling=!1,e._pullAgain&&(e._pullAgain=!1,be(e))}),(t=>{Ae(e,t)}))}function ye(e){Re(e),e._pendingPullIntos=new SimpleQueue}function me(e,t){let r=!1;"closed"===e._state&&(r=!0);const o=_e(t);"default"===t.readerType?G(e,o,r):function(e,t,r){const o=e._reader._readIntoRequests.shift();r?o._closeSteps(t):o._chunkSteps(t)}(e,o,r)}function _e(e){const t=e.bytesFilled,r=e.elementSize;return new e.viewConstructor(e.buffer,e.byteOffset,t/r)}function ge(e,t,r,o){e._queue.push({buffer:t,byteOffset:r,byteLength:o}),e._queueTotalSize+=o}function ve(e,t){const r=t.elementSize,o=t.bytesFilled-t.bytesFilled%r,n=Math.min(e._queueTotalSize,t.byteLength-t.bytesFilled),s=t.bytesFilled+n,i=s-s%r;let a=n,u=!1;i>o&&(a=i-t.bytesFilled,u=!0);const l=e._queue;for(;a>0;){const r=l.peek(),o=Math.min(a,r.byteLength),n=t.byteOffset+t.bytesFilled;ae(t.buffer,n,r.buffer,r.byteOffset,o),r.byteLength===o?l.shift():(r.byteOffset+=o,r.byteLength-=o),e._queueTotalSize-=o,we(e,o,t),a-=o}return u}function we(e,t,r){r.bytesFilled+=t}function Se(e){0===e._queueTotalSize&&e._closeRequested?(Ee(e),hr(e._controlledReadableByteStream)):be(e)}function Re(e){null!==e._byobRequest&&(e._byobRequest._associatedReadableByteStreamController=void 0,e._byobRequest._view=null,e._byobRequest=null)}function Te(e){for(;e._pendingPullIntos.length>0;){if(0===e._queueTotalSize)return;const t=e._pendingPullIntos.peek();ve(e,t)&&(Pe(e),me(e._controlledReadableByteStream,t))}}function qe(e,t){const r=e._pendingPullIntos.peek();Re(e);"closed"===e._controlledReadableByteStream._state?function(e,t){const r=e._controlledReadableByteStream;if(Me(r))for(;Ie(r)>0;)me(r,Pe(e))}(e):function(e,t,r){if(we(0,t,r),r.bytesFilled0){const t=r.byteOffset+r.bytesFilled,n=ue(r.buffer,t-o,t);ge(e,n,0,n.byteLength)}r.bytesFilled-=o,me(e._controlledReadableByteStream,r),Te(e)}(e,t,r),be(e)}function Pe(e){return e._pendingPullIntos.shift()}function Ee(e){e._pullAlgorithm=void 0,e._cancelAlgorithm=void 0}function Ce(e){const t=e._controlledReadableByteStream;if(!e._closeRequested&&"readable"===t._state)if(e._queueTotalSize>0)e._closeRequested=!0;else{if(e._pendingPullIntos.length>0){if(e._pendingPullIntos.peek().bytesFilled>0){const t=new TypeError("Insufficient bytes to fill elements in the given buffer");throw Ae(e,t),t}}Ee(e),hr(t)}}function Oe(e,t){const r=e._controlledReadableByteStream;if(e._closeRequested||"readable"!==r._state)return;const o=t.buffer,n=t.byteOffset,s=t.byteLength,i=o;if(e._pendingPullIntos.length>0){const t=e._pendingPullIntos.peek();t.buffer,0,t.buffer=t.buffer}if(Re(e),K(r))if(0===J(r))ge(e,i,n,s);else{G(r,new Uint8Array(i,n,s),!1)}else Me(r)?(ge(e,i,n,s),Te(e)):ge(e,i,n,s);be(e)}function Ae(e,t){const r=e._controlledReadableByteStream;"readable"===r._state&&(ye(e),fe(e),Ee(e),br(r,t))}function je(e){if(null===e._byobRequest&&e._pendingPullIntos.length>0){const t=e._pendingPullIntos.peek(),r=new Uint8Array(t.buffer,t.byteOffset+t.bytesFilled,t.byteLength-t.bytesFilled),o=Object.create(ReadableStreamBYOBRequest.prototype);!function(e,t,r){e._associatedReadableByteStreamController=t,e._view=r}(o,e,r),e._byobRequest=o}return e._byobRequest}function ke(e){const t=e._controlledReadableByteStream._state;return"errored"===t?null:"closed"===t?0:e._strategyHWM-e._queueTotalSize}function Be(e,t){const r=e._pendingPullIntos.peek();if("closed"===e._controlledReadableByteStream._state){if(0!==t)throw new TypeError("bytesWritten must be 0 when calling respond() on a closed stream")}else{if(0===t)throw new TypeError("bytesWritten must be greater than 0 when calling respond() on a readable stream");if(r.bytesFilled+t>r.byteLength)throw new RangeError("bytesWritten out of range")}r.buffer=r.buffer,qe(e,t)}function We(e,t){const r=e._pendingPullIntos.peek();if("closed"===e._controlledReadableByteStream._state){if(0!==t.byteLength)throw new TypeError("The view's length must be 0 when calling respondWithNewView() on a closed stream")}else if(0===t.byteLength)throw new TypeError("The view's length must be greater than 0 when calling respondWithNewView() on a readable stream");if(r.byteOffset+r.bytesFilled!==t.byteOffset)throw new RangeError("The region specified by view does not match byobRequest");if(r.bufferByteLength!==t.buffer.byteLength)throw new RangeError("The buffer of view has different capacity than byobRequest");if(r.bytesFilled+t.byteLength>r.byteLength)throw new RangeError("The region specified by view is larger than byobRequest");r.buffer=t.buffer,qe(e,t.byteLength)}function xe(e,t,r,o,n,s,i){t._controlledReadableByteStream=e,t._pullAgain=!1,t._pulling=!1,t._byobRequest=null,t._queue=t._queueTotalSize=void 0,fe(t),t._closeRequested=!1,t._started=!1,t._strategyHWM=s,t._pullAlgorithm=o,t._cancelAlgorithm=n,t._autoAllocateChunkSize=i,t._pendingPullIntos=new SimpleQueue,e._readableStreamController=t;y(p(r()),(()=>{t._started=!0,be(t)}),(e=>{Ae(t,e)}))}function De(e){return new TypeError(`ReadableStreamBYOBRequest.prototype.${e} can only be used on a ReadableStreamBYOBRequest`)}function Le(e){return new TypeError(`ReadableByteStreamController.prototype.${e} can only be used on a ReadableByteStreamController`)}function Fe(e){return new ReadableStreamBYOBReader(e)}function ze(e,t){e._reader._readIntoRequests.push(t)}function Ie(e){return e._reader._readIntoRequests.length}function Me(e){const t=e._reader;return void 0!==t&&!!$e(t)}Object.defineProperties(ReadableByteStreamController.prototype,{close:{enumerable:!0},enqueue:{enumerable:!0},error:{enumerable:!0},byobRequest:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableByteStreamController.prototype,o.toStringTag,{value:"ReadableByteStreamController",configurable:!0});class ReadableStreamBYOBReader{constructor(e){if(M(e,1,"ReadableStreamBYOBReader"),Q(e,"First parameter"),fr(e))throw new TypeError("This stream has already been locked for exclusive reading by another reader");if(!pe(e._readableStreamController))throw new TypeError("Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte source");T(this,e),this._readIntoRequests=new SimpleQueue}get closed(){return $e(this)?this._closedPromise:h(Ue("closed"))}cancel(e){return $e(this)?void 0===this._ownerReadableStream?h(E("cancel")):q(this,e):h(Ue("cancel"))}read(e){if(!$e(this))return h(Ue("read"));if(!ArrayBuffer.isView(e))return h(new TypeError("view must be an array buffer view"));if(0===e.byteLength)return h(new TypeError("view must have non-zero byteLength"));if(0===e.buffer.byteLength)return h(new TypeError("view's buffer must have non-zero byteLength"));if(e.buffer,void 0===this._ownerReadableStream)return h(E("read from"));let t,r;const o=f(((e,o)=>{t=e,r=o}));return He(this,e,{_chunkSteps:e=>t({value:e,done:!1}),_closeSteps:e=>t({value:e,done:!0}),_errorSteps:e=>r(e)}),o}releaseLock(){if(!$e(this))throw Ue("releaseLock");if(void 0!==this._ownerReadableStream){if(this._readIntoRequests.length>0)throw new TypeError("Tried to release a reader lock when that reader has pending read() calls un-settled");P(this)}}}function $e(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readIntoRequests")&&e instanceof ReadableStreamBYOBReader)}function He(e,t,r){const o=e._ownerReadableStream;o._disturbed=!0,"errored"===o._state?r._errorSteps(o._storedError):function(e,t,r){const o=e._controlledReadableByteStream;let n=1;t.constructor!==DataView&&(n=t.constructor.BYTES_PER_ELEMENT);const s=t.constructor,i=t.buffer,a={buffer:i,bufferByteLength:i.byteLength,byteOffset:t.byteOffset,byteLength:t.byteLength,bytesFilled:0,elementSize:n,viewConstructor:s,readerType:"byob"};if(e._pendingPullIntos.length>0)return e._pendingPullIntos.push(a),void ze(o,r);if("closed"!==o._state){if(e._queueTotalSize>0){if(ve(e,a)){const t=_e(a);return Se(e),void r._chunkSteps(t)}if(e._closeRequested){const t=new TypeError("Insufficient bytes to fill elements in the given buffer");return Ae(e,t),void r._errorSteps(t)}}e._pendingPullIntos.push(a),ze(o,r),be(e)}else{const e=new s(a.buffer,a.byteOffset,0);r._closeSteps(e)}}(o._readableStreamController,t,r)}function Ue(e){return new TypeError(`ReadableStreamBYOBReader.prototype.${e} can only be used on a ReadableStreamBYOBReader`)}function Ne(e,t){const{highWaterMark:r}=e;if(void 0===r)return t;if(se(r)||r<0)throw new RangeError("Invalid highWaterMark");return r}function Qe(e){const{size:t}=e;return t||(()=>1)}function Ye(e,t){F(e,t);const r=null==e?void 0:e.highWaterMark,o=null==e?void 0:e.size;return{highWaterMark:void 0===r?void 0:H(r),size:void 0===o?void 0:Ve(o,`${t} has member 'size' that`)}}function Ve(e,t){return z(e,t),t=>H(e(t))}function Ge(e,t,r){return z(e,r),r=>R(e,t,[r])}function Je(e,t,r){return z(e,r),()=>R(e,t,[])}function Ke(e,t,r){return z(e,r),r=>S(e,t,[r])}function Ze(e,t,r){return z(e,r),(r,o)=>R(e,t,[r,o])}function Xe(e,t){if(!ot(e))throw new TypeError(`${t} is not a WritableStream.`)}Object.defineProperties(ReadableStreamBYOBReader.prototype,{cancel:{enumerable:!0},read:{enumerable:!0},releaseLock:{enumerable:!0},closed:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamBYOBReader.prototype,o.toStringTag,{value:"ReadableStreamBYOBReader",configurable:!0});const et="function"==typeof AbortController;class WritableStream{constructor(e={},t={}){void 0===e?e=null:I(e,"First parameter");const r=Ye(t,"Second parameter"),o=function(e,t){F(e,t);const r=null==e?void 0:e.abort,o=null==e?void 0:e.close,n=null==e?void 0:e.start,s=null==e?void 0:e.type,i=null==e?void 0:e.write;return{abort:void 0===r?void 0:Ge(r,e,`${t} has member 'abort' that`),close:void 0===o?void 0:Je(o,e,`${t} has member 'close' that`),start:void 0===n?void 0:Ke(n,e,`${t} has member 'start' that`),write:void 0===i?void 0:Ze(i,e,`${t} has member 'write' that`),type:s}}(e,"First parameter");rt(this);if(void 0!==o.type)throw new RangeError("Invalid type is specified");const n=Qe(r);!function(e,t,r,o){const n=Object.create(WritableStreamDefaultController.prototype);let s=()=>{},i=()=>p(void 0),a=()=>p(void 0),u=()=>p(void 0);void 0!==t.start&&(s=()=>t.start(n));void 0!==t.write&&(i=e=>t.write(e,n));void 0!==t.close&&(a=()=>t.close());void 0!==t.abort&&(u=e=>t.abort(e));wt(e,n,s,i,a,u,r,o)}(this,o,Ne(r,1),n)}get locked(){if(!ot(this))throw Ct("locked");return nt(this)}abort(e){return ot(this)?nt(this)?h(new TypeError("Cannot abort a stream that already has a writer")):st(this,e):h(Ct("abort"))}close(){return ot(this)?nt(this)?h(new TypeError("Cannot close a stream that already has a writer")):ct(this)?h(new TypeError("Cannot close an already-closing stream")):it(this):h(Ct("close"))}getWriter(){if(!ot(this))throw Ct("getWriter");return tt(this)}}function tt(e){return new WritableStreamDefaultWriter(e)}function rt(e){e._state="writable",e._storedError=void 0,e._writer=void 0,e._writableStreamController=void 0,e._writeRequests=new SimpleQueue,e._inFlightWriteRequest=void 0,e._closeRequest=void 0,e._inFlightCloseRequest=void 0,e._pendingAbortRequest=void 0,e._backpressure=!1}function ot(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_writableStreamController")&&e instanceof WritableStream)}function nt(e){return void 0!==e._writer}function st(e,t){var r;if("closed"===e._state||"errored"===e._state)return p(void 0);e._writableStreamController._abortReason=t,null===(r=e._writableStreamController._abortController)||void 0===r||r.abort();const o=e._state;if("closed"===o||"errored"===o)return p(void 0);if(void 0!==e._pendingAbortRequest)return e._pendingAbortRequest._promise;let n=!1;"erroring"===o&&(n=!0,t=void 0);const s=f(((r,o)=>{e._pendingAbortRequest={_promise:void 0,_resolve:r,_reject:o,_reason:t,_wasAlreadyErroring:n}}));return e._pendingAbortRequest._promise=s,n||ut(e,t),s}function it(e){const t=e._state;if("closed"===t||"errored"===t)return h(new TypeError(`The stream (in ${t} state) is not in the writable state and cannot be closed`));const r=f(((t,r)=>{const o={_resolve:t,_reject:r};e._closeRequest=o})),o=e._writer;var n;return void 0!==o&&e._backpressure&&"writable"===t&&It(o),de(n=e._writableStreamController,gt,0),Tt(n),r}function at(e,t){"writable"!==e._state?lt(e):ut(e,t)}function ut(e,t){const r=e._writableStreamController;e._state="erroring",e._storedError=t;const o=e._writer;void 0!==o&&yt(o,t),!function(e){if(void 0===e._inFlightWriteRequest&&void 0===e._inFlightCloseRequest)return!1;return!0}(e)&&r._started&<(e)}function lt(e){e._state="errored",e._writableStreamController[B]();const t=e._storedError;if(e._writeRequests.forEach((e=>{e._reject(t)})),e._writeRequests=new SimpleQueue,void 0===e._pendingAbortRequest)return void dt(e);const r=e._pendingAbortRequest;if(e._pendingAbortRequest=void 0,r._wasAlreadyErroring)return r._reject(t),void dt(e);y(e._writableStreamController[k](r._reason),(()=>{r._resolve(),dt(e)}),(t=>{r._reject(t),dt(e)}))}function ct(e){return void 0!==e._closeRequest||void 0!==e._inFlightCloseRequest}function dt(e){void 0!==e._closeRequest&&(e._closeRequest._reject(e._storedError),e._closeRequest=void 0);const t=e._writer;void 0!==t&&Wt(t,e._storedError)}function ft(e,t){const r=e._writer;void 0!==r&&t!==e._backpressure&&(t?function(e){Dt(e)}(r):It(r)),e._backpressure=t}Object.defineProperties(WritableStream.prototype,{abort:{enumerable:!0},close:{enumerable:!0},getWriter:{enumerable:!0},locked:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStream.prototype,o.toStringTag,{value:"WritableStream",configurable:!0});class WritableStreamDefaultWriter{constructor(e){if(M(e,1,"WritableStreamDefaultWriter"),Xe(e,"First parameter"),nt(e))throw new TypeError("This stream has already been locked for exclusive writing by another writer");this._ownerWritableStream=e,e._writer=this;const t=e._state;if("writable"===t)!ct(e)&&e._backpressure?Dt(this):Ft(this),kt(this);else if("erroring"===t)Lt(this,e._storedError),kt(this);else if("closed"===t)Ft(this),kt(r=this),xt(r);else{const t=e._storedError;Lt(this,t),Bt(this,t)}var r}get closed(){return pt(this)?this._closedPromise:h(At("closed"))}get desiredSize(){if(!pt(this))throw At("desiredSize");if(void 0===this._ownerWritableStream)throw jt("desiredSize");return function(e){const t=e._ownerWritableStream,r=t._state;if("errored"===r||"erroring"===r)return null;if("closed"===r)return 0;return Rt(t._writableStreamController)}(this)}get ready(){return pt(this)?this._readyPromise:h(At("ready"))}abort(e){return pt(this)?void 0===this._ownerWritableStream?h(jt("abort")):function(e,t){return st(e._ownerWritableStream,t)}(this,e):h(At("abort"))}close(){if(!pt(this))return h(At("close"));const e=this._ownerWritableStream;return void 0===e?h(jt("close")):ct(e)?h(new TypeError("Cannot close an already-closing stream")):ht(this)}releaseLock(){if(!pt(this))throw At("releaseLock");void 0!==this._ownerWritableStream&&mt(this)}write(e){return pt(this)?void 0===this._ownerWritableStream?h(jt("write to")):_t(this,e):h(At("write"))}}function pt(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_ownerWritableStream")&&e instanceof WritableStreamDefaultWriter)}function ht(e){return it(e._ownerWritableStream)}function bt(e,t){"pending"===e._closedPromiseState?Wt(e,t):function(e,t){Bt(e,t)}(e,t)}function yt(e,t){"pending"===e._readyPromiseState?zt(e,t):function(e,t){Lt(e,t)}(e,t)}function mt(e){const t=e._ownerWritableStream,r=new TypeError("Writer was released and can no longer be used to monitor the stream's closedness");yt(e,r),bt(e,r),t._writer=void 0,e._ownerWritableStream=void 0}function _t(e,t){const r=e._ownerWritableStream,o=r._writableStreamController,n=function(e,t){try{return e._strategySizeAlgorithm(t)}catch(t){return qt(e,t),1}}(o,t);if(r!==e._ownerWritableStream)return h(jt("write to"));const s=r._state;if("errored"===s)return h(r._storedError);if(ct(r)||"closed"===s)return h(new TypeError("The stream is closing or closed and cannot be written to"));if("erroring"===s)return h(r._storedError);const i=function(e){return f(((t,r)=>{const o={_resolve:t,_reject:r};e._writeRequests.push(o)}))}(r);return function(e,t,r){try{de(e,t,r)}catch(t){return void qt(e,t)}const o=e._controlledWritableStream;if(!ct(o)&&"writable"===o._state){ft(o,Pt(e))}Tt(e)}(o,t,n),i}Object.defineProperties(WritableStreamDefaultWriter.prototype,{abort:{enumerable:!0},close:{enumerable:!0},releaseLock:{enumerable:!0},write:{enumerable:!0},closed:{enumerable:!0},desiredSize:{enumerable:!0},ready:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStreamDefaultWriter.prototype,o.toStringTag,{value:"WritableStreamDefaultWriter",configurable:!0});const gt={};class WritableStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get abortReason(){if(!vt(this))throw Ot("abortReason");return this._abortReason}get signal(){if(!vt(this))throw Ot("signal");if(void 0===this._abortController)throw new TypeError("WritableStreamDefaultController.prototype.signal is not supported");return this._abortController.signal}error(e){if(!vt(this))throw Ot("error");"writable"===this._controlledWritableStream._state&&Et(this,e)}[k](e){const t=this._abortAlgorithm(e);return St(this),t}[B](){fe(this)}}function vt(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledWritableStream")&&e instanceof WritableStreamDefaultController)}function wt(e,t,r,o,n,s,i,a){t._controlledWritableStream=e,e._writableStreamController=t,t._queue=void 0,t._queueTotalSize=void 0,fe(t),t._abortReason=void 0,t._abortController=function(){if(et)return new AbortController}(),t._started=!1,t._strategySizeAlgorithm=a,t._strategyHWM=i,t._writeAlgorithm=o,t._closeAlgorithm=n,t._abortAlgorithm=s;const u=Pt(t);ft(e,u);y(p(r()),(()=>{t._started=!0,Tt(t)}),(r=>{t._started=!0,at(e,r)}))}function St(e){e._writeAlgorithm=void 0,e._closeAlgorithm=void 0,e._abortAlgorithm=void 0,e._strategySizeAlgorithm=void 0}function Rt(e){return e._strategyHWM-e._queueTotalSize}function Tt(e){const t=e._controlledWritableStream;if(!e._started)return;if(void 0!==t._inFlightWriteRequest)return;if("erroring"===t._state)return void lt(t);if(0===e._queue.length)return;const r=e._queue.peek().value;r===gt?function(e){const t=e._controlledWritableStream;(function(e){e._inFlightCloseRequest=e._closeRequest,e._closeRequest=void 0})(t),ce(e);const r=e._closeAlgorithm();St(e),y(r,(()=>{!function(e){e._inFlightCloseRequest._resolve(void 0),e._inFlightCloseRequest=void 0,"erroring"===e._state&&(e._storedError=void 0,void 0!==e._pendingAbortRequest&&(e._pendingAbortRequest._resolve(),e._pendingAbortRequest=void 0)),e._state="closed";const t=e._writer;void 0!==t&&xt(t)}(t)}),(e=>{!function(e,t){e._inFlightCloseRequest._reject(t),e._inFlightCloseRequest=void 0,void 0!==e._pendingAbortRequest&&(e._pendingAbortRequest._reject(t),e._pendingAbortRequest=void 0),at(e,t)}(t,e)}))}(e):function(e,t){const r=e._controlledWritableStream;!function(e){e._inFlightWriteRequest=e._writeRequests.shift()}(r);y(e._writeAlgorithm(t),(()=>{!function(e){e._inFlightWriteRequest._resolve(void 0),e._inFlightWriteRequest=void 0}(r);const t=r._state;if(ce(e),!ct(r)&&"writable"===t){const t=Pt(e);ft(r,t)}Tt(e)}),(t=>{"writable"===r._state&&St(e),function(e,t){e._inFlightWriteRequest._reject(t),e._inFlightWriteRequest=void 0,at(e,t)}(r,t)}))}(e,r)}function qt(e,t){"writable"===e._controlledWritableStream._state&&Et(e,t)}function Pt(e){return Rt(e)<=0}function Et(e,t){const r=e._controlledWritableStream;St(e),ut(r,t)}function Ct(e){return new TypeError(`WritableStream.prototype.${e} can only be used on a WritableStream`)}function Ot(e){return new TypeError(`WritableStreamDefaultController.prototype.${e} can only be used on a WritableStreamDefaultController`)}function At(e){return new TypeError(`WritableStreamDefaultWriter.prototype.${e} can only be used on a WritableStreamDefaultWriter`)}function jt(e){return new TypeError("Cannot "+e+" a stream using a released writer")}function kt(e){e._closedPromise=f(((t,r)=>{e._closedPromise_resolve=t,e._closedPromise_reject=r,e._closedPromiseState="pending"}))}function Bt(e,t){kt(e),Wt(e,t)}function Wt(e,t){void 0!==e._closedPromise_reject&&(v(e._closedPromise),e._closedPromise_reject(t),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0,e._closedPromiseState="rejected")}function xt(e){void 0!==e._closedPromise_resolve&&(e._closedPromise_resolve(void 0),e._closedPromise_resolve=void 0,e._closedPromise_reject=void 0,e._closedPromiseState="resolved")}function Dt(e){e._readyPromise=f(((t,r)=>{e._readyPromise_resolve=t,e._readyPromise_reject=r})),e._readyPromiseState="pending"}function Lt(e,t){Dt(e),zt(e,t)}function Ft(e){Dt(e),It(e)}function zt(e,t){void 0!==e._readyPromise_reject&&(v(e._readyPromise),e._readyPromise_reject(t),e._readyPromise_resolve=void 0,e._readyPromise_reject=void 0,e._readyPromiseState="rejected")}function It(e){void 0!==e._readyPromise_resolve&&(e._readyPromise_resolve(void 0),e._readyPromise_resolve=void 0,e._readyPromise_reject=void 0,e._readyPromiseState="fulfilled")}Object.defineProperties(WritableStreamDefaultController.prototype,{error:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(WritableStreamDefaultController.prototype,o.toStringTag,{value:"WritableStreamDefaultController",configurable:!0});const Mt="undefined"!=typeof DOMException?DOMException:void 0;const $t=function(e){if("function"!=typeof e&&"object"!=typeof e)return!1;try{return new e,!0}catch(e){return!1}}(Mt)?Mt:function(){const e=function(e,t){this.message=e||"",this.name=t||"Error",Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)};return e.prototype=Object.create(Error.prototype),Object.defineProperty(e.prototype,"constructor",{value:e,writable:!0,configurable:!0}),e}();function Ht(e,t,r,o,s,i){const a=Y(e),u=tt(t);e._disturbed=!0;let l=!1,c=p(void 0);return f(((d,g)=>{let w;if(void 0!==i){if(w=()=>{const r=new $t("Aborted","AbortError"),n=[];o||n.push((()=>"writable"===t._state?st(t,r):p(void 0))),s||n.push((()=>"readable"===e._state?pr(e,r):p(void 0))),C((()=>Promise.all(n.map((e=>e())))),!0,r)},i.aborted)return void w();i.addEventListener("abort",w)}var S,R,T;if(E(e,a._closedPromise,(e=>{o?O(!0,e):C((()=>st(t,e)),!0,e)})),E(t,u._closedPromise,(t=>{s?O(!0,t):C((()=>pr(e,t)),!0,t)})),S=e,R=a._closedPromise,T=()=>{r?O():C((()=>function(e){const t=e._ownerWritableStream,r=t._state;return ct(t)||"closed"===r?p(void 0):"errored"===r?h(t._storedError):ht(e)}(u)))},"closed"===S._state?T():m(R,T),ct(t)||"closed"===t._state){const t=new TypeError("the destination writable stream closed before all data could be piped to it");s?O(!0,t):C((()=>pr(e,t)),!0,t)}function q(){const e=c;return b(c,(()=>e!==c?q():void 0))}function E(e,t,r){"errored"===e._state?r(e._storedError):_(t,r)}function C(e,r,o){function n(){y(e(),(()=>A(r,o)),(e=>A(!0,e)))}l||(l=!0,"writable"!==t._state||ct(t)?n():m(q(),n))}function O(e,r){l||(l=!0,"writable"!==t._state||ct(t)?A(e,r):m(q(),(()=>A(e,r))))}function A(e,t){mt(u),P(a),void 0!==i&&i.removeEventListener("abort",w),e?g(t):d(void 0)}v(f(((e,t)=>{!function r(o){o?e():b(l?p(!0):b(u._readyPromise,(()=>f(((e,t)=>{X(a,{_chunkSteps:t=>{c=b(_t(u,t),void 0,n),e(!1)},_closeSteps:()=>e(!0),_errorSteps:t})})))),r,t)}(!1)})))}))}class ReadableStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get desiredSize(){if(!Ut(this))throw er("desiredSize");return Kt(this)}close(){if(!Ut(this))throw er("close");if(!Zt(this))throw new TypeError("The stream is not in a state that permits close");Vt(this)}enqueue(e){if(!Ut(this))throw er("enqueue");if(!Zt(this))throw new TypeError("The stream is not in a state that permits enqueue");return Gt(this,e)}error(e){if(!Ut(this))throw er("error");Jt(this,e)}[W](e){fe(this);const t=this._cancelAlgorithm(e);return Yt(this),t}[x](e){const t=this._controlledReadableStream;if(this._queue.length>0){const r=ce(this);this._closeRequested&&0===this._queue.length?(Yt(this),hr(t)):Nt(this),e._chunkSteps(r)}else V(t,e),Nt(this)}}function Ut(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledReadableStream")&&e instanceof ReadableStreamDefaultController)}function Nt(e){if(!Qt(e))return;if(e._pulling)return void(e._pullAgain=!0);e._pulling=!0;y(e._pullAlgorithm(),(()=>{e._pulling=!1,e._pullAgain&&(e._pullAgain=!1,Nt(e))}),(t=>{Jt(e,t)}))}function Qt(e){const t=e._controlledReadableStream;if(!Zt(e))return!1;if(!e._started)return!1;if(fr(t)&&J(t)>0)return!0;return Kt(e)>0}function Yt(e){e._pullAlgorithm=void 0,e._cancelAlgorithm=void 0,e._strategySizeAlgorithm=void 0}function Vt(e){if(!Zt(e))return;const t=e._controlledReadableStream;e._closeRequested=!0,0===e._queue.length&&(Yt(e),hr(t))}function Gt(e,t){if(!Zt(e))return;const r=e._controlledReadableStream;if(fr(r)&&J(r)>0)G(r,t,!1);else{let r;try{r=e._strategySizeAlgorithm(t)}catch(t){throw Jt(e,t),t}try{de(e,t,r)}catch(t){throw Jt(e,t),t}}Nt(e)}function Jt(e,t){const r=e._controlledReadableStream;"readable"===r._state&&(fe(e),Yt(e),br(r,t))}function Kt(e){const t=e._controlledReadableStream._state;return"errored"===t?null:"closed"===t?0:e._strategyHWM-e._queueTotalSize}function Zt(e){const t=e._controlledReadableStream._state;return!e._closeRequested&&"readable"===t}function Xt(e,t,r,o,n,s,i){t._controlledReadableStream=e,t._queue=void 0,t._queueTotalSize=void 0,fe(t),t._started=!1,t._closeRequested=!1,t._pullAgain=!1,t._pulling=!1,t._strategySizeAlgorithm=i,t._strategyHWM=s,t._pullAlgorithm=o,t._cancelAlgorithm=n,e._readableStreamController=t;y(p(r()),(()=>{t._started=!0,Nt(t)}),(e=>{Jt(t,e)}))}function er(e){return new TypeError(`ReadableStreamDefaultController.prototype.${e} can only be used on a ReadableStreamDefaultController`)}function tr(e,t){return pe(e._readableStreamController)?function(e){let t,r,o,n,s,i=Y(e),a=!1,u=!1,l=!1;const c=f((e=>{s=e}));function d(e){_(e._closedPromise,(t=>{e===i&&(Ae(o._readableStreamController,t),Ae(n._readableStreamController,t),u&&l||s(void 0))}))}function h(){$e(i)&&(P(i),i=Y(e),d(i));X(i,{_chunkSteps:t=>{w((()=>{a=!1;const r=t;let i=t;if(!u&&!l)try{i=le(t)}catch(t){return Ae(o._readableStreamController,t),Ae(n._readableStreamController,t),void s(pr(e,t))}u||Oe(o._readableStreamController,r),l||Oe(n._readableStreamController,i)}))},_closeSteps:()=>{a=!1,u||Ce(o._readableStreamController),l||Ce(n._readableStreamController),o._readableStreamController._pendingPullIntos.length>0&&Be(o._readableStreamController,0),n._readableStreamController._pendingPullIntos.length>0&&Be(n._readableStreamController,0),u&&l||s(void 0)},_errorSteps:()=>{a=!1}})}function b(t,r){Z(i)&&(P(i),i=Fe(e),d(i));const c=r?n:o,f=r?o:n;He(i,t,{_chunkSteps:t=>{w((()=>{a=!1;const o=r?l:u;if(r?u:l)o||We(c._readableStreamController,t);else{let r;try{r=le(t)}catch(t){return Ae(c._readableStreamController,t),Ae(f._readableStreamController,t),void s(pr(e,t))}o||We(c._readableStreamController,t),Oe(f._readableStreamController,r)}}))},_closeSteps:e=>{a=!1;const t=r?l:u,o=r?u:l;t||Ce(c._readableStreamController),o||Ce(f._readableStreamController),void 0!==e&&(t||We(c._readableStreamController,e),!o&&f._readableStreamController._pendingPullIntos.length>0&&Be(f._readableStreamController,0)),t&&o||s(void 0)},_errorSteps:()=>{a=!1}})}function y(){if(a)return p(void 0);a=!0;const e=je(o._readableStreamController);return null===e?h():b(e._view,!1),p(void 0)}function m(){if(a)return p(void 0);a=!0;const e=je(n._readableStreamController);return null===e?h():b(e._view,!0),p(void 0)}function g(o){if(u=!0,t=o,l){const o=ie([t,r]),n=pr(e,o);s(n)}return c}function v(o){if(l=!0,r=o,u){const o=ie([t,r]),n=pr(e,o);s(n)}return c}function S(){}return o=lr(S,y,g),n=lr(S,m,v),d(i),[o,n]}(e):function(e,t){const r=Y(e);let o,n,s,i,a,u=!1,l=!1,c=!1;const d=f((e=>{a=e}));function h(){if(u)return p(void 0);u=!0;return X(r,{_chunkSteps:e=>{w((()=>{u=!1;const t=e,r=e;l||Gt(s._readableStreamController,t),c||Gt(i._readableStreamController,r)}))},_closeSteps:()=>{u=!1,l||Vt(s._readableStreamController),c||Vt(i._readableStreamController),l&&c||a(void 0)},_errorSteps:()=>{u=!1}}),p(void 0)}function b(t){if(l=!0,o=t,c){const t=ie([o,n]),r=pr(e,t);a(r)}return d}function y(t){if(c=!0,n=t,l){const t=ie([o,n]),r=pr(e,t);a(r)}return d}function m(){}return s=ur(m,h,b),i=ur(m,h,y),_(r._closedPromise,(e=>{Jt(s._readableStreamController,e),Jt(i._readableStreamController,e),l&&c||a(void 0)})),[s,i]}(e)}function rr(e,t,r){return z(e,r),r=>R(e,t,[r])}function or(e,t,r){return z(e,r),r=>R(e,t,[r])}function nr(e,t,r){return z(e,r),r=>S(e,t,[r])}function sr(e,t){if("bytes"!==(e=`${e}`))throw new TypeError(`${t} '${e}' is not a valid enumeration value for ReadableStreamType`);return e}function ir(e,t){if("byob"!==(e=`${e}`))throw new TypeError(`${t} '${e}' is not a valid enumeration value for ReadableStreamReaderMode`);return e}function ar(e,t){F(e,t);const r=null==e?void 0:e.preventAbort,o=null==e?void 0:e.preventCancel,n=null==e?void 0:e.preventClose,s=null==e?void 0:e.signal;return void 0!==s&&function(e,t){if(!function(e){if("object"!=typeof e||null===e)return!1;try{return"boolean"==typeof e.aborted}catch(e){return!1}}(e))throw new TypeError(`${t} is not an AbortSignal.`)}(s,`${t} has member 'signal' that`),{preventAbort:Boolean(r),preventCancel:Boolean(o),preventClose:Boolean(n),signal:s}}Object.defineProperties(ReadableStreamDefaultController.prototype,{close:{enumerable:!0},enqueue:{enumerable:!0},error:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStreamDefaultController.prototype,o.toStringTag,{value:"ReadableStreamDefaultController",configurable:!0});class ReadableStream{constructor(e={},t={}){void 0===e?e=null:I(e,"First parameter");const r=Ye(t,"Second parameter"),o=function(e,t){F(e,t);const r=e,o=null==r?void 0:r.autoAllocateChunkSize,n=null==r?void 0:r.cancel,s=null==r?void 0:r.pull,i=null==r?void 0:r.start,a=null==r?void 0:r.type;return{autoAllocateChunkSize:void 0===o?void 0:N(o,`${t} has member 'autoAllocateChunkSize' that`),cancel:void 0===n?void 0:rr(n,r,`${t} has member 'cancel' that`),pull:void 0===s?void 0:or(s,r,`${t} has member 'pull' that`),start:void 0===i?void 0:nr(i,r,`${t} has member 'start' that`),type:void 0===a?void 0:sr(a,`${t} has member 'type' that`)}}(e,"First parameter");if(cr(this),"bytes"===o.type){if(void 0!==r.size)throw new RangeError("The strategy for a byte stream cannot have a size function");!function(e,t,r){const o=Object.create(ReadableByteStreamController.prototype);let n=()=>{},s=()=>p(void 0),i=()=>p(void 0);void 0!==t.start&&(n=()=>t.start(o)),void 0!==t.pull&&(s=()=>t.pull(o)),void 0!==t.cancel&&(i=e=>t.cancel(e));const a=t.autoAllocateChunkSize;if(0===a)throw new TypeError("autoAllocateChunkSize must be greater than 0");xe(e,o,n,s,i,r,a)}(this,o,Ne(r,0))}else{const e=Qe(r);!function(e,t,r,o){const n=Object.create(ReadableStreamDefaultController.prototype);let s=()=>{},i=()=>p(void 0),a=()=>p(void 0);void 0!==t.start&&(s=()=>t.start(n)),void 0!==t.pull&&(i=()=>t.pull(n)),void 0!==t.cancel&&(a=e=>t.cancel(e)),Xt(e,n,s,i,a,r,o)}(this,o,Ne(r,1),e)}}get locked(){if(!dr(this))throw yr("locked");return fr(this)}cancel(e){return dr(this)?fr(this)?h(new TypeError("Cannot cancel a stream that already has a reader")):pr(this,e):h(yr("cancel"))}getReader(e){if(!dr(this))throw yr("getReader");return void 0===function(e,t){F(e,t);const r=null==e?void 0:e.mode;return{mode:void 0===r?void 0:ir(r,`${t} has member 'mode' that`)}}(e,"First parameter").mode?Y(this):Fe(this)}pipeThrough(e,t={}){if(!dr(this))throw yr("pipeThrough");M(e,1,"pipeThrough");const r=function(e,t){F(e,t);const r=null==e?void 0:e.readable;$(r,"readable","ReadableWritablePair"),Q(r,`${t} has member 'readable' that`);const o=null==e?void 0:e.writable;return $(o,"writable","ReadableWritablePair"),Xe(o,`${t} has member 'writable' that`),{readable:r,writable:o}}(e,"First parameter"),o=ar(t,"Second parameter");if(fr(this))throw new TypeError("ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream");if(nt(r.writable))throw new TypeError("ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream");return v(Ht(this,r.writable,o.preventClose,o.preventAbort,o.preventCancel,o.signal)),r.readable}pipeTo(e,t={}){if(!dr(this))return h(yr("pipeTo"));if(void 0===e)return h("Parameter 1 is required in 'pipeTo'.");if(!ot(e))return h(new TypeError("ReadableStream.prototype.pipeTo's first argument must be a WritableStream"));let r;try{r=ar(t,"Second parameter")}catch(e){return h(e)}return fr(this)?h(new TypeError("ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream")):nt(e)?h(new TypeError("ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream")):Ht(this,e,r.preventClose,r.preventAbort,r.preventCancel,r.signal)}tee(){if(!dr(this))throw yr("tee");return ie(tr(this))}values(e){if(!dr(this))throw yr("values");return function(e,t){const r=Y(e),o=new ReadableStreamAsyncIteratorImpl(r,t),n=Object.create(re);return n._asyncIteratorImpl=o,n}(this,function(e,t){F(e,t);const r=null==e?void 0:e.preventCancel;return{preventCancel:Boolean(r)}}(e,"First parameter").preventCancel)}}function ur(e,t,r,o=1,n=(()=>1)){const s=Object.create(ReadableStream.prototype);cr(s);return Xt(s,Object.create(ReadableStreamDefaultController.prototype),e,t,r,o,n),s}function lr(e,t,r){const o=Object.create(ReadableStream.prototype);cr(o);return xe(o,Object.create(ReadableByteStreamController.prototype),e,t,r,0,void 0),o}function cr(e){e._state="readable",e._reader=void 0,e._storedError=void 0,e._disturbed=!1}function dr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_readableStreamController")&&e instanceof ReadableStream)}function fr(e){return void 0!==e._reader}function pr(e,t){if(e._disturbed=!0,"closed"===e._state)return p(void 0);if("errored"===e._state)return h(e._storedError);hr(e);const r=e._reader;void 0!==r&&$e(r)&&(r._readIntoRequests.forEach((e=>{e._closeSteps(void 0)})),r._readIntoRequests=new SimpleQueue);return g(e._readableStreamController[W](t),n)}function hr(e){e._state="closed";const t=e._reader;void 0!==t&&(j(t),Z(t)&&(t._readRequests.forEach((e=>{e._closeSteps()})),t._readRequests=new SimpleQueue))}function br(e,t){e._state="errored",e._storedError=t;const r=e._reader;void 0!==r&&(A(r,t),Z(r)?(r._readRequests.forEach((e=>{e._errorSteps(t)})),r._readRequests=new SimpleQueue):(r._readIntoRequests.forEach((e=>{e._errorSteps(t)})),r._readIntoRequests=new SimpleQueue))}function yr(e){return new TypeError(`ReadableStream.prototype.${e} can only be used on a ReadableStream`)}function mr(e,t){F(e,t);const r=null==e?void 0:e.highWaterMark;return $(r,"highWaterMark","QueuingStrategyInit"),{highWaterMark:H(r)}}Object.defineProperties(ReadableStream.prototype,{cancel:{enumerable:!0},getReader:{enumerable:!0},pipeThrough:{enumerable:!0},pipeTo:{enumerable:!0},tee:{enumerable:!0},values:{enumerable:!0},locked:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ReadableStream.prototype,o.toStringTag,{value:"ReadableStream",configurable:!0}),"symbol"==typeof o.asyncIterator&&Object.defineProperty(ReadableStream.prototype,o.asyncIterator,{value:ReadableStream.prototype.values,writable:!0,configurable:!0});const _r=e=>e.byteLength;Object.defineProperty(_r,"name",{value:"size",configurable:!0});class ByteLengthQueuingStrategy{constructor(e){M(e,1,"ByteLengthQueuingStrategy"),e=mr(e,"First parameter"),this._byteLengthQueuingStrategyHighWaterMark=e.highWaterMark}get highWaterMark(){if(!vr(this))throw gr("highWaterMark");return this._byteLengthQueuingStrategyHighWaterMark}get size(){if(!vr(this))throw gr("size");return _r}}function gr(e){return new TypeError(`ByteLengthQueuingStrategy.prototype.${e} can only be used on a ByteLengthQueuingStrategy`)}function vr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_byteLengthQueuingStrategyHighWaterMark")&&e instanceof ByteLengthQueuingStrategy)}Object.defineProperties(ByteLengthQueuingStrategy.prototype,{highWaterMark:{enumerable:!0},size:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(ByteLengthQueuingStrategy.prototype,o.toStringTag,{value:"ByteLengthQueuingStrategy",configurable:!0});const wr=()=>1;Object.defineProperty(wr,"name",{value:"size",configurable:!0});class CountQueuingStrategy{constructor(e){M(e,1,"CountQueuingStrategy"),e=mr(e,"First parameter"),this._countQueuingStrategyHighWaterMark=e.highWaterMark}get highWaterMark(){if(!Rr(this))throw Sr("highWaterMark");return this._countQueuingStrategyHighWaterMark}get size(){if(!Rr(this))throw Sr("size");return wr}}function Sr(e){return new TypeError(`CountQueuingStrategy.prototype.${e} can only be used on a CountQueuingStrategy`)}function Rr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_countQueuingStrategyHighWaterMark")&&e instanceof CountQueuingStrategy)}function Tr(e,t,r){return z(e,r),r=>R(e,t,[r])}function qr(e,t,r){return z(e,r),r=>S(e,t,[r])}function Pr(e,t,r){return z(e,r),(r,o)=>R(e,t,[r,o])}Object.defineProperties(CountQueuingStrategy.prototype,{highWaterMark:{enumerable:!0},size:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(CountQueuingStrategy.prototype,o.toStringTag,{value:"CountQueuingStrategy",configurable:!0});class TransformStream{constructor(e={},t={},r={}){void 0===e&&(e=null);const o=Ye(t,"Second parameter"),n=Ye(r,"Third parameter"),s=function(e,t){F(e,t);const r=null==e?void 0:e.flush,o=null==e?void 0:e.readableType,n=null==e?void 0:e.start,s=null==e?void 0:e.transform,i=null==e?void 0:e.writableType;return{flush:void 0===r?void 0:Tr(r,e,`${t} has member 'flush' that`),readableType:o,start:void 0===n?void 0:qr(n,e,`${t} has member 'start' that`),transform:void 0===s?void 0:Pr(s,e,`${t} has member 'transform' that`),writableType:i}}(e,"First parameter");if(void 0!==s.readableType)throw new RangeError("Invalid readableType specified");if(void 0!==s.writableType)throw new RangeError("Invalid writableType specified");const i=Ne(n,0),a=Qe(n),u=Ne(o,1),l=Qe(o);let c;!function(e,t,r,o,n,s){function i(){return t}function a(t){return function(e,t){const r=e._transformStreamController;if(e._backpressure){return g(e._backpressureChangePromise,(()=>{const o=e._writable;if("erroring"===o._state)throw o._storedError;return Wr(r,t)}))}return Wr(r,t)}(e,t)}function u(t){return function(e,t){return Cr(e,t),p(void 0)}(e,t)}function l(){return function(e){const t=e._readable,r=e._transformStreamController,o=r._flushAlgorithm();return kr(r),g(o,(()=>{if("errored"===t._state)throw t._storedError;Vt(t._readableStreamController)}),(r=>{throw Cr(e,r),t._storedError}))}(e)}function c(){return function(e){return Ar(e,!1),e._backpressureChangePromise}(e)}function d(t){return Or(e,t),p(void 0)}e._writable=function(e,t,r,o,n=1,s=(()=>1)){const i=Object.create(WritableStream.prototype);return rt(i),wt(i,Object.create(WritableStreamDefaultController.prototype),e,t,r,o,n,s),i}(i,a,l,u,r,o),e._readable=ur(i,c,d,n,s),e._backpressure=void 0,e._backpressureChangePromise=void 0,e._backpressureChangePromise_resolve=void 0,Ar(e,!0),e._transformStreamController=void 0}(this,f((e=>{c=e})),u,l,i,a),function(e,t){const r=Object.create(TransformStreamDefaultController.prototype);let o=e=>{try{return Br(r,e),p(void 0)}catch(e){return h(e)}},n=()=>p(void 0);void 0!==t.transform&&(o=e=>t.transform(e,r));void 0!==t.flush&&(n=()=>t.flush(r));!function(e,t,r,o){t._controlledTransformStream=e,e._transformStreamController=t,t._transformAlgorithm=r,t._flushAlgorithm=o}(e,r,o,n)}(this,s),void 0!==s.start?c(s.start(this._transformStreamController)):c(void 0)}get readable(){if(!Er(this))throw Dr("readable");return this._readable}get writable(){if(!Er(this))throw Dr("writable");return this._writable}}function Er(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_transformStreamController")&&e instanceof TransformStream)}function Cr(e,t){Jt(e._readable._readableStreamController,t),Or(e,t)}function Or(e,t){kr(e._transformStreamController),qt(e._writable._writableStreamController,t),e._backpressure&&Ar(e,!1)}function Ar(e,t){void 0!==e._backpressureChangePromise&&e._backpressureChangePromise_resolve(),e._backpressureChangePromise=f((t=>{e._backpressureChangePromise_resolve=t})),e._backpressure=t}Object.defineProperties(TransformStream.prototype,{readable:{enumerable:!0},writable:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(TransformStream.prototype,o.toStringTag,{value:"TransformStream",configurable:!0});class TransformStreamDefaultController{constructor(){throw new TypeError("Illegal constructor")}get desiredSize(){if(!jr(this))throw xr("desiredSize");return Kt(this._controlledTransformStream._readable._readableStreamController)}enqueue(e){if(!jr(this))throw xr("enqueue");Br(this,e)}error(e){if(!jr(this))throw xr("error");var t;t=e,Cr(this._controlledTransformStream,t)}terminate(){if(!jr(this))throw xr("terminate");!function(e){const t=e._controlledTransformStream;Vt(t._readable._readableStreamController);const r=new TypeError("TransformStream terminated");Or(t,r)}(this)}}function jr(e){return!!i(e)&&(!!Object.prototype.hasOwnProperty.call(e,"_controlledTransformStream")&&e instanceof TransformStreamDefaultController)}function kr(e){e._transformAlgorithm=void 0,e._flushAlgorithm=void 0}function Br(e,t){const r=e._controlledTransformStream,o=r._readable._readableStreamController;if(!Zt(o))throw new TypeError("Readable side is not in a state that permits enqueue");try{Gt(o,t)}catch(e){throw Or(r,e),r._readable._storedError}const n=function(e){return!Qt(e)}(o);n!==r._backpressure&&Ar(r,!0)}function Wr(e,t){return g(e._transformAlgorithm(t),void 0,(t=>{throw Cr(e._controlledTransformStream,t),t}))}function xr(e){return new TypeError(`TransformStreamDefaultController.prototype.${e} can only be used on a TransformStreamDefaultController`)}function Dr(e){return new TypeError(`TransformStream.prototype.${e} can only be used on a TransformStream`)}Object.defineProperties(TransformStreamDefaultController.prototype,{enqueue:{enumerable:!0},error:{enumerable:!0},terminate:{enumerable:!0},desiredSize:{enumerable:!0}}),"symbol"==typeof o.toStringTag&&Object.defineProperty(TransformStreamDefaultController.prototype,o.toStringTag,{value:"TransformStreamDefaultController",configurable:!0})}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var s=t[o]={id:o,loaded:!1,exports:{}};return e[o].call(s.exports,s,s.exports,r),s.loaded=!0,s.exports}return r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r(48)})()})); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,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UzhwQyxFQUF5QkUsR0FBWSxDQUNqRDFpQyxHQUFJMGlDLEVBQ0pFLFFBQVEsRUFDUm5xQyxRQUFTLElBVVYsT0FOQW9xQyxFQUFvQkgsR0FBVW5vQyxLQUFLN0IsRUFBT0QsUUFBU0MsRUFBUUEsRUFBT0QsUUFBU2dxQyxHQUczRS9wQyxFQUFPa3FDLFFBQVMsRUFHVGxxQyxFQUFPRCxlQ3ZCZmdxQyxFQUFvQnA3QixFQUFJLENBQUM1TyxFQUFTcXFDLEtBQ2pDLElBQUksSUFBSXZuQyxLQUFPdW5DLEVBQ1hMLEVBQW9CTSxFQUFFRCxFQUFZdm5DLEtBQVNrbkMsRUFBb0JNLEVBQUV0cUMsRUFBUzhDLElBQzVFekMsT0FBT0MsZUFBZU4sRUFBUzhDLEVBQUssQ0FBRXpCLFlBQVksRUFBTUwsSUFBS3FwQyxFQUFXdm5DLE1DSjNFa25DLEVBQW9CTSxFQUFJLENBQUNuK0IsRUFBS28rQixJQUFVbHFDLE9BQU9hLFVBQVU4dEIsZUFBZWx0QixLQUFLcUssRUFBS28rQixHQ0NsRlAsRUFBb0JyVCxFQUFLMzJCLElBQ0gsb0JBQVhzQixRQUEwQkEsT0FBT0MsYUFDMUNsQixPQUFPQyxlQUFlTixFQUFTc0IsT0FBT0MsWUFBYSxDQUFFaEIsTUFBTyxXQUU3REYsT0FBT0MsZUFBZU4sRUFBUyxhQUFjLENBQUVPLE9BQU8sS0NMdkR5cEMsRUFBb0JRLElBQU92cUMsSUFDMUJBLEVBQU93cUMsTUFBUSxHQUNWeHFDLEVBQU95cUMsV0FBVXpxQyxFQUFPeXFDLFNBQVcsSUFDakN6cUMsR0NBa0IrcEMsRUFBb0IsS3hDTzlDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24iLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hYm9ydC1jb250cm9sbGVyL2Rpc3QvYWJvcnQtY29udHJvbGxlci5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9jbGllbnQudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9kb21haW5zLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvZXJyb3IudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9ldmVudHMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9pcC1wb29scy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2lwcy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2xpc3RzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvbWFpbExpc3RNZW1iZXJzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvbWVzc2FnZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9wYXJzZS50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3JlcXVlc3QudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9yb3V0ZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9zdGF0cy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3N1cHByZXNzaW9ucy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL3ZhbGlkYXRlLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvd2ViaG9va3MudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9iYXNlLTY0L2Jhc2U2NC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RhdGEtdXJpLXRvLWJ1ZmZlci9kaXN0L3NyYy9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2V2ZW50LXRhcmdldC1zaGltL2Rpc3QvZXZlbnQtdGFyZ2V0LXNoaW0uanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9mZXRjaC1ibG9iL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMva3ktdW5pdmVyc2FsL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMva3kvdW1kLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvdXJsLWpvaW4vbGliL3VybC1qb2luLmpzIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImNyeXB0b1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImh0dHBcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJodHRwc1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInN0cmVhbVwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInVybFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInV0aWxcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJ6bGliXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9ub2RlLWZldGNoL2Rpc3QvaW5kZXguY2pzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvd2ViLXN0cmVhbXMtcG9seWZpbGwvZGlzdC9wb255ZmlsbC5lczIwMTgubWpzIiwid2VicGFjazovL21haWxndW4vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3J1bnRpbWUvaGFzT3duUHJvcGVydHkgc2hvcnRoYW5kIiwid2VicGFjazovL21haWxndW4vd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9tYWlsZ3VuL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3N0YXJ0dXAiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wibWFpbGd1blwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJtYWlsZ3VuXCJdID0gZmFjdG9yeSgpO1xufSkodGhpcywgZnVuY3Rpb24oKSB7XG5yZXR1cm4gIiwiLyoqXG4gKiBAYXV0aG9yIFRvcnUgTmFnYXNoaW1hIDxodHRwczovL2dpdGh1Yi5jb20vbXlzdGljYXRlYT5cbiAqIFNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBkaXJlY3RvcnkgZm9yIGZ1bGwgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgZXZlbnRUYXJnZXRTaGltID0gcmVxdWlyZSgnZXZlbnQtdGFyZ2V0LXNoaW0nKTtcblxuLyoqXG4gKiBUaGUgc2lnbmFsIGNsYXNzLlxuICogQHNlZSBodHRwczovL2RvbS5zcGVjLndoYXR3Zy5vcmcvI2Fib3J0c2lnbmFsXG4gKi9cbmNsYXNzIEFib3J0U2lnbmFsIGV4dGVuZHMgZXZlbnRUYXJnZXRTaGltLkV2ZW50VGFyZ2V0IHtcbiAgICAvKipcbiAgICAgKiBBYm9ydFNpZ25hbCBjYW5ub3QgYmUgY29uc3RydWN0ZWQgZGlyZWN0bHkuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJBYm9ydFNpZ25hbCBjYW5ub3QgYmUgY29uc3RydWN0ZWQgZGlyZWN0bHlcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYHRydWVgIGlmIHRoaXMgYEFib3J0U2lnbmFsYCdzIGBBYm9ydENvbnRyb2xsZXJgIGhhcyBzaWduYWxlZCB0byBhYm9ydCwgYW5kIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGdldCBhYm9ydGVkKCkge1xuICAgICAgICBjb25zdCBhYm9ydGVkID0gYWJvcnRlZEZsYWdzLmdldCh0aGlzKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhYm9ydGVkICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgRXhwZWN0ZWQgJ3RoaXMnIHRvIGJlIGFuICdBYm9ydFNpZ25hbCcgb2JqZWN0LCBidXQgZ290ICR7dGhpcyA9PT0gbnVsbCA/IFwibnVsbFwiIDogdHlwZW9mIHRoaXN9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFib3J0ZWQ7XG4gICAgfVxufVxuZXZlbnRUYXJnZXRTaGltLmRlZmluZUV2ZW50QXR0cmlidXRlKEFib3J0U2lnbmFsLnByb3RvdHlwZSwgXCJhYm9ydFwiKTtcbi8qKlxuICogQ3JlYXRlIGFuIEFib3J0U2lnbmFsIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQWJvcnRTaWduYWwoKSB7XG4gICAgY29uc3Qgc2lnbmFsID0gT2JqZWN0LmNyZWF0ZShBYm9ydFNpZ25hbC5wcm90b3R5cGUpO1xuICAgIGV2ZW50VGFyZ2V0U2hpbS5FdmVudFRhcmdldC5jYWxsKHNpZ25hbCk7XG4gICAgYWJvcnRlZEZsYWdzLnNldChzaWduYWwsIGZhbHNlKTtcbiAgICByZXR1cm4gc2lnbmFsO1xufVxuLyoqXG4gKiBBYm9ydCBhIGdpdmVuIHNpZ25hbC5cbiAqL1xuZnVuY3Rpb24gYWJvcnRTaWduYWwoc2lnbmFsKSB7XG4gICAgaWYgKGFib3J0ZWRGbGFncy5nZXQoc2lnbmFsKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhYm9ydGVkRmxhZ3Muc2V0KHNpZ25hbCwgdHJ1ZSk7XG4gICAgc2lnbmFsLmRpc3BhdGNoRXZlbnQoeyB0eXBlOiBcImFib3J0XCIgfSk7XG59XG4vKipcbiAqIEFib3J0ZWQgZmxhZyBmb3IgZWFjaCBpbnN0YW5jZXMuXG4gKi9cbmNvbnN0IGFib3J0ZWRGbGFncyA9IG5ldyBXZWFrTWFwKCk7XG4vLyBQcm9wZXJ0aWVzIHNob3VsZCBiZSBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQWJvcnRTaWduYWwucHJvdG90eXBlLCB7XG4gICAgYWJvcnRlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG59KTtcbi8vIGB0b1N0cmluZygpYCBzaG91bGQgcmV0dXJuIGBcIltvYmplY3QgQWJvcnRTaWduYWxdXCJgXG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09IFwic3ltYm9sXCIpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQWJvcnRTaWduYWwucHJvdG90eXBlLCBTeW1ib2wudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogXCJBYm9ydFNpZ25hbFwiLFxuICAgIH0pO1xufVxuXG4vKipcbiAqIFRoZSBBYm9ydENvbnRyb2xsZXIuXG4gKiBAc2VlIGh0dHBzOi8vZG9tLnNwZWMud2hhdHdnLm9yZy8jYWJvcnRjb250cm9sbGVyXG4gKi9cbmNsYXNzIEFib3J0Q29udHJvbGxlciB7XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSB0aGlzIGNvbnRyb2xsZXIuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHNpZ25hbHMuc2V0KHRoaXMsIGNyZWF0ZUFib3J0U2lnbmFsKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBgQWJvcnRTaWduYWxgIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBvYmplY3QuXG4gICAgICovXG4gICAgZ2V0IHNpZ25hbCgpIHtcbiAgICAgICAgcmV0dXJuIGdldFNpZ25hbCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWJvcnQgYW5kIHNpZ25hbCB0byBhbnkgb2JzZXJ2ZXJzIHRoYXQgdGhlIGFzc29jaWF0ZWQgYWN0aXZpdHkgaXMgdG8gYmUgYWJvcnRlZC5cbiAgICAgKi9cbiAgICBhYm9ydCgpIHtcbiAgICAgICAgYWJvcnRTaWduYWwoZ2V0U2lnbmFsKHRoaXMpKTtcbiAgICB9XG59XG4vKipcbiAqIEFzc29jaWF0ZWQgc2lnbmFscy5cbiAqL1xuY29uc3Qgc2lnbmFscyA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEdldCB0aGUgYXNzb2NpYXRlZCBzaWduYWwgb2YgYSBnaXZlbiBjb250cm9sbGVyLlxuICovXG5mdW5jdGlvbiBnZXRTaWduYWwoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHNpZ25hbCA9IHNpZ25hbHMuZ2V0KGNvbnRyb2xsZXIpO1xuICAgIGlmIChzaWduYWwgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBFeHBlY3RlZCAndGhpcycgdG8gYmUgYW4gJ0Fib3J0Q29udHJvbGxlcicgb2JqZWN0LCBidXQgZ290ICR7Y29udHJvbGxlciA9PT0gbnVsbCA/IFwibnVsbFwiIDogdHlwZW9mIGNvbnRyb2xsZXJ9YCk7XG4gICAgfVxuICAgIHJldHVybiBzaWduYWw7XG59XG4vLyBQcm9wZXJ0aWVzIHNob3VsZCBiZSBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQWJvcnRDb250cm9sbGVyLnByb3RvdHlwZSwge1xuICAgIHNpZ25hbDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgYWJvcnQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxufSk7XG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09IFwic3ltYm9sXCIpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQWJvcnRDb250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IFwiQWJvcnRDb250cm9sbGVyXCIsXG4gICAgfSk7XG59XG5cbmV4cG9ydHMuQWJvcnRDb250cm9sbGVyID0gQWJvcnRDb250cm9sbGVyO1xuZXhwb3J0cy5BYm9ydFNpZ25hbCA9IEFib3J0U2lnbmFsO1xuZXhwb3J0cy5kZWZhdWx0ID0gQWJvcnRDb250cm9sbGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFib3J0Q29udHJvbGxlclxubW9kdWxlLmV4cG9ydHMuQWJvcnRDb250cm9sbGVyID0gbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gQWJvcnRDb250cm9sbGVyXG5tb2R1bGUuZXhwb3J0cy5BYm9ydFNpZ25hbCA9IEFib3J0U2lnbmFsXG4vLyMgc291cmNlTWFwcGluZ1VSTD1hYm9ydC1jb250cm9sbGVyLmpzLm1hcFxuIiwiaW1wb3J0IENsaWVudCBmcm9tICcuL2xpYi9jbGllbnQnO1xuaW1wb3J0IHsgSW5wdXRGb3JtRGF0YSB9IGZyb20gJy4vbGliL2ludGVyZmFjZXMvSUZvcm1EYXRhJztcbmltcG9ydCBPcHRpb25zIGZyb20gJy4vbGliL2ludGVyZmFjZXMvT3B0aW9ucyc7XG5cbmNsYXNzIE1haWxndW4ge1xuICBwcml2YXRlIGZvcm1EYXRhOiBJbnB1dEZvcm1EYXRhXG5cbiAgY29uc3RydWN0b3IoRm9ybURhdGE6IElucHV0Rm9ybURhdGEpIHtcbiAgICB0aGlzLmZvcm1EYXRhID0gRm9ybURhdGE7XG4gIH1cblxuICBjbGllbnQob3B0aW9uczogT3B0aW9ucykgOiBDbGllbnQge1xuICAgIHJldHVybiBuZXcgQ2xpZW50KG9wdGlvbnMsIHRoaXMuZm9ybURhdGEpO1xuICB9XG59XG5cbmV4cG9ydCA9IE1haWxndW47XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQgT3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvT3B0aW9ucyc7XG5pbXBvcnQgUmVxdWVzdE9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL1JlcXVlc3RPcHRpb25zJztcblxuaW1wb3J0IERvbWFpbkNsaWVudCBmcm9tICcuL2RvbWFpbnMnO1xuaW1wb3J0IEV2ZW50Q2xpZW50IGZyb20gJy4vZXZlbnRzJztcbmltcG9ydCBTdGF0c0NsaWVudCBmcm9tICcuL3N0YXRzJztcbmltcG9ydCBTdXBwcmVzc2lvbkNsaWVudCBmcm9tICcuL3N1cHByZXNzaW9ucyc7XG5pbXBvcnQgV2ViaG9va0NsaWVudCBmcm9tICcuL3dlYmhvb2tzJztcbmltcG9ydCBNZXNzYWdlc0NsaWVudCBmcm9tICcuL21lc3NhZ2VzJztcbmltcG9ydCBSb3V0ZXNDbGllbnQgZnJvbSAnLi9yb3V0ZXMnO1xuaW1wb3J0IFZhbGlkYXRlQ2xpZW50IGZyb20gJy4vdmFsaWRhdGUnO1xuaW1wb3J0IFBhcnNlQ2xpZW50IGZyb20gJy4vcGFyc2UnO1xuaW1wb3J0IElwc0NsaWVudCBmcm9tICcuL2lwcyc7XG5pbXBvcnQgSXBQb29sc0NsaWVudCBmcm9tICcuL2lwLXBvb2xzJztcbmltcG9ydCBMaXN0c0NsaWVudCBmcm9tICcuL2xpc3RzJztcbmltcG9ydCBNYWlsTGlzdHNNZW1iZXJzIGZyb20gJy4vbWFpbExpc3RNZW1iZXJzJztcbmltcG9ydCB7IElucHV0Rm9ybURhdGEgfSBmcm9tICcuL2ludGVyZmFjZXMvSUZvcm1EYXRhJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2xpZW50IHtcbiAgcHJpdmF0ZSByZXF1ZXN0O1xuXG4gIHB1YmxpYyBkb21haW5zO1xuICBwdWJsaWMgd2ViaG9va3M7XG4gIHB1YmxpYyBldmVudHM7XG4gIHB1YmxpYyBzdGF0cztcbiAgcHVibGljIHN1cHByZXNzaW9ucztcbiAgcHVibGljIG1lc3NhZ2VzO1xuICBwdWJsaWMgcm91dGVzO1xuICBwdWJsaWMgcHVibGljX3JlcXVlc3Q7XG4gIHB1YmxpYyB2YWxpZGF0ZTtcbiAgcHVibGljIHBhcnNlO1xuICBwdWJsaWMgaXBzO1xuICBwdWJsaWMgaXBfcG9vbHM7XG4gIHB1YmxpYyBsaXN0cztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBPcHRpb25zLCBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YSkge1xuICAgIGNvbnN0IGNvbmZpZzogUmVxdWVzdE9wdGlvbnMgPSB7IC4uLm9wdGlvbnMgfSBhcyBSZXF1ZXN0T3B0aW9ucztcblxuICAgIGlmICghY29uZmlnLnVybCkge1xuICAgICAgY29uZmlnLnVybCA9ICdodHRwczovL2FwaS5tYWlsZ3VuLm5ldCc7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcudXNlcm5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFwidXNlcm5hbWVcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLmtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbWV0ZXIgXCJrZXlcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICB0aGlzLnJlcXVlc3QgPSBuZXcgUmVxdWVzdChjb25maWcsIGZvcm1EYXRhKTtcbiAgICBjb25zdCBtYWlsTGlzdHNNZW1iZXJzID0gbmV3IE1haWxMaXN0c01lbWJlcnModGhpcy5yZXF1ZXN0KTtcblxuICAgIHRoaXMuZG9tYWlucyA9IG5ldyBEb21haW5DbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLndlYmhvb2tzID0gbmV3IFdlYmhvb2tDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmV2ZW50cyA9IG5ldyBFdmVudENsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuc3RhdHMgPSBuZXcgU3RhdHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLnN1cHByZXNzaW9ucyA9IG5ldyBTdXBwcmVzc2lvbkNsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMubWVzc2FnZXMgPSBuZXcgTWVzc2FnZXNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLnJvdXRlcyA9IG5ldyBSb3V0ZXNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmlwcyA9IG5ldyBJcHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmlwX3Bvb2xzID0gbmV3IElwUG9vbHNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICB0aGlzLmxpc3RzID0gbmV3IExpc3RzQ2xpZW50KHRoaXMucmVxdWVzdCwgbWFpbExpc3RzTWVtYmVycyk7XG5cbiAgICBpZiAoY29uZmlnLnB1YmxpY19rZXkpIHtcbiAgICAgIGNvbmZpZy5rZXkgPSBjb25maWcucHVibGljX2tleTtcblxuICAgICAgdGhpcy5wdWJsaWNfcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KGNvbmZpZywgZm9ybURhdGEpO1xuICAgICAgdGhpcy52YWxpZGF0ZSA9IG5ldyBWYWxpZGF0ZUNsaWVudCh0aGlzLnB1YmxpY19yZXF1ZXN0KTtcbiAgICAgIHRoaXMucGFyc2UgPSBuZXcgUGFyc2VDbGllbnQodGhpcy5wdWJsaWNfcmVxdWVzdCk7XG4gICAgfVxuICB9XG59XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCB7XG4gIERvbWFpblJlc3BvbnNlRGF0YSxcbiAgRGVzdHJveWVkRG9tYWluLFxuICBEZXN0cm95ZWREb21haW5SZXNwb25zZSxcbiAgRG9tYWluc1F1ZXJ5LFxuICBEb21haW5JbmZvLFxuICBEb21haW5MaXN0UmVzcG9uc2VEYXRhLFxuICBEb21haW5TaG9ydERhdGEsXG4gIEROU1JlY29yZFxufSBmcm9tICcuL2ludGVyZmFjZXMvRG9tYWlucyc7XG5cbmltcG9ydCBBUElSZXNwb25zZSBmcm9tICcuL2ludGVyZmFjZXMvQXBpUmVzcG9uc2UnO1xuaW1wb3J0IEFQSUVycm9yIGZyb20gJy4vZXJyb3InO1xuaW1wb3J0IEFQSUVycm9yT3B0aW9ucyBmcm9tICcuL2ludGVyZmFjZXMvQVBJRXJyb3JPcHRpb25zJztcblxuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcbmltcG9ydCB7XG4gIERvbWFpblRyYWNraW5nUmVzcG9uc2UsXG4gIERvbWFpblRyYWNraW5nRGF0YSxcbiAgT3BlblRyYWNraW5nSW5mbyxcbiAgQ2xpY2tUcmFja2luZ0luZm8sXG4gIFVuc3Vic2NyaWJlVHJhY2tpbmdJbmZvLFxuICBVcGRhdGVEb21haW5UcmFja2luZ1Jlc3BvbnNlLFxuICBVcGRhdGVkT3BlblRyYWNraW5nXG59IGZyb20gJy4vaW50ZXJmYWNlcy9Eb21haW5UcmFja2luZyc7XG5cbmNsYXNzIERvbWFpbiB7XG4gIG5hbWU6IHN0cmluZztcbiAgcmVxdWlyZV90bHM6IGJvb2xlYW47XG4gIHNraXBfdmVyaWZpY2F0aW9uOiBib29sZWFuO1xuICBzdGF0ZTogc3RyaW5nO1xuICB3aWxkY2FyZDogYm9vbGVhbjtcbiAgc3BhbV9hY3Rpb246IHN0cmluZztcbiAgY3JlYXRlZF9hdDogc3RyaW5nO1xuICBzbXRwX3Bhc3N3b3JkOiBzdHJpbmc7XG4gIHNtdHBfbG9naW46IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICByZWNlaXZpbmdfZG5zX3JlY29yZHM6IEROU1JlY29yZFtdIHwgbnVsbDtcbiAgc2VuZGluZ19kbnNfcmVjb3JkczogRE5TUmVjb3JkW10gfCBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IERvbWFpblNob3J0RGF0YSwgcmVjZWl2aW5nPzogRE5TUmVjb3JkW10gfCBudWxsLCBzZW5kaW5nPzogRE5TUmVjb3JkW10gfCBudWxsKSB7XG4gICAgdGhpcy5uYW1lID0gZGF0YS5uYW1lO1xuICAgIHRoaXMucmVxdWlyZV90bHMgPSBkYXRhLnJlcXVpcmVfdGxzO1xuICAgIHRoaXMuc2tpcF92ZXJpZmljYXRpb24gPSBkYXRhLnNraXBfdmVyaWZpY2F0aW9uO1xuICAgIHRoaXMuc3RhdGUgPSBkYXRhLnN0YXRlO1xuICAgIHRoaXMud2lsZGNhcmQgPSBkYXRhLndpbGRjYXJkO1xuICAgIHRoaXMuc3BhbV9hY3Rpb24gPSBkYXRhLnNwYW1fYWN0aW9uO1xuICAgIHRoaXMuY3JlYXRlZF9hdCA9IGRhdGEuY3JlYXRlZF9hdDtcbiAgICB0aGlzLnNtdHBfcGFzc3dvcmQgPSBkYXRhLnNtdHBfcGFzc3dvcmQ7XG4gICAgdGhpcy5zbXRwX2xvZ2luID0gZGF0YS5zbXRwX2xvZ2luO1xuICAgIHRoaXMudHlwZSA9IGRhdGEudHlwZTtcblxuICAgIHRoaXMucmVjZWl2aW5nX2Ruc19yZWNvcmRzID0gcmVjZWl2aW5nIHx8IG51bGw7XG4gICAgdGhpcy5zZW5kaW5nX2Ruc19yZWNvcmRzID0gc2VuZGluZyB8fCBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvbWFpbkNsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VNZXNzYWdlKHJlc3BvbnNlOiBEZXN0cm95ZWREb21haW5SZXNwb25zZSkgOiBEZXN0cm95ZWREb21haW4ge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG5cbiAgX3BhcnNlRG9tYWluTGlzdChyZXNwb25zZTogRG9tYWluTGlzdFJlc3BvbnNlRGF0YSk6IERvbWFpbltdIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBuZXcgRG9tYWluKGl0ZW0pO1xuICAgIH0pO1xuICB9XG5cbiAgX3BhcnNlRG9tYWluKHJlc3BvbnNlOiBEb21haW5SZXNwb25zZURhdGEpOiBEb21haW4ge1xuICAgIHJldHVybiBuZXcgRG9tYWluKFxuICAgICAgcmVzcG9uc2UuYm9keS5kb21haW4sXG4gICAgICByZXNwb25zZS5ib2R5LnJlY2VpdmluZ19kbnNfcmVjb3JkcyxcbiAgICAgIHJlc3BvbnNlLmJvZHkuc2VuZGluZ19kbnNfcmVjb3Jkc1xuICAgICk7XG4gIH1cblxuICBfcGFyc2VUcmFja2luZ1NldHRpbmdzKHJlc3BvbnNlOiBEb21haW5UcmFja2luZ1Jlc3BvbnNlKSA6IERvbWFpblRyYWNraW5nRGF0YSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkudHJhY2tpbmc7XG4gIH1cblxuICBfcGFyc2VUcmFja2luZ1VwZGF0ZShyZXNwb25zZTogVXBkYXRlRG9tYWluVHJhY2tpbmdSZXNwb25zZSkgOlVwZGF0ZWRPcGVuVHJhY2tpbmcge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG5cbiAgbGlzdChxdWVyeTogRG9tYWluc1F1ZXJ5KTogUHJvbWlzZTxEb21haW5bXT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjIvZG9tYWlucycsIHF1ZXJ5KVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbkxpc3QocmVzIGFzIERvbWFpbkxpc3RSZXNwb25zZURhdGEpKTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZykgOiBQcm9taXNlPERvbWFpbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KGAvdjIvZG9tYWlucy8ke2RvbWFpbn1gKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbihyZXMgYXMgRG9tYWluUmVzcG9uc2VEYXRhKSk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogRG9tYWluSW5mbykgOiBQcm9taXNlPERvbWFpbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCgnL3YyL2RvbWFpbnMnLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbihyZXMgYXMgRG9tYWluUmVzcG9uc2VEYXRhKSk7XG4gIH1cblxuICBkZXN0cm95KGRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95ZWREb21haW4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YyL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VNZXNzYWdlKHJlcyBhcyBEZXN0cm95ZWREb21haW5SZXNwb25zZSkpO1xuICB9XG5cbiAgLy8gVHJhY2tpbmdcblxuICBnZXRUcmFja2luZyhkb21haW46IHN0cmluZykgOiBQcm9taXNlPERvbWFpblRyYWNraW5nRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAndHJhY2tpbmcnKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlVHJhY2tpbmdTZXR0aW5ncyk7XG4gIH1cblxuICB1cGRhdGVUcmFja2luZyhcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgZGF0YTogT3BlblRyYWNraW5nSW5mbyB8IENsaWNrVHJhY2tpbmdJbmZvIHwgVW5zdWJzY3JpYmVUcmFja2luZ0luZm9cbiAgKTogUHJvbWlzZTxVcGRhdGVkT3BlblRyYWNraW5nPiB7XG4gICAgaWYgKCEoJ2h0bWxfZm9vdGVyJyBpbiBkYXRhKSAmJiAhKCd0ZXh0X2Zvb3RlcicgaW4gZGF0YSkgJiYgdHlwZW9mIGRhdGE/LmFjdGl2ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyBuZXcgQVBJRXJyb3IoeyBzdGF0dXM6IDQwMCwgc3RhdHVzVGV4dDogJycsIGJvZHk6IHsgbWVzc2FnZTogJ1ZhbHVlIFwiYWN0aXZlXCIgbXVzdCBjb250YWluIHN0cmluZyB2YWx1ZS4nIH0gfSBhcyBBUElFcnJvck9wdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3RyYWNraW5nJywgdHlwZSksIGRhdGEpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVRyYWNraW5nVXBkYXRlKTtcbiAgfVxuXG4gIC8vIElQc1xuXG4gIGdldElwcyhkb21haW46IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBBUElSZXNwb25zZSkgPT4gcmVzcG9uc2U/LmJvZHk/Lml0ZW1zKTtcbiAgfVxuXG4gIGFzc2lnbklwKGRvbWFpbjogc3RyaW5nLCBpcDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IGlwIH0pO1xuICB9XG5cbiAgZGVsZXRlSXAoZG9tYWluOiBzdHJpbmcsIGlwOiBzdHJpbmcpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICdpcHMnLCBpcCkpO1xuICB9XG5cbiAgbGlua0lwUG9vbChkb21haW46IHN0cmluZywgcG9vbF9pZDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IHBvb2xfaWQgfSk7XG4gIH1cblxuICB1bmxpbmtJcFBvbGwoZG9tYWluOiBzdHJpbmcsIHBvb2xfaWQ6IHN0cmluZywgaXA6IHN0cmluZyk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZSh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycsICdpcF9wb29sJyksIHsgcG9vbF9pZCwgaXAgfSk7XG4gIH1cbn1cbiIsImltcG9ydCBBUElFcnJvck9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL0FQSUVycm9yT3B0aW9ucyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFQSUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBzdGF0dXM6IG51bWJlciB8IHN0cmluZztcbiAgc3RhY2s6IHN0cmluZztcbiAgZGV0YWlsczogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHtcbiAgICBzdGF0dXMsXG4gICAgc3RhdHVzVGV4dCxcbiAgICBtZXNzYWdlLFxuICAgIGJvZHkgPSB7fVxuICB9OiBBUElFcnJvck9wdGlvbnMpIHtcbiAgICBjb25zdCB7IG1lc3NhZ2U6IGJvZHlNZXNzYWdlLCBlcnJvciB9ID0gYm9keTtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5zdGFjayA9ICcnO1xuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgZXJyb3IgfHwgc3RhdHVzVGV4dDtcbiAgICB0aGlzLmRldGFpbHMgPSBib2R5TWVzc2FnZTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHtcbiAgRXZlbnRzTGlzdCwgRXZlbnRzUGFnZSwgRXZlbnRzUmVzcG9uc2UsIFBhZ2VzTGlzdCwgUGFnZXNMaXN0QWNjdW11bGF0b3Jcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL0V2ZW50cyc7XG5cbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV2ZW50Q2xpZW50IHtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIF9wYXJzZVBhZ2VOdW1iZXIodXJsOiBzdHJpbmcpIDogc3RyaW5nIHtcbiAgICByZXR1cm4gdXJsLnNwbGl0KCcvJykucG9wKCk7XG4gIH1cblxuICBfcGFyc2VQYWdlKGlkOiBzdHJpbmcsIHVybDogc3RyaW5nKSA6IEV2ZW50c1BhZ2Uge1xuICAgIHJldHVybiB7IGlkLCBudW1iZXI6IHRoaXMuX3BhcnNlUGFnZU51bWJlcih1cmwpLCB1cmwgfTtcbiAgfVxuXG4gIF9wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZTogRXZlbnRzUmVzcG9uc2UpIDogUGFnZXNMaXN0IHtcbiAgICBjb25zdCBwYWdlcyA9IE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmJvZHkucGFnaW5nIGFzIFBhZ2VzTGlzdCk7XG4gICAgcmV0dXJuIHBhZ2VzLnJlZHVjZShcbiAgICAgIChhY2M6IFBhZ2VzTGlzdEFjY3VtdWxhdG9yLCBlbnRyaWU6IFt1cmw6IHN0cmluZywgaWQ6IHN0cmluZ10pID0+IHtcbiAgICAgICAgY29uc3QgaWQgPSBlbnRyaWVbMF07XG4gICAgICAgIGNvbnN0IHVybCA9IGVudHJpZVsxXTtcbiAgICAgICAgYWNjW2lkXSA9IHRoaXMuX3BhcnNlUGFnZShpZCwgdXJsKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIHt9XG4gICAgKSBhcyB1bmtub3duIGFzIFBhZ2VzTGlzdDtcbiAgfVxuXG4gIF9wYXJzZUV2ZW50TGlzdChyZXNwb25zZTogRXZlbnRzUmVzcG9uc2UpIDogRXZlbnRzTGlzdCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1zOiByZXNwb25zZS5ib2R5Lml0ZW1zLFxuICAgICAgcGFnZXM6IHRoaXMuX3BhcnNlUGFnZUxpbmtzKHJlc3BvbnNlKVxuICAgIH07XG4gIH1cblxuICBnZXQoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiB7IHBhZ2U6IHN0cmluZyB9KSA6IFByb21pc2U8RXZlbnRzTGlzdD4ge1xuICAgIGxldCB1cmw7XG4gICAgY29uc3QgcXVlcnlDb3B5ID0geyAuLi5xdWVyeSB9O1xuICAgIGlmIChxdWVyeUNvcHkgJiYgcXVlcnlDb3B5LnBhZ2UpIHtcbiAgICAgIHVybCA9IHVybGpvaW4oJy92MicsIGRvbWFpbiwgJ2V2ZW50cycsIHF1ZXJ5Q29weS5wYWdlKTtcbiAgICAgIGRlbGV0ZSBxdWVyeUNvcHkucGFnZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXJsID0gdXJsam9pbignL3YyJywgZG9tYWluLCAnZXZlbnRzJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybCwgcXVlcnlDb3B5KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBFdmVudHNSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VFdmVudExpc3QocmVzcG9uc2UpKTtcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5pbXBvcnQgeyBJcFBvb2wsIElwUG9vbExpc3RSZXNwb25zZSwgSXBQb29sVXBkYXRlRGF0YSB9IGZyb20gJy4vaW50ZXJmYWNlcy9JcFBvb2xzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSXBQb29sc0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBsaXN0KHF1ZXJ5OiBhbnkpOiBQcm9taXNlPElwUG9vbFtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92MS9pcF9wb29scycsIHF1ZXJ5KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiBJcFBvb2xMaXN0UmVzcG9uc2UpID0+IHRoaXMucGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2UpKTtcbiAgfVxuXG4gIGNyZWF0ZShkYXRhOiB7IG5hbWU6IHN0cmluZywgZGVzY3JpcHRpb24/OiBzdHJpbmcsIGlwcz86IHN0cmluZ1tdIH0pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3QoJy92MS9pcF9wb29scycsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogeyBtZXNzYWdlOiBzdHJpbmcsIHBvb2xfaWQ6IHN0cmluZyB9IH0pID0+IHJlc3BvbnNlPy5ib2R5KTtcbiAgfVxuXG4gIHVwZGF0ZShwb29sSWQ6IHN0cmluZywgZGF0YTogSXBQb29sVXBkYXRlRGF0YSkgOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucGF0Y2goYC92MS9pcF9wb29scy8ke3Bvb2xJZH1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZT8uYm9keSk7XG4gIH1cblxuICBkZWxldGUocG9vbElkOiBzdHJpbmcsIGRhdGE6IHsgaWQ6IHN0cmluZywgcG9vbF9pZDogc3RyaW5nIH0pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YxL2lwX3Bvb2xzLyR7cG9vbElkfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogYW55IH0pID0+IHJlc3BvbnNlPy5ib2R5KTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2U6IHsgYm9keTogYW55IHwgYW55IH0pIHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5pcF9wb29scztcbiAgfVxufVxuIiwiaW1wb3J0IE1nUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHsgSXBEYXRhLCBJcHNMaXN0UmVzcG9uc2VCb2R5IH0gZnJvbSAnLi9pbnRlcmZhY2VzL0lwcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIElwc0NsaWVudCB7XG4gIHJlcXVlc3Q6IE1nUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBNZ1JlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgbGlzdChxdWVyeTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9pcHMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiBJcHNMaXN0UmVzcG9uc2VCb2R5IH0pID0+IHRoaXMucGFyc2VJcHNSZXNwb25zZShyZXNwb25zZSkpO1xuICB9XG5cbiAgZ2V0KGlwOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YzL2lwcy8ke2lwfWApXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogSXBEYXRhIH0pID0+IHRoaXMucGFyc2VJcHNSZXNwb25zZShyZXNwb25zZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUlwc1Jlc3BvbnNlKHJlc3BvbnNlOiB7IGJvZHk6IElwc0xpc3RSZXNwb25zZUJvZHkgfCBJcERhdGEgfSkge1xuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xuICB9XG59XG4iLCJpbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHtcbiAgTGlzdHNRdWVyeSxcbiAgQ3JlYXRlVXBkYXRlTGlzdCxcbiAgRGVzdHJveWVkTGlzdCxcbiAgTWFpbGluZ0xpc3Rcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL2xpc3RzJztcbmltcG9ydCB7IElNYWlsTGlzdHNNZW1iZXJzIH0gZnJvbSAnLi9pbnRlcmZhY2VzL21haWxMaXN0TWVtYmVycyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpc3RzQ2xpZW50IHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG4gIG1lbWJlcnM6IElNYWlsTGlzdHNNZW1iZXJzO1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QsIG1lbWJlcnM6SU1haWxMaXN0c01lbWJlcnMpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My9saXN0cyc7XG4gICAgdGhpcy5tZW1iZXJzID0gbWVtYmVycztcbiAgfVxuXG4gIGxpc3QocXVlcnk/OiBMaXN0c1F1ZXJ5KTogUHJvbWlzZTxNYWlsaW5nTGlzdFtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9L3BhZ2VzYCwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkuaXRlbXMgYXMgTWFpbGluZ0xpc3RbXSk7XG4gIH1cblxuICBnZXQobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogQ3JlYXRlVXBkYXRlTGlzdCk6IFByb21pc2U8TWFpbGluZ0xpc3Q+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodGhpcy5iYXNlUm91dGUsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICB1cGRhdGUobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsIGRhdGE6IENyZWF0ZVVwZGF0ZUxpc3QpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBkZXN0cm95KG1haWxMaXN0QWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95ZWRMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgRGVzdHJveWVkTGlzdCk7XG4gIH1cbn1cbiIsImltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQge1xuICBNYWlsTGlzdE1lbWJlcnNRdWVyeSxcbiAgSU1haWxMaXN0c01lbWJlcnMsXG4gIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVycyxcbiAgTWFpbExpc3RNZW1iZXIsXG4gIE11bHRpcGxlTWVtYmVyc0RhdGEsXG4gIE11bHRpcGxlTWVtYmVyc1JlcURhdGEsXG4gIERlbGV0ZWRNZW1iZXIsXG4gIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1JlcSxcbiAgTmV3TXVsdGlwbGVNZW1iZXJzUmVzcG9uc2Vcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL21haWxMaXN0TWVtYmVycyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1haWxMaXN0c01lbWJlcnMgaW1wbGVtZW50cyBJTWFpbExpc3RzTWVtYmVycyB7XG4gIGJhc2VSb3V0ZTogc3RyaW5nO1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My9saXN0cyc7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQW5kVXBkYXRlRGF0YShkYXRhOiBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnMpIHtcbiAgICBjb25zdCBuZXdEYXRhID0geyAuLi5kYXRhIH07XG5cbiAgICBpZiAodHlwZW9mIGRhdGEudmFycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgIG5ld0RhdGEudmFycyA9IEpTT04uc3RyaW5naWZ5KG5ld0RhdGEudmFycyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkYXRhLnN1YnNjcmliZWQgPT09ICdib29sZWFuJykge1xuICAgICAgbmV3RGF0YS5zdWJzY3JpYmVkID0gZGF0YS5zdWJzY3JpYmVkID8gJ3llcycgOiAnbm8nO1xuICAgIH1cblxuICAgIHJldHVybiBuZXdEYXRhIGFzIENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1JlcTtcbiAgfVxuXG4gIGxpc3RNZW1iZXJzKG1haWxMaXN0QWRkcmVzczogc3RyaW5nLCBxdWVyeT86IE1haWxMaXN0TWVtYmVyc1F1ZXJ5KTogUHJvbWlzZTxNYWlsTGlzdE1lbWJlcltdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzL3BhZ2VzYCwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkuaXRlbXMgYXMgTWFpbExpc3RNZW1iZXJbXSk7XG4gIH1cblxuICBnZXRNZW1iZXIobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsIG1haWxMaXN0TWVtYmVyQWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxNYWlsTGlzdE1lbWJlcj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVycy8ke21haWxMaXN0TWVtYmVyQWRkcmVzc31gKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5Lm1lbWJlciBhcyBNYWlsTGlzdE1lbWJlcik7XG4gIH1cblxuICBjcmVhdGVNZW1iZXIoXG4gICAgbWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsXG4gICAgZGF0YTogQ3JlYXRlVXBkYXRlTWFpbExpc3RNZW1iZXJzXG4gICk6IFByb21pc2U8TWFpbExpc3RNZW1iZXI+IHtcbiAgICBjb25zdCByZXFEYXRhID0gdGhpcy5jaGVja0FuZFVwZGF0ZURhdGEoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVyc2AsIHJlcURhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubWVtYmVyIGFzIE1haWxMaXN0TWVtYmVyKTtcbiAgfVxuXG4gIGNyZWF0ZU1lbWJlcnMoXG4gICAgbWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsXG4gICAgZGF0YTogTXVsdGlwbGVNZW1iZXJzRGF0YVxuICApOiBQcm9taXNlPE5ld011bHRpcGxlTWVtYmVyc1Jlc3BvbnNlPiB7XG4gICAgY29uc3QgbmV3RGF0YTogTXVsdGlwbGVNZW1iZXJzUmVxRGF0YSA9IHtcbiAgICAgIG1lbWJlcnM6IEFycmF5LmlzQXJyYXkoZGF0YS5tZW1iZXJzKSA/IEpTT04uc3RyaW5naWZ5KGRhdGEubWVtYmVycykgOiBkYXRhLm1lbWJlcnMsXG4gICAgICB1cHNlcnQ6IGRhdGEudXBzZXJ0XG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMuanNvbmAsIG5ld0RhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgTmV3TXVsdGlwbGVNZW1iZXJzUmVzcG9uc2UpO1xuICB9XG5cbiAgdXBkYXRlTWVtYmVyKFxuICAgIG1haWxMaXN0QWRkcmVzczogc3RyaW5nLFxuICAgIG1haWxMaXN0TWVtYmVyQWRkcmVzczogc3RyaW5nLFxuICAgIGRhdGE6IENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1xuICApOiBQcm9taXNlPE1haWxMaXN0TWVtYmVyPiB7XG4gICAgY29uc3QgcmVxRGF0YSA9IHRoaXMuY2hlY2tBbmRVcGRhdGVEYXRhKGRhdGEpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucHV0V2l0aEZEKGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vbWVtYmVycy8ke21haWxMaXN0TWVtYmVyQWRkcmVzc31gLCByZXFEYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5Lm1lbWJlciBhcyBNYWlsTGlzdE1lbWJlcik7XG4gIH1cblxuICBkZXN0cm95TWVtYmVyKG1haWxMaXN0QWRkcmVzczogc3RyaW5nLCBtYWlsTGlzdE1lbWJlckFkZHJlc3M6IHN0cmluZykgOiBQcm9taXNlPERlbGV0ZWRNZW1iZXI+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMvJHttYWlsTGlzdE1lbWJlckFkZHJlc3N9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keSBhcyBEZWxldGVkTWVtYmVyKTtcbiAgfVxufVxuIiwiaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWVzc2FnZXNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgX3BhcnNlUmVzcG9uc2UocmVzcG9uc2U6IHsgYm9keTogYW55IH0pIHtcbiAgICBpZiAocmVzcG9uc2UuYm9keSkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlO1xuICB9XG5cbiAgY3JlYXRlKGRvbWFpbjogc3RyaW5nLCBkYXRhOiBhbnkpIHtcbiAgICBpZiAoZGF0YS5tZXNzYWdlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYC92My8ke2RvbWFpbn0vbWVzc2FnZXMubWltZWAsIGRhdGEpXG4gICAgICAgIC50aGVuKHRoaXMuX3BhcnNlUmVzcG9uc2UpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRChgL3YzLyR7ZG9tYWlufS9tZXNzYWdlc2AsIGRhdGEpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVJlc3BvbnNlKTtcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQYXJzZUNsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBnZXQoYWRkcmVzc2VzOiBzdHJpbmdbXSB8IHN0cmluZywgZW5hYmxlRG5zRXNwQ2hlY2tzOiBib29sZWFuKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7fSBhcyB7IGFkZHJlc3Nlczogc3RyaW5nLCBzeW50YXhfb25seTogYm9vbGVhbiB9O1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYWRkcmVzc2VzKSkge1xuICAgICAgcXVlcnkuYWRkcmVzc2VzID0gYWRkcmVzc2VzLmpvaW4oJywnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcXVlcnkuYWRkcmVzc2VzID0gYWRkcmVzc2VzO1xuICAgIH1cblxuICAgIGlmIChlbmFibGVEbnNFc3BDaGVja3MpIHtcbiAgICAgIHF1ZXJ5LnN5bnRheF9vbmx5ID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9hZGRyZXNzL3BhcnNlJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG59XG4iLCJpbXBvcnQgTm9kZUZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5pbXBvcnQgYmFzZTY0IGZyb20gJ2Jhc2UtNjQnO1xuaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IGt5IGZyb20gJ2t5LXVuaXZlcnNhbCc7XG5pbXBvcnQgQVBJRXJyb3IgZnJvbSAnLi9lcnJvcic7XG5pbXBvcnQgUmVxdWVzdE9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL1JlcXVlc3RPcHRpb25zJztcbmltcG9ydCBBUElFcnJvck9wdGlvbnMgZnJvbSAnLi9pbnRlcmZhY2VzL0FQSUVycm9yT3B0aW9ucyc7XG5pbXBvcnQgeyBJbnB1dEZvcm1EYXRhIH0gZnJvbSAnLi9pbnRlcmZhY2VzL0lGb3JtRGF0YSc7XG5pbXBvcnQgQVBJUmVzcG9uc2UgZnJvbSAnLi9pbnRlcmZhY2VzL0FwaVJlc3BvbnNlJztcblxuY29uc3QgaXNTdHJlYW0gPSAoYXR0YWNobWVudDogYW55KSA9PiB0eXBlb2YgYXR0YWNobWVudCA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGF0dGFjaG1lbnQucGlwZSA9PT0gJ2Z1bmN0aW9uJztcblxuZnVuY3Rpb24gaXNOb2RlRm9ybURhdGEoZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEpXG4gIDogZm9ybURhdGFJbnN0YW5jZSBpcyBOb2RlRm9ybURhdGEge1xuICByZXR1cm4gKDxOb2RlRm9ybURhdGE+Zm9ybURhdGFJbnN0YW5jZSkuZ2V0SGVhZGVycyAhPT0gdW5kZWZpbmVkO1xufVxuXG5jb25zdCBnZXRBdHRhY2htZW50T3B0aW9ucyA9IChpdGVtOiBhbnkpOiB7XG4gIGZpbGVuYW1lPzogc3RyaW5nLFxuICBjb250ZW50VHlwZT86IHN0cmluZyxcbiAga25vd25MZW5ndGg/OiBudW1iZXJcbn0gPT4ge1xuICBpZiAodHlwZW9mIGl0ZW0gIT09ICdvYmplY3QnIHx8IGlzU3RyZWFtKGl0ZW0pKSByZXR1cm4ge307XG5cbiAgY29uc3Qge1xuICAgIGZpbGVuYW1lLFxuICAgIGNvbnRlbnRUeXBlLFxuICAgIGtub3duTGVuZ3RoXG4gIH0gPSBpdGVtO1xuXG4gIHJldHVybiB7XG4gICAgLi4uKGZpbGVuYW1lID8geyBmaWxlbmFtZSB9IDogeyBmaWxlbmFtZTogJ2ZpbGUnIH0pLFxuICAgIC4uLihjb250ZW50VHlwZSAmJiB7IGNvbnRlbnRUeXBlIH0pLFxuICAgIC4uLihrbm93bkxlbmd0aCAmJiB7IGtub3duTGVuZ3RoIH0pXG4gIH07XG59O1xuXG5jb25zdCBzdHJlYW1Ub1N0cmluZyA9IChzdHJlYW06IGFueSkgPT4ge1xuICBjb25zdCBjaHVua3M6IGFueSA9IFtdO1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHN0cmVhbS5vbignZGF0YScsIChjaHVuazogYW55KSA9PiBjaHVua3MucHVzaChjaHVuaykpO1xuICAgIHN0cmVhbS5vbignZXJyb3InLCByZWplY3QpO1xuICAgIHN0cmVhbS5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoJ3V0ZjgnKSkpO1xuICB9KTtcbn07XG5cbmNsYXNzIFJlcXVlc3Qge1xuICBwcml2YXRlIHVzZXJuYW1lOiBzdHJpbmc7XG4gIHByaXZhdGUga2V5OiBzdHJpbmc7XG4gIHByaXZhdGUgdXJsOiBzdHJpbmc7XG4gIHByaXZhdGUgdGltZW91dDogbnVtYmVyO1xuICBwcml2YXRlIGhlYWRlcnM6IGFueTtcbiAgcHJpdmF0ZSBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucywgZm9ybURhdGE6IElucHV0Rm9ybURhdGEpIHtcbiAgICB0aGlzLnVzZXJuYW1lID0gb3B0aW9ucy51c2VybmFtZTtcbiAgICB0aGlzLmtleSA9IG9wdGlvbnMua2V5O1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmwgYXMgc3RyaW5nO1xuICAgIHRoaXMudGltZW91dCA9IG9wdGlvbnMudGltZW91dDtcbiAgICB0aGlzLmhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnMgfHwge307XG4gICAgdGhpcy5mb3JtRGF0YSA9IGZvcm1EYXRhO1xuICB9XG5cbiAgYXN5bmMgcmVxdWVzdChtZXRob2Q6IHN0cmluZywgdXJsOiBzdHJpbmcsIGlucHV0T3B0aW9ucz86IGFueSk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBjb25zdCBvcHRpb25zID0geyAuLi5pbnB1dE9wdGlvbnMgfTtcbiAgICBjb25zdCBiYXNpYyA9IGJhc2U2NC5lbmNvZGUoYCR7dGhpcy51c2VybmFtZX06JHt0aGlzLmtleX1gKTtcbiAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgQXV0aG9yaXphdGlvbjogYEJhc2ljICR7YmFzaWN9YCxcbiAgICAgIC4uLnRoaXMuaGVhZGVycyxcbiAgICAgIC4uLm9wdGlvbnM/LmhlYWRlcnNcbiAgICB9O1xuXG4gICAgZGVsZXRlIG9wdGlvbnM/LmhlYWRlcnM7XG5cbiAgICBpZiAoIWhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddKSB7XG4gICAgICAvLyBmb3IgZm9ybS1kYXRhIGl0IHdpbGwgYmUgTnVsbCBzbyB3ZSBuZWVkIHRvIHJlbW92ZSBpdFxuICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcmFtcyA9IHsgLi4ub3B0aW9ucyB9O1xuXG4gICAgaWYgKG9wdGlvbnM/LnF1ZXJ5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9wdGlvbnM/LnF1ZXJ5KS5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJhbXMuc2VhcmNoUGFyYW1zID0gb3B0aW9ucy5xdWVyeTtcbiAgICAgIGRlbGV0ZSBwYXJhbXMucXVlcnk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBreShcbiAgICAgIHVybGpvaW4odGhpcy51cmwsIHVybCksXG4gICAgICB7XG4gICAgICAgIG1ldGhvZDogbWV0aG9kLnRvTG9jYWxlVXBwZXJDYXNlKCksXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHRocm93SHR0cEVycm9yczogZmFsc2UsXG4gICAgICAgIHRpbWVvdXQ6IHRoaXMudGltZW91dCxcbiAgICAgICAgLi4ucGFyYW1zXG4gICAgICB9XG4gICAgKTtcblxuICAgIGlmICghcmVzcG9uc2U/Lm9rKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gcmVzcG9uc2U/LmJvZHkgJiYgaXNTdHJlYW0ocmVzcG9uc2UuYm9keSlcbiAgICAgICAgPyBhd2FpdCBzdHJlYW1Ub1N0cmluZyhyZXNwb25zZS5ib2R5KVxuICAgICAgICA6IGF3YWl0IHJlc3BvbnNlPy5qc29uKCk7XG5cbiAgICAgIHRocm93IG5ldyBBUElFcnJvcih7XG4gICAgICAgIHN0YXR1czogcmVzcG9uc2U/LnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogcmVzcG9uc2U/LnN0YXR1c1RleHQsXG4gICAgICAgIGJvZHk6IHsgbWVzc2FnZSB9XG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGJvZHk6IGF3YWl0IHJlc3BvbnNlPy5qc29uKCksXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlPy5zdGF0dXNcbiAgICB9O1xuICB9XG5cbiAgcXVlcnkobWV0aG9kOiBzdHJpbmcsIHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zPzogYW55KSA6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KG1ldGhvZCwgdXJsLCB7IHF1ZXJ5LCAuLi5vcHRpb25zIH0pO1xuICB9XG5cbiAgY29tbWFuZChtZXRob2Q6IHN0cmluZywgdXJsOiBzdHJpbmcsIGRhdGE6IGFueSwgb3B0aW9ucz86IGFueSkgOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChtZXRob2QsIHVybCwge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSxcbiAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAuLi5vcHRpb25zXG4gICAgfSk7XG4gIH1cblxuICBnZXQodXJsOiBzdHJpbmcsIHF1ZXJ5PzogYW55LCBvcHRpb25zPzogYW55KSA6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeSgnZ2V0JywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBoZWFkKHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zOiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5KCdoZWFkJywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBvcHRpb25zKHVybDogc3RyaW5nLCBxdWVyeTogYW55LCBvcHRpb25zOiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5KCdvcHRpb25zJywgdXJsLCBxdWVyeSwgb3B0aW9ucyk7XG4gIH1cblxuICBwb3N0KHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpIDogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ3Bvc3QnLCB1cmwsIGRhdGEsIG9wdGlvbnMpO1xuICB9XG5cbiAgcG9zdFdpdGhGRCh1cmw6IHN0cmluZywgZGF0YTogYW55KTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIGNvbnN0IHBhcmFtczogYW55ID0ge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogbnVsbCB9XG4gICAgfTtcbiAgICBjb25zdCBmb3JtRGF0YSA9IHRoaXMuY3JlYXRlRm9ybURhdGEoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncG9zdCcsIHVybCwgZm9ybURhdGEsIHBhcmFtcyk7XG4gIH1cblxuICBwdXRXaXRoRkQodXJsOiBzdHJpbmcsIGRhdGE6IGFueSk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBjb25zdCBwYXJhbXM6IGFueSA9IHtcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6IG51bGwgfVxuICAgIH07XG4gICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLmNyZWF0ZUZvcm1EYXRhKGRhdGEpO1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ3B1dCcsIHVybCwgZm9ybURhdGEsIHBhcmFtcyk7XG4gIH1cblxuICBjcmVhdGVGb3JtRGF0YShkYXRhOiBhbnkpOiBOb2RlRm9ybURhdGEgfCBGb3JtRGF0YSB7XG4gICAgY29uc3QgYXBwZW5kRmlsZVRvRkQgPSAoXG4gICAgICBrZXk6IHN0cmluZyxcbiAgICAgIG9iajogYW55LFxuICAgICAgZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgICApOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IGlzU3RyZWFtRGF0YSA9IGlzU3RyZWFtKG9iaik7XG4gICAgICBjb25zdCBvYmpEYXRhID0gaXNTdHJlYW1EYXRhID8gb2JqIDogb2JqLmRhdGE7XG4gICAgICBjb25zdCBvcHRpb25zID0gZ2V0QXR0YWNobWVudE9wdGlvbnMob2JqKTtcbiAgICAgIGlmIChpc05vZGVGb3JtRGF0YShmb3JtRGF0YUluc3RhbmNlKSkge1xuICAgICAgICBmb3JtRGF0YUluc3RhbmNlLmFwcGVuZChrZXksIG9iakRhdGEsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBmb3JtRGF0YUluc3RhbmNlLmFwcGVuZChrZXksIG9iakRhdGEsIG9wdGlvbnMuZmlsZW5hbWUpO1xuICAgIH07XG5cbiAgICBjb25zdCBmb3JtRGF0YTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEgPSBPYmplY3Qua2V5cyhkYXRhKVxuICAgICAgLmZpbHRlcihmdW5jdGlvbiAoa2V5KSB7IHJldHVybiBkYXRhW2tleV07IH0pXG4gICAgICAucmVkdWNlKChmb3JtRGF0YUFjYzogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGEsIGtleSkgPT4ge1xuICAgICAgICBpZiAoa2V5ID09PSAnYXR0YWNobWVudCcgfHwga2V5ID09PSAnaW5saW5lJykge1xuICAgICAgICAgIGNvbnN0IG9iaiA9IGRhdGFba2V5XTtcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgIGFwcGVuZEZpbGVUb0ZEKGtleSwgaXRlbSwgZm9ybURhdGFBY2MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFwcGVuZEZpbGVUb0ZEKGtleSwgb2JqLCBmb3JtRGF0YUFjYyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGZvcm1EYXRhQWNjO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YVtrZXldKSkge1xuICAgICAgICAgIGRhdGFba2V5XS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtOiBhbnkpIHtcbiAgICAgICAgICAgIGZvcm1EYXRhQWNjLmFwcGVuZChrZXksIGl0ZW0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGFba2V5XSAhPSBudWxsKSB7XG4gICAgICAgICAgZm9ybURhdGFBY2MuYXBwZW5kKGtleSwgZGF0YVtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9ybURhdGFBY2M7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbmV3LWNhcFxuICAgICAgfSwgbmV3IHRoaXMuZm9ybURhdGEoKSk7XG4gICAgcmV0dXJuIGZvcm1EYXRhO1xuICB9XG5cbiAgcHV0KHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncHV0JywgdXJsLCBkYXRhLCBvcHRpb25zKTtcbiAgfVxuXG4gIHBhdGNoKHVybDogc3RyaW5nLCBkYXRhOiBhbnksIG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncGF0Y2gnLCB1cmwsIGRhdGEsIG9wdGlvbnMpO1xuICB9XG5cbiAgZGVsZXRlKHVybDogc3RyaW5nLCBkYXRhPzogYW55LCBvcHRpb25zPzogYW55KTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmQoJ2RlbGV0ZScsIHVybCwgZGF0YSwgb3B0aW9ucyk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVxdWVzdDtcbiIsImltcG9ydCB7XG4gIENyZWF0ZVVwZGF0ZVJvdXRlRGF0YSwgRGVzdHJveVJvdXRlUmVzcG9uc2UsIFJvdXRlLCBSb3V0ZXNMaXN0UXVlcnksIFVwZGF0ZVJvdXRlUmVzcG9uc2Vcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL3JvdXRlcyc7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSb3V0ZXNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgbGlzdChxdWVyeTogUm91dGVzTGlzdFF1ZXJ5KTogUHJvbWlzZTxSb3V0ZVtdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9yb3V0ZXMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5pdGVtcyk7XG4gIH1cblxuICBnZXQoaWQ6IHN0cmluZyk6IFByb21pc2U8Um91dGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YzL3JvdXRlcy8ke2lkfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkucm91dGUpO1xuICB9XG5cbiAgY3JlYXRlKGRhdGE6IENyZWF0ZVVwZGF0ZVJvdXRlRGF0YSk6IFByb21pc2U8Um91dGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoJy92My9yb3V0ZXMnLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5LnJvdXRlKTtcbiAgfVxuXG4gIHVwZGF0ZShpZDogc3RyaW5nLCBkYXRhOiBDcmVhdGVVcGRhdGVSb3V0ZURhdGEpOiBQcm9taXNlPFVwZGF0ZVJvdXRlUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRChgL3YzL3JvdXRlcy8ke2lkfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgZGVzdHJveShpZDogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95Um91dGVSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKGAvdjMvcm91dGVzLyR7aWR9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keSk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vcmVxdWVzdCc7XG5pbXBvcnQgU3RhdHNPcHRpb25zIGZyb20gJy4vaW50ZXJmYWNlcy9TdGF0c09wdGlvbnMnO1xuXG5jbGFzcyBTdGF0cyB7XG4gIHN0YXJ0OiBEYXRlO1xuICBlbmQ6IERhdGU7XG4gIHJlc29sdXRpb246IHN0cmluZztcbiAgc3RhdHM6IGFueTtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBTdGF0c09wdGlvbnMpIHtcbiAgICB0aGlzLnN0YXJ0ID0gbmV3IERhdGUoZGF0YS5zdGFydCk7XG4gICAgdGhpcy5lbmQgPSBuZXcgRGF0ZShkYXRhLmVuZCk7XG4gICAgdGhpcy5yZXNvbHV0aW9uID0gZGF0YS5yZXNvbHV0aW9uO1xuICAgIHRoaXMuc3RhdHMgPSBkYXRhLnN0YXRzLm1hcChmdW5jdGlvbiAoc3RhdDogeyB0aW1lOiBzdHJpbmcgfCBEYXRlIH0pIHtcbiAgICAgIGNvbnN0IHJlcyA9IHsgLi4uc3RhdCB9O1xuICAgICAgcmVzLnRpbWUgPSBuZXcgRGF0ZShzdGF0LnRpbWUpO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdGF0c0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBfcGFyc2VTdGF0cyhyZXNwb25zZTogeyBib2R5OiBTdGF0c09wdGlvbnMgfSkge1xuICAgIHJldHVybiBuZXcgU3RhdHMocmVzcG9uc2UuYm9keSk7XG4gIH1cblxuICBnZXREb21haW4oZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjMnLCBkb21haW4sICdzdGF0cy90b3RhbCcpLCBxdWVyeSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlU3RhdHMpO1xuICB9XG5cbiAgZ2V0QWNjb3VudChxdWVyeTogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92My9zdGF0cy90b3RhbCcsIHF1ZXJ5KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VTdGF0cyk7XG4gIH1cbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuaW1wb3J0IHsgQm91bmNlRGF0YSwgQ29tcGxhaW50RGF0YSwgVW5zdWJzY3JpYmVEYXRhIH0gZnJvbSAnLi9pbnRlcmZhY2VzL1N1cHJlc3Npb25zJztcblxuY29uc3QgY3JlYXRlT3B0aW9ucyA9IHtcbiAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH1cbn07XG5cbmNsYXNzIEJvdW5jZSB7XG4gIHR5cGU6IHN0cmluZztcbiAgYWRkcmVzczogc3RyaW5nO1xuICBjb2RlOiBudW1iZXI7XG4gIGVycm9yOiBzdHJpbmc7XG4gIGNyZWF0ZWRfYXQ6IERhdGU7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogQm91bmNlRGF0YSkge1xuICAgIHRoaXMudHlwZSA9ICdib3VuY2VzJztcbiAgICB0aGlzLmFkZHJlc3MgPSBkYXRhLmFkZHJlc3M7XG4gICAgdGhpcy5jb2RlID0gK2RhdGEuY29kZTtcbiAgICB0aGlzLmVycm9yID0gZGF0YS5lcnJvcjtcbiAgICB0aGlzLmNyZWF0ZWRfYXQgPSBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRfYXQpO1xuICB9XG59XG5cbmNsYXNzIENvbXBsYWludCB7XG4gIHR5cGU6IHN0cmluZztcbiAgYWRkcmVzczogYW55O1xuICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IENvbXBsYWludERhdGEpIHtcbiAgICB0aGlzLnR5cGUgPSAnY29tcGxhaW50cyc7XG4gICAgdGhpcy5hZGRyZXNzID0gZGF0YS5hZGRyZXNzO1xuICAgIHRoaXMuY3JlYXRlZF9hdCA9IG5ldyBEYXRlKGRhdGEuY3JlYXRlZF9hdCk7XG4gIH1cbn1cblxuY2xhc3MgVW5zdWJzY3JpYmUge1xuICB0eXBlOiBzdHJpbmc7XG4gIGFkZHJlc3M6IHN0cmluZztcbiAgdGFnczogYW55O1xuICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE6IFVuc3Vic2NyaWJlRGF0YSkge1xuICAgIHRoaXMudHlwZSA9ICd1bnN1YnNjcmliZXMnO1xuICAgIHRoaXMuYWRkcmVzcyA9IGRhdGEuYWRkcmVzcztcbiAgICB0aGlzLnRhZ3MgPSBkYXRhLnRhZ3M7XG4gICAgdGhpcy5jcmVhdGVkX2F0ID0gbmV3IERhdGUoZGF0YS5jcmVhdGVkX2F0KTtcbiAgfVxufVxuXG50eXBlIFRNb2RlbCA9IHR5cGVvZiBCb3VuY2UgfCB0eXBlb2YgQ29tcGxhaW50IHwgdHlwZW9mIFVuc3Vic2NyaWJlO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdXBwcmVzc2lvbkNsaWVudCB7XG4gIHJlcXVlc3Q6IGFueTtcbiAgbW9kZWxzOiB7XG4gICAgYm91bmNlczogdHlwZW9mIEJvdW5jZTtcbiAgICBjb21wbGFpbnRzOiB0eXBlb2YgQ29tcGxhaW50O1xuICAgIHVuc3Vic2NyaWJlczogdHlwZW9mIFVuc3Vic2NyaWJlO1xuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMubW9kZWxzID0ge1xuICAgICAgYm91bmNlczogQm91bmNlLFxuICAgICAgY29tcGxhaW50czogQ29tcGxhaW50LFxuICAgICAgdW5zdWJzY3JpYmVzOiBVbnN1YnNjcmliZVxuICAgIH07XG4gIH1cblxuICBfcGFyc2VQYWdlKGlkOiBzdHJpbmcsIHBhZ2VVcmw6IHN0cmluZykge1xuICAgIGNvbnN0IHBhcnNlZFVybCA9IHVybC5wYXJzZShwYWdlVXJsLCB0cnVlKTtcbiAgICBjb25zdCB7IHF1ZXJ5IH0gPSBwYXJzZWRVcmw7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQsXG4gICAgICBwYWdlOiBxdWVyeS5wYWdlLFxuICAgICAgYWRkcmVzczogcXVlcnkuYWRkcmVzcyxcbiAgICAgIHVybDogcGFnZVVybFxuICAgIH07XG4gIH1cblxuICBfcGFyc2VQYWdlTGlua3MocmVzcG9uc2U6IHsgYm9keTogeyBwYWdpbmc6IGFueSB9IH0pIHtcbiAgICBjb25zdCBwYWdlcyA9IE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmJvZHkucGFnaW5nKTtcbiAgICByZXR1cm4gcGFnZXMucmVkdWNlKFxuICAgICAgKGFjYzogYW55LCBbaWQsIHBhZ2VVcmxdOiBbcGFnZVVybDogc3RyaW5nLCBpZDogc3RyaW5nXSkgPT4ge1xuICAgICAgICBhY2NbaWRdID0gdGhpcy5fcGFyc2VQYWdlKGlkLCBwYWdlVXJsKTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIHt9XG4gICAgKTtcbiAgfVxuXG4gIF9wYXJzZUxpc3QocmVzcG9uc2U6IHsgYm9keTogeyBpdGVtczogYW55LCBwYWdpbmc6IGFueSB9IH0sIE1vZGVsOiBUTW9kZWwpIHtcbiAgICBjb25zdCBkYXRhID0ge30gYXMgYW55O1xuXG4gICAgZGF0YS5pdGVtcyA9IHJlc3BvbnNlLmJvZHkuaXRlbXMubWFwKChkOiBhbnkpID0+IG5ldyBNb2RlbChkKSk7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5fcGFyc2VQYWdlTGlua3MocmVzcG9uc2UpO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBfcGFyc2VJdGVtKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9LCBNb2RlbDogVE1vZGVsKSB7XG4gICAgcmV0dXJuIG5ldyBNb2RlbChyZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIGxpc3QoZG9tYWluOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IG1vZGVsID0gKHRoaXMubW9kZWxzIGFzIGFueSlbdHlwZV07XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAuZ2V0KHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlKSwgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogeyBpdGVtczogYW55LCBwYWdpbmc6IGFueSB9IH0pID0+IHRoaXMuX3BhcnNlTGlzdChyZXNwb25zZSwgbW9kZWwpKTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZywgdHlwZTogc3RyaW5nLCBhZGRyZXNzOiBzdHJpbmcpIHtcbiAgICBjb25zdCBtb2RlbCA9ICh0aGlzLm1vZGVscyBhcyBhbnkpW3R5cGVdO1xuXG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFxuICAgICAgLmdldCh1cmxqb2luKCd2MycsIGRvbWFpbiwgdHlwZSwgZW5jb2RlVVJJQ29tcG9uZW50KGFkZHJlc3MpKSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogeyBib2R5OiBhbnkgfSkgPT4gdGhpcy5fcGFyc2VJdGVtKHJlc3BvbnNlLCBtb2RlbCkpO1xuICB9XG5cbiAgY3JlYXRlKGRvbWFpbjogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIGRhdGE6IGFueSkge1xuICAgIC8vIHN1cHBvcnRzIGFkZGluZyBtdWx0aXBsZSBzdXBwcmVzc2lvbnMgYnkgZGVmYXVsdFxuICAgIGxldCBwb3N0RGF0YTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHBvc3REYXRhID0gW2RhdGFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3N0RGF0YSA9IHsgLi4uZGF0YSB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAgIC5wb3N0KHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlKSwgcG9zdERhdGEsIGNyZWF0ZU9wdGlvbnMpXG4gICAgICAudGhlbigocmVzcG9uc2U6IHsgYm9keTogYW55IH0pID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgZGVzdHJveShkb21haW46IHN0cmluZywgdHlwZTogc3RyaW5nLCBhZGRyZXNzOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAuZGVsZXRlKHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlLCBlbmNvZGVVUklDb21wb25lbnQoYWRkcmVzcykpKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlOiB7IGJvZHk6IGFueSB9KSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN1cHByZXNzaW9uQ2xpZW50O1xuIiwiaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9yZXF1ZXN0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmFsaWRhdGVDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgZ2V0KGFkZHJlc3M6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvYWRkcmVzcy92YWxpZGF0ZScsIHsgYWRkcmVzcyB9KVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHsgV2ViaG9va0xpc3QsIFdlYmhvb2tSZXNwb25zZSwgV2ViaG9va3NRdWVyeSB9IGZyb20gJy4vaW50ZXJmYWNlcy9XZWJob29rcyc7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL3JlcXVlc3QnO1xuXG5jbGFzcyBXZWJob29rIHtcbiAgaWQ6IHN0cmluZztcbiAgdXJsOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgdXJsOiBzdHJpbmcpIHtcbiAgICB0aGlzLmlkID0gaWQ7XG4gICAgdGhpcy51cmwgPSB1cmw7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2ViaG9va0NsaWVudCB7XG4gIHJlcXVlc3Q6IGFueTtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tMaXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgd2ViaG9va3M6IFdlYmhvb2tMaXN0IH0gfSk6IFdlYmhvb2tMaXN0IHtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS53ZWJob29rcztcbiAgfVxuXG4gIF9wYXJzZVdlYmhvb2tXaXRoSUQoaWQ6IHN0cmluZykge1xuICAgIHJldHVybiBmdW5jdGlvbiAocmVzcG9uc2U6IFdlYmhvb2tSZXNwb25zZSk6IFdlYmhvb2sge1xuICAgICAgY29uc3Qgd2ViaG9va1Jlc3BvbnNlID0gcmVzcG9uc2U/LmJvZHk/LndlYmhvb2s7XG4gICAgICBsZXQgdXJsID0gd2ViaG9va1Jlc3BvbnNlPy51cmw7XG4gICAgICBpZiAoIXVybCkge1xuICAgICAgICB1cmwgPSB3ZWJob29rUmVzcG9uc2U/LnVybHMgJiYgd2ViaG9va1Jlc3BvbnNlLnVybHMubGVuZ3RoID8gd2ViaG9va1Jlc3BvbnNlLnVybHNbMF0gOiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBXZWJob29rKGlkLCB1cmwpO1xuICAgIH07XG4gIH1cblxuICBfcGFyc2VXZWJob29rVGVzdChyZXNwb25zZTogeyBib2R5OiB7IGNvZGU6IG51bWJlciwgbWVzc2FnZTogc3RyaW5nIH0gfSlcbiAgOiB7Y29kZTogbnVtYmVyLCBtZXNzYWdlOnN0cmluZ30ge1xuICAgIHJldHVybiB7IGNvZGU6IHJlc3BvbnNlLmJvZHkuY29kZSwgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlIH07XG4gIH1cblxuICBsaXN0KGRvbWFpbjogc3RyaW5nLCBxdWVyeTogV2ViaG9va3NRdWVyeSk6IFByb21pc2U8V2ViaG9va0xpc3Q+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJyksIHF1ZXJ5KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rTGlzdCk7XG4gIH1cblxuICBnZXQoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpOiBQcm9taXNlPFdlYmhvb2s+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKCcvdjIvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJywgaWQpKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rV2l0aElEKGlkKSk7XG4gIH1cblxuICBjcmVhdGUoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcsIHVybDogc3RyaW5nLCB0ZXN0ID0gZmFsc2UpOiBQcm9taXNlPFdlYmhvb2s+IHtcbiAgICBpZiAodGVzdCkge1xuICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkLCAndGVzdCcpLCB7IHVybCB9KVxuICAgICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tUZXN0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycpLCB7IGlkLCB1cmwgfSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG5cbiAgdXBkYXRlKGRvbWFpbjogc3RyaW5nLCBpZDogc3RyaW5nLCB1cmw6IHN0cmluZyk6IFByb21pc2U8V2ViaG9vaz4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucHV0V2l0aEZEKHVybGpvaW4oJy92Mi9kb21haW5zJywgZG9tYWluLCAnd2ViaG9va3MnLCBpZCksIHsgdXJsIH0pXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tXaXRoSUQoaWQpKTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpIDogUHJvbWlzZTxXZWJob29rPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YyL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG59XG4iLCIvKiEgaHR0cHM6Ly9tdGhzLmJlL2Jhc2U2NCB2MS4wLjAgYnkgQG1hdGhpYXMgfCBNSVQgbGljZW5zZSAqL1xuOyhmdW5jdGlvbihyb290KSB7XG5cblx0Ly8gRGV0ZWN0IGZyZWUgdmFyaWFibGVzIGBleHBvcnRzYC5cblx0dmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cztcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC5cblx0dmFyIGZyZWVNb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJlxuXHRcdG1vZHVsZS5leHBvcnRzID09IGZyZWVFeHBvcnRzICYmIG1vZHVsZTtcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCwgZnJvbSBOb2RlLmpzIG9yIEJyb3dzZXJpZmllZCBjb2RlLCBhbmQgdXNlXG5cdC8vIGl0IGFzIGByb290YC5cblx0dmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcblx0aWYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsKSB7XG5cdFx0cm9vdCA9IGZyZWVHbG9iYWw7XG5cdH1cblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHR2YXIgSW52YWxpZENoYXJhY3RlckVycm9yID0gZnVuY3Rpb24obWVzc2FnZSkge1xuXHRcdHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG5cdH07XG5cdEludmFsaWRDaGFyYWN0ZXJFcnJvci5wcm90b3R5cGUgPSBuZXcgRXJyb3I7XG5cdEludmFsaWRDaGFyYWN0ZXJFcnJvci5wcm90b3R5cGUubmFtZSA9ICdJbnZhbGlkQ2hhcmFjdGVyRXJyb3InO1xuXG5cdHZhciBlcnJvciA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcblx0XHQvLyBOb3RlOiB0aGUgZXJyb3IgbWVzc2FnZXMgdXNlZCB0aHJvdWdob3V0IHRoaXMgZmlsZSBtYXRjaCB0aG9zZSB1c2VkIGJ5XG5cdFx0Ly8gdGhlIG5hdGl2ZSBgYXRvYmAvYGJ0b2FgIGltcGxlbWVudGF0aW9uIGluIENocm9taXVtLlxuXHRcdHRocm93IG5ldyBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IobWVzc2FnZSk7XG5cdH07XG5cblx0dmFyIFRBQkxFID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXHQvLyBodHRwOi8vd2hhdHdnLm9yZy9odG1sL2NvbW1vbi1taWNyb3N5bnRheGVzLmh0bWwjc3BhY2UtY2hhcmFjdGVyXG5cdHZhciBSRUdFWF9TUEFDRV9DSEFSQUNURVJTID0gL1tcXHRcXG5cXGZcXHIgXS9nO1xuXG5cdC8vIGBkZWNvZGVgIGlzIGRlc2lnbmVkIHRvIGJlIGZ1bGx5IGNvbXBhdGlibGUgd2l0aCBgYXRvYmAgYXMgZGVzY3JpYmVkIGluIHRoZVxuXHQvLyBIVE1MIFN0YW5kYXJkLiBodHRwOi8vd2hhdHdnLm9yZy9odG1sL3dlYmFwcGFwaXMuaHRtbCNkb20td2luZG93YmFzZTY0LWF0b2Jcblx0Ly8gVGhlIG9wdGltaXplZCBiYXNlNjQtZGVjb2RpbmcgYWxnb3JpdGhtIHVzZWQgaXMgYmFzZWQgb24gQGF0a+KAmXMgZXhjZWxsZW50XG5cdC8vIGltcGxlbWVudGF0aW9uLiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9hdGsvMTAyMDM5NlxuXHR2YXIgZGVjb2RlID0gZnVuY3Rpb24oaW5wdXQpIHtcblx0XHRpbnB1dCA9IFN0cmluZyhpbnB1dClcblx0XHRcdC5yZXBsYWNlKFJFR0VYX1NQQUNFX0NIQVJBQ1RFUlMsICcnKTtcblx0XHR2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXHRcdGlmIChsZW5ndGggJSA0ID09IDApIHtcblx0XHRcdGlucHV0ID0gaW5wdXQucmVwbGFjZSgvPT0/JC8sICcnKTtcblx0XHRcdGxlbmd0aCA9IGlucHV0Lmxlbmd0aDtcblx0XHR9XG5cdFx0aWYgKFxuXHRcdFx0bGVuZ3RoICUgNCA9PSAxIHx8XG5cdFx0XHQvLyBodHRwOi8vd2hhdHdnLm9yZy9DI2FscGhhbnVtZXJpYy1hc2NpaS1jaGFyYWN0ZXJzXG5cdFx0XHQvW14rYS16QS1aMC05L10vLnRlc3QoaW5wdXQpXG5cdFx0KSB7XG5cdFx0XHRlcnJvcihcblx0XHRcdFx0J0ludmFsaWQgY2hhcmFjdGVyOiB0aGUgc3RyaW5nIHRvIGJlIGRlY29kZWQgaXMgbm90IGNvcnJlY3RseSBlbmNvZGVkLidcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHZhciBiaXRDb3VudGVyID0gMDtcblx0XHR2YXIgYml0U3RvcmFnZTtcblx0XHR2YXIgYnVmZmVyO1xuXHRcdHZhciBvdXRwdXQgPSAnJztcblx0XHR2YXIgcG9zaXRpb24gPSAtMTtcblx0XHR3aGlsZSAoKytwb3NpdGlvbiA8IGxlbmd0aCkge1xuXHRcdFx0YnVmZmVyID0gVEFCTEUuaW5kZXhPZihpbnB1dC5jaGFyQXQocG9zaXRpb24pKTtcblx0XHRcdGJpdFN0b3JhZ2UgPSBiaXRDb3VudGVyICUgNCA/IGJpdFN0b3JhZ2UgKiA2NCArIGJ1ZmZlciA6IGJ1ZmZlcjtcblx0XHRcdC8vIFVubGVzcyB0aGlzIGlzIHRoZSBmaXJzdCBvZiBhIGdyb3VwIG9mIDQgY2hhcmFjdGVyc+KAplxuXHRcdFx0aWYgKGJpdENvdW50ZXIrKyAlIDQpIHtcblx0XHRcdFx0Ly8g4oCmY29udmVydCB0aGUgZmlyc3QgOCBiaXRzIHRvIGEgc2luZ2xlIEFTQ0lJIGNoYXJhY3Rlci5cblx0XHRcdFx0b3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG5cdFx0XHRcdFx0MHhGRiAmIGJpdFN0b3JhZ2UgPj4gKC0yICogYml0Q291bnRlciAmIDYpXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH07XG5cblx0Ly8gYGVuY29kZWAgaXMgZGVzaWduZWQgdG8gYmUgZnVsbHkgY29tcGF0aWJsZSB3aXRoIGBidG9hYCBhcyBkZXNjcmliZWQgaW4gdGhlXG5cdC8vIEhUTUwgU3RhbmRhcmQ6IGh0dHA6Ly93aGF0d2cub3JnL2h0bWwvd2ViYXBwYXBpcy5odG1sI2RvbS13aW5kb3diYXNlNjQtYnRvYVxuXHR2YXIgZW5jb2RlID0gZnVuY3Rpb24oaW5wdXQpIHtcblx0XHRpbnB1dCA9IFN0cmluZyhpbnB1dCk7XG5cdFx0aWYgKC9bXlxcMC1cXHhGRl0vLnRlc3QoaW5wdXQpKSB7XG5cdFx0XHQvLyBOb3RlOiBubyBuZWVkIHRvIHNwZWNpYWwtY2FzZSBhc3RyYWwgc3ltYm9scyBoZXJlLCBhcyBzdXJyb2dhdGVzIGFyZVxuXHRcdFx0Ly8gbWF0Y2hlZCwgYW5kIHRoZSBpbnB1dCBpcyBzdXBwb3NlZCB0byBvbmx5IGNvbnRhaW4gQVNDSUkgYW55d2F5LlxuXHRcdFx0ZXJyb3IoXG5cdFx0XHRcdCdUaGUgc3RyaW5nIHRvIGJlIGVuY29kZWQgY29udGFpbnMgY2hhcmFjdGVycyBvdXRzaWRlIG9mIHRoZSAnICtcblx0XHRcdFx0J0xhdGluMSByYW5nZS4nXG5cdFx0XHQpO1xuXHRcdH1cblx0XHR2YXIgcGFkZGluZyA9IGlucHV0Lmxlbmd0aCAlIDM7XG5cdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdHZhciBwb3NpdGlvbiA9IC0xO1xuXHRcdHZhciBhO1xuXHRcdHZhciBiO1xuXHRcdHZhciBjO1xuXHRcdHZhciBidWZmZXI7XG5cdFx0Ly8gTWFrZSBzdXJlIGFueSBwYWRkaW5nIGlzIGhhbmRsZWQgb3V0c2lkZSBvZiB0aGUgbG9vcC5cblx0XHR2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoIC0gcGFkZGluZztcblxuXHRcdHdoaWxlICgrK3Bvc2l0aW9uIDwgbGVuZ3RoKSB7XG5cdFx0XHQvLyBSZWFkIHRocmVlIGJ5dGVzLCBpLmUuIDI0IGJpdHMuXG5cdFx0XHRhID0gaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbikgPDwgMTY7XG5cdFx0XHRiID0gaW5wdXQuY2hhckNvZGVBdCgrK3Bvc2l0aW9uKSA8PCA4O1xuXHRcdFx0YyA9IGlucHV0LmNoYXJDb2RlQXQoKytwb3NpdGlvbik7XG5cdFx0XHRidWZmZXIgPSBhICsgYiArIGM7XG5cdFx0XHQvLyBUdXJuIHRoZSAyNCBiaXRzIGludG8gZm91ciBjaHVua3Mgb2YgNiBiaXRzIGVhY2gsIGFuZCBhcHBlbmQgdGhlXG5cdFx0XHQvLyBtYXRjaGluZyBjaGFyYWN0ZXIgZm9yIGVhY2ggb2YgdGhlbSB0byB0aGUgb3V0cHV0LlxuXHRcdFx0b3V0cHV0ICs9IChcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxOCAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxMiAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiA2ICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyICYgMHgzRilcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0aWYgKHBhZGRpbmcgPT0gMikge1xuXHRcdFx0YSA9IGlucHV0LmNoYXJDb2RlQXQocG9zaXRpb24pIDw8IDg7XG5cdFx0XHRiID0gaW5wdXQuY2hhckNvZGVBdCgrK3Bvc2l0aW9uKTtcblx0XHRcdGJ1ZmZlciA9IGEgKyBiO1xuXHRcdFx0b3V0cHV0ICs9IChcblx0XHRcdFx0VEFCTEUuY2hhckF0KGJ1ZmZlciA+PiAxMCkgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoKGJ1ZmZlciA+PiA0KSAmIDB4M0YpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KChidWZmZXIgPDwgMikgJiAweDNGKSArXG5cdFx0XHRcdCc9J1xuXHRcdFx0KTtcblx0XHR9IGVsc2UgaWYgKHBhZGRpbmcgPT0gMSkge1xuXHRcdFx0YnVmZmVyID0gaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbik7XG5cdFx0XHRvdXRwdXQgKz0gKFxuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDIpICtcblx0XHRcdFx0VEFCTEUuY2hhckF0KChidWZmZXIgPDwgNCkgJiAweDNGKSArXG5cdFx0XHRcdCc9PSdcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fTtcblxuXHR2YXIgYmFzZTY0ID0ge1xuXHRcdCdlbmNvZGUnOiBlbmNvZGUsXG5cdFx0J2RlY29kZSc6IGRlY29kZSxcblx0XHQndmVyc2lvbic6ICcxLjAuMCdcblx0fTtcblxuXHQvLyBTb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBzcGVjaWZpYyBjb25kaXRpb24gcGF0dGVybnNcblx0Ly8gbGlrZSB0aGUgZm9sbG93aW5nOlxuXHRpZiAoXG5cdFx0dHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiZcblx0XHRkZWZpbmUuYW1kXG5cdCkge1xuXHRcdGRlZmluZShmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBiYXNlNjQ7XG5cdFx0fSk7XG5cdH1cdGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmICFmcmVlRXhwb3J0cy5ub2RlVHlwZSkge1xuXHRcdGlmIChmcmVlTW9kdWxlKSB7IC8vIGluIE5vZGUuanMgb3IgUmluZ29KUyB2MC44LjArXG5cdFx0XHRmcmVlTW9kdWxlLmV4cG9ydHMgPSBiYXNlNjQ7XG5cdFx0fSBlbHNlIHsgLy8gaW4gTmFyd2hhbCBvciBSaW5nb0pTIHYwLjcuMC1cblx0XHRcdGZvciAodmFyIGtleSBpbiBiYXNlNjQpIHtcblx0XHRcdFx0YmFzZTY0Lmhhc093blByb3BlcnR5KGtleSkgJiYgKGZyZWVFeHBvcnRzW2tleV0gPSBiYXNlNjRba2V5XSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgeyAvLyBpbiBSaGlubyBvciBhIHdlYiBicm93c2VyXG5cdFx0cm9vdC5iYXNlNjQgPSBiYXNlNjQ7XG5cdH1cblxufSh0aGlzKSk7XG4iLCJcInVzZSBzdHJpY3RcIjtcbi8qKlxuICogUmV0dXJucyBhIGBCdWZmZXJgIGluc3RhbmNlIGZyb20gdGhlIGdpdmVuIGRhdGEgVVJJIGB1cmlgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmkgRGF0YSBVUkkgdG8gdHVybiBpbnRvIGEgQnVmZmVyIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtCdWZmZXJ9IEJ1ZmZlciBpbnN0YW5jZSBmcm9tIERhdGEgVVJJXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBkYXRhVXJpVG9CdWZmZXIodXJpKSB7XG4gICAgaWYgKCEvXmRhdGE6L2kudGVzdCh1cmkpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2B1cmlgIGRvZXMgbm90IGFwcGVhciB0byBiZSBhIERhdGEgVVJJIChtdXN0IGJlZ2luIHdpdGggXCJkYXRhOlwiKScpO1xuICAgIH1cbiAgICAvLyBzdHJpcCBuZXdsaW5lc1xuICAgIHVyaSA9IHVyaS5yZXBsYWNlKC9cXHI/XFxuL2csICcnKTtcbiAgICAvLyBzcGxpdCB0aGUgVVJJIHVwIGludG8gdGhlIFwibWV0YWRhdGFcIiBhbmQgdGhlIFwiZGF0YVwiIHBvcnRpb25zXG4gICAgY29uc3QgZmlyc3RDb21tYSA9IHVyaS5pbmRleE9mKCcsJyk7XG4gICAgaWYgKGZpcnN0Q29tbWEgPT09IC0xIHx8IGZpcnN0Q29tbWEgPD0gNCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtYWxmb3JtZWQgZGF0YTogVVJJJyk7XG4gICAgfVxuICAgIC8vIHJlbW92ZSB0aGUgXCJkYXRhOlwiIHNjaGVtZSBhbmQgcGFyc2UgdGhlIG1ldGFkYXRhXG4gICAgY29uc3QgbWV0YSA9IHVyaS5zdWJzdHJpbmcoNSwgZmlyc3RDb21tYSkuc3BsaXQoJzsnKTtcbiAgICBsZXQgY2hhcnNldCA9ICcnO1xuICAgIGxldCBiYXNlNjQgPSBmYWxzZTtcbiAgICBjb25zdCB0eXBlID0gbWV0YVswXSB8fCAndGV4dC9wbGFpbic7XG4gICAgbGV0IHR5cGVGdWxsID0gdHlwZTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IG1ldGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKG1ldGFbaV0gPT09ICdiYXNlNjQnKSB7XG4gICAgICAgICAgICBiYXNlNjQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdHlwZUZ1bGwgKz0gYDske21ldGFbaV19YDtcbiAgICAgICAgICAgIGlmIChtZXRhW2ldLmluZGV4T2YoJ2NoYXJzZXQ9JykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBjaGFyc2V0ID0gbWV0YVtpXS5zdWJzdHJpbmcoOCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gZGVmYXVsdHMgdG8gVVMtQVNDSUkgb25seSBpZiB0eXBlIGlzIG5vdCBwcm92aWRlZFxuICAgIGlmICghbWV0YVswXSAmJiAhY2hhcnNldC5sZW5ndGgpIHtcbiAgICAgICAgdHlwZUZ1bGwgKz0gJztjaGFyc2V0PVVTLUFTQ0lJJztcbiAgICAgICAgY2hhcnNldCA9ICdVUy1BU0NJSSc7XG4gICAgfVxuICAgIC8vIGdldCB0aGUgZW5jb2RlZCBkYXRhIHBvcnRpb24gYW5kIGRlY29kZSBVUkktZW5jb2RlZCBjaGFyc1xuICAgIGNvbnN0IGVuY29kaW5nID0gYmFzZTY0ID8gJ2Jhc2U2NCcgOiAnYXNjaWknO1xuICAgIGNvbnN0IGRhdGEgPSB1bmVzY2FwZSh1cmkuc3Vic3RyaW5nKGZpcnN0Q29tbWEgKyAxKSk7XG4gICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oZGF0YSwgZW5jb2RpbmcpO1xuICAgIC8vIHNldCBgLnR5cGVgIGFuZCBgLnR5cGVGdWxsYCBwcm9wZXJ0aWVzIHRvIE1JTUUgdHlwZVxuICAgIGJ1ZmZlci50eXBlID0gdHlwZTtcbiAgICBidWZmZXIudHlwZUZ1bGwgPSB0eXBlRnVsbDtcbiAgICAvLyBzZXQgdGhlIGAuY2hhcnNldGAgcHJvcGVydHlcbiAgICBidWZmZXIuY2hhcnNldCA9IGNoYXJzZXQ7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbn1cbm1vZHVsZS5leHBvcnRzID0gZGF0YVVyaVRvQnVmZmVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiLyoqXG4gKiBAYXV0aG9yIFRvcnUgTmFnYXNoaW1hIDxodHRwczovL2dpdGh1Yi5jb20vbXlzdGljYXRlYT5cbiAqIEBjb3B5cmlnaHQgMjAxNSBUb3J1IE5hZ2FzaGltYS4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIFNlZSBMSUNFTlNFIGZpbGUgaW4gcm9vdCBkaXJlY3RvcnkgZm9yIGZ1bGwgbGljZW5zZS5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFByaXZhdGVEYXRhXG4gKiBAcHJvcGVydHkge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0LlxuICogQHByb3BlcnR5IHt7dHlwZTpzdHJpbmd9fSBldmVudCBUaGUgb3JpZ2luYWwgZXZlbnQgb2JqZWN0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGV2ZW50UGhhc2UgVGhlIGN1cnJlbnQgZXZlbnQgcGhhc2UuXG4gKiBAcHJvcGVydHkge0V2ZW50VGFyZ2V0fG51bGx9IGN1cnJlbnRUYXJnZXQgVGhlIGN1cnJlbnQgZXZlbnQgdGFyZ2V0LlxuICogQHByb3BlcnR5IHtib29sZWFufSBjYW5jZWxlZCBUaGUgZmxhZyB0byBwcmV2ZW50IGRlZmF1bHQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHN0b3BwZWQgVGhlIGZsYWcgdG8gc3RvcCBwcm9wYWdhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gaW1tZWRpYXRlU3RvcHBlZCBUaGUgZmxhZyB0byBzdG9wIHByb3BhZ2F0aW9uIGltbWVkaWF0ZWx5LlxuICogQHByb3BlcnR5IHtGdW5jdGlvbnxudWxsfSBwYXNzaXZlTGlzdGVuZXIgVGhlIGxpc3RlbmVyIGlmIHRoZSBjdXJyZW50IGxpc3RlbmVyIGlzIHBhc3NpdmUuIE90aGVyd2lzZSB0aGlzIGlzIG51bGwuXG4gKiBAcHJvcGVydHkge251bWJlcn0gdGltZVN0YW1wIFRoZSB1bml4IHRpbWUuXG4gKiBAcHJpdmF0ZVxuICovXG5cbi8qKlxuICogUHJpdmF0ZSBkYXRhIGZvciBldmVudCB3cmFwcGVycy5cbiAqIEB0eXBlIHtXZWFrTWFwPEV2ZW50LCBQcml2YXRlRGF0YT59XG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBwcml2YXRlRGF0YSA9IG5ldyBXZWFrTWFwKCk7XG5cbi8qKlxuICogQ2FjaGUgZm9yIHdyYXBwZXIgY2xhc3Nlcy5cbiAqIEB0eXBlIHtXZWFrTWFwPE9iamVjdCwgRnVuY3Rpb24+fVxuICogQHByaXZhdGVcbiAqL1xuY29uc3Qgd3JhcHBlcnMgPSBuZXcgV2Vha01hcCgpO1xuXG4vKipcbiAqIEdldCBwcml2YXRlIGRhdGEuXG4gKiBAcGFyYW0ge0V2ZW50fSBldmVudCBUaGUgZXZlbnQgb2JqZWN0IHRvIGdldCBwcml2YXRlIGRhdGEuXG4gKiBAcmV0dXJucyB7UHJpdmF0ZURhdGF9IFRoZSBwcml2YXRlIGRhdGEgb2YgdGhlIGV2ZW50LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gcGQoZXZlbnQpIHtcbiAgICBjb25zdCByZXR2ID0gcHJpdmF0ZURhdGEuZ2V0KGV2ZW50KTtcbiAgICBjb25zb2xlLmFzc2VydChcbiAgICAgICAgcmV0diAhPSBudWxsLFxuICAgICAgICBcIid0aGlzJyBpcyBleHBlY3RlZCBhbiBFdmVudCBvYmplY3QsIGJ1dCBnb3RcIixcbiAgICAgICAgZXZlbnRcbiAgICApO1xuICAgIHJldHVybiByZXR2XG59XG5cbi8qKlxuICogaHR0cHM6Ly9kb20uc3BlYy53aGF0d2cub3JnLyNzZXQtdGhlLWNhbmNlbGVkLWZsYWdcbiAqIEBwYXJhbSBkYXRhIHtQcml2YXRlRGF0YX0gcHJpdmF0ZSBkYXRhLlxuICovXG5mdW5jdGlvbiBzZXRDYW5jZWxGbGFnKGRhdGEpIHtcbiAgICBpZiAoZGF0YS5wYXNzaXZlTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUuZXJyb3IgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgXCJVbmFibGUgdG8gcHJldmVudERlZmF1bHQgaW5zaWRlIHBhc3NpdmUgZXZlbnQgbGlzdGVuZXIgaW52b2NhdGlvbi5cIixcbiAgICAgICAgICAgICAgICBkYXRhLnBhc3NpdmVMaXN0ZW5lclxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCFkYXRhLmV2ZW50LmNhbmNlbGFibGUpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgZGF0YS5jYW5jZWxlZCA9IHRydWU7XG4gICAgaWYgKHR5cGVvZiBkYXRhLmV2ZW50LnByZXZlbnREZWZhdWx0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgZGF0YS5ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZG9tLnNwZWMud2hhdHdnLm9yZy8jaW50ZXJmYWNlLWV2ZW50XG4gKiBAcHJpdmF0ZVxuICovXG4vKipcbiAqIFRoZSBldmVudCB3cmFwcGVyLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0IG9mIHRoaXMgZGlzcGF0Y2hpbmcuXG4gKiBAcGFyYW0ge0V2ZW50fHt0eXBlOnN0cmluZ319IGV2ZW50IFRoZSBvcmlnaW5hbCBldmVudCB0byB3cmFwLlxuICovXG5mdW5jdGlvbiBFdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICBwcml2YXRlRGF0YS5zZXQodGhpcywge1xuICAgICAgICBldmVudFRhcmdldCxcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIGV2ZW50UGhhc2U6IDIsXG4gICAgICAgIGN1cnJlbnRUYXJnZXQ6IGV2ZW50VGFyZ2V0LFxuICAgICAgICBjYW5jZWxlZDogZmFsc2UsXG4gICAgICAgIHN0b3BwZWQ6IGZhbHNlLFxuICAgICAgICBpbW1lZGlhdGVTdG9wcGVkOiBmYWxzZSxcbiAgICAgICAgcGFzc2l2ZUxpc3RlbmVyOiBudWxsLFxuICAgICAgICB0aW1lU3RhbXA6IGV2ZW50LnRpbWVTdGFtcCB8fCBEYXRlLm5vdygpLFxuICAgIH0pO1xuXG4gICAgLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jVW5mb3JnZWFibGVcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJpc1RydXN0ZWRcIiwgeyB2YWx1ZTogZmFsc2UsIGVudW1lcmFibGU6IHRydWUgfSk7XG5cbiAgICAvLyBEZWZpbmUgYWNjZXNzb3JzXG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGV2ZW50KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgaWYgKCEoa2V5IGluIHRoaXMpKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCBkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3Ioa2V5KSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIFNob3VsZCBiZSBlbnVtZXJhYmxlLCBidXQgY2xhc3MgbWV0aG9kcyBhcmUgbm90IGVudW1lcmFibGUuXG5FdmVudC5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuZXZlbnQudHlwZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdGFyZ2V0IG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge0V2ZW50VGFyZ2V0fVxuICAgICAqL1xuICAgIGdldCB0YXJnZXQoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5ldmVudFRhcmdldFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdGFyZ2V0IG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge0V2ZW50VGFyZ2V0fVxuICAgICAqL1xuICAgIGdldCBjdXJyZW50VGFyZ2V0KCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuY3VycmVudFRhcmdldFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB7RXZlbnRUYXJnZXRbXX0gVGhlIGNvbXBvc2VkIHBhdGggb2YgdGhpcyBldmVudC5cbiAgICAgKi9cbiAgICBjb21wb3NlZFBhdGgoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUYXJnZXQgPSBwZCh0aGlzKS5jdXJyZW50VGFyZ2V0O1xuICAgICAgICBpZiAoY3VycmVudFRhcmdldCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gW11cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2N1cnJlbnRUYXJnZXRdXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENvbnN0YW50IG9mIE5PTkUuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgTk9ORSgpIHtcbiAgICAgICAgcmV0dXJuIDBcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQ0FQVFVSSU5HX1BIQVNFLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0IENBUFRVUklOR19QSEFTRSgpIHtcbiAgICAgICAgcmV0dXJuIDFcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQVRfVEFSR0VULlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgZ2V0IEFUX1RBUkdFVCgpIHtcbiAgICAgICAgcmV0dXJuIDJcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ29uc3RhbnQgb2YgQlVCQkxJTkdfUEhBU0UuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgQlVCQkxJTkdfUEhBU0UoKSB7XG4gICAgICAgIHJldHVybiAzXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIGdldCBldmVudFBoYXNlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuZXZlbnRQaGFzZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTdG9wIGV2ZW50IGJ1YmJsaW5nLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHN0b3BQcm9wYWdhdGlvbigpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHBkKHRoaXMpO1xuXG4gICAgICAgIGRhdGEuc3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YS5ldmVudC5zdG9wUHJvcGFnYXRpb24gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgZGF0YS5ldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTdG9wIGV2ZW50IGJ1YmJsaW5nLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHBkKHRoaXMpO1xuXG4gICAgICAgIGRhdGEuc3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGRhdGEuaW1tZWRpYXRlU3RvcHBlZCA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YS5ldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgZGF0YS5ldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBiZSBidWJibGluZy5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgYnViYmxlcygpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4ocGQodGhpcykuZXZlbnQuYnViYmxlcylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVGhlIGZsYWcgdG8gYmUgY2FuY2VsYWJsZS5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgY2FuY2VsYWJsZSgpIHtcbiAgICAgICAgcmV0dXJuIEJvb2xlYW4ocGQodGhpcykuZXZlbnQuY2FuY2VsYWJsZSlcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2FuY2VsIHRoaXMgZXZlbnQuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHQoKSB7XG4gICAgICAgIHNldENhbmNlbEZsYWcocGQodGhpcykpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBpbmRpY2F0ZSBjYW5jZWxsYXRpb24gc3RhdGUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgZ2V0IGRlZmF1bHRQcmV2ZW50ZWQoKSB7XG4gICAgICAgIHJldHVybiBwZCh0aGlzKS5jYW5jZWxlZFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBiZSBjb21wb3NlZC5cbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBnZXQgY29tcG9zZWQoKSB7XG4gICAgICAgIHJldHVybiBCb29sZWFuKHBkKHRoaXMpLmV2ZW50LmNvbXBvc2VkKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdW5peCB0aW1lIG9mIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICBnZXQgdGltZVN0YW1wKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykudGltZVN0YW1wXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSB0YXJnZXQgb2YgdGhpcyBldmVudC5cbiAgICAgKiBAdHlwZSB7RXZlbnRUYXJnZXR9XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgc3JjRWxlbWVudCgpIHtcbiAgICAgICAgcmV0dXJuIHBkKHRoaXMpLmV2ZW50VGFyZ2V0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRoZSBmbGFnIHRvIHN0b3AgZXZlbnQgYnViYmxpbmcuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgY2FuY2VsQnViYmxlKCkge1xuICAgICAgICByZXR1cm4gcGQodGhpcykuc3RvcHBlZFxuICAgIH0sXG4gICAgc2V0IGNhbmNlbEJ1YmJsZSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkYXRhID0gcGQodGhpcyk7XG5cbiAgICAgICAgZGF0YS5zdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhLmV2ZW50LmNhbmNlbEJ1YmJsZSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgICAgIGRhdGEuZXZlbnQuY2FuY2VsQnViYmxlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZmxhZyB0byBpbmRpY2F0ZSBjYW5jZWxsYXRpb24gc3RhdGUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXQgcmV0dXJuVmFsdWUoKSB7XG4gICAgICAgIHJldHVybiAhcGQodGhpcykuY2FuY2VsZWRcbiAgICB9LFxuICAgIHNldCByZXR1cm5WYWx1ZSh2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICBzZXRDYW5jZWxGbGFnKHBkKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIHRoaXMgZXZlbnQgb2JqZWN0LiBCdXQgZG8gbm90aGluZyB1bmRlciBldmVudCBkaXNwYXRjaGluZy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtidWJibGVzPWZhbHNlXSBUaGUgZmxhZyB0byBiZSBwb3NzaWJsZSB0byBidWJibGUgdXAuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY2FuY2VsYWJsZT1mYWxzZV0gVGhlIGZsYWcgdG8gYmUgcG9zc2libGUgdG8gY2FuY2VsLlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgaW5pdEV2ZW50KCkge1xuICAgICAgICAvLyBEbyBub3RoaW5nLlxuICAgIH0sXG59O1xuXG4vLyBgY29uc3RydWN0b3JgIGlzIG5vdCBlbnVtZXJhYmxlLlxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50LnByb3RvdHlwZSwgXCJjb25zdHJ1Y3RvclwiLCB7XG4gICAgdmFsdWU6IEV2ZW50LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB3cml0YWJsZTogdHJ1ZSxcbn0pO1xuXG4vLyBFbnN1cmUgYGV2ZW50IGluc3RhbmNlb2Ygd2luZG93LkV2ZW50YCBpcyBgdHJ1ZWAuXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB0eXBlb2Ygd2luZG93LkV2ZW50ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEV2ZW50LnByb3RvdHlwZSwgd2luZG93LkV2ZW50LnByb3RvdHlwZSk7XG5cbiAgICAvLyBNYWtlIGFzc29jaWF0aW9uIGZvciB3cmFwcGVycy5cbiAgICB3cmFwcGVycy5zZXQod2luZG93LkV2ZW50LnByb3RvdHlwZSwgRXZlbnQpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgcHJvcGVydHkgZGVzY3JpcHRvciB0byByZWRpcmVjdCBhIGdpdmVuIHByb3BlcnR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBQcm9wZXJ0eSBuYW1lIHRvIGRlZmluZSBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICogQHJldHVybnMge1Byb3BlcnR5RGVzY3JpcHRvcn0gVGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgdG8gcmVkaXJlY3QgdGhlIHByb3BlcnR5LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lUmVkaXJlY3REZXNjcmlwdG9yKGtleSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgIHJldHVybiBwZCh0aGlzKS5ldmVudFtrZXldXG4gICAgICAgIH0sXG4gICAgICAgIHNldCh2YWx1ZSkge1xuICAgICAgICAgICAgcGQodGhpcykuZXZlbnRba2V5XSA9IHZhbHVlO1xuICAgICAgICB9LFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgcHJvcGVydHkgZGVzY3JpcHRvciB0byBjYWxsIGEgZ2l2ZW4gbWV0aG9kIHByb3BlcnR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBQcm9wZXJ0eSBuYW1lIHRvIGRlZmluZSBwcm9wZXJ0eSBkZXNjcmlwdG9yLlxuICogQHJldHVybnMge1Byb3BlcnR5RGVzY3JpcHRvcn0gVGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgdG8gY2FsbCB0aGUgbWV0aG9kIHByb3BlcnR5LlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZGVmaW5lQ2FsbERlc2NyaXB0b3Ioa2V5KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmFsdWUoKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHBkKHRoaXMpLmV2ZW50O1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50W2tleV0uYXBwbHkoZXZlbnQsIGFyZ3VtZW50cylcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIH1cbn1cblxuLyoqXG4gKiBEZWZpbmUgbmV3IHdyYXBwZXIgY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBCYXNlRXZlbnQgVGhlIGJhc2Ugd3JhcHBlciBjbGFzcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90byBUaGUgcHJvdG90eXBlIG9mIHRoZSBvcmlnaW5hbCBldmVudC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gVGhlIGRlZmluZWQgd3JhcHBlciBjbGFzcy5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZVdyYXBwZXIoQmFzZUV2ZW50LCBwcm90bykge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhwcm90byk7XG4gICAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCYXNlRXZlbnRcbiAgICB9XG5cbiAgICAvKiogQ3VzdG9tRXZlbnQgKi9cbiAgICBmdW5jdGlvbiBDdXN0b21FdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICAgICAgQmFzZUV2ZW50LmNhbGwodGhpcywgZXZlbnRUYXJnZXQsIGV2ZW50KTtcbiAgICB9XG5cbiAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VFdmVudC5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHsgdmFsdWU6IEN1c3RvbUV2ZW50LCBjb25maWd1cmFibGU6IHRydWUsIHdyaXRhYmxlOiB0cnVlIH0sXG4gICAgfSk7XG5cbiAgICAvLyBEZWZpbmUgYWNjZXNzb3JzLlxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICBjb25zdCBrZXkgPSBrZXlzW2ldO1xuICAgICAgICBpZiAoIShrZXkgaW4gQmFzZUV2ZW50LnByb3RvdHlwZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3RvLCBrZXkpO1xuICAgICAgICAgICAgY29uc3QgaXNGdW5jID0gdHlwZW9mIGRlc2NyaXB0b3IudmFsdWUgPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcbiAgICAgICAgICAgICAgICBDdXN0b21FdmVudC5wcm90b3R5cGUsXG4gICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgIGlzRnVuY1xuICAgICAgICAgICAgICAgICAgICA/IGRlZmluZUNhbGxEZXNjcmlwdG9yKGtleSlcbiAgICAgICAgICAgICAgICAgICAgOiBkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3Ioa2V5KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBDdXN0b21FdmVudFxufVxuXG4vKipcbiAqIEdldCB0aGUgd3JhcHBlciBjbGFzcyBvZiBhIGdpdmVuIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90byBUaGUgcHJvdG90eXBlIG9mIHRoZSBvcmlnaW5hbCBldmVudCB0byBnZXQgaXRzIHdyYXBwZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFRoZSB3cmFwcGVyIGNsYXNzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0V3JhcHBlcihwcm90bykge1xuICAgIGlmIChwcm90byA9PSBudWxsIHx8IHByb3RvID09PSBPYmplY3QucHJvdG90eXBlKSB7XG4gICAgICAgIHJldHVybiBFdmVudFxuICAgIH1cblxuICAgIGxldCB3cmFwcGVyID0gd3JhcHBlcnMuZ2V0KHByb3RvKTtcbiAgICBpZiAod3JhcHBlciA9PSBudWxsKSB7XG4gICAgICAgIHdyYXBwZXIgPSBkZWZpbmVXcmFwcGVyKGdldFdyYXBwZXIoT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKSksIHByb3RvKTtcbiAgICAgICAgd3JhcHBlcnMuc2V0KHByb3RvLCB3cmFwcGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIHdyYXBwZXJcbn1cblxuLyoqXG4gKiBXcmFwIGEgZ2l2ZW4gZXZlbnQgdG8gbWFuYWdlbWVudCBhIGRpc3BhdGNoaW5nLlxuICogQHBhcmFtIHtFdmVudFRhcmdldH0gZXZlbnRUYXJnZXQgVGhlIGV2ZW50IHRhcmdldCBvZiB0aGlzIGRpc3BhdGNoaW5nLlxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IFRoZSBldmVudCB0byB3cmFwLlxuICogQHJldHVybnMge0V2ZW50fSBUaGUgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHdyYXBFdmVudChldmVudFRhcmdldCwgZXZlbnQpIHtcbiAgICBjb25zdCBXcmFwcGVyID0gZ2V0V3JhcHBlcihPYmplY3QuZ2V0UHJvdG90eXBlT2YoZXZlbnQpKTtcbiAgICByZXR1cm4gbmV3IFdyYXBwZXIoZXZlbnRUYXJnZXQsIGV2ZW50KVxufVxuXG4vKipcbiAqIEdldCB0aGUgaW1tZWRpYXRlU3RvcHBlZCBmbGFnIG9mIGEgZ2l2ZW4gZXZlbnQuXG4gKiBAcGFyYW0ge0V2ZW50fSBldmVudCBUaGUgZXZlbnQgdG8gZ2V0LlxuICogQHJldHVybnMge2Jvb2xlYW59IFRoZSBmbGFnIHRvIHN0b3AgcHJvcGFnYXRpb24gaW1tZWRpYXRlbHkuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBpc1N0b3BwZWQoZXZlbnQpIHtcbiAgICByZXR1cm4gcGQoZXZlbnQpLmltbWVkaWF0ZVN0b3BwZWRcbn1cblxuLyoqXG4gKiBTZXQgdGhlIGN1cnJlbnQgZXZlbnQgcGhhc2Ugb2YgYSBnaXZlbiBldmVudC5cbiAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IFRoZSBldmVudCB0byBzZXQgY3VycmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZXZlbnRQaGFzZSBOZXcgZXZlbnQgcGhhc2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNldEV2ZW50UGhhc2UoZXZlbnQsIGV2ZW50UGhhc2UpIHtcbiAgICBwZChldmVudCkuZXZlbnRQaGFzZSA9IGV2ZW50UGhhc2U7XG59XG5cbi8qKlxuICogU2V0IHRoZSBjdXJyZW50IHRhcmdldCBvZiBhIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIHNldCBjdXJyZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8bnVsbH0gY3VycmVudFRhcmdldCBOZXcgY3VycmVudCB0YXJnZXQuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNldEN1cnJlbnRUYXJnZXQoZXZlbnQsIGN1cnJlbnRUYXJnZXQpIHtcbiAgICBwZChldmVudCkuY3VycmVudFRhcmdldCA9IGN1cnJlbnRUYXJnZXQ7XG59XG5cbi8qKlxuICogU2V0IGEgcGFzc2l2ZSBsaXN0ZW5lciBvZiBhIGdpdmVuIGV2ZW50LlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIHNldCBjdXJyZW50IHRhcmdldC5cbiAqIEBwYXJhbSB7RnVuY3Rpb258bnVsbH0gcGFzc2l2ZUxpc3RlbmVyIE5ldyBwYXNzaXZlIGxpc3RlbmVyLlxuICogQHJldHVybnMge3ZvaWR9XG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBzZXRQYXNzaXZlTGlzdGVuZXIoZXZlbnQsIHBhc3NpdmVMaXN0ZW5lcikge1xuICAgIHBkKGV2ZW50KS5wYXNzaXZlTGlzdGVuZXIgPSBwYXNzaXZlTGlzdGVuZXI7XG59XG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gTGlzdGVuZXJOb2RlXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBsaXN0ZW5lclxuICogQHByb3BlcnR5IHsxfDJ8M30gbGlzdGVuZXJUeXBlXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHBhc3NpdmVcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gb25jZVxuICogQHByb3BlcnR5IHtMaXN0ZW5lck5vZGV8bnVsbH0gbmV4dFxuICogQHByaXZhdGVcbiAqL1xuXG4vKipcbiAqIEB0eXBlIHtXZWFrTWFwPG9iamVjdCwgTWFwPHN0cmluZywgTGlzdGVuZXJOb2RlPj59XG4gKiBAcHJpdmF0ZVxuICovXG5jb25zdCBsaXN0ZW5lcnNNYXAgPSBuZXcgV2Vha01hcCgpO1xuXG4vLyBMaXN0ZW5lciB0eXBlc1xuY29uc3QgQ0FQVFVSRSA9IDE7XG5jb25zdCBCVUJCTEUgPSAyO1xuY29uc3QgQVRUUklCVVRFID0gMztcblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gdmFsdWUgaXMgYW4gb2JqZWN0IG9yIG5vdC5cbiAqIEBwYXJhbSB7YW55fSB4IFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGFuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QoeCkge1xuICAgIHJldHVybiB4ICE9PSBudWxsICYmIHR5cGVvZiB4ID09PSBcIm9iamVjdFwiIC8vZXNsaW50LWRpc2FibGUtbGluZSBuby1yZXN0cmljdGVkLXN5bnRheFxufVxuXG4vKipcbiAqIEdldCBsaXN0ZW5lcnMuXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSBldmVudFRhcmdldCBUaGUgZXZlbnQgdGFyZ2V0IHRvIGdldC5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBMaXN0ZW5lck5vZGU+fSBUaGUgbGlzdGVuZXJzLlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2ZW50VGFyZ2V0KSB7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gbGlzdGVuZXJzTWFwLmdldChldmVudFRhcmdldCk7XG4gICAgaWYgKGxpc3RlbmVycyA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBcIid0aGlzJyBpcyBleHBlY3RlZCBhbiBFdmVudFRhcmdldCBvYmplY3QsIGJ1dCBnb3QgYW5vdGhlciB2YWx1ZS5cIlxuICAgICAgICApXG4gICAgfVxuICAgIHJldHVybiBsaXN0ZW5lcnNcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHByb3BlcnR5IGRlc2NyaXB0b3IgZm9yIHRoZSBldmVudCBhdHRyaWJ1dGUgb2YgYSBnaXZlbiBldmVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gZ2V0IHByb3BlcnR5IGRlc2NyaXB0b3IuXG4gKiBAcmV0dXJucyB7UHJvcGVydHlEZXNjcmlwdG9yfSBUaGUgcHJvcGVydHkgZGVzY3JpcHRvci5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvcihldmVudE5hbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGxpc3RlbmVycy5nZXQoZXZlbnROYW1lKTtcbiAgICAgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5saXN0ZW5lclR5cGUgPT09IEFUVFJJQlVURSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5saXN0ZW5lclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfSxcblxuICAgICAgICBzZXQobGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09IFwiZnVuY3Rpb25cIiAmJiAhaXNPYmplY3QobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBudWxsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG5cbiAgICAgICAgICAgIC8vIFRyYXZlcnNlIHRvIHRoZSB0YWlsIHdoaWxlIHJlbW92aW5nIG9sZCB2YWx1ZS5cbiAgICAgICAgICAgIGxldCBwcmV2ID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICAgICAgd2hpbGUgKG5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmxpc3RlbmVyVHlwZSA9PT0gQVRUUklCVVRFKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBvbGQgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHQgPSBub2RlLm5leHQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobm9kZS5uZXh0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5kZWxldGUoZXZlbnROYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYgPSBub2RlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFkZCBuZXcgdmFsdWUuXG4gICAgICAgICAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdOb2RlID0ge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcixcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJUeXBlOiBBVFRSSUJVVEUsXG4gICAgICAgICAgICAgICAgICAgIHBhc3NpdmU6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBvbmNlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbmV4dDogbnVsbCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zZXQoZXZlbnROYW1lLCBuZXdOb2RlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIH1cbn1cblxuLyoqXG4gKiBEZWZpbmUgYW4gZXZlbnQgYXR0cmlidXRlIChlLmcuIGBldmVudFRhcmdldC5vbmNsaWNrYCkuXG4gKiBAcGFyYW0ge09iamVjdH0gZXZlbnRUYXJnZXRQcm90b3R5cGUgVGhlIGV2ZW50IHRhcmdldCBwcm90b3R5cGUgdG8gZGVmaW5lIGFuIGV2ZW50IGF0dHJiaXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byBkZWZpbmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gZGVmaW5lRXZlbnRBdHRyaWJ1dGUoZXZlbnRUYXJnZXRQcm90b3R5cGUsIGV2ZW50TmFtZSkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcbiAgICAgICAgZXZlbnRUYXJnZXRQcm90b3R5cGUsXG4gICAgICAgIGBvbiR7ZXZlbnROYW1lfWAsXG4gICAgICAgIGRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvcihldmVudE5hbWUpXG4gICAgKTtcbn1cblxuLyoqXG4gKiBEZWZpbmUgYSBjdXN0b20gRXZlbnRUYXJnZXQgd2l0aCBldmVudCBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gZXZlbnROYW1lcyBFdmVudCBuYW1lcyBmb3IgZXZlbnQgYXR0cmlidXRlcy5cbiAqIEByZXR1cm5zIHtFdmVudFRhcmdldH0gVGhlIGN1c3RvbSBFdmVudFRhcmdldC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KGV2ZW50TmFtZXMpIHtcbiAgICAvKiogQ3VzdG9tRXZlbnRUYXJnZXQgKi9cbiAgICBmdW5jdGlvbiBDdXN0b21FdmVudFRhcmdldCgpIHtcbiAgICAgICAgRXZlbnRUYXJnZXQuY2FsbCh0aGlzKTtcbiAgICB9XG5cbiAgICBDdXN0b21FdmVudFRhcmdldC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEV2ZW50VGFyZ2V0LnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgICAgdmFsdWU6IEN1c3RvbUV2ZW50VGFyZ2V0LFxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV2ZW50TmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgZGVmaW5lRXZlbnRBdHRyaWJ1dGUoQ3VzdG9tRXZlbnRUYXJnZXQucHJvdG90eXBlLCBldmVudE5hbWVzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gQ3VzdG9tRXZlbnRUYXJnZXRcbn1cblxuLyoqXG4gKiBFdmVudFRhcmdldC5cbiAqXG4gKiAtIFRoaXMgaXMgY29uc3RydWN0b3IgaWYgbm8gYXJndW1lbnRzLlxuICogLSBUaGlzIGlzIGEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhIEN1c3RvbUV2ZW50VGFyZ2V0IGNvbnN0cnVjdG9yIGlmIHRoZXJlIGFyZSBhcmd1bWVudHMuXG4gKlxuICogRm9yIGV4YW1wbGU6XG4gKlxuICogICAgIGNsYXNzIEEgZXh0ZW5kcyBFdmVudFRhcmdldCB7fVxuICogICAgIGNsYXNzIEIgZXh0ZW5kcyBFdmVudFRhcmdldChcIm1lc3NhZ2VcIikge31cbiAqICAgICBjbGFzcyBDIGV4dGVuZHMgRXZlbnRUYXJnZXQoXCJtZXNzYWdlXCIsIFwiZXJyb3JcIikge31cbiAqICAgICBjbGFzcyBEIGV4dGVuZHMgRXZlbnRUYXJnZXQoW1wibWVzc2FnZVwiLCBcImVycm9yXCJdKSB7fVxuICovXG5mdW5jdGlvbiBFdmVudFRhcmdldCgpIHtcbiAgICAvKmVzbGludC1kaXNhYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBFdmVudFRhcmdldCkge1xuICAgICAgICBsaXN0ZW5lcnNNYXAuc2V0KHRoaXMsIG5ldyBNYXAoKSk7XG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiBBcnJheS5pc0FycmF5KGFyZ3VtZW50c1swXSkpIHtcbiAgICAgICAgcmV0dXJuIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KGFyZ3VtZW50c1swXSlcbiAgICB9XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdHlwZXNbaV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0KHR5cGVzKVxuICAgIH1cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpXG4gICAgLyplc2xpbnQtZW5hYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG59XG5cbi8vIFNob3VsZCBiZSBlbnVtZXJhYmxlLCBidXQgY2xhc3MgbWV0aG9kcyBhcmUgbm90IGVudW1lcmFibGUuXG5FdmVudFRhcmdldC5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogQWRkIGEgZ2l2ZW4gbGlzdGVuZXIgdG8gdGhpcyBldmVudCB0YXJnZXQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byBhZGQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIHRvIGFkZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW58e2NhcHR1cmU/OmJvb2xlYW4scGFzc2l2ZT86Ym9vbGVhbixvbmNlPzpib29sZWFufX0gW29wdGlvbnNdIFRoZSBvcHRpb25zIGZvciB0aGlzIGxpc3RlbmVyLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIGFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgICAgICBpZiAobGlzdGVuZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gXCJmdW5jdGlvblwiICYmICFpc09iamVjdChsaXN0ZW5lcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCInbGlzdGVuZXInIHNob3VsZCBiZSBhIGZ1bmN0aW9uIG9yIGFuIG9iamVjdC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxpc3RlbmVycyA9IGdldExpc3RlbmVycyh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9uc0lzT2JqID0gaXNPYmplY3Qob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGNhcHR1cmUgPSBvcHRpb25zSXNPYmpcbiAgICAgICAgICAgID8gQm9vbGVhbihvcHRpb25zLmNhcHR1cmUpXG4gICAgICAgICAgICA6IEJvb2xlYW4ob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyVHlwZSA9IGNhcHR1cmUgPyBDQVBUVVJFIDogQlVCQkxFO1xuICAgICAgICBjb25zdCBuZXdOb2RlID0ge1xuICAgICAgICAgICAgbGlzdGVuZXIsXG4gICAgICAgICAgICBsaXN0ZW5lclR5cGUsXG4gICAgICAgICAgICBwYXNzaXZlOiBvcHRpb25zSXNPYmogJiYgQm9vbGVhbihvcHRpb25zLnBhc3NpdmUpLFxuICAgICAgICAgICAgb25jZTogb3B0aW9uc0lzT2JqICYmIEJvb2xlYW4ob3B0aW9ucy5vbmNlKSxcbiAgICAgICAgICAgIG5leHQ6IG51bGwsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0IGl0IGFzIHRoZSBmaXJzdCBub2RlIGlmIHRoZSBmaXJzdCBub2RlIGlzIG51bGwuXG4gICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbmV3Tm9kZSk7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyYXZlcnNlIHRvIHRoZSB0YWlsIHdoaWxlIGNoZWNraW5nIGR1cGxpY2F0aW9uLi5cbiAgICAgICAgbGV0IHByZXYgPSBudWxsO1xuICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgbm9kZS5saXN0ZW5lciA9PT0gbGlzdGVuZXIgJiZcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyVHlwZSA9PT0gbGlzdGVuZXJUeXBlXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAvLyBTaG91bGQgaWdub3JlIGR1cGxpY2F0aW9uLlxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJldiA9IG5vZGU7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGl0LlxuICAgICAgICBwcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBnaXZlbiBsaXN0ZW5lciBmcm9tIHRoaXMgZXZlbnQgdGFyZ2V0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gcmVtb3ZlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIFRoZSBsaXN0ZW5lciB0byByZW1vdmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufHtjYXB0dXJlPzpib29sZWFuLHBhc3NpdmU/OmJvb2xlYW4sb25jZT86Ym9vbGVhbn19IFtvcHRpb25zXSBUaGUgb3B0aW9ucyBmb3IgdGhpcyBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICAgKi9cbiAgICByZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKGxpc3RlbmVyID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGlzdGVuZXJzID0gZ2V0TGlzdGVuZXJzKHRoaXMpO1xuICAgICAgICBjb25zdCBjYXB0dXJlID0gaXNPYmplY3Qob3B0aW9ucylcbiAgICAgICAgICAgID8gQm9vbGVhbihvcHRpb25zLmNhcHR1cmUpXG4gICAgICAgICAgICA6IEJvb2xlYW4ob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyVHlwZSA9IGNhcHR1cmUgPyBDQVBUVVJFIDogQlVCQkxFO1xuXG4gICAgICAgIGxldCBwcmV2ID0gbnVsbDtcbiAgICAgICAgbGV0IG5vZGUgPSBsaXN0ZW5lcnMuZ2V0KGV2ZW50TmFtZSk7XG4gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyID09PSBsaXN0ZW5lciAmJlxuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXJUeXBlID09PSBsaXN0ZW5lclR5cGVcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IG5vZGUubmV4dDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUubmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwcmV2ID0gbm9kZTtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLm5leHQ7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRGlzcGF0Y2ggYSBnaXZlbiBldmVudC5cbiAgICAgKiBAcGFyYW0ge0V2ZW50fHt0eXBlOnN0cmluZ319IGV2ZW50IFRoZSBldmVudCB0byBkaXNwYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYGZhbHNlYCBpZiBjYW5jZWxlZC5cbiAgICAgKi9cbiAgICBkaXNwYXRjaEV2ZW50KGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudCA9PSBudWxsIHx8IHR5cGVvZiBldmVudC50eXBlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImV2ZW50LnR5cGVcIiBzaG91bGQgYmUgYSBzdHJpbmcuJylcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIGxpc3RlbmVycyBhcmVuJ3QgcmVnaXN0ZXJlZCwgdGVybWluYXRlLlxuICAgICAgICBjb25zdCBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnModGhpcyk7XG4gICAgICAgIGNvbnN0IGV2ZW50TmFtZSA9IGV2ZW50LnR5cGU7XG4gICAgICAgIGxldCBub2RlID0gbGlzdGVuZXJzLmdldChldmVudE5hbWUpO1xuICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2luY2Ugd2UgY2Fubm90IHJld3JpdGUgc2V2ZXJhbCBwcm9wZXJ0aWVzLCBzbyB3cmFwIG9iamVjdC5cbiAgICAgICAgY29uc3Qgd3JhcHBlZEV2ZW50ID0gd3JhcEV2ZW50KHRoaXMsIGV2ZW50KTtcblxuICAgICAgICAvLyBUaGlzIGRvZXNuJ3QgcHJvY2VzcyBjYXB0dXJpbmcgcGhhc2UgYW5kIGJ1YmJsaW5nIHBoYXNlLlxuICAgICAgICAvLyBUaGlzIGlzbid0IHBhcnRpY2lwYXRpbmcgaW4gYSB0cmVlLlxuICAgICAgICBsZXQgcHJldiA9IG51bGw7XG4gICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGlzIGxpc3RlbmVyIGlmIGl0J3Mgb25jZVxuICAgICAgICAgICAgaWYgKG5vZGUub25jZSkge1xuICAgICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXYubmV4dCA9IG5vZGUubmV4dDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUubmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbm9kZS5uZXh0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmV2ID0gbm9kZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2FsbCB0aGlzIGxpc3RlbmVyXG4gICAgICAgICAgICBzZXRQYXNzaXZlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgd3JhcHBlZEV2ZW50LFxuICAgICAgICAgICAgICAgIG5vZGUucGFzc2l2ZSA/IG5vZGUubGlzdGVuZXIgOiBudWxsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBub2RlLmxpc3RlbmVyID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyLmNhbGwodGhpcywgd3JhcHBlZEV2ZW50KTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlLmVycm9yID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIG5vZGUubGlzdGVuZXJUeXBlICE9PSBBVFRSSUJVVEUgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2Ygbm9kZS5saXN0ZW5lci5oYW5kbGVFdmVudCA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBub2RlLmxpc3RlbmVyLmhhbmRsZUV2ZW50KHdyYXBwZWRFdmVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEJyZWFrIGlmIGBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb25gIHdhcyBjYWxsZWQuXG4gICAgICAgICAgICBpZiAoaXNTdG9wcGVkKHdyYXBwZWRFdmVudCkpIHtcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBub2RlID0gbm9kZS5uZXh0O1xuICAgICAgICB9XG4gICAgICAgIHNldFBhc3NpdmVMaXN0ZW5lcih3cmFwcGVkRXZlbnQsIG51bGwpO1xuICAgICAgICBzZXRFdmVudFBoYXNlKHdyYXBwZWRFdmVudCwgMCk7XG4gICAgICAgIHNldEN1cnJlbnRUYXJnZXQod3JhcHBlZEV2ZW50LCBudWxsKTtcblxuICAgICAgICByZXR1cm4gIXdyYXBwZWRFdmVudC5kZWZhdWx0UHJldmVudGVkXG4gICAgfSxcbn07XG5cbi8vIGBjb25zdHJ1Y3RvcmAgaXMgbm90IGVudW1lcmFibGUuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRUYXJnZXQucHJvdG90eXBlLCBcImNvbnN0cnVjdG9yXCIsIHtcbiAgICB2YWx1ZTogRXZlbnRUYXJnZXQsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxufSk7XG5cbi8vIEVuc3VyZSBgZXZlbnRUYXJnZXQgaW5zdGFuY2VvZiB3aW5kb3cuRXZlbnRUYXJnZXRgIGlzIGB0cnVlYC5cbmlmIChcbiAgICB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgdHlwZW9mIHdpbmRvdy5FdmVudFRhcmdldCAhPT0gXCJ1bmRlZmluZWRcIlxuKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEV2ZW50VGFyZ2V0LnByb3RvdHlwZSwgd2luZG93LkV2ZW50VGFyZ2V0LnByb3RvdHlwZSk7XG59XG5cbmV4cG9ydHMuZGVmaW5lRXZlbnRBdHRyaWJ1dGUgPSBkZWZpbmVFdmVudEF0dHJpYnV0ZTtcbmV4cG9ydHMuRXZlbnRUYXJnZXQgPSBFdmVudFRhcmdldDtcbmV4cG9ydHMuZGVmYXVsdCA9IEV2ZW50VGFyZ2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50VGFyZ2V0XG5tb2R1bGUuZXhwb3J0cy5FdmVudFRhcmdldCA9IG1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IEV2ZW50VGFyZ2V0XG5tb2R1bGUuZXhwb3J0cy5kZWZpbmVFdmVudEF0dHJpYnV0ZSA9IGRlZmluZUV2ZW50QXR0cmlidXRlXG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC10YXJnZXQtc2hpbS5qcy5tYXBcbiIsImNvbnN0IHtSZWFkYWJsZX0gPSByZXF1aXJlKCdzdHJlYW0nKTtcblxuLyoqXG4gKiBAdHlwZSB7V2Vha01hcDxCbG9iLCB7dHlwZTogc3RyaW5nLCBzaXplOiBudW1iZXIsIHBhcnRzOiAoQmxvYiB8IEJ1ZmZlcilbXSB9Pn1cbiAqL1xuY29uc3Qgd20gPSBuZXcgV2Vha01hcCgpO1xuXG5hc3luYyBmdW5jdGlvbiAqIHJlYWQocGFydHMpIHtcblx0Zm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG5cdFx0aWYgKCdzdHJlYW0nIGluIHBhcnQpIHtcblx0XHRcdHlpZWxkICogcGFydC5zdHJlYW0oKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0eWllbGQgcGFydDtcblx0XHR9XG5cdH1cbn1cblxuY2xhc3MgQmxvYiB7XG5cdC8qKlxuXHQgKiBUaGUgQmxvYigpIGNvbnN0cnVjdG9yIHJldHVybnMgYSBuZXcgQmxvYiBvYmplY3QuIFRoZSBjb250ZW50XG5cdCAqIG9mIHRoZSBibG9iIGNvbnNpc3RzIG9mIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoZSB2YWx1ZXMgZ2l2ZW5cblx0ICogaW4gdGhlIHBhcmFtZXRlciBhcnJheS5cblx0ICpcblx0ICogQHBhcmFtIHsoQXJyYXlCdWZmZXJMaWtlIHwgQXJyYXlCdWZmZXJWaWV3IHwgQmxvYiB8IEJ1ZmZlciB8IHN0cmluZylbXX0gYmxvYlBhcnRzXG5cdCAqIEBwYXJhbSB7eyB0eXBlPzogc3RyaW5nIH19IFtvcHRpb25zXVxuXHQgKi9cblx0Y29uc3RydWN0b3IoYmxvYlBhcnRzID0gW10sIG9wdGlvbnMgPSB7fSkge1xuXHRcdGxldCBzaXplID0gMDtcblxuXHRcdGNvbnN0IHBhcnRzID0gYmxvYlBhcnRzLm1hcChlbGVtZW50ID0+IHtcblx0XHRcdGxldCBidWZmZXI7XG5cdFx0XHRpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuXHRcdFx0XHRidWZmZXIgPSBlbGVtZW50O1xuXHRcdFx0fSBlbHNlIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcoZWxlbWVudCkpIHtcblx0XHRcdFx0YnVmZmVyID0gQnVmZmVyLmZyb20oZWxlbWVudC5idWZmZXIsIGVsZW1lbnQuYnl0ZU9mZnNldCwgZWxlbWVudC5ieXRlTGVuZ3RoKTtcblx0XHRcdH0gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG5cdFx0XHRcdGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGVsZW1lbnQpO1xuXHRcdFx0fSBlbHNlIGlmIChlbGVtZW50IGluc3RhbmNlb2YgQmxvYikge1xuXHRcdFx0XHRidWZmZXIgPSBlbGVtZW50O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YnVmZmVyID0gQnVmZmVyLmZyb20odHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnID8gZWxlbWVudCA6IFN0cmluZyhlbGVtZW50KSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL2V4cGxpY2l0LWxlbmd0aC1jaGVja1xuXHRcdFx0c2l6ZSArPSBidWZmZXIubGVuZ3RoIHx8IGJ1ZmZlci5zaXplIHx8IDA7XG5cdFx0XHRyZXR1cm4gYnVmZmVyO1xuXHRcdH0pO1xuXG5cdFx0Y29uc3QgdHlwZSA9IG9wdGlvbnMudHlwZSA9PT0gdW5kZWZpbmVkID8gJycgOiBTdHJpbmcob3B0aW9ucy50eXBlKS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0d20uc2V0KHRoaXMsIHtcblx0XHRcdHR5cGU6IC9bXlxcdTAwMjAtXFx1MDA3RV0vLnRlc3QodHlwZSkgPyAnJyA6IHR5cGUsXG5cdFx0XHRzaXplLFxuXHRcdFx0cGFydHNcblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgQmxvYiBpbnRlcmZhY2UncyBzaXplIHByb3BlcnR5IHJldHVybnMgdGhlXG5cdCAqIHNpemUgb2YgdGhlIEJsb2IgaW4gYnl0ZXMuXG5cdCAqL1xuXHRnZXQgc2l6ZSgpIHtcblx0XHRyZXR1cm4gd20uZ2V0KHRoaXMpLnNpemU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHR5cGUgcHJvcGVydHkgb2YgYSBCbG9iIG9iamVjdCByZXR1cm5zIHRoZSBNSU1FIHR5cGUgb2YgdGhlIGZpbGUuXG5cdCAqL1xuXHRnZXQgdHlwZSgpIHtcblx0XHRyZXR1cm4gd20uZ2V0KHRoaXMpLnR5cGU7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIHRleHQoKSBtZXRob2QgaW4gdGhlIEJsb2IgaW50ZXJmYWNlIHJldHVybnMgYSBQcm9taXNlXG5cdCAqIHRoYXQgcmVzb2x2ZXMgd2l0aCBhIHN0cmluZyBjb250YWluaW5nIHRoZSBjb250ZW50cyBvZlxuXHQgKiB0aGUgYmxvYiwgaW50ZXJwcmV0ZWQgYXMgVVRGLTguXG5cdCAqXG5cdCAqIEByZXR1cm4ge1Byb21pc2U8c3RyaW5nPn1cblx0ICovXG5cdGFzeW5jIHRleHQoKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5mcm9tKGF3YWl0IHRoaXMuYXJyYXlCdWZmZXIoKSkudG9TdHJpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgYXJyYXlCdWZmZXIoKSBtZXRob2QgaW4gdGhlIEJsb2IgaW50ZXJmYWNlIHJldHVybnMgYVxuXHQgKiBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgY29udGVudHMgb2YgdGhlIGJsb2IgYXNcblx0ICogYmluYXJ5IGRhdGEgY29udGFpbmVkIGluIGFuIEFycmF5QnVmZmVyLlxuXHQgKlxuXHQgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5QnVmZmVyPn1cblx0ICovXG5cdGFzeW5jIGFycmF5QnVmZmVyKCkge1xuXHRcdGNvbnN0IGRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLnNpemUpO1xuXHRcdGxldCBvZmZzZXQgPSAwO1xuXHRcdGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgdGhpcy5zdHJlYW0oKSkge1xuXHRcdFx0ZGF0YS5zZXQoY2h1bmssIG9mZnNldCk7XG5cdFx0XHRvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuXHRcdH1cblxuXHRcdHJldHVybiBkYXRhLmJ1ZmZlcjtcblx0fVxuXG5cdC8qKlxuXHQgKiBUaGUgQmxvYiBpbnRlcmZhY2UncyBzdHJlYW0oKSBtZXRob2QgaXMgZGlmZmVyZW5jZSBmcm9tIG5hdGl2ZVxuXHQgKiBhbmQgdXNlcyBub2RlIHN0cmVhbXMgaW5zdGVhZCBvZiB3aGF0d2cgc3RyZWFtcy5cblx0ICpcblx0ICogQHJldHVybnMge1JlYWRhYmxlfSBOb2RlIHJlYWRhYmxlIHN0cmVhbVxuXHQgKi9cblx0c3RyZWFtKCkge1xuXHRcdHJldHVybiBSZWFkYWJsZS5mcm9tKHJlYWQod20uZ2V0KHRoaXMpLnBhcnRzKSk7XG5cdH1cblxuXHQvKipcblx0ICogVGhlIEJsb2IgaW50ZXJmYWNlJ3Mgc2xpY2UoKSBtZXRob2QgY3JlYXRlcyBhbmQgcmV0dXJucyBhXG5cdCAqIG5ldyBCbG9iIG9iamVjdCB3aGljaCBjb250YWlucyBkYXRhIGZyb20gYSBzdWJzZXQgb2YgdGhlXG5cdCAqIGJsb2Igb24gd2hpY2ggaXQncyBjYWxsZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnRdXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbZW5kXVxuXHQgKiBAcGFyYW0ge3N0cmluZ30gW3R5cGVdXG5cdCAqL1xuXHRzbGljZShzdGFydCA9IDAsIGVuZCA9IHRoaXMuc2l6ZSwgdHlwZSA9ICcnKSB7XG5cdFx0Y29uc3Qge3NpemV9ID0gdGhpcztcblxuXHRcdGxldCByZWxhdGl2ZVN0YXJ0ID0gc3RhcnQgPCAwID8gTWF0aC5tYXgoc2l6ZSArIHN0YXJ0LCAwKSA6IE1hdGgubWluKHN0YXJ0LCBzaXplKTtcblx0XHRsZXQgcmVsYXRpdmVFbmQgPSBlbmQgPCAwID8gTWF0aC5tYXgoc2l6ZSArIGVuZCwgMCkgOiBNYXRoLm1pbihlbmQsIHNpemUpO1xuXG5cdFx0Y29uc3Qgc3BhbiA9IE1hdGgubWF4KHJlbGF0aXZlRW5kIC0gcmVsYXRpdmVTdGFydCwgMCk7XG5cdFx0Y29uc3QgcGFydHMgPSB3bS5nZXQodGhpcykucGFydHMudmFsdWVzKCk7XG5cdFx0Y29uc3QgYmxvYlBhcnRzID0gW107XG5cdFx0bGV0IGFkZGVkID0gMDtcblxuXHRcdGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuXHRcdFx0Y29uc3Qgc2l6ZSA9IEFycmF5QnVmZmVyLmlzVmlldyhwYXJ0KSA/IHBhcnQuYnl0ZUxlbmd0aCA6IHBhcnQuc2l6ZTtcblx0XHRcdGlmIChyZWxhdGl2ZVN0YXJ0ICYmIHNpemUgPD0gcmVsYXRpdmVTdGFydCkge1xuXHRcdFx0XHQvLyBTa2lwIHRoZSBiZWdpbm5pbmcgYW5kIGNoYW5nZSB0aGUgcmVsYXRpdmVcblx0XHRcdFx0Ly8gc3RhcnQgJiBlbmQgcG9zaXRpb24gYXMgd2Ugc2tpcCB0aGUgdW53YW50ZWQgcGFydHNcblx0XHRcdFx0cmVsYXRpdmVTdGFydCAtPSBzaXplO1xuXHRcdFx0XHRyZWxhdGl2ZUVuZCAtPSBzaXplO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3QgY2h1bmsgPSBwYXJ0LnNsaWNlKHJlbGF0aXZlU3RhcnQsIE1hdGgubWluKHNpemUsIHJlbGF0aXZlRW5kKSk7XG5cdFx0XHRcdGJsb2JQYXJ0cy5wdXNoKGNodW5rKTtcblx0XHRcdFx0YWRkZWQgKz0gQXJyYXlCdWZmZXIuaXNWaWV3KGNodW5rKSA/IGNodW5rLmJ5dGVMZW5ndGggOiBjaHVuay5zaXplO1xuXHRcdFx0XHRyZWxhdGl2ZVN0YXJ0ID0gMDsgLy8gQWxsIG5leHQgc2VxdWVudGFsIHBhcnRzIHNob3VsZCBzdGFydCBhdCAwXG5cblx0XHRcdFx0Ly8gZG9uJ3QgYWRkIHRoZSBvdmVyZmxvdyB0byBuZXcgYmxvYlBhcnRzXG5cdFx0XHRcdGlmIChhZGRlZCA+PSBzcGFuKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRjb25zdCBibG9iID0gbmV3IEJsb2IoW10sIHt0eXBlOiBTdHJpbmcodHlwZSkudG9Mb3dlckNhc2UoKX0pO1xuXHRcdE9iamVjdC5hc3NpZ24od20uZ2V0KGJsb2IpLCB7c2l6ZTogc3BhbiwgcGFydHM6IGJsb2JQYXJ0c30pO1xuXG5cdFx0cmV0dXJuIGJsb2I7XG5cdH1cblxuXHRnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG5cdFx0cmV0dXJuICdCbG9iJztcblx0fVxuXG5cdHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXShvYmplY3QpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0b2JqZWN0ICYmXG5cdFx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdFx0dHlwZW9mIG9iamVjdC5zdHJlYW0gPT09ICdmdW5jdGlvbicgJiZcblx0XHRcdG9iamVjdC5zdHJlYW0ubGVuZ3RoID09PSAwICYmXG5cdFx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0XHQvXihCbG9ifEZpbGUpJC8udGVzdChvYmplY3RbU3ltYm9sLnRvU3RyaW5nVGFnXSlcblx0XHQpO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJsb2IucHJvdG90eXBlLCB7XG5cdHNpemU6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0dHlwZToge2VudW1lcmFibGU6IHRydWV9LFxuXHRzbGljZToge2VudW1lcmFibGU6IHRydWV9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBCbG9iO1xuIiwiJ3VzZSBzdHJpY3QnO1xuY29uc3QgZmV0Y2ggPSByZXF1aXJlKCdub2RlLWZldGNoJyk7XG5jb25zdCBBYm9ydENvbnRyb2xsZXIgPSByZXF1aXJlKCdhYm9ydC1jb250cm9sbGVyJyk7XG5cbmNvbnN0IFRFTl9NRUdBQllURVMgPSAxMDAwICogMTAwMCAqIDEwO1xuXG5pZiAoIWdsb2JhbC5mZXRjaCkge1xuXHRnbG9iYWwuZmV0Y2ggPSAodXJsLCBvcHRpb25zKSA9PiBmZXRjaCh1cmwsIHtoaWdoV2F0ZXJNYXJrOiBURU5fTUVHQUJZVEVTLCAuLi5vcHRpb25zfSk7XG59XG5cbmlmICghZ2xvYmFsLkhlYWRlcnMpIHtcblx0Z2xvYmFsLkhlYWRlcnMgPSBmZXRjaC5IZWFkZXJzO1xufVxuXG5pZiAoIWdsb2JhbC5SZXF1ZXN0KSB7XG5cdGdsb2JhbC5SZXF1ZXN0ID0gZmV0Y2guUmVxdWVzdDtcbn1cblxuaWYgKCFnbG9iYWwuUmVzcG9uc2UpIHtcblx0Z2xvYmFsLlJlc3BvbnNlID0gZmV0Y2guUmVzcG9uc2U7XG59XG5cbmlmICghZ2xvYmFsLkFib3J0Q29udHJvbGxlcikge1xuXHRnbG9iYWwuQWJvcnRDb250cm9sbGVyID0gQWJvcnRDb250cm9sbGVyO1xufVxuXG5pZiAoIWdsb2JhbC5SZWFkYWJsZVN0cmVhbSkge1xuXHR0cnkge1xuXHRcdGdsb2JhbC5SZWFkYWJsZVN0cmVhbSA9IHJlcXVpcmUoJ3dlYi1zdHJlYW1zLXBvbHlmaWxsL3BvbnlmaWxsL2VzMjAxOCcpO1xuXHR9IGNhdGNoIChfKSB7fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ2t5L3VtZCcpO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuXHR0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuXHQoZ2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IGdsb2JhbCB8fCBzZWxmLCBnbG9iYWwua3kgPSBmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cblx0LyohIE1JVCBMaWNlbnNlIMKpIFNpbmRyZSBTb3JodXMgKi9cblxuXHRjb25zdCBnbG9iYWxzID0ge307XG5cblx0Y29uc3QgZ2V0R2xvYmFsID0gcHJvcGVydHkgPT4ge1xuXHRcdC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5cdFx0aWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmICYmIHByb3BlcnR5IGluIHNlbGYpIHtcblx0XHRcdHJldHVybiBzZWxmO1xuXHRcdH1cblxuXHRcdC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5cdFx0aWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdyAmJiBwcm9wZXJ0eSBpbiB3aW5kb3cpIHtcblx0XHRcdHJldHVybiB3aW5kb3c7XG5cdFx0fVxuXG5cdFx0aWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbCAmJiBwcm9wZXJ0eSBpbiBnbG9iYWwpIHtcblx0XHRcdHJldHVybiBnbG9iYWw7XG5cdFx0fVxuXG5cdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbFRoaXMpIHtcblx0XHRcdHJldHVybiBnbG9iYWxUaGlzO1xuXHRcdH1cblx0fTtcblxuXHRjb25zdCBnbG9iYWxQcm9wZXJ0aWVzID0gW1xuXHRcdCdIZWFkZXJzJyxcblx0XHQnUmVxdWVzdCcsXG5cdFx0J1Jlc3BvbnNlJyxcblx0XHQnUmVhZGFibGVTdHJlYW0nLFxuXHRcdCdmZXRjaCcsXG5cdFx0J0Fib3J0Q29udHJvbGxlcicsXG5cdFx0J0Zvcm1EYXRhJ1xuXHRdO1xuXG5cdGZvciAoY29uc3QgcHJvcGVydHkgb2YgZ2xvYmFsUHJvcGVydGllcykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxzLCBwcm9wZXJ0eSwge1xuXHRcdFx0Z2V0KCkge1xuXHRcdFx0XHRjb25zdCBnbG9iYWxPYmplY3QgPSBnZXRHbG9iYWwocHJvcGVydHkpO1xuXHRcdFx0XHRjb25zdCB2YWx1ZSA9IGdsb2JhbE9iamVjdCAmJiBnbG9iYWxPYmplY3RbcHJvcGVydHldO1xuXHRcdFx0XHRyZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gdmFsdWUuYmluZChnbG9iYWxPYmplY3QpIDogdmFsdWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRjb25zdCBpc09iamVjdCA9IHZhbHVlID0+IHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCc7XG5cdGNvbnN0IHN1cHBvcnRzQWJvcnRDb250cm9sbGVyID0gdHlwZW9mIGdsb2JhbHMuQWJvcnRDb250cm9sbGVyID09PSAnZnVuY3Rpb24nO1xuXHRjb25zdCBzdXBwb3J0c1N0cmVhbXMgPSB0eXBlb2YgZ2xvYmFscy5SZWFkYWJsZVN0cmVhbSA9PT0gJ2Z1bmN0aW9uJztcblx0Y29uc3Qgc3VwcG9ydHNGb3JtRGF0YSA9IHR5cGVvZiBnbG9iYWxzLkZvcm1EYXRhID09PSAnZnVuY3Rpb24nO1xuXG5cdGNvbnN0IG1lcmdlSGVhZGVycyA9IChzb3VyY2UxLCBzb3VyY2UyKSA9PiB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gbmV3IGdsb2JhbHMuSGVhZGVycyhzb3VyY2UxIHx8IHt9KTtcblx0XHRjb25zdCBpc0hlYWRlcnNJbnN0YW5jZSA9IHNvdXJjZTIgaW5zdGFuY2VvZiBnbG9iYWxzLkhlYWRlcnM7XG5cdFx0Y29uc3Qgc291cmNlID0gbmV3IGdsb2JhbHMuSGVhZGVycyhzb3VyY2UyIHx8IHt9KTtcblxuXHRcdGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHNvdXJjZSkge1xuXHRcdFx0aWYgKChpc0hlYWRlcnNJbnN0YW5jZSAmJiB2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmVzdWx0LmRlbGV0ZShrZXkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmVzdWx0LnNldChrZXksIHZhbHVlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9O1xuXG5cdGNvbnN0IGRlZXBNZXJnZSA9ICguLi5zb3VyY2VzKSA9PiB7XG5cdFx0bGV0IHJldHVyblZhbHVlID0ge307XG5cdFx0bGV0IGhlYWRlcnMgPSB7fTtcblxuXHRcdGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcblx0XHRcdGlmIChBcnJheS5pc0FycmF5KHNvdXJjZSkpIHtcblx0XHRcdFx0aWYgKCEoQXJyYXkuaXNBcnJheShyZXR1cm5WYWx1ZSkpKSB7XG5cdFx0XHRcdFx0cmV0dXJuVmFsdWUgPSBbXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVyblZhbHVlID0gWy4uLnJldHVyblZhbHVlLCAuLi5zb3VyY2VdO1xuXHRcdFx0fSBlbHNlIGlmIChpc09iamVjdChzb3VyY2UpKSB7XG5cdFx0XHRcdGZvciAobGV0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhzb3VyY2UpKSB7XG5cdFx0XHRcdFx0aWYgKGlzT2JqZWN0KHZhbHVlKSAmJiAoa2V5IGluIHJldHVyblZhbHVlKSkge1xuXHRcdFx0XHRcdFx0dmFsdWUgPSBkZWVwTWVyZ2UocmV0dXJuVmFsdWVba2V5XSwgdmFsdWUpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVyblZhbHVlID0gey4uLnJldHVyblZhbHVlLCBba2V5XTogdmFsdWV9O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGlzT2JqZWN0KHNvdXJjZS5oZWFkZXJzKSkge1xuXHRcdFx0XHRcdGhlYWRlcnMgPSBtZXJnZUhlYWRlcnMoaGVhZGVycywgc291cmNlLmhlYWRlcnMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVyblZhbHVlLmhlYWRlcnMgPSBoZWFkZXJzO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXR1cm5WYWx1ZTtcblx0fTtcblxuXHRjb25zdCByZXF1ZXN0TWV0aG9kcyA9IFtcblx0XHQnZ2V0Jyxcblx0XHQncG9zdCcsXG5cdFx0J3B1dCcsXG5cdFx0J3BhdGNoJyxcblx0XHQnaGVhZCcsXG5cdFx0J2RlbGV0ZSdcblx0XTtcblxuXHRjb25zdCByZXNwb25zZVR5cGVzID0ge1xuXHRcdGpzb246ICdhcHBsaWNhdGlvbi9qc29uJyxcblx0XHR0ZXh0OiAndGV4dC8qJyxcblx0XHRmb3JtRGF0YTogJ211bHRpcGFydC9mb3JtLWRhdGEnLFxuXHRcdGFycmF5QnVmZmVyOiAnKi8qJyxcblx0XHRibG9iOiAnKi8qJ1xuXHR9O1xuXG5cdGNvbnN0IHJldHJ5TWV0aG9kcyA9IFtcblx0XHQnZ2V0Jyxcblx0XHQncHV0Jyxcblx0XHQnaGVhZCcsXG5cdFx0J2RlbGV0ZScsXG5cdFx0J29wdGlvbnMnLFxuXHRcdCd0cmFjZSdcblx0XTtcblxuXHRjb25zdCByZXRyeVN0YXR1c0NvZGVzID0gW1xuXHRcdDQwOCxcblx0XHQ0MTMsXG5cdFx0NDI5LFxuXHRcdDUwMCxcblx0XHQ1MDIsXG5cdFx0NTAzLFxuXHRcdDUwNFxuXHRdO1xuXG5cdGNvbnN0IHJldHJ5QWZ0ZXJTdGF0dXNDb2RlcyA9IFtcblx0XHQ0MTMsXG5cdFx0NDI5LFxuXHRcdDUwM1xuXHRdO1xuXG5cdGNvbnN0IHN0b3AgPSBTeW1ib2woJ3N0b3AnKTtcblxuXHRjbGFzcyBIVFRQRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdFx0Y29uc3RydWN0b3IocmVzcG9uc2UpIHtcblx0XHRcdC8vIFNldCB0aGUgbWVzc2FnZSB0byB0aGUgc3RhdHVzIHRleHQsIHN1Y2ggYXMgVW5hdXRob3JpemVkLFxuXHRcdFx0Ly8gd2l0aCBzb21lIGZhbGxiYWNrcy4gVGhpcyBtZXNzYWdlIHNob3VsZCBuZXZlciBiZSB1bmRlZmluZWQuXG5cdFx0XHRzdXBlcihcblx0XHRcdFx0cmVzcG9uc2Uuc3RhdHVzVGV4dCB8fFxuXHRcdFx0XHRTdHJpbmcoXG5cdFx0XHRcdFx0KHJlc3BvbnNlLnN0YXR1cyA9PT0gMCB8fCByZXNwb25zZS5zdGF0dXMpID9cblx0XHRcdFx0XHRcdHJlc3BvbnNlLnN0YXR1cyA6ICdVbmtub3duIHJlc3BvbnNlIGVycm9yJ1xuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdFx0dGhpcy5uYW1lID0gJ0hUVFBFcnJvcic7XG5cdFx0XHR0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG5cdFx0fVxuXHR9XG5cblx0Y2xhc3MgVGltZW91dEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRcdGNvbnN0cnVjdG9yKHJlcXVlc3QpIHtcblx0XHRcdHN1cGVyKCdSZXF1ZXN0IHRpbWVkIG91dCcpO1xuXHRcdFx0dGhpcy5uYW1lID0gJ1RpbWVvdXRFcnJvcic7XG5cdFx0XHR0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuXHRcdH1cblx0fVxuXG5cdGNvbnN0IGRlbGF5ID0gbXMgPT4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG5cblx0Ly8gYFByb21pc2UucmFjZSgpYCB3b3JrYXJvdW5kICgjOTEpXG5cdGNvbnN0IHRpbWVvdXQgPSAocmVxdWVzdCwgYWJvcnRDb250cm9sbGVyLCBvcHRpb25zKSA9PlxuXHRcdG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRcdGNvbnN0IHRpbWVvdXRJRCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRpZiAoYWJvcnRDb250cm9sbGVyKSB7XG5cdFx0XHRcdFx0YWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZWplY3QobmV3IFRpbWVvdXRFcnJvcihyZXF1ZXN0KSk7XG5cdFx0XHR9LCBvcHRpb25zLnRpbWVvdXQpO1xuXG5cdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBwcm9taXNlL3ByZWZlci1hd2FpdC10by10aGVuICovXG5cdFx0XHRvcHRpb25zLmZldGNoKHJlcXVlc3QpXG5cdFx0XHRcdC50aGVuKHJlc29sdmUpXG5cdFx0XHRcdC5jYXRjaChyZWplY3QpXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHRjbGVhclRpbWVvdXQodGltZW91dElEKTtcblx0XHRcdFx0fSk7XG5cdFx0XHQvKiBlc2xpbnQtZW5hYmxlIHByb21pc2UvcHJlZmVyLWF3YWl0LXRvLXRoZW4gKi9cblx0XHR9KTtcblxuXHRjb25zdCBub3JtYWxpemVSZXF1ZXN0TWV0aG9kID0gaW5wdXQgPT4gcmVxdWVzdE1ldGhvZHMuaW5jbHVkZXMoaW5wdXQpID8gaW5wdXQudG9VcHBlckNhc2UoKSA6IGlucHV0O1xuXG5cdGNvbnN0IGRlZmF1bHRSZXRyeU9wdGlvbnMgPSB7XG5cdFx0bGltaXQ6IDIsXG5cdFx0bWV0aG9kczogcmV0cnlNZXRob2RzLFxuXHRcdHN0YXR1c0NvZGVzOiByZXRyeVN0YXR1c0NvZGVzLFxuXHRcdGFmdGVyU3RhdHVzQ29kZXM6IHJldHJ5QWZ0ZXJTdGF0dXNDb2Rlc1xuXHR9O1xuXG5cdGNvbnN0IG5vcm1hbGl6ZVJldHJ5T3B0aW9ucyA9IChyZXRyeSA9IHt9KSA9PiB7XG5cdFx0aWYgKHR5cGVvZiByZXRyeSA9PT0gJ251bWJlcicpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdC4uLmRlZmF1bHRSZXRyeU9wdGlvbnMsXG5cdFx0XHRcdGxpbWl0OiByZXRyeVxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAocmV0cnkubWV0aG9kcyAmJiAhQXJyYXkuaXNBcnJheShyZXRyeS5tZXRob2RzKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdyZXRyeS5tZXRob2RzIG11c3QgYmUgYW4gYXJyYXknKTtcblx0XHR9XG5cblx0XHRpZiAocmV0cnkuc3RhdHVzQ29kZXMgJiYgIUFycmF5LmlzQXJyYXkocmV0cnkuc3RhdHVzQ29kZXMpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ3JldHJ5LnN0YXR1c0NvZGVzIG11c3QgYmUgYW4gYXJyYXknKTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0Li4uZGVmYXVsdFJldHJ5T3B0aW9ucyxcblx0XHRcdC4uLnJldHJ5LFxuXHRcdFx0YWZ0ZXJTdGF0dXNDb2RlczogcmV0cnlBZnRlclN0YXR1c0NvZGVzXG5cdFx0fTtcblx0fTtcblxuXHQvLyBUaGUgbWF4aW11bSB2YWx1ZSBvZiBhIDMyYml0IGludCAoc2VlIGlzc3VlICMxMTcpXG5cdGNvbnN0IG1heFNhZmVUaW1lb3V0ID0gMjE0NzQ4MzY0NztcblxuXHRjbGFzcyBLeSB7XG5cdFx0Y29uc3RydWN0b3IoaW5wdXQsIG9wdGlvbnMgPSB7fSkge1xuXHRcdFx0dGhpcy5fcmV0cnlDb3VudCA9IDA7XG5cdFx0XHR0aGlzLl9pbnB1dCA9IGlucHV0O1xuXHRcdFx0dGhpcy5fb3B0aW9ucyA9IHtcblx0XHRcdFx0Ly8gVE9ETzogY3JlZGVudGlhbHMgY2FuIGJlIHJlbW92ZWQgd2hlbiB0aGUgc3BlYyBjaGFuZ2UgaXMgaW1wbGVtZW50ZWQgaW4gYWxsIGJyb3dzZXJzLiBDb250ZXh0OiBodHRwczovL3d3dy5jaHJvbWVzdGF0dXMuY29tL2ZlYXR1cmUvNDUzOTQ3MzMxMjM1MDIwOFxuXHRcdFx0XHRjcmVkZW50aWFsczogdGhpcy5faW5wdXQuY3JlZGVudGlhbHMgfHwgJ3NhbWUtb3JpZ2luJyxcblx0XHRcdFx0Li4ub3B0aW9ucyxcblx0XHRcdFx0aGVhZGVyczogbWVyZ2VIZWFkZXJzKHRoaXMuX2lucHV0LmhlYWRlcnMsIG9wdGlvbnMuaGVhZGVycyksXG5cdFx0XHRcdGhvb2tzOiBkZWVwTWVyZ2Uoe1xuXHRcdFx0XHRcdGJlZm9yZVJlcXVlc3Q6IFtdLFxuXHRcdFx0XHRcdGJlZm9yZVJldHJ5OiBbXSxcblx0XHRcdFx0XHRhZnRlclJlc3BvbnNlOiBbXVxuXHRcdFx0XHR9LCBvcHRpb25zLmhvb2tzKSxcblx0XHRcdFx0bWV0aG9kOiBub3JtYWxpemVSZXF1ZXN0TWV0aG9kKG9wdGlvbnMubWV0aG9kIHx8IHRoaXMuX2lucHV0Lm1ldGhvZCksXG5cdFx0XHRcdHByZWZpeFVybDogU3RyaW5nKG9wdGlvbnMucHJlZml4VXJsIHx8ICcnKSxcblx0XHRcdFx0cmV0cnk6IG5vcm1hbGl6ZVJldHJ5T3B0aW9ucyhvcHRpb25zLnJldHJ5KSxcblx0XHRcdFx0dGhyb3dIdHRwRXJyb3JzOiBvcHRpb25zLnRocm93SHR0cEVycm9ycyAhPT0gZmFsc2UsXG5cdFx0XHRcdHRpbWVvdXQ6IHR5cGVvZiBvcHRpb25zLnRpbWVvdXQgPT09ICd1bmRlZmluZWQnID8gMTAwMDAgOiBvcHRpb25zLnRpbWVvdXQsXG5cdFx0XHRcdGZldGNoOiBvcHRpb25zLmZldGNoIHx8IGdsb2JhbHMuZmV0Y2hcblx0XHRcdH07XG5cblx0XHRcdGlmICh0eXBlb2YgdGhpcy5faW5wdXQgIT09ICdzdHJpbmcnICYmICEodGhpcy5faW5wdXQgaW5zdGFuY2VvZiBVUkwgfHwgdGhpcy5faW5wdXQgaW5zdGFuY2VvZiBnbG9iYWxzLlJlcXVlc3QpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ2BpbnB1dGAgbXVzdCBiZSBhIHN0cmluZywgVVJMLCBvciBSZXF1ZXN0Jyk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnByZWZpeFVybCAmJiB0eXBlb2YgdGhpcy5faW5wdXQgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdGlmICh0aGlzLl9pbnB1dC5zdGFydHNXaXRoKCcvJykpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ2BpbnB1dGAgbXVzdCBub3QgYmVnaW4gd2l0aCBhIHNsYXNoIHdoZW4gdXNpbmcgYHByZWZpeFVybGAnKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICghdGhpcy5fb3B0aW9ucy5wcmVmaXhVcmwuZW5kc1dpdGgoJy8nKSkge1xuXHRcdFx0XHRcdHRoaXMuX29wdGlvbnMucHJlZml4VXJsICs9ICcvJztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMuX2lucHV0ID0gdGhpcy5fb3B0aW9ucy5wcmVmaXhVcmwgKyB0aGlzLl9pbnB1dDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHN1cHBvcnRzQWJvcnRDb250cm9sbGVyKSB7XG5cdFx0XHRcdHRoaXMuYWJvcnRDb250cm9sbGVyID0gbmV3IGdsb2JhbHMuQWJvcnRDb250cm9sbGVyKCk7XG5cdFx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnNpZ25hbCkge1xuXHRcdFx0XHRcdHRoaXMuX29wdGlvbnMuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5hYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHRoaXMuX29wdGlvbnMuc2lnbmFsID0gdGhpcy5hYm9ydENvbnRyb2xsZXIuc2lnbmFsO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnJlcXVlc3QgPSBuZXcgZ2xvYmFscy5SZXF1ZXN0KHRoaXMuX2lucHV0LCB0aGlzLl9vcHRpb25zKTtcblxuXHRcdFx0aWYgKHRoaXMuX29wdGlvbnMuc2VhcmNoUGFyYW1zKSB7XG5cdFx0XHRcdGNvbnN0IHNlYXJjaFBhcmFtcyA9ICc/JyArIG5ldyBVUkxTZWFyY2hQYXJhbXModGhpcy5fb3B0aW9ucy5zZWFyY2hQYXJhbXMpLnRvU3RyaW5nKCk7XG5cdFx0XHRcdGNvbnN0IHVybCA9IHRoaXMucmVxdWVzdC51cmwucmVwbGFjZSgvKD86XFw/Lio/KT8oPz0jfCQpLywgc2VhcmNoUGFyYW1zKTtcblxuXHRcdFx0XHQvLyBUbyBwcm92aWRlIGNvcnJlY3QgZm9ybSBib3VuZGFyeSwgQ29udGVudC1UeXBlIGhlYWRlciBzaG91bGQgYmUgZGVsZXRlZCBlYWNoIHRpbWUgd2hlbiBuZXcgUmVxdWVzdCBpbnN0YW50aWF0ZWQgZnJvbSBhbm90aGVyIG9uZVxuXHRcdFx0XHRpZiAoKChzdXBwb3J0c0Zvcm1EYXRhICYmIHRoaXMuX29wdGlvbnMuYm9keSBpbnN0YW5jZW9mIGdsb2JhbHMuRm9ybURhdGEpIHx8IHRoaXMuX29wdGlvbnMuYm9keSBpbnN0YW5jZW9mIFVSTFNlYXJjaFBhcmFtcykgJiYgISh0aGlzLl9vcHRpb25zLmhlYWRlcnMgJiYgdGhpcy5fb3B0aW9ucy5oZWFkZXJzWydjb250ZW50LXR5cGUnXSkpIHtcblx0XHRcdFx0XHR0aGlzLnJlcXVlc3QuaGVhZGVycy5kZWxldGUoJ2NvbnRlbnQtdHlwZScpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5yZXF1ZXN0ID0gbmV3IGdsb2JhbHMuUmVxdWVzdChuZXcgZ2xvYmFscy5SZXF1ZXN0KHVybCwgdGhpcy5yZXF1ZXN0KSwgdGhpcy5fb3B0aW9ucyk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLmpzb24gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHR0aGlzLl9vcHRpb25zLmJvZHkgPSBKU09OLnN0cmluZ2lmeSh0aGlzLl9vcHRpb25zLmpzb24pO1xuXHRcdFx0XHR0aGlzLnJlcXVlc3QuaGVhZGVycy5zZXQoJ2NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XG5cdFx0XHRcdHRoaXMucmVxdWVzdCA9IG5ldyBnbG9iYWxzLlJlcXVlc3QodGhpcy5yZXF1ZXN0LCB7Ym9keTogdGhpcy5fb3B0aW9ucy5ib2R5fSk7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IGZuID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aW1lb3V0ID4gbWF4U2FmZVRpbWVvdXQpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVGhlIFxcYHRpbWVvdXRcXGAgb3B0aW9uIGNhbm5vdCBiZSBncmVhdGVyIHRoYW4gJHttYXhTYWZlVGltZW91dH1gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGF3YWl0IGRlbGF5KDEpO1xuXHRcdFx0XHRsZXQgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9mZXRjaCgpO1xuXG5cdFx0XHRcdGZvciAoY29uc3QgaG9vayBvZiB0aGlzLl9vcHRpb25zLmhvb2tzLmFmdGVyUmVzcG9uc2UpIHtcblx0XHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuXHRcdFx0XHRcdGNvbnN0IG1vZGlmaWVkUmVzcG9uc2UgPSBhd2FpdCBob29rKFxuXHRcdFx0XHRcdFx0dGhpcy5yZXF1ZXN0LFxuXHRcdFx0XHRcdFx0dGhpcy5fb3B0aW9ucyxcblx0XHRcdFx0XHRcdHRoaXMuX2RlY29yYXRlUmVzcG9uc2UocmVzcG9uc2UuY2xvbmUoKSlcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0aWYgKG1vZGlmaWVkUmVzcG9uc2UgaW5zdGFuY2VvZiBnbG9iYWxzLlJlc3BvbnNlKSB7XG5cdFx0XHRcdFx0XHRyZXNwb25zZSA9IG1vZGlmaWVkUmVzcG9uc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5fZGVjb3JhdGVSZXNwb25zZShyZXNwb25zZSk7XG5cblx0XHRcdFx0aWYgKCFyZXNwb25zZS5vayAmJiB0aGlzLl9vcHRpb25zLnRocm93SHR0cEVycm9ycykge1xuXHRcdFx0XHRcdHRocm93IG5ldyBIVFRQRXJyb3IocmVzcG9uc2UpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSWYgYG9uRG93bmxvYWRQcm9ncmVzc2AgaXMgcGFzc2VkLCBpdCB1c2VzIHRoZSBzdHJlYW0gQVBJIGludGVybmFsbHlcblx0XHRcdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRcdFx0aWYgKHRoaXMuX29wdGlvbnMub25Eb3dubG9hZFByb2dyZXNzKSB7XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLl9vcHRpb25zLm9uRG93bmxvYWRQcm9ncmVzcyAhPT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGBvbkRvd25sb2FkUHJvZ3Jlc3NgIG9wdGlvbiBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIXN1cHBvcnRzU3RyZWFtcykge1xuXHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCdTdHJlYW1zIGFyZSBub3Qgc3VwcG9ydGVkIGluIHlvdXIgZW52aXJvbm1lbnQuIGBSZWFkYWJsZVN0cmVhbWAgaXMgbWlzc2luZy4nKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5fc3RyZWFtKHJlc3BvbnNlLmNsb25lKCksIHRoaXMuX29wdGlvbnMub25Eb3dubG9hZFByb2dyZXNzKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiByZXNwb25zZTtcblx0XHRcdH07XG5cblx0XHRcdGNvbnN0IGlzUmV0cmlhYmxlTWV0aG9kID0gdGhpcy5fb3B0aW9ucy5yZXRyeS5tZXRob2RzLmluY2x1ZGVzKHRoaXMucmVxdWVzdC5tZXRob2QudG9Mb3dlckNhc2UoKSk7XG5cdFx0XHRjb25zdCByZXN1bHQgPSBpc1JldHJpYWJsZU1ldGhvZCA/IHRoaXMuX3JldHJ5KGZuKSA6IGZuKCk7XG5cblx0XHRcdGZvciAoY29uc3QgW3R5cGUsIG1pbWVUeXBlXSBvZiBPYmplY3QuZW50cmllcyhyZXNwb25zZVR5cGVzKSkge1xuXHRcdFx0XHRyZXN1bHRbdHlwZV0gPSBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5yZXF1ZXN0LmhlYWRlcnMuc2V0KCdhY2NlcHQnLCB0aGlzLnJlcXVlc3QuaGVhZGVycy5nZXQoJ2FjY2VwdCcpIHx8IG1pbWVUeXBlKTtcblxuXHRcdFx0XHRcdGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IHJlc3VsdCkuY2xvbmUoKTtcblxuXHRcdFx0XHRcdGlmICh0eXBlID09PSAnanNvbicpIHtcblx0XHRcdFx0XHRcdGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDIwNCkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gJyc7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmIChvcHRpb25zLnBhcnNlSnNvbikge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gb3B0aW9ucy5wYXJzZUpzb24oYXdhaXQgcmVzcG9uc2UudGV4dCgpKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gcmVzcG9uc2VbdHlwZV0oKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cblx0XHRfY2FsY3VsYXRlUmV0cnlEZWxheShlcnJvcikge1xuXHRcdFx0dGhpcy5fcmV0cnlDb3VudCsrO1xuXG5cdFx0XHRpZiAodGhpcy5fcmV0cnlDb3VudCA8IHRoaXMuX29wdGlvbnMucmV0cnkubGltaXQgJiYgIShlcnJvciBpbnN0YW5jZW9mIFRpbWVvdXRFcnJvcikpIHtcblx0XHRcdFx0aWYgKGVycm9yIGluc3RhbmNlb2YgSFRUUEVycm9yKSB7XG5cdFx0XHRcdFx0aWYgKCF0aGlzLl9vcHRpb25zLnJldHJ5LnN0YXR1c0NvZGVzLmluY2x1ZGVzKGVycm9yLnJlc3BvbnNlLnN0YXR1cykpIHtcblx0XHRcdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGNvbnN0IHJldHJ5QWZ0ZXIgPSBlcnJvci5yZXNwb25zZS5oZWFkZXJzLmdldCgnUmV0cnktQWZ0ZXInKTtcblx0XHRcdFx0XHRpZiAocmV0cnlBZnRlciAmJiB0aGlzLl9vcHRpb25zLnJldHJ5LmFmdGVyU3RhdHVzQ29kZXMuaW5jbHVkZXMoZXJyb3IucmVzcG9uc2Uuc3RhdHVzKSkge1xuXHRcdFx0XHRcdFx0bGV0IGFmdGVyID0gTnVtYmVyKHJldHJ5QWZ0ZXIpO1xuXHRcdFx0XHRcdFx0aWYgKE51bWJlci5pc05hTihhZnRlcikpIHtcblx0XHRcdFx0XHRcdFx0YWZ0ZXIgPSBEYXRlLnBhcnNlKHJldHJ5QWZ0ZXIpIC0gRGF0ZS5ub3coKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGFmdGVyICo9IDEwMDA7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGlmICh0eXBlb2YgdGhpcy5fb3B0aW9ucy5yZXRyeS5tYXhSZXRyeUFmdGVyICE9PSAndW5kZWZpbmVkJyAmJiBhZnRlciA+IHRoaXMuX29wdGlvbnMucmV0cnkubWF4UmV0cnlBZnRlcikge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIGFmdGVyO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmIChlcnJvci5yZXNwb25zZS5zdGF0dXMgPT09IDQxMykge1xuXHRcdFx0XHRcdFx0cmV0dXJuIDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29uc3QgQkFDS09GRl9GQUNUT1IgPSAwLjM7XG5cdFx0XHRcdHJldHVybiBCQUNLT0ZGX0ZBQ1RPUiAqICgyICoqICh0aGlzLl9yZXRyeUNvdW50IC0gMSkpICogMTAwMDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0X2RlY29yYXRlUmVzcG9uc2UocmVzcG9uc2UpIHtcblx0XHRcdGlmICh0aGlzLl9vcHRpb25zLnBhcnNlSnNvbikge1xuXHRcdFx0XHRyZXNwb25zZS5qc29uID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9vcHRpb25zLnBhcnNlSnNvbihhd2FpdCByZXNwb25zZS50ZXh0KCkpO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzcG9uc2U7XG5cdFx0fVxuXG5cdFx0YXN5bmMgX3JldHJ5KGZuKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRyZXR1cm4gYXdhaXQgZm4oKTtcblx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdGNvbnN0IG1zID0gTWF0aC5taW4odGhpcy5fY2FsY3VsYXRlUmV0cnlEZWxheShlcnJvciksIG1heFNhZmVUaW1lb3V0KTtcblx0XHRcdFx0aWYgKG1zICE9PSAwICYmIHRoaXMuX3JldHJ5Q291bnQgPiAwKSB7XG5cdFx0XHRcdFx0YXdhaXQgZGVsYXkobXMpO1xuXG5cdFx0XHRcdFx0Zm9yIChjb25zdCBob29rIG9mIHRoaXMuX29wdGlvbnMuaG9va3MuYmVmb3JlUmV0cnkpIHtcblx0XHRcdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG5cdFx0XHRcdFx0XHRjb25zdCBob29rUmVzdWx0ID0gYXdhaXQgaG9vayh7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3Q6IHRoaXMucmVxdWVzdCxcblx0XHRcdFx0XHRcdFx0b3B0aW9uczogdGhpcy5fb3B0aW9ucyxcblx0XHRcdFx0XHRcdFx0ZXJyb3IsXG5cdFx0XHRcdFx0XHRcdHJldHJ5Q291bnQ6IHRoaXMuX3JldHJ5Q291bnRcblx0XHRcdFx0XHRcdH0pO1xuXG5cdFx0XHRcdFx0XHQvLyBJZiBgc3RvcGAgaXMgcmV0dXJuZWQgZnJvbSB0aGUgaG9vaywgdGhlIHJldHJ5IHByb2Nlc3MgaXMgc3RvcHBlZFxuXHRcdFx0XHRcdFx0aWYgKGhvb2tSZXN1bHQgPT09IHN0b3ApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzLl9yZXRyeShmbik7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aHJvd0h0dHBFcnJvcnMpIHtcblx0XHRcdFx0XHR0aHJvdyBlcnJvcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGFzeW5jIF9mZXRjaCgpIHtcblx0XHRcdGZvciAoY29uc3QgaG9vayBvZiB0aGlzLl9vcHRpb25zLmhvb2tzLmJlZm9yZVJlcXVlc3QpIHtcblx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3Bcblx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgaG9vayh0aGlzLnJlcXVlc3QsIHRoaXMuX29wdGlvbnMpO1xuXG5cdFx0XHRcdGlmIChyZXN1bHQgaW5zdGFuY2VvZiBSZXF1ZXN0KSB7XG5cdFx0XHRcdFx0dGhpcy5yZXF1ZXN0ID0gcmVzdWx0O1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKHJlc3VsdCBpbnN0YW5jZW9mIFJlc3BvbnNlKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAodGhpcy5fb3B0aW9ucy50aW1lb3V0ID09PSBmYWxzZSkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5fb3B0aW9ucy5mZXRjaCh0aGlzLnJlcXVlc3QuY2xvbmUoKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aW1lb3V0KHRoaXMucmVxdWVzdC5jbG9uZSgpLCB0aGlzLmFib3J0Q29udHJvbGxlciwgdGhpcy5fb3B0aW9ucyk7XG5cdFx0fVxuXG5cdFx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHRfc3RyZWFtKHJlc3BvbnNlLCBvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcblx0XHRcdGNvbnN0IHRvdGFsQnl0ZXMgPSBOdW1iZXIocmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJykpIHx8IDA7XG5cdFx0XHRsZXQgdHJhbnNmZXJyZWRCeXRlcyA9IDA7XG5cblx0XHRcdHJldHVybiBuZXcgZ2xvYmFscy5SZXNwb25zZShcblx0XHRcdFx0bmV3IGdsb2JhbHMuUmVhZGFibGVTdHJlYW0oe1xuXHRcdFx0XHRcdHN0YXJ0KGNvbnRyb2xsZXIpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG5cblx0XHRcdFx0XHRcdGlmIChvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcblx0XHRcdFx0XHRcdFx0b25Eb3dubG9hZFByb2dyZXNzKHtwZXJjZW50OiAwLCB0cmFuc2ZlcnJlZEJ5dGVzOiAwLCB0b3RhbEJ5dGVzfSwgbmV3IFVpbnQ4QXJyYXkoKSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGFzeW5jIGZ1bmN0aW9uIHJlYWQoKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IHtkb25lLCB2YWx1ZX0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuXHRcdFx0XHRcdFx0XHRpZiAoZG9uZSkge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnRyb2xsZXIuY2xvc2UoKTtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRpZiAob25Eb3dubG9hZFByb2dyZXNzKSB7XG5cdFx0XHRcdFx0XHRcdFx0dHJhbnNmZXJyZWRCeXRlcyArPSB2YWx1ZS5ieXRlTGVuZ3RoO1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHBlcmNlbnQgPSB0b3RhbEJ5dGVzID09PSAwID8gMCA6IHRyYW5zZmVycmVkQnl0ZXMgLyB0b3RhbEJ5dGVzO1xuXHRcdFx0XHRcdFx0XHRcdG9uRG93bmxvYWRQcm9ncmVzcyh7cGVyY2VudCwgdHJhbnNmZXJyZWRCeXRlcywgdG90YWxCeXRlc30sIHZhbHVlKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGNvbnRyb2xsZXIuZW5xdWV1ZSh2YWx1ZSk7XG5cdFx0XHRcdFx0XHRcdHJlYWQoKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmVhZCgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cblx0Y29uc3QgdmFsaWRhdGVBbmRNZXJnZSA9ICguLi5zb3VyY2VzKSA9PiB7XG5cdFx0Zm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykge1xuXHRcdFx0aWYgKCghaXNPYmplY3Qoc291cmNlKSB8fCBBcnJheS5pc0FycmF5KHNvdXJjZSkpICYmIHR5cGVvZiBzb3VyY2UgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBgb3B0aW9uc2AgYXJndW1lbnQgbXVzdCBiZSBhbiBvYmplY3QnKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZGVlcE1lcmdlKHt9LCAuLi5zb3VyY2VzKTtcblx0fTtcblxuXHRjb25zdCBjcmVhdGVJbnN0YW5jZSA9IGRlZmF1bHRzID0+IHtcblx0XHRjb25zdCBreSA9IChpbnB1dCwgb3B0aW9ucykgPT4gbmV3IEt5KGlucHV0LCB2YWxpZGF0ZUFuZE1lcmdlKGRlZmF1bHRzLCBvcHRpb25zKSk7XG5cblx0XHRmb3IgKGNvbnN0IG1ldGhvZCBvZiByZXF1ZXN0TWV0aG9kcykge1xuXHRcdFx0a3lbbWV0aG9kXSA9IChpbnB1dCwgb3B0aW9ucykgPT4gbmV3IEt5KGlucHV0LCB2YWxpZGF0ZUFuZE1lcmdlKGRlZmF1bHRzLCBvcHRpb25zLCB7bWV0aG9kfSkpO1xuXHRcdH1cblxuXHRcdGt5LkhUVFBFcnJvciA9IEhUVFBFcnJvcjtcblx0XHRreS5UaW1lb3V0RXJyb3IgPSBUaW1lb3V0RXJyb3I7XG5cdFx0a3kuY3JlYXRlID0gbmV3RGVmYXVsdHMgPT4gY3JlYXRlSW5zdGFuY2UodmFsaWRhdGVBbmRNZXJnZShuZXdEZWZhdWx0cykpO1xuXHRcdGt5LmV4dGVuZCA9IG5ld0RlZmF1bHRzID0+IGNyZWF0ZUluc3RhbmNlKHZhbGlkYXRlQW5kTWVyZ2UoZGVmYXVsdHMsIG5ld0RlZmF1bHRzKSk7XG5cdFx0a3kuc3RvcCA9IHN0b3A7XG5cblx0XHRyZXR1cm4ga3k7XG5cdH07XG5cblx0dmFyIGluZGV4ID0gY3JlYXRlSW5zdGFuY2UoKTtcblxuXHRyZXR1cm4gaW5kZXg7XG5cbn0pKSk7XG4iLCJmdW5jdGlvbiBub3JtYWxpemUgKHN0cikge1xuICByZXR1cm4gc3RyXG4gICAgICAgICAgLnJlcGxhY2UoL1tcXC9dKy9nLCAnLycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcL1xcPy9nLCAnPycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcL1xcIy9nLCAnIycpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcOlxcLy9nLCAnOi8vJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgam9pbmVkID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApLmpvaW4oJy8nKTtcbiAgcmV0dXJuIG5vcm1hbGl6ZShqb2luZWQpO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjcnlwdG9cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJodHRwc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJzdHJlYW1cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidXJsXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInV0aWxcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiemxpYlwiKTsiLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZldGNoO1xuXG5jb25zdCBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xuY29uc3QgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpO1xuY29uc3QgemxpYiA9IHJlcXVpcmUoJ3psaWInKTtcbmNvbnN0IFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xuY29uc3QgZGF0YVVyaVRvQnVmZmVyID0gcmVxdWlyZSgnZGF0YS11cmktdG8tYnVmZmVyJyk7XG5jb25zdCB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuY29uc3QgQmxvYiA9IHJlcXVpcmUoJ2ZldGNoLWJsb2InKTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5cbmNsYXNzIEZldGNoQmFzZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRjb25zdHJ1Y3RvcihtZXNzYWdlLCB0eXBlKSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0Ly8gSGlkZSBjdXN0b20gZXJyb3IgaW1wbGVtZW50YXRpb24gZGV0YWlscyBmcm9tIGVuZC11c2Vyc1xuXHRcdEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpO1xuXG5cdFx0dGhpcy50eXBlID0gdHlwZTtcblx0fVxuXG5cdGdldCBuYW1lKCkge1xuXHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG5cdH1cblxuXHRnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG5cdFx0cmV0dXJuIHRoaXMuY29uc3RydWN0b3IubmFtZTtcblx0fVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHt7IGFkZHJlc3M/OiBzdHJpbmcsIGNvZGU6IHN0cmluZywgZGVzdD86IHN0cmluZywgZXJybm86IG51bWJlciwgaW5mbz86IG9iamVjdCwgbWVzc2FnZTogc3RyaW5nLCBwYXRoPzogc3RyaW5nLCBwb3J0PzogbnVtYmVyLCBzeXNjYWxsOiBzdHJpbmd9fSBTeXN0ZW1FcnJvclxuKi9cblxuLyoqXG4gKiBGZXRjaEVycm9yIGludGVyZmFjZSBmb3Igb3BlcmF0aW9uYWwgZXJyb3JzXG4gKi9cbmNsYXNzIEZldGNoRXJyb3IgZXh0ZW5kcyBGZXRjaEJhc2VFcnJvciB7XG5cdC8qKlxuXHQgKiBAcGFyYW0gIHtzdHJpbmd9IG1lc3NhZ2UgLSAgICAgIEVycm9yIG1lc3NhZ2UgZm9yIGh1bWFuXG5cdCAqIEBwYXJhbSAge3N0cmluZ30gW3R5cGVdIC0gICAgICAgIEVycm9yIHR5cGUgZm9yIG1hY2hpbmVcblx0ICogQHBhcmFtICB7U3lzdGVtRXJyb3J9IFtzeXN0ZW1FcnJvcl0gLSBGb3IgTm9kZS5qcyBzeXN0ZW0gZXJyb3Jcblx0ICovXG5cdGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHR5cGUsIHN5c3RlbUVycm9yKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgdHlwZSk7XG5cdFx0Ly8gV2hlbiBlcnIudHlwZSBpcyBgc3lzdGVtYCwgZXJyLmVycm9yZWRTeXNDYWxsIGNvbnRhaW5zIHN5c3RlbSBlcnJvciBhbmQgZXJyLmNvZGUgY29udGFpbnMgc3lzdGVtIGVycm9yIGNvZGVcblx0XHRpZiAoc3lzdGVtRXJyb3IpIHtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1tdWx0aS1hc3NpZ25cblx0XHRcdHRoaXMuY29kZSA9IHRoaXMuZXJybm8gPSBzeXN0ZW1FcnJvci5jb2RlO1xuXHRcdFx0dGhpcy5lcnJvcmVkU3lzQ2FsbCA9IHN5c3RlbUVycm9yLnN5c2NhbGw7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogSXMuanNcbiAqXG4gKiBPYmplY3QgdHlwZSBjaGVja3MuXG4gKi9cblxuY29uc3QgTkFNRSA9IFN5bWJvbC50b1N0cmluZ1RhZztcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIFVSTFNlYXJjaFBhcmFtcyBvYmplY3RcbiAqIHJlZjogaHR0cHM6Ly9naXRodWIuY29tL25vZGUtZmV0Y2gvbm9kZS1mZXRjaC9pc3N1ZXMvMjk2I2lzc3VlY29tbWVudC0zMDc1OTgxNDNcbiAqXG4gKiBAcGFyYW0gIHsqfSBvYmpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGlzVVJMU2VhcmNoUGFyYW1ldGVycyA9IG9iamVjdCA9PiB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmFwcGVuZCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZGVsZXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5nZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmdldEFsbCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuaGFzID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5zZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnNvcnQgPT09ICdmdW5jdGlvbicgJiZcblx0XHRvYmplY3RbTkFNRV0gPT09ICdVUkxTZWFyY2hQYXJhbXMnXG5cdCk7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGBvYmplY3RgIGlzIGEgVzNDIGBCbG9iYCBvYmplY3QgKHdoaWNoIGBGaWxlYCBpbmhlcml0cyBmcm9tKVxuICpcbiAqIEBwYXJhbSAgeyp9IG9ialxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuY29uc3QgaXNCbG9iID0gb2JqZWN0ID0+IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuYXJyYXlCdWZmZXIgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LnR5cGUgPT09ICdzdHJpbmcnICYmXG5cdFx0dHlwZW9mIG9iamVjdC5zdHJlYW0gPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0L14oQmxvYnxGaWxlKSQvLnRlc3Qob2JqZWN0W05BTUVdKVxuXHQpO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBhIHNwZWMtY29tcGxpYW50IGBGb3JtRGF0YWAgb2JqZWN0XG4gKlxuICogQHBhcmFtIHsqfSBvYmplY3RcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzRm9ybURhdGEob2JqZWN0KSB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmFwcGVuZCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3Quc2V0ID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5nZXQgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmdldEFsbCA9PT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBvYmplY3QuZGVsZXRlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC5rZXlzID09PSAnZnVuY3Rpb24nICYmXG5cdFx0dHlwZW9mIG9iamVjdC52YWx1ZXMgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmVudHJpZXMgPT09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nICYmXG5cdFx0b2JqZWN0W05BTUVdID09PSAnRm9ybURhdGEnXG5cdCk7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYW4gaW5zdGFuY2Ugb2YgQWJvcnRTaWduYWwuXG4gKlxuICogQHBhcmFtICB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBpc0Fib3J0U2lnbmFsID0gb2JqZWN0ID0+IHtcblx0cmV0dXJuIChcblx0XHR0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJlxuXHRcdG9iamVjdFtOQU1FXSA9PT0gJ0Fib3J0U2lnbmFsJ1xuXHQpO1xufTtcblxuY29uc3QgY2FycmlhZ2UgPSAnXFxyXFxuJztcbmNvbnN0IGRhc2hlcyA9ICctJy5yZXBlYXQoMik7XG5jb25zdCBjYXJyaWFnZUxlbmd0aCA9IEJ1ZmZlci5ieXRlTGVuZ3RoKGNhcnJpYWdlKTtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRhcnlcbiAqL1xuY29uc3QgZ2V0Rm9vdGVyID0gYm91bmRhcnkgPT4gYCR7ZGFzaGVzfSR7Ym91bmRhcnl9JHtkYXNoZXN9JHtjYXJyaWFnZS5yZXBlYXQoMil9YDtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gYm91bmRhcnlcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0geyp9IGZpZWxkXG4gKlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBnZXRIZWFkZXIoYm91bmRhcnksIG5hbWUsIGZpZWxkKSB7XG5cdGxldCBoZWFkZXIgPSAnJztcblxuXHRoZWFkZXIgKz0gYCR7ZGFzaGVzfSR7Ym91bmRhcnl9JHtjYXJyaWFnZX1gO1xuXHRoZWFkZXIgKz0gYENvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT1cIiR7bmFtZX1cImA7XG5cblx0aWYgKGlzQmxvYihmaWVsZCkpIHtcblx0XHRoZWFkZXIgKz0gYDsgZmlsZW5hbWU9XCIke2ZpZWxkLm5hbWV9XCIke2NhcnJpYWdlfWA7XG5cdFx0aGVhZGVyICs9IGBDb250ZW50LVR5cGU6ICR7ZmllbGQudHlwZSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJ31gO1xuXHR9XG5cblx0cmV0dXJuIGAke2hlYWRlcn0ke2NhcnJpYWdlLnJlcGVhdCgyKX1gO1xufVxuXG4vKipcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuY29uc3QgZ2V0Qm91bmRhcnkgPSAoKSA9PiBjcnlwdG8ucmFuZG9tQnl0ZXMoOCkudG9TdHJpbmcoJ2hleCcpO1xuXG4vKipcbiAqIEBwYXJhbSB7Rm9ybURhdGF9IGZvcm1cbiAqIEBwYXJhbSB7c3RyaW5nfSBib3VuZGFyeVxuICovXG5hc3luYyBmdW5jdGlvbiAqIGZvcm1EYXRhSXRlcmF0b3IoZm9ybSwgYm91bmRhcnkpIHtcblx0Zm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIGZvcm0pIHtcblx0XHR5aWVsZCBnZXRIZWFkZXIoYm91bmRhcnksIG5hbWUsIHZhbHVlKTtcblxuXHRcdGlmIChpc0Jsb2IodmFsdWUpKSB7XG5cdFx0XHR5aWVsZCAqIHZhbHVlLnN0cmVhbSgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR5aWVsZCB2YWx1ZTtcblx0XHR9XG5cblx0XHR5aWVsZCBjYXJyaWFnZTtcblx0fVxuXG5cdHlpZWxkIGdldEZvb3Rlcihib3VuZGFyeSk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtGb3JtRGF0YX0gZm9ybVxuICogQHBhcmFtIHtzdHJpbmd9IGJvdW5kYXJ5XG4gKi9cbmZ1bmN0aW9uIGdldEZvcm1EYXRhTGVuZ3RoKGZvcm0sIGJvdW5kYXJ5KSB7XG5cdGxldCBsZW5ndGggPSAwO1xuXG5cdGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBmb3JtKSB7XG5cdFx0bGVuZ3RoICs9IEJ1ZmZlci5ieXRlTGVuZ3RoKGdldEhlYWRlcihib3VuZGFyeSwgbmFtZSwgdmFsdWUpKTtcblxuXHRcdGlmIChpc0Jsb2IodmFsdWUpKSB7XG5cdFx0XHRsZW5ndGggKz0gdmFsdWUuc2l6ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bGVuZ3RoICs9IEJ1ZmZlci5ieXRlTGVuZ3RoKFN0cmluZyh2YWx1ZSkpO1xuXHRcdH1cblxuXHRcdGxlbmd0aCArPSBjYXJyaWFnZUxlbmd0aDtcblx0fVxuXG5cdGxlbmd0aCArPSBCdWZmZXIuYnl0ZUxlbmd0aChnZXRGb290ZXIoYm91bmRhcnkpKTtcblxuXHRyZXR1cm4gbGVuZ3RoO1xufVxuXG5jb25zdCBJTlRFUk5BTFMgPSBTeW1ib2woJ0JvZHkgaW50ZXJuYWxzJyk7XG5cbi8qKlxuICogQm9keSBtaXhpblxuICpcbiAqIFJlZjogaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2JvZHlcbiAqXG4gKiBAcGFyYW0gICBTdHJlYW0gIGJvZHkgIFJlYWRhYmxlIHN0cmVhbVxuICogQHBhcmFtICAgT2JqZWN0ICBvcHRzICBSZXNwb25zZSBvcHRpb25zXG4gKiBAcmV0dXJuICBWb2lkXG4gKi9cbmNsYXNzIEJvZHkge1xuXHRjb25zdHJ1Y3Rvcihib2R5LCB7XG5cdFx0c2l6ZSA9IDBcblx0fSA9IHt9KSB7XG5cdFx0bGV0IGJvdW5kYXJ5ID0gbnVsbDtcblxuXHRcdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0XHQvLyBCb2R5IGlzIHVuZGVmaW5lZCBvciBudWxsXG5cdFx0XHRib2R5ID0gbnVsbDtcblx0XHR9IGVsc2UgaWYgKGlzVVJMU2VhcmNoUGFyYW1ldGVycyhib2R5KSkge1xuXHRcdC8vIEJvZHkgaXMgYSBVUkxTZWFyY2hQYXJhbXNcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5LnRvU3RyaW5nKCkpO1xuXHRcdH0gZWxzZSBpZiAoaXNCbG9iKGJvZHkpKSA7IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSkgOyBlbHNlIGlmICh1dGlsLnR5cGVzLmlzQW55QXJyYXlCdWZmZXIoYm9keSkpIHtcblx0XHRcdC8vIEJvZHkgaXMgQXJyYXlCdWZmZXJcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5KTtcblx0XHR9IGVsc2UgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhib2R5KSkge1xuXHRcdFx0Ly8gQm9keSBpcyBBcnJheUJ1ZmZlclZpZXdcblx0XHRcdGJvZHkgPSBCdWZmZXIuZnJvbShib2R5LmJ1ZmZlciwgYm9keS5ieXRlT2Zmc2V0LCBib2R5LmJ5dGVMZW5ndGgpO1xuXHRcdH0gZWxzZSBpZiAoYm9keSBpbnN0YW5jZW9mIFN0cmVhbSkgOyBlbHNlIGlmIChpc0Zvcm1EYXRhKGJvZHkpKSB7XG5cdFx0XHQvLyBCb2R5IGlzIGFuIGluc3RhbmNlIG9mIGZvcm1kYXRhLW5vZGVcblx0XHRcdGJvdW5kYXJ5ID0gYE5vZGVGZXRjaEZvcm1EYXRhQm91bmRhcnkke2dldEJvdW5kYXJ5KCl9YDtcblx0XHRcdGJvZHkgPSBTdHJlYW0uUmVhZGFibGUuZnJvbShmb3JtRGF0YUl0ZXJhdG9yKGJvZHksIGJvdW5kYXJ5KSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIE5vbmUgb2YgdGhlIGFib3ZlXG5cdFx0XHQvLyBjb2VyY2UgdG8gc3RyaW5nIHRoZW4gYnVmZmVyXG5cdFx0XHRib2R5ID0gQnVmZmVyLmZyb20oU3RyaW5nKGJvZHkpKTtcblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMU10gPSB7XG5cdFx0XHRib2R5LFxuXHRcdFx0Ym91bmRhcnksXG5cdFx0XHRkaXN0dXJiZWQ6IGZhbHNlLFxuXHRcdFx0ZXJyb3I6IG51bGxcblx0XHR9O1xuXHRcdHRoaXMuc2l6ZSA9IHNpemU7XG5cblx0XHRpZiAoYm9keSBpbnN0YW5jZW9mIFN0cmVhbSkge1xuXHRcdFx0Ym9keS5vbignZXJyb3InLCBlcnIgPT4ge1xuXHRcdFx0XHRjb25zdCBlcnJvciA9IGVyciBpbnN0YW5jZW9mIEZldGNoQmFzZUVycm9yID9cblx0XHRcdFx0XHRlcnIgOlxuXHRcdFx0XHRcdG5ldyBGZXRjaEVycm9yKGBJbnZhbGlkIHJlc3BvbnNlIGJvZHkgd2hpbGUgdHJ5aW5nIHRvIGZldGNoICR7dGhpcy51cmx9OiAke2Vyci5tZXNzYWdlfWAsICdzeXN0ZW0nLCBlcnIpO1xuXHRcdFx0XHR0aGlzW0lOVEVSTkFMU10uZXJyb3IgPSBlcnJvcjtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdGdldCBib2R5KCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMU10uYm9keTtcblx0fVxuXG5cdGdldCBib2R5VXNlZCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFNdLmRpc3R1cmJlZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWNvZGUgcmVzcG9uc2UgYXMgQXJyYXlCdWZmZXJcblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMgYXJyYXlCdWZmZXIoKSB7XG5cdFx0Y29uc3Qge2J1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aH0gPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gYnVmZmVyLnNsaWNlKGJ5dGVPZmZzZXQsIGJ5dGVPZmZzZXQgKyBieXRlTGVuZ3RoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm4gcmF3IHJlc3BvbnNlIGFzIEJsb2Jcblx0ICpcblx0ICogQHJldHVybiBQcm9taXNlXG5cdCAqL1xuXHRhc3luYyBibG9iKCkge1xuXHRcdGNvbnN0IGN0ID0gKHRoaXMuaGVhZGVycyAmJiB0aGlzLmhlYWRlcnMuZ2V0KCdjb250ZW50LXR5cGUnKSkgfHwgKHRoaXNbSU5URVJOQUxTXS5ib2R5ICYmIHRoaXNbSU5URVJOQUxTXS5ib2R5LnR5cGUpIHx8ICcnO1xuXHRcdGNvbnN0IGJ1ZiA9IGF3YWl0IHRoaXMuYnVmZmVyKCk7XG5cblx0XHRyZXR1cm4gbmV3IEJsb2IoW2J1Zl0sIHtcblx0XHRcdHR5cGU6IGN0XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIGpzb25cblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMganNvbigpIHtcblx0XHRjb25zdCBidWZmZXIgPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gSlNPTi5wYXJzZShidWZmZXIudG9TdHJpbmcoKSk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIHRleHRcblx0ICpcblx0ICogQHJldHVybiAgUHJvbWlzZVxuXHQgKi9cblx0YXN5bmMgdGV4dCgpIHtcblx0XHRjb25zdCBidWZmZXIgPSBhd2FpdCBjb25zdW1lQm9keSh0aGlzKTtcblx0XHRyZXR1cm4gYnVmZmVyLnRvU3RyaW5nKCk7XG5cdH1cblxuXHQvKipcblx0ICogRGVjb2RlIHJlc3BvbnNlIGFzIGJ1ZmZlciAobm9uLXNwZWMgYXBpKVxuXHQgKlxuXHQgKiBAcmV0dXJuICBQcm9taXNlXG5cdCAqL1xuXHRidWZmZXIoKSB7XG5cdFx0cmV0dXJuIGNvbnN1bWVCb2R5KHRoaXMpO1xuXHR9XG59XG5cbi8vIEluIGJyb3dzZXJzLCBhbGwgcHJvcGVydGllcyBhcmUgZW51bWVyYWJsZS5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEJvZHkucHJvdG90eXBlLCB7XG5cdGJvZHk6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0Ym9keVVzZWQ6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0YXJyYXlCdWZmZXI6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0YmxvYjoge2VudW1lcmFibGU6IHRydWV9LFxuXHRqc29uOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHRleHQ6IHtlbnVtZXJhYmxlOiB0cnVlfVxufSk7XG5cbi8qKlxuICogQ29uc3VtZSBhbmQgY29udmVydCBhbiBlbnRpcmUgQm9keSB0byBhIEJ1ZmZlci5cbiAqXG4gKiBSZWY6IGh0dHBzOi8vZmV0Y2guc3BlYy53aGF0d2cub3JnLyNjb25jZXB0LWJvZHktY29uc3VtZS1ib2R5XG4gKlxuICogQHJldHVybiBQcm9taXNlXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvbnN1bWVCb2R5KGRhdGEpIHtcblx0aWYgKGRhdGFbSU5URVJOQUxTXS5kaXN0dXJiZWQpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKGBib2R5IHVzZWQgYWxyZWFkeSBmb3I6ICR7ZGF0YS51cmx9YCk7XG5cdH1cblxuXHRkYXRhW0lOVEVSTkFMU10uZGlzdHVyYmVkID0gdHJ1ZTtcblxuXHRpZiAoZGF0YVtJTlRFUk5BTFNdLmVycm9yKSB7XG5cdFx0dGhyb3cgZGF0YVtJTlRFUk5BTFNdLmVycm9yO1xuXHR9XG5cblx0bGV0IHtib2R5fSA9IGRhdGE7XG5cblx0Ly8gQm9keSBpcyBudWxsXG5cdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5hbGxvYygwKTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgYmxvYlxuXHRpZiAoaXNCbG9iKGJvZHkpKSB7XG5cdFx0Ym9keSA9IGJvZHkuc3RyZWFtKCk7XG5cdH1cblxuXHQvLyBCb2R5IGlzIGJ1ZmZlclxuXHRpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSB7XG5cdFx0cmV0dXJuIGJvZHk7XG5cdH1cblxuXHQvKiBjOCBpZ25vcmUgbmV4dCAzICovXG5cdGlmICghKGJvZHkgaW5zdGFuY2VvZiBTdHJlYW0pKSB7XG5cdFx0cmV0dXJuIEJ1ZmZlci5hbGxvYygwKTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgc3RyZWFtXG5cdC8vIGdldCByZWFkeSB0byBhY3R1YWxseSBjb25zdW1lIHRoZSBib2R5XG5cdGNvbnN0IGFjY3VtID0gW107XG5cdGxldCBhY2N1bUJ5dGVzID0gMDtcblxuXHR0cnkge1xuXHRcdGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgYm9keSkge1xuXHRcdFx0aWYgKGRhdGEuc2l6ZSA+IDAgJiYgYWNjdW1CeXRlcyArIGNodW5rLmxlbmd0aCA+IGRhdGEuc2l6ZSkge1xuXHRcdFx0XHRjb25zdCBlcnIgPSBuZXcgRmV0Y2hFcnJvcihgY29udGVudCBzaXplIGF0ICR7ZGF0YS51cmx9IG92ZXIgbGltaXQ6ICR7ZGF0YS5zaXplfWAsICdtYXgtc2l6ZScpO1xuXHRcdFx0XHRib2R5LmRlc3Ryb3koZXJyKTtcblx0XHRcdFx0dGhyb3cgZXJyO1xuXHRcdFx0fVxuXG5cdFx0XHRhY2N1bUJ5dGVzICs9IGNodW5rLmxlbmd0aDtcblx0XHRcdGFjY3VtLnB1c2goY2h1bmspO1xuXHRcdH1cblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRpZiAoZXJyb3IgaW5zdGFuY2VvZiBGZXRjaEJhc2VFcnJvcikge1xuXHRcdFx0dGhyb3cgZXJyb3I7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIE90aGVyIGVycm9ycywgc3VjaCBhcyBpbmNvcnJlY3QgY29udGVudC1lbmNvZGluZ1xuXHRcdFx0dGhyb3cgbmV3IEZldGNoRXJyb3IoYEludmFsaWQgcmVzcG9uc2UgYm9keSB3aGlsZSB0cnlpbmcgdG8gZmV0Y2ggJHtkYXRhLnVybH06ICR7ZXJyb3IubWVzc2FnZX1gLCAnc3lzdGVtJywgZXJyb3IpO1xuXHRcdH1cblx0fVxuXG5cdGlmIChib2R5LnJlYWRhYmxlRW5kZWQgPT09IHRydWUgfHwgYm9keS5fcmVhZGFibGVTdGF0ZS5lbmRlZCA9PT0gdHJ1ZSkge1xuXHRcdHRyeSB7XG5cdFx0XHRpZiAoYWNjdW0uZXZlcnkoYyA9PiB0eXBlb2YgYyA9PT0gJ3N0cmluZycpKSB7XG5cdFx0XHRcdHJldHVybiBCdWZmZXIuZnJvbShhY2N1bS5qb2luKCcnKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBCdWZmZXIuY29uY2F0KGFjY3VtLCBhY2N1bUJ5dGVzKTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhyb3cgbmV3IEZldGNoRXJyb3IoYENvdWxkIG5vdCBjcmVhdGUgQnVmZmVyIGZyb20gcmVzcG9uc2UgYm9keSBmb3IgJHtkYXRhLnVybH06ICR7ZXJyb3IubWVzc2FnZX1gLCAnc3lzdGVtJywgZXJyb3IpO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHR0aHJvdyBuZXcgRmV0Y2hFcnJvcihgUHJlbWF0dXJlIGNsb3NlIG9mIHNlcnZlciByZXNwb25zZSB3aGlsZSB0cnlpbmcgdG8gZmV0Y2ggJHtkYXRhLnVybH1gKTtcblx0fVxufVxuXG4vKipcbiAqIENsb25lIGJvZHkgZ2l2ZW4gUmVzL1JlcSBpbnN0YW5jZVxuICpcbiAqIEBwYXJhbSAgIE1peGVkICAgaW5zdGFuY2UgICAgICAgUmVzcG9uc2Ugb3IgUmVxdWVzdCBpbnN0YW5jZVxuICogQHBhcmFtICAgU3RyaW5nICBoaWdoV2F0ZXJNYXJrICBoaWdoV2F0ZXJNYXJrIGZvciBib3RoIFBhc3NUaHJvdWdoIGJvZHkgc3RyZWFtc1xuICogQHJldHVybiAgTWl4ZWRcbiAqL1xuY29uc3QgY2xvbmUgPSAoaW5zdGFuY2UsIGhpZ2hXYXRlck1hcmspID0+IHtcblx0bGV0IHAxO1xuXHRsZXQgcDI7XG5cdGxldCB7Ym9keX0gPSBpbnN0YW5jZTtcblxuXHQvLyBEb24ndCBhbGxvdyBjbG9uaW5nIGEgdXNlZCBib2R5XG5cdGlmIChpbnN0YW5jZS5ib2R5VXNlZCkge1xuXHRcdHRocm93IG5ldyBFcnJvcignY2Fubm90IGNsb25lIGJvZHkgYWZ0ZXIgaXQgaXMgdXNlZCcpO1xuXHR9XG5cblx0Ly8gQ2hlY2sgdGhhdCBib2R5IGlzIGEgc3RyZWFtIGFuZCBub3QgZm9ybS1kYXRhIG9iamVjdFxuXHQvLyBub3RlOiB3ZSBjYW4ndCBjbG9uZSB0aGUgZm9ybS1kYXRhIG9iamVjdCB3aXRob3V0IGhhdmluZyBpdCBhcyBhIGRlcGVuZGVuY3lcblx0aWYgKChib2R5IGluc3RhbmNlb2YgU3RyZWFtKSAmJiAodHlwZW9mIGJvZHkuZ2V0Qm91bmRhcnkgIT09ICdmdW5jdGlvbicpKSB7XG5cdFx0Ly8gVGVlIGluc3RhbmNlIGJvZHlcblx0XHRwMSA9IG5ldyBTdHJlYW0uUGFzc1Rocm91Z2goe2hpZ2hXYXRlck1hcmt9KTtcblx0XHRwMiA9IG5ldyBTdHJlYW0uUGFzc1Rocm91Z2goe2hpZ2hXYXRlck1hcmt9KTtcblx0XHRib2R5LnBpcGUocDEpO1xuXHRcdGJvZHkucGlwZShwMik7XG5cdFx0Ly8gU2V0IGluc3RhbmNlIGJvZHkgdG8gdGVlZCBib2R5IGFuZCByZXR1cm4gdGhlIG90aGVyIHRlZWQgYm9keVxuXHRcdGluc3RhbmNlW0lOVEVSTkFMU10uYm9keSA9IHAxO1xuXHRcdGJvZHkgPSBwMjtcblx0fVxuXG5cdHJldHVybiBib2R5O1xufTtcblxuLyoqXG4gKiBQZXJmb3JtcyB0aGUgb3BlcmF0aW9uIFwiZXh0cmFjdCBhIGBDb250ZW50LVR5cGVgIHZhbHVlIGZyb20gfG9iamVjdHxcIiBhc1xuICogc3BlY2lmaWVkIGluIHRoZSBzcGVjaWZpY2F0aW9uOlxuICogaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2NvbmNlcHQtYm9keWluaXQtZXh0cmFjdFxuICpcbiAqIFRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IGluc3RhbmNlLmJvZHkgaXMgcHJlc2VudC5cbiAqXG4gKiBAcGFyYW0ge2FueX0gYm9keSBBbnkgb3B0aW9ucy5ib2R5IGlucHV0XG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH1cbiAqL1xuY29uc3QgZXh0cmFjdENvbnRlbnRUeXBlID0gKGJvZHksIHJlcXVlc3QpID0+IHtcblx0Ly8gQm9keSBpcyBudWxsIG9yIHVuZGVmaW5lZFxuXHRpZiAoYm9keSA9PT0gbnVsbCkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBzdHJpbmdcblx0aWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuXHRcdHJldHVybiAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04Jztcblx0fVxuXG5cdC8vIEJvZHkgaXMgYSBVUkxTZWFyY2hQYXJhbXNcblx0aWYgKGlzVVJMU2VhcmNoUGFyYW1ldGVycyhib2R5KSkge1xuXHRcdHJldHVybiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9VVRGLTgnO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBibG9iXG5cdGlmIChpc0Jsb2IoYm9keSkpIHtcblx0XHRyZXR1cm4gYm9keS50eXBlIHx8IG51bGw7XG5cdH1cblxuXHQvLyBCb2R5IGlzIGEgQnVmZmVyIChCdWZmZXIsIEFycmF5QnVmZmVyIG9yIEFycmF5QnVmZmVyVmlldylcblx0aWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSB8fCB1dGlsLnR5cGVzLmlzQW55QXJyYXlCdWZmZXIoYm9keSkgfHwgQXJyYXlCdWZmZXIuaXNWaWV3KGJvZHkpKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvLyBEZXRlY3QgZm9ybSBkYXRhIGlucHV0IGZyb20gZm9ybS1kYXRhIG1vZHVsZVxuXHRpZiAoYm9keSAmJiB0eXBlb2YgYm9keS5nZXRCb3VuZGFyeSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdHJldHVybiBgbXVsdGlwYXJ0L2Zvcm0tZGF0YTtib3VuZGFyeT0ke2JvZHkuZ2V0Qm91bmRhcnkoKX1gO1xuXHR9XG5cblx0aWYgKGlzRm9ybURhdGEoYm9keSkpIHtcblx0XHRyZXR1cm4gYG11bHRpcGFydC9mb3JtLWRhdGE7IGJvdW5kYXJ5PSR7cmVxdWVzdFtJTlRFUk5BTFNdLmJvdW5kYXJ5fWA7XG5cdH1cblxuXHQvLyBCb2R5IGlzIHN0cmVhbSAtIGNhbid0IHJlYWxseSBkbyBtdWNoIGFib3V0IHRoaXNcblx0aWYgKGJvZHkgaW5zdGFuY2VvZiBTdHJlYW0pIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIEJvZHkgY29uc3RydWN0b3IgZGVmYXVsdHMgb3RoZXIgdGhpbmdzIHRvIHN0cmluZ1xuXHRyZXR1cm4gJ3RleHQvcGxhaW47Y2hhcnNldD1VVEYtOCc7XG59O1xuXG4vKipcbiAqIFRoZSBGZXRjaCBTdGFuZGFyZCB0cmVhdHMgdGhpcyBhcyBpZiBcInRvdGFsIGJ5dGVzXCIgaXMgYSBwcm9wZXJ0eSBvbiB0aGUgYm9keS5cbiAqIEZvciB1cywgd2UgaGF2ZSB0byBleHBsaWNpdGx5IGdldCBpdCB3aXRoIGEgZnVuY3Rpb24uXG4gKlxuICogcmVmOiBodHRwczovL2ZldGNoLnNwZWMud2hhdHdnLm9yZy8jY29uY2VwdC1ib2R5LXRvdGFsLWJ5dGVzXG4gKlxuICogQHBhcmFtIHthbnl9IG9iai5ib2R5IEJvZHkgb2JqZWN0IGZyb20gdGhlIEJvZHkgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVsbH1cbiAqL1xuY29uc3QgZ2V0VG90YWxCeXRlcyA9IHJlcXVlc3QgPT4ge1xuXHRjb25zdCB7Ym9keX0gPSByZXF1ZXN0O1xuXG5cdC8vIEJvZHkgaXMgbnVsbCBvciB1bmRlZmluZWRcblx0aWYgKGJvZHkgPT09IG51bGwpIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXG5cdC8vIEJvZHkgaXMgQmxvYlxuXHRpZiAoaXNCbG9iKGJvZHkpKSB7XG5cdFx0cmV0dXJuIGJvZHkuc2l6ZTtcblx0fVxuXG5cdC8vIEJvZHkgaXMgQnVmZmVyXG5cdGlmIChCdWZmZXIuaXNCdWZmZXIoYm9keSkpIHtcblx0XHRyZXR1cm4gYm9keS5sZW5ndGg7XG5cdH1cblxuXHQvLyBEZXRlY3QgZm9ybSBkYXRhIGlucHV0IGZyb20gZm9ybS1kYXRhIG1vZHVsZVxuXHRpZiAoYm9keSAmJiB0eXBlb2YgYm9keS5nZXRMZW5ndGhTeW5jID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0cmV0dXJuIGJvZHkuaGFzS25vd25MZW5ndGggJiYgYm9keS5oYXNLbm93bkxlbmd0aCgpID8gYm9keS5nZXRMZW5ndGhTeW5jKCkgOiBudWxsO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBhIHNwZWMtY29tcGxpYW50IGZvcm0tZGF0YVxuXHRpZiAoaXNGb3JtRGF0YShib2R5KSkge1xuXHRcdHJldHVybiBnZXRGb3JtRGF0YUxlbmd0aChyZXF1ZXN0W0lOVEVSTkFMU10uYm91bmRhcnkpO1xuXHR9XG5cblx0Ly8gQm9keSBpcyBzdHJlYW1cblx0cmV0dXJuIG51bGw7XG59O1xuXG4vKipcbiAqIFdyaXRlIGEgQm9keSB0byBhIE5vZGUuanMgV3JpdGFibGVTdHJlYW0gKGUuZy4gaHR0cC5SZXF1ZXN0KSBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtTdHJlYW0uV3JpdGFibGV9IGRlc3QgVGhlIHN0cmVhbSB0byB3cml0ZSB0by5cbiAqIEBwYXJhbSBvYmouYm9keSBCb2R5IG9iamVjdCBmcm9tIHRoZSBCb2R5IGluc3RhbmNlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmNvbnN0IHdyaXRlVG9TdHJlYW0gPSAoZGVzdCwge2JvZHl9KSA9PiB7XG5cdGlmIChib2R5ID09PSBudWxsKSB7XG5cdFx0Ly8gQm9keSBpcyBudWxsXG5cdFx0ZGVzdC5lbmQoKTtcblx0fSBlbHNlIGlmIChpc0Jsb2IoYm9keSkpIHtcblx0XHQvLyBCb2R5IGlzIEJsb2Jcblx0XHRib2R5LnN0cmVhbSgpLnBpcGUoZGVzdCk7XG5cdH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKGJvZHkpKSB7XG5cdFx0Ly8gQm9keSBpcyBidWZmZXJcblx0XHRkZXN0LndyaXRlKGJvZHkpO1xuXHRcdGRlc3QuZW5kKCk7XG5cdH0gZWxzZSB7XG5cdFx0Ly8gQm9keSBpcyBzdHJlYW1cblx0XHRib2R5LnBpcGUoZGVzdCk7XG5cdH1cbn07XG5cbi8qKlxuICogSGVhZGVycy5qc1xuICpcbiAqIEhlYWRlcnMgY2xhc3Mgb2ZmZXJzIGNvbnZlbmllbnQgaGVscGVyc1xuICovXG5cbmNvbnN0IHZhbGlkYXRlSGVhZGVyTmFtZSA9IHR5cGVvZiBodHRwLnZhbGlkYXRlSGVhZGVyTmFtZSA9PT0gJ2Z1bmN0aW9uJyA/XG5cdGh0dHAudmFsaWRhdGVIZWFkZXJOYW1lIDpcblx0bmFtZSA9PiB7XG5cdFx0aWYgKCEvXltcXF5gXFwtXFx3ISMkJSYnKisufH5dKyQvLnRlc3QobmFtZSkpIHtcblx0XHRcdGNvbnN0IGVyciA9IG5ldyBUeXBlRXJyb3IoYEhlYWRlciBuYW1lIG11c3QgYmUgYSB2YWxpZCBIVFRQIHRva2VuIFske25hbWV9XWApO1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGVyciwgJ2NvZGUnLCB7dmFsdWU6ICdFUlJfSU5WQUxJRF9IVFRQX1RPS0VOJ30pO1xuXHRcdFx0dGhyb3cgZXJyO1xuXHRcdH1cblx0fTtcblxuY29uc3QgdmFsaWRhdGVIZWFkZXJWYWx1ZSA9IHR5cGVvZiBodHRwLnZhbGlkYXRlSGVhZGVyVmFsdWUgPT09ICdmdW5jdGlvbicgP1xuXHRodHRwLnZhbGlkYXRlSGVhZGVyVmFsdWUgOlxuXHQobmFtZSwgdmFsdWUpID0+IHtcblx0XHRpZiAoL1teXFx0XFx1MDAyMC1cXHUwMDdFXFx1MDA4MC1cXHUwMEZGXS8udGVzdCh2YWx1ZSkpIHtcblx0XHRcdGNvbnN0IGVyciA9IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgY2hhcmFjdGVyIGluIGhlYWRlciBjb250ZW50IFtcIiR7bmFtZX1cIl1gKTtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlcnIsICdjb2RlJywge3ZhbHVlOiAnRVJSX0lOVkFMSURfQ0hBUid9KTtcblx0XHRcdHRocm93IGVycjtcblx0XHR9XG5cdH07XG5cbi8qKlxuICogQHR5cGVkZWYge0hlYWRlcnMgfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHwgSXRlcmFibGU8cmVhZG9ubHkgW3N0cmluZywgc3RyaW5nXT4gfCBJdGVyYWJsZTxJdGVyYWJsZTxzdHJpbmc+Pn0gSGVhZGVyc0luaXRcbiAqL1xuXG4vKipcbiAqIFRoaXMgRmV0Y2ggQVBJIGludGVyZmFjZSBhbGxvd3MgeW91IHRvIHBlcmZvcm0gdmFyaW91cyBhY3Rpb25zIG9uIEhUVFAgcmVxdWVzdCBhbmQgcmVzcG9uc2UgaGVhZGVycy5cbiAqIFRoZXNlIGFjdGlvbnMgaW5jbHVkZSByZXRyaWV2aW5nLCBzZXR0aW5nLCBhZGRpbmcgdG8sIGFuZCByZW1vdmluZy5cbiAqIEEgSGVhZGVycyBvYmplY3QgaGFzIGFuIGFzc29jaWF0ZWQgaGVhZGVyIGxpc3QsIHdoaWNoIGlzIGluaXRpYWxseSBlbXB0eSBhbmQgY29uc2lzdHMgb2YgemVybyBvciBtb3JlIG5hbWUgYW5kIHZhbHVlIHBhaXJzLlxuICogWW91IGNhbiBhZGQgdG8gdGhpcyB1c2luZyBtZXRob2RzIGxpa2UgYXBwZW5kKCkgKHNlZSBFeGFtcGxlcy4pXG4gKiBJbiBhbGwgbWV0aG9kcyBvZiB0aGlzIGludGVyZmFjZSwgaGVhZGVyIG5hbWVzIGFyZSBtYXRjaGVkIGJ5IGNhc2UtaW5zZW5zaXRpdmUgYnl0ZSBzZXF1ZW5jZS5cbiAqXG4gKi9cbmNsYXNzIEhlYWRlcnMgZXh0ZW5kcyBVUkxTZWFyY2hQYXJhbXMge1xuXHQvKipcblx0ICogSGVhZGVycyBjbGFzc1xuXHQgKlxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQHBhcmFtIHtIZWFkZXJzSW5pdH0gW2luaXRdIC0gUmVzcG9uc2UgaGVhZGVyc1xuXHQgKi9cblx0Y29uc3RydWN0b3IoaW5pdCkge1xuXHRcdC8vIFZhbGlkYXRlIGFuZCBub3JtYWxpemUgaW5pdCBvYmplY3QgaW4gW25hbWUsIHZhbHVlKHMpXVtdXG5cdFx0LyoqIEB0eXBlIHtzdHJpbmdbXVtdfSAqL1xuXHRcdGxldCByZXN1bHQgPSBbXTtcblx0XHRpZiAoaW5pdCBpbnN0YW5jZW9mIEhlYWRlcnMpIHtcblx0XHRcdGNvbnN0IHJhdyA9IGluaXQucmF3KCk7XG5cdFx0XHRmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZXNdIG9mIE9iamVjdC5lbnRyaWVzKHJhdykpIHtcblx0XHRcdFx0cmVzdWx0LnB1c2goLi4udmFsdWVzLm1hcCh2YWx1ZSA9PiBbbmFtZSwgdmFsdWVdKSk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChpbml0ID09IG51bGwpIDsgZWxzZSBpZiAodHlwZW9mIGluaXQgPT09ICdvYmplY3QnICYmICF1dGlsLnR5cGVzLmlzQm94ZWRQcmltaXRpdmUoaW5pdCkpIHtcblx0XHRcdGNvbnN0IG1ldGhvZCA9IGluaXRbU3ltYm9sLml0ZXJhdG9yXTtcblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lcS1udWxsLCBlcWVxZXFcblx0XHRcdGlmIChtZXRob2QgPT0gbnVsbCkge1xuXHRcdFx0XHQvLyBSZWNvcmQ8Qnl0ZVN0cmluZywgQnl0ZVN0cmluZz5cblx0XHRcdFx0cmVzdWx0LnB1c2goLi4uT2JqZWN0LmVudHJpZXMoaW5pdCkpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aWYgKHR5cGVvZiBtZXRob2QgIT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdIZWFkZXIgcGFpcnMgbXVzdCBiZSBpdGVyYWJsZScpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU2VxdWVuY2U8c2VxdWVuY2U8Qnl0ZVN0cmluZz4+XG5cdFx0XHRcdC8vIE5vdGU6IHBlciBzcGVjIHdlIGhhdmUgdG8gZmlyc3QgZXhoYXVzdCB0aGUgbGlzdHMgdGhlbiBwcm9jZXNzIHRoZW1cblx0XHRcdFx0cmVzdWx0ID0gWy4uLmluaXRdXG5cdFx0XHRcdFx0Lm1hcChwYWlyID0+IHtcblx0XHRcdFx0XHRcdGlmIChcblx0XHRcdFx0XHRcdFx0dHlwZW9mIHBhaXIgIT09ICdvYmplY3QnIHx8IHV0aWwudHlwZXMuaXNCb3hlZFByaW1pdGl2ZShwYWlyKVxuXHRcdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ0VhY2ggaGVhZGVyIHBhaXIgbXVzdCBiZSBhbiBpdGVyYWJsZSBvYmplY3QnKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIFsuLi5wYWlyXTtcblx0XHRcdFx0XHR9KS5tYXAocGFpciA9PiB7XG5cdFx0XHRcdFx0XHRpZiAocGFpci5sZW5ndGggIT09IDIpIHtcblx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRWFjaCBoZWFkZXIgcGFpciBtdXN0IGJlIGEgbmFtZS92YWx1ZSB0dXBsZScpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXR1cm4gWy4uLnBhaXJdO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdGYWlsZWQgdG8gY29uc3RydWN0IFxcJ0hlYWRlcnNcXCc6IFRoZSBwcm92aWRlZCB2YWx1ZSBpcyBub3Qgb2YgdHlwZSBcXCcoc2VxdWVuY2U8c2VxdWVuY2U8Qnl0ZVN0cmluZz4+IG9yIHJlY29yZDxCeXRlU3RyaW5nLCBCeXRlU3RyaW5nPiknKTtcblx0XHR9XG5cblx0XHQvLyBWYWxpZGF0ZSBhbmQgbG93ZXJjYXNlXG5cdFx0cmVzdWx0ID1cblx0XHRcdHJlc3VsdC5sZW5ndGggPiAwID9cblx0XHRcdFx0cmVzdWx0Lm1hcCgoW25hbWUsIHZhbHVlXSkgPT4ge1xuXHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyTmFtZShuYW1lKTtcblx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlclZhbHVlKG5hbWUsIFN0cmluZyh2YWx1ZSkpO1xuXHRcdFx0XHRcdHJldHVybiBbU3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKCksIFN0cmluZyh2YWx1ZSldO1xuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdHVuZGVmaW5lZDtcblxuXHRcdHN1cGVyKHJlc3VsdCk7XG5cblx0XHQvLyBSZXR1cm5pbmcgYSBQcm94eSB0aGF0IHdpbGwgbG93ZXJjYXNlIGtleSBuYW1lcywgdmFsaWRhdGUgcGFyYW1ldGVycyBhbmQgc29ydCBrZXlzXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnN0cnVjdG9yLXJldHVyblxuXHRcdHJldHVybiBuZXcgUHJveHkodGhpcywge1xuXHRcdFx0Z2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpIHtcblx0XHRcdFx0c3dpdGNoIChwKSB7XG5cdFx0XHRcdFx0Y2FzZSAnYXBwZW5kJzpcblx0XHRcdFx0XHRjYXNlICdzZXQnOlxuXHRcdFx0XHRcdFx0cmV0dXJuIChuYW1lLCB2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlck5hbWUobmFtZSk7XG5cdFx0XHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyVmFsdWUobmFtZSwgU3RyaW5nKHZhbHVlKSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlW3BdLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0cmVjZWl2ZXIsXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKCksXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKHZhbHVlKVxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdGNhc2UgJ2RlbGV0ZSc6XG5cdFx0XHRcdFx0Y2FzZSAnaGFzJzpcblx0XHRcdFx0XHRjYXNlICdnZXRBbGwnOlxuXHRcdFx0XHRcdFx0cmV0dXJuIG5hbWUgPT4ge1xuXHRcdFx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlck5hbWUobmFtZSk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlW3BdLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0cmVjZWl2ZXIsXG5cdFx0XHRcdFx0XHRcdFx0U3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKClcblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRjYXNlICdrZXlzJzpcblx0XHRcdFx0XHRcdHJldHVybiAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRhcmdldC5zb3J0KCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBuZXcgU2V0KFVSTFNlYXJjaFBhcmFtcy5wcm90b3R5cGUua2V5cy5jYWxsKHRhcmdldCkpLmtleXMoKTtcblx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0cmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcCwgcmVjZWl2ZXIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvKiBjOCBpZ25vcmUgbmV4dCAqL1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0IFtTeW1ib2wudG9TdHJpbmdUYWddKCkge1xuXHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG5cdH1cblxuXHR0b1N0cmluZygpIHtcblx0XHRyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRoaXMpO1xuXHR9XG5cblx0Z2V0KG5hbWUpIHtcblx0XHRjb25zdCB2YWx1ZXMgPSB0aGlzLmdldEFsbChuYW1lKTtcblx0XHRpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0bGV0IHZhbHVlID0gdmFsdWVzLmpvaW4oJywgJyk7XG5cdFx0aWYgKC9eY29udGVudC1lbmNvZGluZyQvaS50ZXN0KG5hbWUpKSB7XG5cdFx0XHR2YWx1ZSA9IHZhbHVlLnRvTG93ZXJDYXNlKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9XG5cblx0Zm9yRWFjaChjYWxsYmFjaykge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0Y2FsbGJhY2sodGhpcy5nZXQobmFtZSksIG5hbWUpO1xuXHRcdH1cblx0fVxuXG5cdCogdmFsdWVzKCkge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0eWllbGQgdGhpcy5nZXQobmFtZSk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEB0eXBlIHsoKSA9PiBJdGVyYWJsZUl0ZXJhdG9yPFtzdHJpbmcsIHN0cmluZ10+fVxuXHQgKi9cblx0KiBlbnRyaWVzKCkge1xuXHRcdGZvciAoY29uc3QgbmFtZSBvZiB0aGlzLmtleXMoKSkge1xuXHRcdFx0eWllbGQgW25hbWUsIHRoaXMuZ2V0KG5hbWUpXTtcblx0XHR9XG5cdH1cblxuXHRbU3ltYm9sLml0ZXJhdG9yXSgpIHtcblx0XHRyZXR1cm4gdGhpcy5lbnRyaWVzKCk7XG5cdH1cblxuXHQvKipcblx0ICogTm9kZS1mZXRjaCBub24tc3BlYyBtZXRob2Rcblx0ICogcmV0dXJuaW5nIGFsbCBoZWFkZXJzIGFuZCB0aGVpciB2YWx1ZXMgYXMgYXJyYXlcblx0ICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHN0cmluZ1tdPn1cblx0ICovXG5cdHJhdygpIHtcblx0XHRyZXR1cm4gWy4uLnRoaXMua2V5cygpXS5yZWR1Y2UoKHJlc3VsdCwga2V5KSA9PiB7XG5cdFx0XHRyZXN1bHRba2V5XSA9IHRoaXMuZ2V0QWxsKGtleSk7XG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0sIHt9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBGb3IgYmV0dGVyIGNvbnNvbGUubG9nKGhlYWRlcnMpIGFuZCBhbHNvIHRvIGNvbnZlcnQgSGVhZGVycyBpbnRvIE5vZGUuanMgUmVxdWVzdCBjb21wYXRpYmxlIGZvcm1hdFxuXHQgKi9cblx0W1N5bWJvbC5mb3IoJ25vZGVqcy51dGlsLmluc3BlY3QuY3VzdG9tJyldKCkge1xuXHRcdHJldHVybiBbLi4udGhpcy5rZXlzKCldLnJlZHVjZSgocmVzdWx0LCBrZXkpID0+IHtcblx0XHRcdGNvbnN0IHZhbHVlcyA9IHRoaXMuZ2V0QWxsKGtleSk7XG5cdFx0XHQvLyBIdHRwLnJlcXVlc3QoKSBvbmx5IHN1cHBvcnRzIHN0cmluZyBhcyBIb3N0IGhlYWRlci5cblx0XHRcdC8vIFRoaXMgaGFjayBtYWtlcyBzcGVjaWZ5aW5nIGN1c3RvbSBIb3N0IGhlYWRlciBwb3NzaWJsZS5cblx0XHRcdGlmIChrZXkgPT09ICdob3N0Jykge1xuXHRcdFx0XHRyZXN1bHRba2V5XSA9IHZhbHVlc1swXTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJlc3VsdFtrZXldID0gdmFsdWVzLmxlbmd0aCA+IDEgPyB2YWx1ZXMgOiB2YWx1ZXNbMF07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fSwge30pO1xuXHR9XG59XG5cbi8qKlxuICogUmUtc2hhcGluZyBvYmplY3QgZm9yIFdlYiBJREwgdGVzdHNcbiAqIE9ubHkgbmVlZCB0byBkbyBpdCBmb3Igb3ZlcnJpZGRlbiBtZXRob2RzXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFxuXHRIZWFkZXJzLnByb3RvdHlwZSxcblx0WydnZXQnLCAnZW50cmllcycsICdmb3JFYWNoJywgJ3ZhbHVlcyddLnJlZHVjZSgocmVzdWx0LCBwcm9wZXJ0eSkgPT4ge1xuXHRcdHJlc3VsdFtwcm9wZXJ0eV0gPSB7ZW51bWVyYWJsZTogdHJ1ZX07XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSwge30pXG4pO1xuXG4vKipcbiAqIENyZWF0ZSBhIEhlYWRlcnMgb2JqZWN0IGZyb20gYW4gaHR0cC5JbmNvbWluZ01lc3NhZ2UucmF3SGVhZGVycywgaWdub3JpbmcgdGhvc2UgdGhhdCBkb1xuICogbm90IGNvbmZvcm0gdG8gSFRUUCBncmFtbWFyIHByb2R1Y3Rpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoJ2h0dHAnKS5JbmNvbWluZ01lc3NhZ2VbJ3Jhd0hlYWRlcnMnXX0gaGVhZGVyc1xuICovXG5mdW5jdGlvbiBmcm9tUmF3SGVhZGVycyhoZWFkZXJzID0gW10pIHtcblx0cmV0dXJuIG5ldyBIZWFkZXJzKFxuXHRcdGhlYWRlcnNcblx0XHRcdC8vIFNwbGl0IGludG8gcGFpcnNcblx0XHRcdC5yZWR1Y2UoKHJlc3VsdCwgdmFsdWUsIGluZGV4LCBhcnJheSkgPT4ge1xuXHRcdFx0XHRpZiAoaW5kZXggJSAyID09PSAwKSB7XG5cdFx0XHRcdFx0cmVzdWx0LnB1c2goYXJyYXkuc2xpY2UoaW5kZXgsIGluZGV4ICsgMikpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH0sIFtdKVxuXHRcdFx0LmZpbHRlcigoW25hbWUsIHZhbHVlXSkgPT4ge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHZhbGlkYXRlSGVhZGVyTmFtZShuYW1lKTtcblx0XHRcdFx0XHR2YWxpZGF0ZUhlYWRlclZhbHVlKG5hbWUsIFN0cmluZyh2YWx1ZSkpO1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0pXG5cblx0KTtcbn1cblxuY29uc3QgcmVkaXJlY3RTdGF0dXMgPSBuZXcgU2V0KFszMDEsIDMwMiwgMzAzLCAzMDcsIDMwOF0pO1xuXG4vKipcbiAqIFJlZGlyZWN0IGNvZGUgbWF0Y2hpbmdcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gY29kZSAtIFN0YXR1cyBjb2RlXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBpc1JlZGlyZWN0ID0gY29kZSA9PiB7XG5cdHJldHVybiByZWRpcmVjdFN0YXR1cy5oYXMoY29kZSk7XG59O1xuXG4vKipcbiAqIFJlc3BvbnNlLmpzXG4gKlxuICogUmVzcG9uc2UgY2xhc3MgcHJvdmlkZXMgY29udGVudCBkZWNvZGluZ1xuICovXG5cbmNvbnN0IElOVEVSTkFMUyQxID0gU3ltYm9sKCdSZXNwb25zZSBpbnRlcm5hbHMnKTtcblxuLyoqXG4gKiBSZXNwb25zZSBjbGFzc1xuICpcbiAqIEBwYXJhbSAgIFN0cmVhbSAgYm9keSAgUmVhZGFibGUgc3RyZWFtXG4gKiBAcGFyYW0gICBPYmplY3QgIG9wdHMgIFJlc3BvbnNlIG9wdGlvbnNcbiAqIEByZXR1cm4gIFZvaWRcbiAqL1xuY2xhc3MgUmVzcG9uc2UgZXh0ZW5kcyBCb2R5IHtcblx0Y29uc3RydWN0b3IoYm9keSA9IG51bGwsIG9wdGlvbnMgPSB7fSkge1xuXHRcdHN1cGVyKGJvZHksIG9wdGlvbnMpO1xuXG5cdFx0Y29uc3Qgc3RhdHVzID0gb3B0aW9ucy5zdGF0dXMgfHwgMjAwO1xuXHRcdGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyhvcHRpb25zLmhlYWRlcnMpO1xuXG5cdFx0aWYgKGJvZHkgIT09IG51bGwgJiYgIWhlYWRlcnMuaGFzKCdDb250ZW50LVR5cGUnKSkge1xuXHRcdFx0Y29uc3QgY29udGVudFR5cGUgPSBleHRyYWN0Q29udGVudFR5cGUoYm9keSk7XG5cdFx0XHRpZiAoY29udGVudFR5cGUpIHtcblx0XHRcdFx0aGVhZGVycy5hcHBlbmQoJ0NvbnRlbnQtVHlwZScsIGNvbnRlbnRUeXBlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMUyQxXSA9IHtcblx0XHRcdHVybDogb3B0aW9ucy51cmwsXG5cdFx0XHRzdGF0dXMsXG5cdFx0XHRzdGF0dXNUZXh0OiBvcHRpb25zLnN0YXR1c1RleHQgfHwgJycsXG5cdFx0XHRoZWFkZXJzLFxuXHRcdFx0Y291bnRlcjogb3B0aW9ucy5jb3VudGVyLFxuXHRcdFx0aGlnaFdhdGVyTWFyazogb3B0aW9ucy5oaWdoV2F0ZXJNYXJrXG5cdFx0fTtcblx0fVxuXG5cdGdldCB1cmwoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLnVybCB8fCAnJztcblx0fVxuXG5cdGdldCBzdGF0dXMoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLnN0YXR1cztcblx0fVxuXG5cdC8qKlxuXHQgKiBDb252ZW5pZW5jZSBwcm9wZXJ0eSByZXByZXNlbnRpbmcgaWYgdGhlIHJlcXVlc3QgZW5kZWQgbm9ybWFsbHlcblx0ICovXG5cdGdldCBvaygpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uc3RhdHVzID49IDIwMCAmJiB0aGlzW0lOVEVSTkFMUyQxXS5zdGF0dXMgPCAzMDA7XG5cdH1cblxuXHRnZXQgcmVkaXJlY3RlZCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uY291bnRlciA+IDA7XG5cdH1cblxuXHRnZXQgc3RhdHVzVGV4dCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMV0uc3RhdHVzVGV4dDtcblx0fVxuXG5cdGdldCBoZWFkZXJzKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQxXS5oZWFkZXJzO1xuXHR9XG5cblx0Z2V0IGhpZ2hXYXRlck1hcmsoKSB7XG5cdFx0cmV0dXJuIHRoaXNbSU5URVJOQUxTJDFdLmhpZ2hXYXRlck1hcms7XG5cdH1cblxuXHQvKipcblx0ICogQ2xvbmUgdGhpcyByZXNwb25zZVxuXHQgKlxuXHQgKiBAcmV0dXJuICBSZXNwb25zZVxuXHQgKi9cblx0Y2xvbmUoKSB7XG5cdFx0cmV0dXJuIG5ldyBSZXNwb25zZShjbG9uZSh0aGlzLCB0aGlzLmhpZ2hXYXRlck1hcmspLCB7XG5cdFx0XHR1cmw6IHRoaXMudXJsLFxuXHRcdFx0c3RhdHVzOiB0aGlzLnN0YXR1cyxcblx0XHRcdHN0YXR1c1RleHQ6IHRoaXMuc3RhdHVzVGV4dCxcblx0XHRcdGhlYWRlcnM6IHRoaXMuaGVhZGVycyxcblx0XHRcdG9rOiB0aGlzLm9rLFxuXHRcdFx0cmVkaXJlY3RlZDogdGhpcy5yZWRpcmVjdGVkLFxuXHRcdFx0c2l6ZTogdGhpcy5zaXplXG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogQHBhcmFtIHtzdHJpbmd9IHVybCAgICBUaGUgVVJMIHRoYXQgdGhlIG5ldyByZXNwb25zZSBpcyB0byBvcmlnaW5hdGUgZnJvbS5cblx0ICogQHBhcmFtIHtudW1iZXJ9IHN0YXR1cyBBbiBvcHRpb25hbCBzdGF0dXMgY29kZSBmb3IgdGhlIHJlc3BvbnNlIChlLmcuLCAzMDIuKVxuXHQgKiBAcmV0dXJucyB7UmVzcG9uc2V9ICAgIEEgUmVzcG9uc2Ugb2JqZWN0LlxuXHQgKi9cblx0c3RhdGljIHJlZGlyZWN0KHVybCwgc3RhdHVzID0gMzAyKSB7XG5cdFx0aWYgKCFpc1JlZGlyZWN0KHN0YXR1cykpIHtcblx0XHRcdHRocm93IG5ldyBSYW5nZUVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSBcInJlZGlyZWN0XCIgb24gXCJyZXNwb25zZVwiOiBJbnZhbGlkIHN0YXR1cyBjb2RlJyk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBSZXNwb25zZShudWxsLCB7XG5cdFx0XHRoZWFkZXJzOiB7XG5cdFx0XHRcdGxvY2F0aW9uOiBuZXcgVVJMKHVybCkudG9TdHJpbmcoKVxuXHRcdFx0fSxcblx0XHRcdHN0YXR1c1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0IFtTeW1ib2wudG9TdHJpbmdUYWddKCkge1xuXHRcdHJldHVybiAnUmVzcG9uc2UnO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlc3BvbnNlLnByb3RvdHlwZSwge1xuXHR1cmw6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0c3RhdHVzOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdG9rOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdHJlZGlyZWN0ZWQ6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0c3RhdHVzVGV4dDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRoZWFkZXJzOiB7ZW51bWVyYWJsZTogdHJ1ZX0sXG5cdGNsb25lOiB7ZW51bWVyYWJsZTogdHJ1ZX1cbn0pO1xuXG5jb25zdCBnZXRTZWFyY2ggPSBwYXJzZWRVUkwgPT4ge1xuXHRpZiAocGFyc2VkVVJMLnNlYXJjaCkge1xuXHRcdHJldHVybiBwYXJzZWRVUkwuc2VhcmNoO1xuXHR9XG5cblx0Y29uc3QgbGFzdE9mZnNldCA9IHBhcnNlZFVSTC5ocmVmLmxlbmd0aCAtIDE7XG5cdGNvbnN0IGhhc2ggPSBwYXJzZWRVUkwuaGFzaCB8fCAocGFyc2VkVVJMLmhyZWZbbGFzdE9mZnNldF0gPT09ICcjJyA/ICcjJyA6ICcnKTtcblx0cmV0dXJuIHBhcnNlZFVSTC5ocmVmW2xhc3RPZmZzZXQgLSBoYXNoLmxlbmd0aF0gPT09ICc/JyA/ICc/JyA6ICcnO1xufTtcblxuY29uc3QgSU5URVJOQUxTJDIgPSBTeW1ib2woJ1JlcXVlc3QgaW50ZXJuYWxzJyk7XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYW4gaW5zdGFuY2Ugb2YgUmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gIHsqfSBvYmpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGlzUmVxdWVzdCA9IG9iamVjdCA9PiB7XG5cdHJldHVybiAoXG5cdFx0dHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiZcblx0XHR0eXBlb2Ygb2JqZWN0W0lOVEVSTkFMUyQyXSA9PT0gJ29iamVjdCdcblx0KTtcbn07XG5cbi8qKlxuICogUmVxdWVzdCBjbGFzc1xuICpcbiAqIEBwYXJhbSAgIE1peGVkICAgaW5wdXQgIFVybCBvciBSZXF1ZXN0IGluc3RhbmNlXG4gKiBAcGFyYW0gICBPYmplY3QgIGluaXQgICBDdXN0b20gb3B0aW9uc1xuICogQHJldHVybiAgVm9pZFxuICovXG5jbGFzcyBSZXF1ZXN0IGV4dGVuZHMgQm9keSB7XG5cdGNvbnN0cnVjdG9yKGlucHV0LCBpbml0ID0ge30pIHtcblx0XHRsZXQgcGFyc2VkVVJMO1xuXG5cdFx0Ly8gTm9ybWFsaXplIGlucHV0IGFuZCBmb3JjZSBVUkwgdG8gYmUgZW5jb2RlZCBhcyBVVEYtOCAoaHR0cHM6Ly9naXRodWIuY29tL25vZGUtZmV0Y2gvbm9kZS1mZXRjaC9pc3N1ZXMvMjQ1KVxuXHRcdGlmIChpc1JlcXVlc3QoaW5wdXQpKSB7XG5cdFx0XHRwYXJzZWRVUkwgPSBuZXcgVVJMKGlucHV0LnVybCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBhcnNlZFVSTCA9IG5ldyBVUkwoaW5wdXQpO1xuXHRcdFx0aW5wdXQgPSB7fTtcblx0XHR9XG5cblx0XHRsZXQgbWV0aG9kID0gaW5pdC5tZXRob2QgfHwgaW5wdXQubWV0aG9kIHx8ICdHRVQnO1xuXHRcdG1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVxLW51bGwsIGVxZXFlcVxuXHRcdGlmICgoKGluaXQuYm9keSAhPSBudWxsIHx8IGlzUmVxdWVzdChpbnB1dCkpICYmIGlucHV0LmJvZHkgIT09IG51bGwpICYmXG5cdFx0XHQobWV0aG9kID09PSAnR0VUJyB8fCBtZXRob2QgPT09ICdIRUFEJykpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlcXVlc3Qgd2l0aCBHRVQvSEVBRCBtZXRob2QgY2Fubm90IGhhdmUgYm9keScpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGlucHV0Qm9keSA9IGluaXQuYm9keSA/XG5cdFx0XHRpbml0LmJvZHkgOlxuXHRcdFx0KGlzUmVxdWVzdChpbnB1dCkgJiYgaW5wdXQuYm9keSAhPT0gbnVsbCA/XG5cdFx0XHRcdGNsb25lKGlucHV0KSA6XG5cdFx0XHRcdG51bGwpO1xuXG5cdFx0c3VwZXIoaW5wdXRCb2R5LCB7XG5cdFx0XHRzaXplOiBpbml0LnNpemUgfHwgaW5wdXQuc2l6ZSB8fCAwXG5cdFx0fSk7XG5cblx0XHRjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoaW5pdC5oZWFkZXJzIHx8IGlucHV0LmhlYWRlcnMgfHwge30pO1xuXG5cdFx0aWYgKGlucHV0Qm9keSAhPT0gbnVsbCAmJiAhaGVhZGVycy5oYXMoJ0NvbnRlbnQtVHlwZScpKSB7XG5cdFx0XHRjb25zdCBjb250ZW50VHlwZSA9IGV4dHJhY3RDb250ZW50VHlwZShpbnB1dEJvZHksIHRoaXMpO1xuXHRcdFx0aWYgKGNvbnRlbnRUeXBlKSB7XG5cdFx0XHRcdGhlYWRlcnMuYXBwZW5kKCdDb250ZW50LVR5cGUnLCBjb250ZW50VHlwZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0bGV0IHNpZ25hbCA9IGlzUmVxdWVzdChpbnB1dCkgP1xuXHRcdFx0aW5wdXQuc2lnbmFsIDpcblx0XHRcdG51bGw7XG5cdFx0aWYgKCdzaWduYWwnIGluIGluaXQpIHtcblx0XHRcdHNpZ25hbCA9IGluaXQuc2lnbmFsO1xuXHRcdH1cblxuXHRcdGlmIChzaWduYWwgIT09IG51bGwgJiYgIWlzQWJvcnRTaWduYWwoc2lnbmFsKSkge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgc2lnbmFsIHRvIGJlIGFuIGluc3RhbmNlb2YgQWJvcnRTaWduYWwnKTtcblx0XHR9XG5cblx0XHR0aGlzW0lOVEVSTkFMUyQyXSA9IHtcblx0XHRcdG1ldGhvZCxcblx0XHRcdHJlZGlyZWN0OiBpbml0LnJlZGlyZWN0IHx8IGlucHV0LnJlZGlyZWN0IHx8ICdmb2xsb3cnLFxuXHRcdFx0aGVhZGVycyxcblx0XHRcdHBhcnNlZFVSTCxcblx0XHRcdHNpZ25hbFxuXHRcdH07XG5cblx0XHQvLyBOb2RlLWZldGNoLW9ubHkgb3B0aW9uc1xuXHRcdHRoaXMuZm9sbG93ID0gaW5pdC5mb2xsb3cgPT09IHVuZGVmaW5lZCA/IChpbnB1dC5mb2xsb3cgPT09IHVuZGVmaW5lZCA/IDIwIDogaW5wdXQuZm9sbG93KSA6IGluaXQuZm9sbG93O1xuXHRcdHRoaXMuY29tcHJlc3MgPSBpbml0LmNvbXByZXNzID09PSB1bmRlZmluZWQgPyAoaW5wdXQuY29tcHJlc3MgPT09IHVuZGVmaW5lZCA/IHRydWUgOiBpbnB1dC5jb21wcmVzcykgOiBpbml0LmNvbXByZXNzO1xuXHRcdHRoaXMuY291bnRlciA9IGluaXQuY291bnRlciB8fCBpbnB1dC5jb3VudGVyIHx8IDA7XG5cdFx0dGhpcy5hZ2VudCA9IGluaXQuYWdlbnQgfHwgaW5wdXQuYWdlbnQ7XG5cdFx0dGhpcy5oaWdoV2F0ZXJNYXJrID0gaW5pdC5oaWdoV2F0ZXJNYXJrIHx8IGlucHV0LmhpZ2hXYXRlck1hcmsgfHwgMTYzODQ7XG5cdFx0dGhpcy5pbnNlY3VyZUhUVFBQYXJzZXIgPSBpbml0Lmluc2VjdXJlSFRUUFBhcnNlciB8fCBpbnB1dC5pbnNlY3VyZUhUVFBQYXJzZXIgfHwgZmFsc2U7XG5cdH1cblxuXHRnZXQgbWV0aG9kKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQyXS5tZXRob2Q7XG5cdH1cblxuXHRnZXQgdXJsKCkge1xuXHRcdHJldHVybiB1cmwuZm9ybWF0KHRoaXNbSU5URVJOQUxTJDJdLnBhcnNlZFVSTCk7XG5cdH1cblxuXHRnZXQgaGVhZGVycygpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMl0uaGVhZGVycztcblx0fVxuXG5cdGdldCByZWRpcmVjdCgpIHtcblx0XHRyZXR1cm4gdGhpc1tJTlRFUk5BTFMkMl0ucmVkaXJlY3Q7XG5cdH1cblxuXHRnZXQgc2lnbmFsKCkge1xuXHRcdHJldHVybiB0aGlzW0lOVEVSTkFMUyQyXS5zaWduYWw7XG5cdH1cblxuXHQvKipcblx0ICogQ2xvbmUgdGhpcyByZXF1ZXN0XG5cdCAqXG5cdCAqIEByZXR1cm4gIFJlcXVlc3Rcblx0ICovXG5cdGNsb25lKCkge1xuXHRcdHJldHVybiBuZXcgUmVxdWVzdCh0aGlzKTtcblx0fVxuXG5cdGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcblx0XHRyZXR1cm4gJ1JlcXVlc3QnO1xuXHR9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlcXVlc3QucHJvdG90eXBlLCB7XG5cdG1ldGhvZDoge2VudW1lcmFibGU6IHRydWV9LFxuXHR1cmw6IHtlbnVtZXJhYmxlOiB0cnVlfSxcblx0aGVhZGVyczoge2VudW1lcmFibGU6IHRydWV9LFxuXHRyZWRpcmVjdDoge2VudW1lcmFibGU6IHRydWV9LFxuXHRjbG9uZToge2VudW1lcmFibGU6IHRydWV9LFxuXHRzaWduYWw6IHtlbnVtZXJhYmxlOiB0cnVlfVxufSk7XG5cbi8qKlxuICogQ29udmVydCBhIFJlcXVlc3QgdG8gTm9kZS5qcyBodHRwIHJlcXVlc3Qgb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0gICBSZXF1ZXN0ICBBIFJlcXVlc3QgaW5zdGFuY2VcbiAqIEByZXR1cm4gIE9iamVjdCAgIFRoZSBvcHRpb25zIG9iamVjdCB0byBiZSBwYXNzZWQgdG8gaHR0cC5yZXF1ZXN0XG4gKi9cbmNvbnN0IGdldE5vZGVSZXF1ZXN0T3B0aW9ucyA9IHJlcXVlc3QgPT4ge1xuXHRjb25zdCB7cGFyc2VkVVJMfSA9IHJlcXVlc3RbSU5URVJOQUxTJDJdO1xuXHRjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMocmVxdWVzdFtJTlRFUk5BTFMkMl0uaGVhZGVycyk7XG5cblx0Ly8gRmV0Y2ggc3RlcCAxLjNcblx0aWYgKCFoZWFkZXJzLmhhcygnQWNjZXB0JykpIHtcblx0XHRoZWFkZXJzLnNldCgnQWNjZXB0JywgJyovKicpO1xuXHR9XG5cblx0Ly8gSFRUUC1uZXR3b3JrLW9yLWNhY2hlIGZldGNoIHN0ZXBzIDIuNC0yLjdcblx0bGV0IGNvbnRlbnRMZW5ndGhWYWx1ZSA9IG51bGw7XG5cdGlmIChyZXF1ZXN0LmJvZHkgPT09IG51bGwgJiYgL14ocG9zdHxwdXQpJC9pLnRlc3QocmVxdWVzdC5tZXRob2QpKSB7XG5cdFx0Y29udGVudExlbmd0aFZhbHVlID0gJzAnO1xuXHR9XG5cblx0aWYgKHJlcXVlc3QuYm9keSAhPT0gbnVsbCkge1xuXHRcdGNvbnN0IHRvdGFsQnl0ZXMgPSBnZXRUb3RhbEJ5dGVzKHJlcXVlc3QpO1xuXHRcdC8vIFNldCBDb250ZW50LUxlbmd0aCBpZiB0b3RhbEJ5dGVzIGlzIGEgbnVtYmVyICh0aGF0IGlzIG5vdCBOYU4pXG5cdFx0aWYgKHR5cGVvZiB0b3RhbEJ5dGVzID09PSAnbnVtYmVyJyAmJiAhTnVtYmVyLmlzTmFOKHRvdGFsQnl0ZXMpKSB7XG5cdFx0XHRjb250ZW50TGVuZ3RoVmFsdWUgPSBTdHJpbmcodG90YWxCeXRlcyk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGNvbnRlbnRMZW5ndGhWYWx1ZSkge1xuXHRcdGhlYWRlcnMuc2V0KCdDb250ZW50LUxlbmd0aCcsIGNvbnRlbnRMZW5ndGhWYWx1ZSk7XG5cdH1cblxuXHQvLyBIVFRQLW5ldHdvcmstb3ItY2FjaGUgZmV0Y2ggc3RlcCAyLjExXG5cdGlmICghaGVhZGVycy5oYXMoJ1VzZXItQWdlbnQnKSkge1xuXHRcdGhlYWRlcnMuc2V0KCdVc2VyLUFnZW50JywgJ25vZGUtZmV0Y2gnKTtcblx0fVxuXG5cdC8vIEhUVFAtbmV0d29yay1vci1jYWNoZSBmZXRjaCBzdGVwIDIuMTVcblx0aWYgKHJlcXVlc3QuY29tcHJlc3MgJiYgIWhlYWRlcnMuaGFzKCdBY2NlcHQtRW5jb2RpbmcnKSkge1xuXHRcdGhlYWRlcnMuc2V0KCdBY2NlcHQtRW5jb2RpbmcnLCAnZ3ppcCxkZWZsYXRlLGJyJyk7XG5cdH1cblxuXHRsZXQge2FnZW50fSA9IHJlcXVlc3Q7XG5cdGlmICh0eXBlb2YgYWdlbnQgPT09ICdmdW5jdGlvbicpIHtcblx0XHRhZ2VudCA9IGFnZW50KHBhcnNlZFVSTCk7XG5cdH1cblxuXHRpZiAoIWhlYWRlcnMuaGFzKCdDb25uZWN0aW9uJykgJiYgIWFnZW50KSB7XG5cdFx0aGVhZGVycy5zZXQoJ0Nvbm5lY3Rpb24nLCAnY2xvc2UnKTtcblx0fVxuXG5cdC8vIEhUVFAtbmV0d29yayBmZXRjaCBzdGVwIDQuMlxuXHQvLyBjaHVua2VkIGVuY29kaW5nIGlzIGhhbmRsZWQgYnkgTm9kZS5qc1xuXG5cdGNvbnN0IHNlYXJjaCA9IGdldFNlYXJjaChwYXJzZWRVUkwpO1xuXG5cdC8vIE1hbnVhbGx5IHNwcmVhZCB0aGUgVVJMIG9iamVjdCBpbnN0ZWFkIG9mIHNwcmVhZCBzeW50YXhcblx0Y29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG5cdFx0cGF0aDogcGFyc2VkVVJMLnBhdGhuYW1lICsgc2VhcmNoLFxuXHRcdHBhdGhuYW1lOiBwYXJzZWRVUkwucGF0aG5hbWUsXG5cdFx0aG9zdG5hbWU6IHBhcnNlZFVSTC5ob3N0bmFtZSxcblx0XHRwcm90b2NvbDogcGFyc2VkVVJMLnByb3RvY29sLFxuXHRcdHBvcnQ6IHBhcnNlZFVSTC5wb3J0LFxuXHRcdGhhc2g6IHBhcnNlZFVSTC5oYXNoLFxuXHRcdHNlYXJjaDogcGFyc2VkVVJMLnNlYXJjaCxcblx0XHRxdWVyeTogcGFyc2VkVVJMLnF1ZXJ5LFxuXHRcdGhyZWY6IHBhcnNlZFVSTC5ocmVmLFxuXHRcdG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG5cdFx0aGVhZGVyczogaGVhZGVyc1tTeW1ib2wuZm9yKCdub2RlanMudXRpbC5pbnNwZWN0LmN1c3RvbScpXSgpLFxuXHRcdGluc2VjdXJlSFRUUFBhcnNlcjogcmVxdWVzdC5pbnNlY3VyZUhUVFBQYXJzZXIsXG5cdFx0YWdlbnRcblx0fTtcblxuXHRyZXR1cm4gcmVxdWVzdE9wdGlvbnM7XG59O1xuXG4vKipcbiAqIEFib3J0RXJyb3IgaW50ZXJmYWNlIGZvciBjYW5jZWxsZWQgcmVxdWVzdHNcbiAqL1xuY2xhc3MgQWJvcnRFcnJvciBleHRlbmRzIEZldGNoQmFzZUVycm9yIHtcblx0Y29uc3RydWN0b3IobWVzc2FnZSwgdHlwZSA9ICdhYm9ydGVkJykge1xuXHRcdHN1cGVyKG1lc3NhZ2UsIHR5cGUpO1xuXHR9XG59XG5cbi8qKlxuICogSW5kZXguanNcbiAqXG4gKiBhIHJlcXVlc3QgQVBJIGNvbXBhdGlibGUgd2l0aCB3aW5kb3cuZmV0Y2hcbiAqXG4gKiBBbGwgc3BlYyBhbGdvcml0aG0gc3RlcCBudW1iZXJzIGFyZSBiYXNlZCBvbiBodHRwczovL2ZldGNoLnNwZWMud2hhdHdnLm9yZy9jb21taXQtc25hcHNob3RzL2FlNzE2ODIyY2IzYTYxODQzMjI2Y2QwOTBlZWZjNjU4OTQ0NmMxZDIvLlxuICovXG5cbmNvbnN0IHN1cHBvcnRlZFNjaGVtYXMgPSBuZXcgU2V0KFsnZGF0YTonLCAnaHR0cDonLCAnaHR0cHM6J10pO1xuXG4vKipcbiAqIEZldGNoIGZ1bmN0aW9uXG4gKlxuICogQHBhcmFtICAge3N0cmluZyB8IFVSTCB8IGltcG9ydCgnLi9yZXF1ZXN0JykuZGVmYXVsdH0gdXJsIC0gQWJzb2x1dGUgdXJsIG9yIFJlcXVlc3QgaW5zdGFuY2VcbiAqIEBwYXJhbSAgIHsqfSBbb3B0aW9uc19dIC0gRmV0Y2ggb3B0aW9uc1xuICogQHJldHVybiAge1Byb21pc2U8aW1wb3J0KCcuL3Jlc3BvbnNlJykuZGVmYXVsdD59XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZldGNoKHVybCwgb3B0aW9uc18pIHtcblx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHQvLyBCdWlsZCByZXF1ZXN0IG9iamVjdFxuXHRcdGNvbnN0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdCh1cmwsIG9wdGlvbnNfKTtcblx0XHRjb25zdCBvcHRpb25zID0gZ2V0Tm9kZVJlcXVlc3RPcHRpb25zKHJlcXVlc3QpO1xuXHRcdGlmICghc3VwcG9ydGVkU2NoZW1hcy5oYXMob3B0aW9ucy5wcm90b2NvbCkpIHtcblx0XHRcdHRocm93IG5ldyBUeXBlRXJyb3IoYG5vZGUtZmV0Y2ggY2Fubm90IGxvYWQgJHt1cmx9LiBVUkwgc2NoZW1lIFwiJHtvcHRpb25zLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpfVwiIGlzIG5vdCBzdXBwb3J0ZWQuYCk7XG5cdFx0fVxuXG5cdFx0aWYgKG9wdGlvbnMucHJvdG9jb2wgPT09ICdkYXRhOicpIHtcblx0XHRcdGNvbnN0IGRhdGEgPSBkYXRhVXJpVG9CdWZmZXIocmVxdWVzdC51cmwpO1xuXHRcdFx0Y29uc3QgcmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UoZGF0YSwge2hlYWRlcnM6IHsnQ29udGVudC1UeXBlJzogZGF0YS50eXBlRnVsbH19KTtcblx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFdyYXAgaHR0cC5yZXF1ZXN0IGludG8gZmV0Y2hcblx0XHRjb25zdCBzZW5kID0gKG9wdGlvbnMucHJvdG9jb2wgPT09ICdodHRwczonID8gaHR0cHMgOiBodHRwKS5yZXF1ZXN0O1xuXHRcdGNvbnN0IHtzaWduYWx9ID0gcmVxdWVzdDtcblx0XHRsZXQgcmVzcG9uc2UgPSBudWxsO1xuXG5cdFx0Y29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdFx0XHRjb25zdCBlcnJvciA9IG5ldyBBYm9ydEVycm9yKCdUaGUgb3BlcmF0aW9uIHdhcyBhYm9ydGVkLicpO1xuXHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdGlmIChyZXF1ZXN0LmJvZHkgJiYgcmVxdWVzdC5ib2R5IGluc3RhbmNlb2YgU3RyZWFtLlJlYWRhYmxlKSB7XG5cdFx0XHRcdHJlcXVlc3QuYm9keS5kZXN0cm95KGVycm9yKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCFyZXNwb25zZSB8fCAhcmVzcG9uc2UuYm9keSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHJlc3BvbnNlLmJvZHkuZW1pdCgnZXJyb3InLCBlcnJvcik7XG5cdFx0fTtcblxuXHRcdGlmIChzaWduYWwgJiYgc2lnbmFsLmFib3J0ZWQpIHtcblx0XHRcdGFib3J0KCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgYWJvcnRBbmRGaW5hbGl6ZSA9ICgpID0+IHtcblx0XHRcdGFib3J0KCk7XG5cdFx0XHRmaW5hbGl6ZSgpO1xuXHRcdH07XG5cblx0XHQvLyBTZW5kIHJlcXVlc3Rcblx0XHRjb25zdCByZXF1ZXN0XyA9IHNlbmQob3B0aW9ucyk7XG5cblx0XHRpZiAoc2lnbmFsKSB7XG5cdFx0XHRzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFuZEZpbmFsaXplKTtcblx0XHR9XG5cblx0XHRjb25zdCBmaW5hbGl6ZSA9ICgpID0+IHtcblx0XHRcdHJlcXVlc3RfLmFib3J0KCk7XG5cdFx0XHRpZiAoc2lnbmFsKSB7XG5cdFx0XHRcdHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0QW5kRmluYWxpemUpO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRyZXF1ZXN0Xy5vbignZXJyb3InLCBlcnIgPT4ge1xuXHRcdFx0cmVqZWN0KG5ldyBGZXRjaEVycm9yKGByZXF1ZXN0IHRvICR7cmVxdWVzdC51cmx9IGZhaWxlZCwgcmVhc29uOiAke2Vyci5tZXNzYWdlfWAsICdzeXN0ZW0nLCBlcnIpKTtcblx0XHRcdGZpbmFsaXplKCk7XG5cdFx0fSk7XG5cblx0XHRyZXF1ZXN0Xy5vbigncmVzcG9uc2UnLCByZXNwb25zZV8gPT4ge1xuXHRcdFx0cmVxdWVzdF8uc2V0VGltZW91dCgwKTtcblx0XHRcdGNvbnN0IGhlYWRlcnMgPSBmcm9tUmF3SGVhZGVycyhyZXNwb25zZV8ucmF3SGVhZGVycyk7XG5cblx0XHRcdC8vIEhUVFAgZmV0Y2ggc3RlcCA1XG5cdFx0XHRpZiAoaXNSZWRpcmVjdChyZXNwb25zZV8uc3RhdHVzQ29kZSkpIHtcblx0XHRcdFx0Ly8gSFRUUCBmZXRjaCBzdGVwIDUuMlxuXHRcdFx0XHRjb25zdCBsb2NhdGlvbiA9IGhlYWRlcnMuZ2V0KCdMb2NhdGlvbicpO1xuXG5cdFx0XHRcdC8vIEhUVFAgZmV0Y2ggc3RlcCA1LjNcblx0XHRcdFx0Y29uc3QgbG9jYXRpb25VUkwgPSBsb2NhdGlvbiA9PT0gbnVsbCA/IG51bGwgOiBuZXcgVVJMKGxvY2F0aW9uLCByZXF1ZXN0LnVybCk7XG5cblx0XHRcdFx0Ly8gSFRUUCBmZXRjaCBzdGVwIDUuNVxuXHRcdFx0XHRzd2l0Y2ggKHJlcXVlc3QucmVkaXJlY3QpIHtcblx0XHRcdFx0XHRjYXNlICdlcnJvcic6XG5cdFx0XHRcdFx0XHRyZWplY3QobmV3IEZldGNoRXJyb3IoYHVyaSByZXF1ZXN0ZWQgcmVzcG9uZHMgd2l0aCBhIHJlZGlyZWN0LCByZWRpcmVjdCBtb2RlIGlzIHNldCB0byBlcnJvcjogJHtyZXF1ZXN0LnVybH1gLCAnbm8tcmVkaXJlY3QnKSk7XG5cdFx0XHRcdFx0XHRmaW5hbGl6ZSgpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdGNhc2UgJ21hbnVhbCc6XG5cdFx0XHRcdFx0XHQvLyBOb2RlLWZldGNoLXNwZWNpZmljIHN0ZXA6IG1ha2UgbWFudWFsIHJlZGlyZWN0IGEgYml0IGVhc2llciB0byB1c2UgYnkgc2V0dGluZyB0aGUgTG9jYXRpb24gaGVhZGVyIHZhbHVlIHRvIHRoZSByZXNvbHZlZCBVUkwuXG5cdFx0XHRcdFx0XHRpZiAobG9jYXRpb25VUkwgIT09IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGNvcnJ1cHRlZCBoZWFkZXJcblx0XHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0XHRoZWFkZXJzLnNldCgnTG9jYXRpb24nLCBsb2NhdGlvblVSTCk7XG5cdFx0XHRcdFx0XHRcdFx0LyogYzggaWdub3JlIG5leHQgMyAqL1xuXHRcdFx0XHRcdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnZm9sbG93Jzoge1xuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDJcblx0XHRcdFx0XHRcdGlmIChsb2NhdGlvblVSTCA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDVcblx0XHRcdFx0XHRcdGlmIChyZXF1ZXN0LmNvdW50ZXIgPj0gcmVxdWVzdC5mb2xsb3cpIHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KG5ldyBGZXRjaEVycm9yKGBtYXhpbXVtIHJlZGlyZWN0IHJlYWNoZWQgYXQ6ICR7cmVxdWVzdC51cmx9YCwgJ21heC1yZWRpcmVjdCcpKTtcblx0XHRcdFx0XHRcdFx0ZmluYWxpemUoKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgNiAoY291bnRlciBpbmNyZW1lbnQpXG5cdFx0XHRcdFx0XHQvLyBDcmVhdGUgYSBuZXcgUmVxdWVzdCBvYmplY3QuXG5cdFx0XHRcdFx0XHRjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcblx0XHRcdFx0XHRcdFx0aGVhZGVyczogbmV3IEhlYWRlcnMocmVxdWVzdC5oZWFkZXJzKSxcblx0XHRcdFx0XHRcdFx0Zm9sbG93OiByZXF1ZXN0LmZvbGxvdyxcblx0XHRcdFx0XHRcdFx0Y291bnRlcjogcmVxdWVzdC5jb3VudGVyICsgMSxcblx0XHRcdFx0XHRcdFx0YWdlbnQ6IHJlcXVlc3QuYWdlbnQsXG5cdFx0XHRcdFx0XHRcdGNvbXByZXNzOiByZXF1ZXN0LmNvbXByZXNzLFxuXHRcdFx0XHRcdFx0XHRtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuXHRcdFx0XHRcdFx0XHRib2R5OiByZXF1ZXN0LmJvZHksXG5cdFx0XHRcdFx0XHRcdHNpZ25hbDogcmVxdWVzdC5zaWduYWwsXG5cdFx0XHRcdFx0XHRcdHNpemU6IHJlcXVlc3Quc2l6ZVxuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDlcblx0XHRcdFx0XHRcdGlmIChyZXNwb25zZV8uc3RhdHVzQ29kZSAhPT0gMzAzICYmIHJlcXVlc3QuYm9keSAmJiBvcHRpb25zXy5ib2R5IGluc3RhbmNlb2YgU3RyZWFtLlJlYWRhYmxlKSB7XG5cdFx0XHRcdFx0XHRcdHJlamVjdChuZXcgRmV0Y2hFcnJvcignQ2Fubm90IGZvbGxvdyByZWRpcmVjdCB3aXRoIGJvZHkgYmVpbmcgYSByZWFkYWJsZSBzdHJlYW0nLCAndW5zdXBwb3J0ZWQtcmVkaXJlY3QnKSk7XG5cdFx0XHRcdFx0XHRcdGZpbmFsaXplKCk7XG5cdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSFRUUC1yZWRpcmVjdCBmZXRjaCBzdGVwIDExXG5cdFx0XHRcdFx0XHRpZiAocmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwMyB8fCAoKHJlc3BvbnNlXy5zdGF0dXNDb2RlID09PSAzMDEgfHwgcmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwMikgJiYgcmVxdWVzdC5tZXRob2QgPT09ICdQT1NUJykpIHtcblx0XHRcdFx0XHRcdFx0cmVxdWVzdE9wdGlvbnMubWV0aG9kID0gJ0dFVCc7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RPcHRpb25zLmJvZHkgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RPcHRpb25zLmhlYWRlcnMuZGVsZXRlKCdjb250ZW50LWxlbmd0aCcpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBIVFRQLXJlZGlyZWN0IGZldGNoIHN0ZXAgMTVcblx0XHRcdFx0XHRcdHJlc29sdmUoZmV0Y2gobmV3IFJlcXVlc3QobG9jYXRpb25VUkwsIHJlcXVlc3RPcHRpb25zKSkpO1xuXHRcdFx0XHRcdFx0ZmluYWxpemUoKTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gRG8gbm90aGluZ1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFByZXBhcmUgcmVzcG9uc2Vcblx0XHRcdHJlc3BvbnNlXy5vbmNlKCdlbmQnLCAoKSA9PiB7XG5cdFx0XHRcdGlmIChzaWduYWwpIHtcblx0XHRcdFx0XHRzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFuZEZpbmFsaXplKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGxldCBib2R5ID0gU3RyZWFtLnBpcGVsaW5lKHJlc3BvbnNlXywgbmV3IFN0cmVhbS5QYXNzVGhyb3VnaCgpLCBlcnJvciA9PiB7XG5cdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHR9KTtcblx0XHRcdC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvcHVsbC8yOTM3NlxuXHRcdFx0aWYgKHByb2Nlc3MudmVyc2lvbiA8ICd2MTIuMTAnKSB7XG5cdFx0XHRcdHJlc3BvbnNlXy5vbignYWJvcnRlZCcsIGFib3J0QW5kRmluYWxpemUpO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCByZXNwb25zZU9wdGlvbnMgPSB7XG5cdFx0XHRcdHVybDogcmVxdWVzdC51cmwsXG5cdFx0XHRcdHN0YXR1czogcmVzcG9uc2VfLnN0YXR1c0NvZGUsXG5cdFx0XHRcdHN0YXR1c1RleHQ6IHJlc3BvbnNlXy5zdGF0dXNNZXNzYWdlLFxuXHRcdFx0XHRoZWFkZXJzLFxuXHRcdFx0XHRzaXplOiByZXF1ZXN0LnNpemUsXG5cdFx0XHRcdGNvdW50ZXI6IHJlcXVlc3QuY291bnRlcixcblx0XHRcdFx0aGlnaFdhdGVyTWFyazogcmVxdWVzdC5oaWdoV2F0ZXJNYXJrXG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBIVFRQLW5ldHdvcmsgZmV0Y2ggc3RlcCAxMi4xLjEuM1xuXHRcdFx0Y29uc3QgY29kaW5ncyA9IGhlYWRlcnMuZ2V0KCdDb250ZW50LUVuY29kaW5nJyk7XG5cblx0XHRcdC8vIEhUVFAtbmV0d29yayBmZXRjaCBzdGVwIDEyLjEuMS40OiBoYW5kbGUgY29udGVudCBjb2RpbmdzXG5cblx0XHRcdC8vIGluIGZvbGxvd2luZyBzY2VuYXJpb3Mgd2UgaWdub3JlIGNvbXByZXNzaW9uIHN1cHBvcnRcblx0XHRcdC8vIDEuIGNvbXByZXNzaW9uIHN1cHBvcnQgaXMgZGlzYWJsZWRcblx0XHRcdC8vIDIuIEhFQUQgcmVxdWVzdFxuXHRcdFx0Ly8gMy4gbm8gQ29udGVudC1FbmNvZGluZyBoZWFkZXJcblx0XHRcdC8vIDQuIG5vIGNvbnRlbnQgcmVzcG9uc2UgKDIwNClcblx0XHRcdC8vIDUuIGNvbnRlbnQgbm90IG1vZGlmaWVkIHJlc3BvbnNlICgzMDQpXG5cdFx0XHRpZiAoIXJlcXVlc3QuY29tcHJlc3MgfHwgcmVxdWVzdC5tZXRob2QgPT09ICdIRUFEJyB8fCBjb2RpbmdzID09PSBudWxsIHx8IHJlc3BvbnNlXy5zdGF0dXNDb2RlID09PSAyMDQgfHwgcmVzcG9uc2VfLnN0YXR1c0NvZGUgPT09IDMwNCkge1xuXHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgTm9kZSB2Nitcblx0XHRcdC8vIEJlIGxlc3Mgc3RyaWN0IHdoZW4gZGVjb2RpbmcgY29tcHJlc3NlZCByZXNwb25zZXMsIHNpbmNlIHNvbWV0aW1lc1xuXHRcdFx0Ly8gc2VydmVycyBzZW5kIHNsaWdodGx5IGludmFsaWQgcmVzcG9uc2VzIHRoYXQgYXJlIHN0aWxsIGFjY2VwdGVkXG5cdFx0XHQvLyBieSBjb21tb24gYnJvd3NlcnMuXG5cdFx0XHQvLyBBbHdheXMgdXNpbmcgWl9TWU5DX0ZMVVNIIGlzIHdoYXQgY1VSTCBkb2VzLlxuXHRcdFx0Y29uc3QgemxpYk9wdGlvbnMgPSB7XG5cdFx0XHRcdGZsdXNoOiB6bGliLlpfU1lOQ19GTFVTSCxcblx0XHRcdFx0ZmluaXNoRmx1c2g6IHpsaWIuWl9TWU5DX0ZMVVNIXG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBGb3IgZ3ppcFxuXHRcdFx0aWYgKGNvZGluZ3MgPT09ICdnemlwJyB8fCBjb2RpbmdzID09PSAneC1nemlwJykge1xuXHRcdFx0XHRib2R5ID0gU3RyZWFtLnBpcGVsaW5lKGJvZHksIHpsaWIuY3JlYXRlR3VuemlwKHpsaWJPcHRpb25zKSwgZXJyb3IgPT4ge1xuXHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgZGVmbGF0ZVxuXHRcdFx0aWYgKGNvZGluZ3MgPT09ICdkZWZsYXRlJyB8fCBjb2RpbmdzID09PSAneC1kZWZsYXRlJykge1xuXHRcdFx0XHQvLyBIYW5kbGUgdGhlIGluZmFtb3VzIHJhdyBkZWZsYXRlIHJlc3BvbnNlIGZyb20gb2xkIHNlcnZlcnNcblx0XHRcdFx0Ly8gYSBoYWNrIGZvciBvbGQgSUlTIGFuZCBBcGFjaGUgc2VydmVyc1xuXHRcdFx0XHRjb25zdCByYXcgPSBTdHJlYW0ucGlwZWxpbmUocmVzcG9uc2VfLCBuZXcgU3RyZWFtLlBhc3NUaHJvdWdoKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmF3Lm9uY2UoJ2RhdGEnLCBjaHVuayA9PiB7XG5cdFx0XHRcdFx0Ly8gU2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzc1MTk4Mjhcblx0XHRcdFx0XHRpZiAoKGNodW5rWzBdICYgMHgwRikgPT09IDB4MDgpIHtcblx0XHRcdFx0XHRcdGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUoYm9keSwgemxpYi5jcmVhdGVJbmZsYXRlKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRcdFx0cmVqZWN0KGVycm9yKTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRib2R5ID0gU3RyZWFtLnBpcGVsaW5lKGJvZHksIHpsaWIuY3JlYXRlSW5mbGF0ZVJhdygpLCBlcnJvciA9PiB7XG5cdFx0XHRcdFx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXNwb25zZSA9IG5ldyBSZXNwb25zZShib2R5LCByZXNwb25zZU9wdGlvbnMpO1xuXHRcdFx0XHRcdHJlc29sdmUocmVzcG9uc2UpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3IgYnJcblx0XHRcdGlmIChjb2RpbmdzID09PSAnYnInKSB7XG5cdFx0XHRcdGJvZHkgPSBTdHJlYW0ucGlwZWxpbmUoYm9keSwgemxpYi5jcmVhdGVCcm90bGlEZWNvbXByZXNzKCksIGVycm9yID0+IHtcblx0XHRcdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0cmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UoYm9keSwgcmVzcG9uc2VPcHRpb25zKTtcblx0XHRcdFx0cmVzb2x2ZShyZXNwb25zZSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3RoZXJ3aXNlLCB1c2UgcmVzcG9uc2UgYXMtaXNcblx0XHRcdHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKGJvZHksIHJlc3BvbnNlT3B0aW9ucyk7XG5cdFx0XHRyZXNvbHZlKHJlc3BvbnNlKTtcblx0XHR9KTtcblxuXHRcdHdyaXRlVG9TdHJlYW0ocmVxdWVzdF8sIHJlcXVlc3QpO1xuXHR9KTtcbn1cblxuZXhwb3J0cy5BYm9ydEVycm9yID0gQWJvcnRFcnJvcjtcbmV4cG9ydHMuRmV0Y2hFcnJvciA9IEZldGNoRXJyb3I7XG5leHBvcnRzLkhlYWRlcnMgPSBIZWFkZXJzO1xuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcbmV4cG9ydHMuUmVzcG9uc2UgPSBSZXNwb25zZTtcbmV4cG9ydHMuZGVmYXVsdCA9IGZldGNoO1xuZXhwb3J0cy5pc1JlZGlyZWN0ID0gaXNSZWRpcmVjdDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmNqcy5tYXBcbiIsIi8qKlxuICogd2ViLXN0cmVhbXMtcG9seWZpbGwgdjMuMS4xXG4gKi9cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5zeW1ib2xcIiAvPlxuY29uc3QgU3ltYm9sUG9seWZpbGwgPSB0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09ICdzeW1ib2wnID9cbiAgICBTeW1ib2wgOlxuICAgIGRlc2NyaXB0aW9uID0+IGBTeW1ib2woJHtkZXNjcmlwdGlvbn0pYDtcblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZG9tXCIgLz5cbmZ1bmN0aW9uIG5vb3AoKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGdldEdsb2JhbHMoKSB7XG4gICAgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gc2VsZjtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdztcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIGdsb2JhbDtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbmNvbnN0IGdsb2JhbHMgPSBnZXRHbG9iYWxzKCk7XG5cbmZ1bmN0aW9uIHR5cGVJc09iamVjdCh4KSB7XG4gICAgcmV0dXJuICh0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCkgfHwgdHlwZW9mIHggPT09ICdmdW5jdGlvbic7XG59XG5jb25zdCByZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24gPSBub29wO1xuXG5jb25zdCBvcmlnaW5hbFByb21pc2UgPSBQcm9taXNlO1xuY29uc3Qgb3JpZ2luYWxQcm9taXNlVGhlbiA9IFByb21pc2UucHJvdG90eXBlLnRoZW47XG5jb25zdCBvcmlnaW5hbFByb21pc2VSZXNvbHZlID0gUHJvbWlzZS5yZXNvbHZlLmJpbmQob3JpZ2luYWxQcm9taXNlKTtcbmNvbnN0IG9yaWdpbmFsUHJvbWlzZVJlamVjdCA9IFByb21pc2UucmVqZWN0LmJpbmQob3JpZ2luYWxQcm9taXNlKTtcbmZ1bmN0aW9uIG5ld1Byb21pc2UoZXhlY3V0b3IpIHtcbiAgICByZXR1cm4gbmV3IG9yaWdpbmFsUHJvbWlzZShleGVjdXRvcik7XG59XG5mdW5jdGlvbiBwcm9taXNlUmVzb2x2ZWRXaXRoKHZhbHVlKSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsUHJvbWlzZVJlc29sdmUodmFsdWUpO1xufVxuZnVuY3Rpb24gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFzb24pIHtcbiAgICByZXR1cm4gb3JpZ2luYWxQcm9taXNlUmVqZWN0KHJlYXNvbik7XG59XG5mdW5jdGlvbiBQZXJmb3JtUHJvbWlzZVRoZW4ocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAvLyBUaGVyZSBkb2Vzbid0IGFwcGVhciB0byBiZSBhbnkgd2F5IHRvIGNvcnJlY3RseSBlbXVsYXRlIHRoZSBiZWhhdmlvdXIgZnJvbSBKYXZhU2NyaXB0LCBzbyB0aGlzIGlzIGp1c3QgYW5cbiAgICAvLyBhcHByb3hpbWF0aW9uLlxuICAgIHJldHVybiBvcmlnaW5hbFByb21pc2VUaGVuLmNhbGwocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpO1xufVxuZnVuY3Rpb24gdXBvblByb21pc2UocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICBQZXJmb3JtUHJvbWlzZVRoZW4oUGVyZm9ybVByb21pc2VUaGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSwgdW5kZWZpbmVkLCByZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24pO1xufVxuZnVuY3Rpb24gdXBvbkZ1bGZpbGxtZW50KHByb21pc2UsIG9uRnVsZmlsbGVkKSB7XG4gICAgdXBvblByb21pc2UocHJvbWlzZSwgb25GdWxmaWxsZWQpO1xufVxuZnVuY3Rpb24gdXBvblJlamVjdGlvbihwcm9taXNlLCBvblJlamVjdGVkKSB7XG4gICAgdXBvblByb21pc2UocHJvbWlzZSwgdW5kZWZpbmVkLCBvblJlamVjdGVkKTtcbn1cbmZ1bmN0aW9uIHRyYW5zZm9ybVByb21pc2VXaXRoKHByb21pc2UsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcikge1xuICAgIHJldHVybiBQZXJmb3JtUHJvbWlzZVRoZW4ocHJvbWlzZSwgZnVsZmlsbG1lbnRIYW5kbGVyLCByZWplY3Rpb25IYW5kbGVyKTtcbn1cbmZ1bmN0aW9uIHNldFByb21pc2VJc0hhbmRsZWRUb1RydWUocHJvbWlzZSkge1xuICAgIFBlcmZvcm1Qcm9taXNlVGhlbihwcm9taXNlLCB1bmRlZmluZWQsIHJldGhyb3dBc3NlcnRpb25FcnJvclJlamVjdGlvbik7XG59XG5jb25zdCBxdWV1ZU1pY3JvdGFzayA9ICgoKSA9PiB7XG4gICAgY29uc3QgZ2xvYmFsUXVldWVNaWNyb3Rhc2sgPSBnbG9iYWxzICYmIGdsb2JhbHMucXVldWVNaWNyb3Rhc2s7XG4gICAgaWYgKHR5cGVvZiBnbG9iYWxRdWV1ZU1pY3JvdGFzayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gZ2xvYmFsUXVldWVNaWNyb3Rhc2s7XG4gICAgfVxuICAgIGNvbnN0IHJlc29sdmVkUHJvbWlzZSA9IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICByZXR1cm4gKGZuKSA9PiBQZXJmb3JtUHJvbWlzZVRoZW4ocmVzb2x2ZWRQcm9taXNlLCBmbik7XG59KSgpO1xuZnVuY3Rpb24gcmVmbGVjdENhbGwoRiwgViwgYXJncykge1xuICAgIGlmICh0eXBlb2YgRiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBpcyBub3QgYSBmdW5jdGlvbicpO1xuICAgIH1cbiAgICByZXR1cm4gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoRiwgViwgYXJncyk7XG59XG5mdW5jdGlvbiBwcm9taXNlQ2FsbChGLCBWLCBhcmdzKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgocmVmbGVjdENhbGwoRiwgViwgYXJncykpO1xuICAgIH1cbiAgICBjYXRjaCAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgodmFsdWUpO1xuICAgIH1cbn1cblxuLy8gT3JpZ2luYWwgZnJvbSBDaHJvbWl1bVxuLy8gaHR0cHM6Ly9jaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYy8rLzBhZWU0NDM0YTRkYmE0MmE0MmFiYWVhOWJmYmMwY2QxOTZhNjNiYzEvdGhpcmRfcGFydHkvYmxpbmsvcmVuZGVyZXIvY29yZS9zdHJlYW1zL1NpbXBsZVF1ZXVlLmpzXG5jb25zdCBRVUVVRV9NQVhfQVJSQVlfU0laRSA9IDE2Mzg0O1xuLyoqXG4gKiBTaW1wbGUgcXVldWUgc3RydWN0dXJlLlxuICpcbiAqIEF2b2lkcyBzY2FsYWJpbGl0eSBpc3N1ZXMgd2l0aCB1c2luZyBhIHBhY2tlZCBhcnJheSBkaXJlY3RseSBieSB1c2luZ1xuICogbXVsdGlwbGUgYXJyYXlzIGluIGEgbGlua2VkIGxpc3QgYW5kIGtlZXBpbmcgdGhlIGFycmF5IHNpemUgYm91bmRlZC5cbiAqL1xuY2xhc3MgU2ltcGxlUXVldWUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLl9jdXJzb3IgPSAwO1xuICAgICAgICB0aGlzLl9zaXplID0gMDtcbiAgICAgICAgLy8gX2Zyb250IGFuZCBfYmFjayBhcmUgYWx3YXlzIGRlZmluZWQuXG4gICAgICAgIHRoaXMuX2Zyb250ID0ge1xuICAgICAgICAgICAgX2VsZW1lbnRzOiBbXSxcbiAgICAgICAgICAgIF9uZXh0OiB1bmRlZmluZWRcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fYmFjayA9IHRoaXMuX2Zyb250O1xuICAgICAgICAvLyBUaGUgY3Vyc29yIGlzIHVzZWQgdG8gYXZvaWQgY2FsbGluZyBBcnJheS5zaGlmdCgpLlxuICAgICAgICAvLyBJdCBjb250YWlucyB0aGUgaW5kZXggb2YgdGhlIGZyb250IGVsZW1lbnQgb2YgdGhlIGFycmF5IGluc2lkZSB0aGVcbiAgICAgICAgLy8gZnJvbnQtbW9zdCBub2RlLiBJdCBpcyBhbHdheXMgaW4gdGhlIHJhbmdlIFswLCBRVUVVRV9NQVhfQVJSQVlfU0laRSkuXG4gICAgICAgIHRoaXMuX2N1cnNvciA9IDA7XG4gICAgICAgIC8vIFdoZW4gdGhlcmUgaXMgb25seSBvbmUgbm9kZSwgc2l6ZSA9PT0gZWxlbWVudHMubGVuZ3RoIC0gY3Vyc29yLlxuICAgICAgICB0aGlzLl9zaXplID0gMDtcbiAgICB9XG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpemU7XG4gICAgfVxuICAgIC8vIEZvciBleGNlcHRpb24gc2FmZXR5LCB0aGlzIG1ldGhvZCBpcyBzdHJ1Y3R1cmVkIGluIG9yZGVyOlxuICAgIC8vIDEuIFJlYWQgc3RhdGVcbiAgICAvLyAyLiBDYWxjdWxhdGUgcmVxdWlyZWQgc3RhdGUgbXV0YXRpb25zXG4gICAgLy8gMy4gUGVyZm9ybSBzdGF0ZSBtdXRhdGlvbnNcbiAgICBwdXNoKGVsZW1lbnQpIHtcbiAgICAgICAgY29uc3Qgb2xkQmFjayA9IHRoaXMuX2JhY2s7XG4gICAgICAgIGxldCBuZXdCYWNrID0gb2xkQmFjaztcbiAgICAgICAgaWYgKG9sZEJhY2suX2VsZW1lbnRzLmxlbmd0aCA9PT0gUVVFVUVfTUFYX0FSUkFZX1NJWkUgLSAxKSB7XG4gICAgICAgICAgICBuZXdCYWNrID0ge1xuICAgICAgICAgICAgICAgIF9lbGVtZW50czogW10sXG4gICAgICAgICAgICAgICAgX25leHQ6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBwdXNoKCkgaXMgdGhlIG11dGF0aW9uIG1vc3QgbGlrZWx5IHRvIHRocm93IGFuIGV4Y2VwdGlvbiwgc28gaXRcbiAgICAgICAgLy8gZ29lcyBmaXJzdC5cbiAgICAgICAgb2xkQmFjay5fZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgICAgaWYgKG5ld0JhY2sgIT09IG9sZEJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuX2JhY2sgPSBuZXdCYWNrO1xuICAgICAgICAgICAgb2xkQmFjay5fbmV4dCA9IG5ld0JhY2s7XG4gICAgICAgIH1cbiAgICAgICAgKyt0aGlzLl9zaXplO1xuICAgIH1cbiAgICAvLyBMaWtlIHB1c2goKSwgc2hpZnQoKSBmb2xsb3dzIHRoZSByZWFkIC0+IGNhbGN1bGF0ZSAtPiBtdXRhdGUgcGF0dGVybiBmb3JcbiAgICAvLyBleGNlcHRpb24gc2FmZXR5LlxuICAgIHNoaWZ0KCkgeyAvLyBtdXN0IG5vdCBiZSBjYWxsZWQgb24gYW4gZW1wdHkgcXVldWVcbiAgICAgICAgY29uc3Qgb2xkRnJvbnQgPSB0aGlzLl9mcm9udDtcbiAgICAgICAgbGV0IG5ld0Zyb250ID0gb2xkRnJvbnQ7XG4gICAgICAgIGNvbnN0IG9sZEN1cnNvciA9IHRoaXMuX2N1cnNvcjtcbiAgICAgICAgbGV0IG5ld0N1cnNvciA9IG9sZEN1cnNvciArIDE7XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gb2xkRnJvbnQuX2VsZW1lbnRzO1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gZWxlbWVudHNbb2xkQ3Vyc29yXTtcbiAgICAgICAgaWYgKG5ld0N1cnNvciA9PT0gUVVFVUVfTUFYX0FSUkFZX1NJWkUpIHtcbiAgICAgICAgICAgIG5ld0Zyb250ID0gb2xkRnJvbnQuX25leHQ7XG4gICAgICAgICAgICBuZXdDdXJzb3IgPSAwO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vIG11dGF0aW9ucyBiZWZvcmUgdGhpcyBwb2ludC5cbiAgICAgICAgLS10aGlzLl9zaXplO1xuICAgICAgICB0aGlzLl9jdXJzb3IgPSBuZXdDdXJzb3I7XG4gICAgICAgIGlmIChvbGRGcm9udCAhPT0gbmV3RnJvbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2Zyb250ID0gbmV3RnJvbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUGVybWl0IHNoaWZ0ZWQgZWxlbWVudCB0byBiZSBnYXJiYWdlIGNvbGxlY3RlZC5cbiAgICAgICAgZWxlbWVudHNbb2xkQ3Vyc29yXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICAgIC8vIFRoZSB0cmlja3kgdGhpbmcgYWJvdXQgZm9yRWFjaCgpIGlzIHRoYXQgaXQgY2FuIGJlIGNhbGxlZFxuICAgIC8vIHJlLWVudHJhbnRseS4gVGhlIHF1ZXVlIG1heSBiZSBtdXRhdGVkIGluc2lkZSB0aGUgY2FsbGJhY2suIEl0IGlzIGVhc3kgdG9cbiAgICAvLyBzZWUgdGhhdCBwdXNoKCkgd2l0aGluIHRoZSBjYWxsYmFjayBoYXMgbm8gbmVnYXRpdmUgZWZmZWN0cyBzaW5jZSB0aGUgZW5kXG4gICAgLy8gb2YgdGhlIHF1ZXVlIGlzIGNoZWNrZWQgZm9yIG9uIGV2ZXJ5IGl0ZXJhdGlvbi4gSWYgc2hpZnQoKSBpcyBjYWxsZWRcbiAgICAvLyByZXBlYXRlZGx5IHdpdGhpbiB0aGUgY2FsbGJhY2sgdGhlbiB0aGUgbmV4dCBpdGVyYXRpb24gbWF5IHJldHVybiBhblxuICAgIC8vIGVsZW1lbnQgdGhhdCBoYXMgYmVlbiByZW1vdmVkLiBJbiB0aGlzIGNhc2UgdGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkXG4gICAgLy8gd2l0aCB1bmRlZmluZWQgdmFsdWVzIHVudGlsIHdlIGVpdGhlciBcImNhdGNoIHVwXCIgd2l0aCBlbGVtZW50cyB0aGF0IHN0aWxsXG4gICAgLy8gZXhpc3Qgb3IgcmVhY2ggdGhlIGJhY2sgb2YgdGhlIHF1ZXVlLlxuICAgIGZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgbGV0IGkgPSB0aGlzLl9jdXJzb3I7XG4gICAgICAgIGxldCBub2RlID0gdGhpcy5fZnJvbnQ7XG4gICAgICAgIGxldCBlbGVtZW50cyA9IG5vZGUuX2VsZW1lbnRzO1xuICAgICAgICB3aGlsZSAoaSAhPT0gZWxlbWVudHMubGVuZ3RoIHx8IG5vZGUuX25leHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKGkgPT09IGVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLl9uZXh0O1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzID0gbm9kZS5fZWxlbWVudHM7XG4gICAgICAgICAgICAgICAgaSA9IDA7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYWxsYmFjayhlbGVtZW50c1tpXSk7XG4gICAgICAgICAgICArK2k7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gUmV0dXJuIHRoZSBlbGVtZW50IHRoYXQgd291bGQgYmUgcmV0dXJuZWQgaWYgc2hpZnQoKSB3YXMgY2FsbGVkIG5vdyxcbiAgICAvLyB3aXRob3V0IG1vZGlmeWluZyB0aGUgcXVldWUuXG4gICAgcGVlaygpIHsgLy8gbXVzdCBub3QgYmUgY2FsbGVkIG9uIGFuIGVtcHR5IHF1ZXVlXG4gICAgICAgIGNvbnN0IGZyb250ID0gdGhpcy5fZnJvbnQ7XG4gICAgICAgIGNvbnN0IGN1cnNvciA9IHRoaXMuX2N1cnNvcjtcbiAgICAgICAgcmV0dXJuIGZyb250Ll9lbGVtZW50c1tjdXJzb3JdO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZShyZWFkZXIsIHN0cmVhbSkge1xuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9IHN0cmVhbTtcbiAgICBzdHJlYW0uX3JlYWRlciA9IHJlYWRlcjtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ3JlYWRhYmxlJykge1xuICAgICAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZChyZWFkZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZChyZWFkZXIsIHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbn1cbi8vIEEgY2xpZW50IG9mIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciBhbmQgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyIG1heSB1c2UgdGhlc2UgZnVuY3Rpb25zIGRpcmVjdGx5IHRvIGJ5cGFzcyBzdGF0ZVxuLy8gY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNDYW5jZWwocmVhZGVyLCByZWFzb24pIHtcbiAgICBjb25zdCBzdHJlYW0gPSByZWFkZXIuX293bmVyUmVhZGFibGVTdHJlYW07XG4gICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKSB7XG4gICAgaWYgKHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbS5fc3RhdGUgPT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCBuZXcgVHlwZUVycm9yKGBSZWFkZXIgd2FzIHJlbGVhc2VkIGFuZCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgdG8gbW9uaXRvciB0aGUgc3RyZWFtJ3MgY2xvc2VkbmVzc2ApKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzZXRUb1JlamVjdGVkKHJlYWRlciwgbmV3IFR5cGVFcnJvcihgUmVhZGVyIHdhcyByZWxlYXNlZCBhbmQgY2FuIG5vIGxvbmdlciBiZSB1c2VkIHRvIG1vbml0b3IgdGhlIHN0cmVhbSdzIGNsb3NlZG5lc3NgKSk7XG4gICAgfVxuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbS5fcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgIHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9IHVuZGVmaW5lZDtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSByZWFkZXJzLlxuZnVuY3Rpb24gcmVhZGVyTG9ja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCAnICsgbmFtZSArICcgYSBzdHJlYW0gdXNpbmcgYSByZWxlYXNlZCByZWFkZXInKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIuXG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKSB7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlID0gbmV3UHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHJlamVjdDtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQocmVhZGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUocmVhZGVyKTtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlamVjdChyZWFkZXIsIHJlYXNvbik7XG59XG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHJlYWRlcikge1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZShyZWFkZXIpO1xuICAgIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzb2x2ZShyZWFkZXIpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCByZWFzb24pIHtcbiAgICBpZiAocmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShyZWFkZXIuX2Nsb3NlZFByb21pc2UpO1xuICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QocmVhc29uKTtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9IHVuZGVmaW5lZDtcbiAgICByZWFkZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQocmVhZGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHJlYWRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVzb2x2ZShyZWFkZXIpIHtcbiAgICBpZiAocmVhZGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlYWRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgcmVhZGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbn1cblxuY29uc3QgQWJvcnRTdGVwcyA9IFN5bWJvbFBvbHlmaWxsKCdbW0Fib3J0U3RlcHNdXScpO1xuY29uc3QgRXJyb3JTdGVwcyA9IFN5bWJvbFBvbHlmaWxsKCdbW0Vycm9yU3RlcHNdXScpO1xuY29uc3QgQ2FuY2VsU3RlcHMgPSBTeW1ib2xQb2x5ZmlsbCgnW1tDYW5jZWxTdGVwc11dJyk7XG5jb25zdCBQdWxsU3RlcHMgPSBTeW1ib2xQb2x5ZmlsbCgnW1tQdWxsU3RlcHNdXScpO1xuXG4vLy8gPHJlZmVyZW5jZSBsaWI9XCJlczIwMTUuY29yZVwiIC8+XG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9OdW1iZXIvaXNGaW5pdGUjUG9seWZpbGxcbmNvbnN0IE51bWJlcklzRmluaXRlID0gTnVtYmVyLmlzRmluaXRlIHx8IGZ1bmN0aW9uICh4KSB7XG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZSh4KTtcbn07XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5jb3JlXCIgLz5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL01hdGgvdHJ1bmMjUG9seWZpbGxcbmNvbnN0IE1hdGhUcnVuYyA9IE1hdGgudHJ1bmMgfHwgZnVuY3Rpb24gKHYpIHtcbiAgICByZXR1cm4gdiA8IDAgPyBNYXRoLmNlaWwodikgOiBNYXRoLmZsb29yKHYpO1xufTtcblxuLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jaWRsLWRpY3Rpb25hcmllc1xuZnVuY3Rpb24gaXNEaWN0aW9uYXJ5KHgpIHtcbiAgICByZXR1cm4gdHlwZW9mIHggPT09ICdvYmplY3QnIHx8IHR5cGVvZiB4ID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gYXNzZXJ0RGljdGlvbmFyeShvYmosIGNvbnRleHQpIHtcbiAgICBpZiAob2JqICE9PSB1bmRlZmluZWQgJiYgIWlzRGljdGlvbmFyeShvYmopKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGFuIG9iamVjdC5gKTtcbiAgICB9XG59XG4vLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNpZGwtY2FsbGJhY2stZnVuY3Rpb25zXG5mdW5jdGlvbiBhc3NlcnRGdW5jdGlvbih4LCBjb250ZXh0KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGEgZnVuY3Rpb24uYCk7XG4gICAgfVxufVxuLy8gaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jaWRsLW9iamVjdFxuZnVuY3Rpb24gaXNPYmplY3QoeCkge1xuICAgIHJldHVybiAodHlwZW9mIHggPT09ICdvYmplY3QnICYmIHggIT09IG51bGwpIHx8IHR5cGVvZiB4ID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gYXNzZXJ0T2JqZWN0KHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGFuIG9iamVjdC5gKTtcbiAgICB9XG59XG5mdW5jdGlvbiBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHgsIHBvc2l0aW9uLCBjb250ZXh0KSB7XG4gICAgaWYgKHggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBQYXJhbWV0ZXIgJHtwb3NpdGlvbn0gaXMgcmVxdWlyZWQgaW4gJyR7Y29udGV4dH0nLmApO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGFzc2VydFJlcXVpcmVkRmllbGQoeCwgZmllbGQsIGNvbnRleHQpIHtcbiAgICBpZiAoeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7ZmllbGR9IGlzIHJlcXVpcmVkIGluICcke2NvbnRleHR9Jy5gKTtcbiAgICB9XG59XG4vLyBodHRwczovL2hleWNhbS5naXRodWIuaW8vd2ViaWRsLyNpZGwtdW5yZXN0cmljdGVkLWRvdWJsZVxuZnVuY3Rpb24gY29udmVydFVucmVzdHJpY3RlZERvdWJsZSh2YWx1ZSkge1xuICAgIHJldHVybiBOdW1iZXIodmFsdWUpO1xufVxuZnVuY3Rpb24gY2Vuc29yTmVnYXRpdmVaZXJvKHgpIHtcbiAgICByZXR1cm4geCA9PT0gMCA/IDAgOiB4O1xufVxuZnVuY3Rpb24gaW50ZWdlclBhcnQoeCkge1xuICAgIHJldHVybiBjZW5zb3JOZWdhdGl2ZVplcm8oTWF0aFRydW5jKHgpKTtcbn1cbi8vIGh0dHBzOi8vaGV5Y2FtLmdpdGh1Yi5pby93ZWJpZGwvI2lkbC11bnNpZ25lZC1sb25nLWxvbmdcbmZ1bmN0aW9uIGNvbnZlcnRVbnNpZ25lZExvbmdMb25nV2l0aEVuZm9yY2VSYW5nZSh2YWx1ZSwgY29udGV4dCkge1xuICAgIGNvbnN0IGxvd2VyQm91bmQgPSAwO1xuICAgIGNvbnN0IHVwcGVyQm91bmQgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbiAgICBsZXQgeCA9IE51bWJlcih2YWx1ZSk7XG4gICAgeCA9IGNlbnNvck5lZ2F0aXZlWmVybyh4KTtcbiAgICBpZiAoIU51bWJlcklzRmluaXRlKHgpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgbm90IGEgZmluaXRlIG51bWJlcmApO1xuICAgIH1cbiAgICB4ID0gaW50ZWdlclBhcnQoeCk7XG4gICAgaWYgKHggPCBsb3dlckJvdW5kIHx8IHggPiB1cHBlckJvdW5kKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gaXMgb3V0c2lkZSB0aGUgYWNjZXB0ZWQgcmFuZ2Ugb2YgJHtsb3dlckJvdW5kfSB0byAke3VwcGVyQm91bmR9LCBpbmNsdXNpdmVgKTtcbiAgICB9XG4gICAgaWYgKCFOdW1iZXJJc0Zpbml0ZSh4KSB8fCB4ID09PSAwKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvLyBUT0RPIFVzZSBCaWdJbnQgaWYgc3VwcG9ydGVkP1xuICAgIC8vIGxldCB4QmlnSW50ID0gQmlnSW50KGludGVnZXJQYXJ0KHgpKTtcbiAgICAvLyB4QmlnSW50ID0gQmlnSW50LmFzVWludE4oNjQsIHhCaWdJbnQpO1xuICAgIC8vIHJldHVybiBOdW1iZXIoeEJpZ0ludCk7XG4gICAgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGFzc2VydFJlYWRhYmxlU3RyZWFtKHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0oeCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYSBSZWFkYWJsZVN0cmVhbS5gKTtcbiAgICB9XG59XG5cbi8vIEFic3RyYWN0IG9wZXJhdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbS5cbmZ1bmN0aW9uIEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKSB7XG4gICAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKTtcbn1cbi8vIFJlYWRhYmxlU3RyZWFtIEFQSSBleHBvc2VkIGZvciBjb250cm9sbGVycy5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtQWRkUmVhZFJlcXVlc3Qoc3RyZWFtLCByZWFkUmVxdWVzdCkge1xuICAgIHN0cmVhbS5fcmVhZGVyLl9yZWFkUmVxdWVzdHMucHVzaChyZWFkUmVxdWVzdCk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUZ1bGZpbGxSZWFkUmVxdWVzdChzdHJlYW0sIGNodW5rLCBkb25lKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgY29uc3QgcmVhZFJlcXVlc3QgPSByZWFkZXIuX3JlYWRSZXF1ZXN0cy5zaGlmdCgpO1xuICAgIGlmIChkb25lKSB7XG4gICAgICAgIHJlYWRSZXF1ZXN0Ll9jbG9zZVN0ZXBzKCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZWFkUmVxdWVzdC5fY2h1bmtTdGVwcyhjaHVuayk7XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSB7XG4gICAgcmV0dXJuIHN0cmVhbS5fcmVhZGVyLl9yZWFkUmVxdWVzdHMubGVuZ3RoO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1IYXNEZWZhdWx0UmVhZGVyKHN0cmVhbSkge1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5fcmVhZGVyO1xuICAgIGlmIChyZWFkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBBIGRlZmF1bHQgcmVhZGVyIHZlbmRlZCBieSBhIHtAbGluayBSZWFkYWJsZVN0cmVhbX0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIge1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHN0cmVhbSwgMSwgJ1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcicpO1xuICAgICAgICBhc3NlcnRSZWFkYWJsZVN0cmVhbShzdHJlYW0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKElzUmVhZGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhpcyBzdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBsb2NrZWQgZm9yIGV4Y2x1c2l2ZSByZWFkaW5nIGJ5IGFub3RoZXIgcmVhZGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZSh0aGlzLCBzdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBzdHJlYW0gYmVjb21lcyBjbG9zZWQsXG4gICAgICogb3IgcmVqZWN0ZWQgaWYgdGhlIHN0cmVhbSBldmVyIGVycm9ycyBvciB0aGUgcmVhZGVyJ3MgbG9jayBpcyByZWxlYXNlZCBiZWZvcmUgdGhlIHN0cmVhbSBmaW5pc2hlcyBjbG9zaW5nLlxuICAgICAqL1xuICAgIGdldCBjbG9zZWQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdjbG9zZWQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb3NlZFByb21pc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSByZWFkZXIgaXMgYWN0aXZlLCBiZWhhdmVzIHRoZSBzYW1lIGFzIHtAbGluayBSZWFkYWJsZVN0cmVhbS5jYW5jZWwgfCBzdHJlYW0uY2FuY2VsKHJlYXNvbil9LlxuICAgICAqL1xuICAgIGNhbmNlbChyZWFzb24gPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2NhbmNlbCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFkZXJMb2NrRXhjZXB0aW9uKCdjYW5jZWwnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbCh0aGlzLCByZWFzb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGFsbG93cyBhY2Nlc3MgdG8gdGhlIG5leHQgY2h1bmsgZnJvbSB0aGUgc3RyZWFtJ3MgaW50ZXJuYWwgcXVldWUsIGlmIGF2YWlsYWJsZS5cbiAgICAgKlxuICAgICAqIElmIHJlYWRpbmcgYSBjaHVuayBjYXVzZXMgdGhlIHF1ZXVlIHRvIGJlY29tZSBlbXB0eSwgbW9yZSBkYXRhIHdpbGwgYmUgcHVsbGVkIGZyb20gdGhlIHVuZGVybHlpbmcgc291cmNlLlxuICAgICAqL1xuICAgIHJlYWQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lclJlYWRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHJlYWRlckxvY2tFeGNlcHRpb24oJ3JlYWQgZnJvbScpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzb2x2ZVByb21pc2U7XG4gICAgICAgIGxldCByZWplY3RQcm9taXNlO1xuICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3UHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgICAgICAgICByZWplY3RQcm9taXNlID0gcmVqZWN0O1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVhZFJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pLFxuICAgICAgICAgICAgX2Nsb3NlU3RlcHM6ICgpID0+IHJlc29sdmVQcm9taXNlKHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9KSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiBlID0+IHJlamVjdFByb21pc2UoZSlcbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZCh0aGlzLCByZWFkUmVxdWVzdCk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlcyB0aGUgcmVhZGVyJ3MgbG9jayBvbiB0aGUgY29ycmVzcG9uZGluZyBzdHJlYW0uIEFmdGVyIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmVhZGVyIGlzIG5vIGxvbmdlciBhY3RpdmUuXG4gICAgICogSWYgdGhlIGFzc29jaWF0ZWQgc3RyZWFtIGlzIGVycm9yZWQgd2hlbiB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJlYWRlciB3aWxsIGFwcGVhciBlcnJvcmVkIGluIHRoZSBzYW1lIHdheVxuICAgICAqIGZyb20gbm93IG9uOyBvdGhlcndpc2UsIHRoZSByZWFkZXIgd2lsbCBhcHBlYXIgY2xvc2VkLlxuICAgICAqXG4gICAgICogQSByZWFkZXIncyBsb2NrIGNhbm5vdCBiZSByZWxlYXNlZCB3aGlsZSBpdCBzdGlsbCBoYXMgYSBwZW5kaW5nIHJlYWQgcmVxdWVzdCwgaS5lLiwgaWYgYSBwcm9taXNlIHJldHVybmVkIGJ5XG4gICAgICogdGhlIHJlYWRlcidzIHtAbGluayBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIucmVhZCB8IHJlYWQoKX0gbWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gc2V0dGxlZC4gQXR0ZW1wdGluZyB0b1xuICAgICAqIGRvIHNvIHdpbGwgdGhyb3cgYSBgVHlwZUVycm9yYCBhbmQgbGVhdmUgdGhlIHJlYWRlciBsb2NrZWQgdG8gdGhlIHN0cmVhbS5cbiAgICAgKi9cbiAgICByZWxlYXNlTG9jaygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdFJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlbGVhc2VMb2NrJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yZWFkUmVxdWVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVHJpZWQgdG8gcmVsZWFzZSBhIHJlYWRlciBsb2NrIHdoZW4gdGhhdCByZWFkZXIgaGFzIHBlbmRpbmcgcmVhZCgpIGNhbGxzIHVuLXNldHRsZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHRoaXMpO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUsIHtcbiAgICBjYW5jZWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlYWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlbGVhc2VMb2NrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBjbG9zZWQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9XG59KTtcbmlmICh0eXBlb2YgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgcmVhZGVycy5cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfcmVhZFJlcXVlc3RzJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4geCBpbnN0YW5jZW9mIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcjtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQocmVhZGVyLCByZWFkUmVxdWVzdCkge1xuICAgIGNvbnN0IHN0cmVhbSA9IHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbTtcbiAgICBzdHJlYW0uX2Rpc3R1cmJlZCA9IHRydWU7XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJlYWRSZXF1ZXN0Ll9jbG9zZVN0ZXBzKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZWFkUmVxdWVzdC5fZXJyb3JTdGVwcyhzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHN0cmVhbS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpO1xuICAgIH1cbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIuXG5mdW5jdGlvbiBkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyYCk7XG59XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxOC5hc3luY2l0ZXJhYmxlXCIgLz5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvbiAqL1xuY29uc3QgQXN5bmNJdGVyYXRvclByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihPYmplY3QuZ2V0UHJvdG90eXBlT2YoYXN5bmMgZnVuY3Rpb24qICgpIHsgfSkucHJvdG90eXBlKTtcblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZXMyMDE4LmFzeW5jaXRlcmFibGVcIiAvPlxuY2xhc3MgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9ySW1wbCB7XG4gICAgY29uc3RydWN0b3IocmVhZGVyLCBwcmV2ZW50Q2FuY2VsKSB7XG4gICAgICAgIHRoaXMuX29uZ29pbmdQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLl9pc0ZpbmlzaGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3JlYWRlciA9IHJlYWRlcjtcbiAgICAgICAgdGhpcy5fcHJldmVudENhbmNlbCA9IHByZXZlbnRDYW5jZWw7XG4gICAgfVxuICAgIG5leHQoKSB7XG4gICAgICAgIGNvbnN0IG5leHRTdGVwcyA9ICgpID0+IHRoaXMuX25leHRTdGVwcygpO1xuICAgICAgICB0aGlzLl9vbmdvaW5nUHJvbWlzZSA9IHRoaXMuX29uZ29pbmdQcm9taXNlID9cbiAgICAgICAgICAgIHRyYW5zZm9ybVByb21pc2VXaXRoKHRoaXMuX29uZ29pbmdQcm9taXNlLCBuZXh0U3RlcHMsIG5leHRTdGVwcykgOlxuICAgICAgICAgICAgbmV4dFN0ZXBzKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9vbmdvaW5nUHJvbWlzZTtcbiAgICB9XG4gICAgcmV0dXJuKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHJldHVyblN0ZXBzID0gKCkgPT4gdGhpcy5fcmV0dXJuU3RlcHModmFsdWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fb25nb2luZ1Byb21pc2UgP1xuICAgICAgICAgICAgdHJhbnNmb3JtUHJvbWlzZVdpdGgodGhpcy5fb25nb2luZ1Byb21pc2UsIHJldHVyblN0ZXBzLCByZXR1cm5TdGVwcykgOlxuICAgICAgICAgICAgcmV0dXJuU3RlcHMoKTtcbiAgICB9XG4gICAgX25leHRTdGVwcygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRlciA9IHRoaXMuX3JlYWRlcjtcbiAgICAgICAgaWYgKHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChyZWFkZXJMb2NrRXhjZXB0aW9uKCdpdGVyYXRlJykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNvbHZlUHJvbWlzZTtcbiAgICAgICAgbGV0IHJlamVjdFByb21pc2U7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgIHJlamVjdFByb21pc2UgPSByZWplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZWFkUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9jaHVua1N0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb25nb2luZ1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBiZSBkZWxheWVkIGJ5IG9uZSBtaWNyb3Rhc2ssIG90aGVyd2lzZSB3ZSBzdG9wIHB1bGxpbmcgdG9vIGVhcmx5IHdoaWNoIGJyZWFrcyBhIHRlc3QuXG4gICAgICAgICAgICAgICAgLy8gRklYTUUgSXMgdGhpcyBhIGJ1ZyBpbiB0aGUgc3BlY2lmaWNhdGlvbiwgb3IgaW4gdGhlIHRlc3Q/XG4gICAgICAgICAgICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfY2xvc2VTdGVwczogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX29uZ29pbmdQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzRmluaXNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlUHJvbWlzZSh7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgX2Vycm9yU3RlcHM6IHJlYXNvbiA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb25nb2luZ1Byb21pc2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNGaW5pc2hlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgICAgIHJlamVjdFByb21pc2UocmVhc29uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZChyZWFkZXIsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuICAgIF9yZXR1cm5TdGVwcyh2YWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5faXNGaW5pc2hlZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHZhbHVlLCBkb25lOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2lzRmluaXNoZWQgPSB0cnVlO1xuICAgICAgICBjb25zdCByZWFkZXIgPSB0aGlzLl9yZWFkZXI7XG4gICAgICAgIGlmIChyZWFkZXIuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbignZmluaXNoIGl0ZXJhdGluZycpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuX3ByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbChyZWFkZXIsIHZhbHVlKTtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY1JlbGVhc2UocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1Qcm9taXNlV2l0aChyZXN1bHQsICgpID0+ICh7IHZhbHVlLCBkb25lOiB0cnVlIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHJlYWRlcik7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHsgdmFsdWUsIGRvbmU6IHRydWUgfSk7XG4gICAgfVxufVxuY29uc3QgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlID0ge1xuICAgIG5leHQoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbUFzeW5jSXRlcmF0b3JCcmFuZENoZWNrRXhjZXB0aW9uKCduZXh0JykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hc3luY0l0ZXJhdG9ySW1wbC5uZXh0KCk7XG4gICAgfSxcbiAgICByZXR1cm4odmFsdWUpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQXN5bmNJdGVyYXRvckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JldHVybicpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYXN5bmNJdGVyYXRvckltcGwucmV0dXJuKHZhbHVlKTtcbiAgICB9XG59O1xuaWYgKEFzeW5jSXRlcmF0b3JQcm90b3R5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JQcm90b3R5cGUsIEFzeW5jSXRlcmF0b3JQcm90b3R5cGUpO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gQWNxdWlyZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcihzdHJlYW0sIHByZXZlbnRDYW5jZWwpIHtcbiAgICBjb25zdCByZWFkZXIgPSBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHN0cmVhbSk7XG4gICAgY29uc3QgaW1wbCA9IG5ldyBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JJbXBsKHJlYWRlciwgcHJldmVudENhbmNlbCk7XG4gICAgY29uc3QgaXRlcmF0b3IgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvclByb3RvdHlwZSk7XG4gICAgaXRlcmF0b3IuX2FzeW5jSXRlcmF0b3JJbXBsID0gaW1wbDtcbiAgICByZXR1cm4gaXRlcmF0b3I7XG59XG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2FzeW5jSXRlcmF0b3JJbXBsJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyBub2luc3BlY3Rpb24gU3VzcGljaW91c1R5cGVPZkd1YXJkXG4gICAgICAgIHJldHVybiB4Ll9hc3luY0l0ZXJhdG9ySW1wbCBpbnN0YW5jZW9mXG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3JJbXBsO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZVN0cmVhbS5cbmZ1bmN0aW9uIHN0cmVhbUFzeW5jSXRlcmF0b3JCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RlYW1Bc3luY0l0ZXJhdG9yYCk7XG59XG5cbi8vLyA8cmVmZXJlbmNlIGxpYj1cImVzMjAxNS5jb3JlXCIgLz5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL051bWJlci9pc05hTiNQb2x5ZmlsbFxuY29uc3QgTnVtYmVySXNOYU4gPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gKHgpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgcmV0dXJuIHggIT09IHg7XG59O1xuXG5mdW5jdGlvbiBDcmVhdGVBcnJheUZyb21MaXN0KGVsZW1lbnRzKSB7XG4gICAgLy8gV2UgdXNlIGFycmF5cyB0byByZXByZXNlbnQgbGlzdHMsIHNvIHRoaXMgaXMgYmFzaWNhbGx5IGEgbm8tb3AuXG4gICAgLy8gRG8gYSBzbGljZSB0aG91Z2gganVzdCBpbiBjYXNlIHdlIGhhcHBlbiB0byBkZXBlbmQgb24gdGhlIHVuaXF1ZS1uZXNzLlxuICAgIHJldHVybiBlbGVtZW50cy5zbGljZSgpO1xufVxuZnVuY3Rpb24gQ29weURhdGFCbG9ja0J5dGVzKGRlc3QsIGRlc3RPZmZzZXQsIHNyYywgc3JjT2Zmc2V0LCBuKSB7XG4gICAgbmV3IFVpbnQ4QXJyYXkoZGVzdCkuc2V0KG5ldyBVaW50OEFycmF5KHNyYywgc3JjT2Zmc2V0LCBuKSwgZGVzdE9mZnNldCk7XG59XG4vLyBOb3QgaW1wbGVtZW50ZWQgY29ycmVjdGx5XG5mdW5jdGlvbiBUcmFuc2ZlckFycmF5QnVmZmVyKE8pIHtcbiAgICByZXR1cm4gTztcbn1cbi8vIE5vdCBpbXBsZW1lbnRlZCBjb3JyZWN0bHlcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbmZ1bmN0aW9uIElzRGV0YWNoZWRCdWZmZXIoTykge1xuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIEFycmF5QnVmZmVyU2xpY2UoYnVmZmVyLCBiZWdpbiwgZW5kKSB7XG4gICAgLy8gQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBhdmFpbGFibGUgb24gSUUxMFxuICAgIC8vIGh0dHBzOi8vd3d3LmNhbml1c2UuY29tL21kbi1qYXZhc2NyaXB0X2J1aWx0aW5zX2FycmF5YnVmZmVyX3NsaWNlXG4gICAgaWYgKGJ1ZmZlci5zbGljZSkge1xuICAgICAgICByZXR1cm4gYnVmZmVyLnNsaWNlKGJlZ2luLCBlbmQpO1xuICAgIH1cbiAgICBjb25zdCBsZW5ndGggPSBlbmQgLSBiZWdpbjtcbiAgICBjb25zdCBzbGljZSA9IG5ldyBBcnJheUJ1ZmZlcihsZW5ndGgpO1xuICAgIENvcHlEYXRhQmxvY2tCeXRlcyhzbGljZSwgMCwgYnVmZmVyLCBiZWdpbiwgbGVuZ3RoKTtcbiAgICByZXR1cm4gc2xpY2U7XG59XG5cbmZ1bmN0aW9uIElzTm9uTmVnYXRpdmVOdW1iZXIodikge1xuICAgIGlmICh0eXBlb2YgdiAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoTnVtYmVySXNOYU4odikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodiA8IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIENsb25lQXNVaW50OEFycmF5KE8pIHtcbiAgICBjb25zdCBidWZmZXIgPSBBcnJheUJ1ZmZlclNsaWNlKE8uYnVmZmVyLCBPLmJ5dGVPZmZzZXQsIE8uYnl0ZU9mZnNldCArIE8uYnl0ZUxlbmd0aCk7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG59XG5cbmZ1bmN0aW9uIERlcXVldWVWYWx1ZShjb250YWluZXIpIHtcbiAgICBjb25zdCBwYWlyID0gY29udGFpbmVyLl9xdWV1ZS5zaGlmdCgpO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgLT0gcGFpci5zaXplO1xuICAgIGlmIChjb250YWluZXIuX3F1ZXVlVG90YWxTaXplIDwgMCkge1xuICAgICAgICBjb250YWluZXIuX3F1ZXVlVG90YWxTaXplID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHBhaXIudmFsdWU7XG59XG5mdW5jdGlvbiBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250YWluZXIsIHZhbHVlLCBzaXplKSB7XG4gICAgaWYgKCFJc05vbk5lZ2F0aXZlTnVtYmVyKHNpemUpIHx8IHNpemUgPT09IEluZmluaXR5KSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdTaXplIG11c3QgYmUgYSBmaW5pdGUsIG5vbi1OYU4sIG5vbi1uZWdhdGl2ZSBudW1iZXIuJyk7XG4gICAgfVxuICAgIGNvbnRhaW5lci5fcXVldWUucHVzaCh7IHZhbHVlLCBzaXplIH0pO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgKz0gc2l6ZTtcbn1cbmZ1bmN0aW9uIFBlZWtRdWV1ZVZhbHVlKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IHBhaXIgPSBjb250YWluZXIuX3F1ZXVlLnBlZWsoKTtcbiAgICByZXR1cm4gcGFpci52YWx1ZTtcbn1cbmZ1bmN0aW9uIFJlc2V0UXVldWUoY29udGFpbmVyKSB7XG4gICAgY29udGFpbmVyLl9xdWV1ZSA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIGNvbnRhaW5lci5fcXVldWVUb3RhbFNpemUgPSAwO1xufVxuXG4vKipcbiAqIEEgcHVsbC1pbnRvIHJlcXVlc3QgaW4gYSB7QGxpbmsgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcn0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2aWV3IGZvciB3cml0aW5nIGluIHRvLCBvciBgbnVsbGAgaWYgdGhlIEJZT0IgcmVxdWVzdCBoYXMgYWxyZWFkeSBiZWVuIHJlc3BvbmRlZCB0by5cbiAgICAgKi9cbiAgICBnZXQgdmlldygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbigndmlldycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl92aWV3O1xuICAgIH1cbiAgICByZXNwb25kKGJ5dGVzV3JpdHRlbikge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uKCdyZXNwb25kJyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChieXRlc1dyaXR0ZW4sIDEsICdyZXNwb25kJyk7XG4gICAgICAgIGJ5dGVzV3JpdHRlbiA9IGNvbnZlcnRVbnNpZ25lZExvbmdMb25nV2l0aEVuZm9yY2VSYW5nZShieXRlc1dyaXR0ZW4sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoaXMgQllPQiByZXF1ZXN0IGhhcyBiZWVuIGludmFsaWRhdGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIodGhpcy5fdmlldy5idWZmZXIpKSA7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLCBieXRlc1dyaXR0ZW4pO1xuICAgIH1cbiAgICByZXNwb25kV2l0aE5ld1ZpZXcodmlldykge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uKCdyZXNwb25kV2l0aE5ld1ZpZXcnKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHZpZXcsIDEsICdyZXNwb25kV2l0aE5ld1ZpZXcnKTtcbiAgICAgICAgaWYgKCFBcnJheUJ1ZmZlci5pc1ZpZXcodmlldykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1lvdSBjYW4gb25seSByZXNwb25kIHdpdGggYXJyYXkgYnVmZmVyIHZpZXdzJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoaXMgQllPQiByZXF1ZXN0IGhhcyBiZWVuIGludmFsaWRhdGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIodmlldy5idWZmZXIpKSA7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcodGhpcy5fYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIsIHZpZXcpO1xuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlLCB7XG4gICAgcmVzcG9uZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcmVzcG9uZFdpdGhOZXdWaWV3OiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB2aWV3OiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vKipcbiAqIEFsbG93cyBjb250cm9sIG9mIGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtIHwgcmVhZGFibGUgYnl0ZSBzdHJlYW19J3Mgc3RhdGUgYW5kIGludGVybmFsIHF1ZXVlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0lsbGVnYWwgY29uc3RydWN0b3InKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCBCWU9CIHB1bGwgcmVxdWVzdCwgb3IgYG51bGxgIGlmIHRoZXJlIGlzbid0IG9uZS5cbiAgICAgKi9cbiAgICBnZXQgYnlvYlJlcXVlc3QoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlU3RyZWFtQ29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2J5b2JSZXF1ZXN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIGNvbnRyb2xsZWQgc3RyZWFtJ3MgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzXG4gICAgICogb3Zlci1mdWxsLiBBbiB1bmRlcmx5aW5nIGJ5dGUgc291cmNlIG91Z2h0IHRvIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSB3aGVuIGFuZCBob3cgdG8gYXBwbHkgYmFja3ByZXNzdXJlLlxuICAgICAqL1xuICAgIGdldCBkZXNpcmVkU2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVTdHJlYW1Db250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbignZGVzaXJlZFNpemUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldERlc2lyZWRTaXplKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIGNvbnRyb2xsZWQgcmVhZGFibGUgc3RyZWFtLiBDb25zdW1lcnMgd2lsbCBzdGlsbCBiZSBhYmxlIHRvIHJlYWQgYW55IHByZXZpb3VzbHktZW5xdWV1ZWQgY2h1bmtzIGZyb21cbiAgICAgKiB0aGUgc3RyZWFtLCBidXQgb25jZSB0aG9zZSBhcmUgcmVhZCwgdGhlIHN0cmVhbSB3aWxsIGJlY29tZSBjbG9zZWQuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBieXRlU3RyZWFtQ29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2Nsb3NlUmVxdWVzdGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkOyBkbyBub3QgY2xvc2UgaXQgYWdhaW4hJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICAgICAgaWYgKHN0YXRlICE9PSAncmVhZGFibGUnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgc3RyZWFtIChpbiAke3N0YXRlfSBzdGF0ZSkgaXMgbm90IGluIHRoZSByZWFkYWJsZSBzdGF0ZSBhbmQgY2Fubm90IGJlIGNsb3NlZGApO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuaykge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlbnF1ZXVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChjaHVuaywgMSwgJ2VucXVldWUnKTtcbiAgICAgICAgaWYgKCFBcnJheUJ1ZmZlci5pc1ZpZXcoY2h1bmspKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdjaHVuayBtdXN0IGJlIGFuIGFycmF5IGJ1ZmZlciB2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NodW5rIG11c3QgaGF2ZSBub24temVybyBieXRlTGVuZ3RoJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNodW5rLmJ1ZmZlci5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBjaHVuaydzIGJ1ZmZlciBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aGApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9jbG9zZVJlcXVlc3RlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc3RyZWFtIGlzIGNsb3NlZCBvciBkcmFpbmluZycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbS5fc3RhdGU7XG4gICAgICAgIGlmIChzdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHN0cmVhbSAoaW4gJHtzdGF0ZX0gc3RhdGUpIGlzIG5vdCBpbiB0aGUgcmVhZGFibGUgc3RhdGUgYW5kIGNhbm5vdCBiZSBlbnF1ZXVlZCB0b2ApO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlKHRoaXMsIGNodW5rKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRXJyb3JzIHRoZSBjb250cm9sbGVkIHJlYWRhYmxlIHN0cmVhbSwgbWFraW5nIGFsbCBmdXR1cmUgaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuXG4gICAgICovXG4gICAgZXJyb3IoZSA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcih0aGlzLCBlKTtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtDYW5jZWxTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhclBlbmRpbmdQdWxsSW50b3ModGhpcyk7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NhbmNlbEFsZ29yaXRobShyZWFzb24pO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKHRoaXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKiogQGludGVybmFsICovXG4gICAgW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpIHtcbiAgICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICAgICAgaWYgKHRoaXMuX3F1ZXVlVG90YWxTaXplID4gMCkge1xuICAgICAgICAgICAgY29uc3QgZW50cnkgPSB0aGlzLl9xdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgdGhpcy5fcXVldWVUb3RhbFNpemUgLT0gZW50cnkuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJIYW5kbGVRdWV1ZURyYWluKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KGVudHJ5LmJ1ZmZlciwgZW50cnkuYnl0ZU9mZnNldCwgZW50cnkuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICByZWFkUmVxdWVzdC5fY2h1bmtTdGVwcyh2aWV3KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhdXRvQWxsb2NhdGVDaHVua1NpemUgPSB0aGlzLl9hdXRvQWxsb2NhdGVDaHVua1NpemU7XG4gICAgICAgIGlmIChhdXRvQWxsb2NhdGVDaHVua1NpemUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbGV0IGJ1ZmZlcjtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoYnVmZmVyRSkge1xuICAgICAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9lcnJvclN0ZXBzKGJ1ZmZlckUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHB1bGxJbnRvRGVzY3JpcHRvciA9IHtcbiAgICAgICAgICAgICAgICBidWZmZXIsXG4gICAgICAgICAgICAgICAgYnVmZmVyQnl0ZUxlbmd0aDogYXV0b0FsbG9jYXRlQ2h1bmtTaXplLFxuICAgICAgICAgICAgICAgIGJ5dGVPZmZzZXQ6IDAsXG4gICAgICAgICAgICAgICAgYnl0ZUxlbmd0aDogYXV0b0FsbG9jYXRlQ2h1bmtTaXplLFxuICAgICAgICAgICAgICAgIGJ5dGVzRmlsbGVkOiAwLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRTaXplOiAxLFxuICAgICAgICAgICAgICAgIHZpZXdDb25zdHJ1Y3RvcjogVWludDhBcnJheSxcbiAgICAgICAgICAgICAgICByZWFkZXJUeXBlOiAnZGVmYXVsdCdcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9wZW5kaW5nUHVsbEludG9zLnB1c2gocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbUFkZFJlYWRSZXF1ZXN0KHN0cmVhbSwgcmVhZFJlcXVlc3QpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSwge1xuICAgIGNsb3NlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlbnF1ZXVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgYnlvYlJlcXVlc3Q6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGRlc2lyZWRTaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5cbmZ1bmN0aW9uIElzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdCh4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyJykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4geCBpbnN0YW5jZW9mIFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3Q7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc2hvdWxkUHVsbCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKTtcbiAgICBpZiAoIXNob3VsZFB1bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcHVsbGluZykge1xuICAgICAgICBjb250cm9sbGVyLl9wdWxsQWdhaW4gPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSB0cnVlO1xuICAgIC8vIFRPRE86IFRlc3QgY29udHJvbGxlciBhcmd1bWVudFxuICAgIGNvbnN0IHB1bGxQcm9taXNlID0gY29udHJvbGxlci5fcHVsbEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHB1bGxQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIuX3B1bGxBZ2Fpbikge1xuICAgICAgICAgICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gZmFsc2U7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICAgICAgfVxuICAgIH0sIGUgPT4ge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSk7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJQZW5kaW5nUHVsbEludG9zKGNvbnRyb2xsZXIpIHtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySW52YWxpZGF0ZUJZT0JSZXF1ZXN0KGNvbnRyb2xsZXIpO1xuICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MgPSBuZXcgU2ltcGxlUXVldWUoKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb21taXRQdWxsSW50b0Rlc2NyaXB0b3Ioc3RyZWFtLCBwdWxsSW50b0Rlc2NyaXB0b3IpIHtcbiAgICBsZXQgZG9uZSA9IGZhbHNlO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZmlsbGVkVmlldyA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb252ZXJ0UHVsbEludG9EZXNjcmlwdG9yKHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgaWYgKHB1bGxJbnRvRGVzY3JpcHRvci5yZWFkZXJUeXBlID09PSAnZGVmYXVsdCcpIHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3Qoc3RyZWFtLCBmaWxsZWRWaWV3LCBkb25lKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIGZpbGxlZFZpZXcsIGRvbmUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb252ZXJ0UHVsbEludG9EZXNjcmlwdG9yKHB1bGxJbnRvRGVzY3JpcHRvcikge1xuICAgIGNvbnN0IGJ5dGVzRmlsbGVkID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkO1xuICAgIGNvbnN0IGVsZW1lbnRTaXplID0gcHVsbEludG9EZXNjcmlwdG9yLmVsZW1lbnRTaXplO1xuICAgIHJldHVybiBuZXcgcHVsbEludG9EZXNjcmlwdG9yLnZpZXdDb25zdHJ1Y3RvcihwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZU9mZnNldCwgYnl0ZXNGaWxsZWQgLyBlbGVtZW50U2l6ZSk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCBidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpIHtcbiAgICBjb250cm9sbGVyLl9xdWV1ZS5wdXNoKHsgYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoIH0pO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplICs9IGJ5dGVMZW5ndGg7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpIHtcbiAgICBjb25zdCBlbGVtZW50U2l6ZSA9IHB1bGxJbnRvRGVzY3JpcHRvci5lbGVtZW50U2l6ZTtcbiAgICBjb25zdCBjdXJyZW50QWxpZ25lZEJ5dGVzID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkIC0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICUgZWxlbWVudFNpemU7XG4gICAgY29uc3QgbWF4Qnl0ZXNUb0NvcHkgPSBNYXRoLm1pbihjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSwgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVMZW5ndGggLSBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQpO1xuICAgIGNvbnN0IG1heEJ5dGVzRmlsbGVkID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICsgbWF4Qnl0ZXNUb0NvcHk7XG4gICAgY29uc3QgbWF4QWxpZ25lZEJ5dGVzID0gbWF4Qnl0ZXNGaWxsZWQgLSBtYXhCeXRlc0ZpbGxlZCAlIGVsZW1lbnRTaXplO1xuICAgIGxldCB0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nID0gbWF4Qnl0ZXNUb0NvcHk7XG4gICAgbGV0IHJlYWR5ID0gZmFsc2U7XG4gICAgaWYgKG1heEFsaWduZWRCeXRlcyA+IGN1cnJlbnRBbGlnbmVkQnl0ZXMpIHtcbiAgICAgICAgdG90YWxCeXRlc1RvQ29weVJlbWFpbmluZyA9IG1heEFsaWduZWRCeXRlcyAtIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZDtcbiAgICAgICAgcmVhZHkgPSB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBxdWV1ZSA9IGNvbnRyb2xsZXIuX3F1ZXVlO1xuICAgIHdoaWxlICh0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nID4gMCkge1xuICAgICAgICBjb25zdCBoZWFkT2ZRdWV1ZSA9IHF1ZXVlLnBlZWsoKTtcbiAgICAgICAgY29uc3QgYnl0ZXNUb0NvcHkgPSBNYXRoLm1pbih0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nLCBoZWFkT2ZRdWV1ZS5ieXRlTGVuZ3RoKTtcbiAgICAgICAgY29uc3QgZGVzdFN0YXJ0ID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVPZmZzZXQgKyBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZXNGaWxsZWQ7XG4gICAgICAgIENvcHlEYXRhQmxvY2tCeXRlcyhwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBkZXN0U3RhcnQsIGhlYWRPZlF1ZXVlLmJ1ZmZlciwgaGVhZE9mUXVldWUuYnl0ZU9mZnNldCwgYnl0ZXNUb0NvcHkpO1xuICAgICAgICBpZiAoaGVhZE9mUXVldWUuYnl0ZUxlbmd0aCA9PT0gYnl0ZXNUb0NvcHkpIHtcbiAgICAgICAgICAgIHF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBoZWFkT2ZRdWV1ZS5ieXRlT2Zmc2V0ICs9IGJ5dGVzVG9Db3B5O1xuICAgICAgICAgICAgaGVhZE9mUXVldWUuYnl0ZUxlbmd0aCAtPSBieXRlc1RvQ29weTtcbiAgICAgICAgfVxuICAgICAgICBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSAtPSBieXRlc1RvQ29weTtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxIZWFkUHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIsIGJ5dGVzVG9Db3B5LCBwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgICAgICB0b3RhbEJ5dGVzVG9Db3B5UmVtYWluaW5nIC09IGJ5dGVzVG9Db3B5O1xuICAgIH1cbiAgICByZXR1cm4gcmVhZHk7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbEhlYWRQdWxsSW50b0Rlc2NyaXB0b3IoY29udHJvbGxlciwgc2l6ZSwgcHVsbEludG9EZXNjcmlwdG9yKSB7XG4gICAgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICs9IHNpemU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbihjb250cm9sbGVyKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID09PSAwICYmIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQ2xvc2UoY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySW52YWxpZGF0ZUJZT0JSZXF1ZXN0KGNvbnRyb2xsZXIpIHtcbiAgICBpZiAoY29udHJvbGxlci5fYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb250cm9sbGVyLl9ieW9iUmVxdWVzdC5fYXNzb2NpYXRlZFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIgPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYnlvYlJlcXVlc3QuX3ZpZXcgPSBudWxsO1xuICAgIGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID0gbnVsbDtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJQcm9jZXNzUHVsbEludG9EZXNjcmlwdG9yc1VzaW5nUXVldWUoY29udHJvbGxlcikge1xuICAgIHdoaWxlIChjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaWYgKGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHVsbEludG9EZXNjcmlwdG9yID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgICAgIGlmIChSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpKSB7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8oY29udHJvbGxlcik7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ29tbWl0UHVsbEludG9EZXNjcmlwdG9yKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8oY29udHJvbGxlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBsZXQgZWxlbWVudFNpemUgPSAxO1xuICAgIGlmICh2aWV3LmNvbnN0cnVjdG9yICE9PSBEYXRhVmlldykge1xuICAgICAgICBlbGVtZW50U2l6ZSA9IHZpZXcuY29uc3RydWN0b3IuQllURVNfUEVSX0VMRU1FTlQ7XG4gICAgfVxuICAgIGNvbnN0IGN0b3IgPSB2aWV3LmNvbnN0cnVjdG9yO1xuICAgIC8vIHRyeSB7XG4gICAgY29uc3QgYnVmZmVyID0gVHJhbnNmZXJBcnJheUJ1ZmZlcih2aWV3LmJ1ZmZlcik7XG4gICAgLy8gfSBjYXRjaCAoZSkge1xuICAgIC8vICAgcmVhZEludG9SZXF1ZXN0Ll9lcnJvclN0ZXBzKGUpO1xuICAgIC8vICAgcmV0dXJuO1xuICAgIC8vIH1cbiAgICBjb25zdCBwdWxsSW50b0Rlc2NyaXB0b3IgPSB7XG4gICAgICAgIGJ1ZmZlcixcbiAgICAgICAgYnVmZmVyQnl0ZUxlbmd0aDogYnVmZmVyLmJ5dGVMZW5ndGgsXG4gICAgICAgIGJ5dGVPZmZzZXQ6IHZpZXcuYnl0ZU9mZnNldCxcbiAgICAgICAgYnl0ZUxlbmd0aDogdmlldy5ieXRlTGVuZ3RoLFxuICAgICAgICBieXRlc0ZpbGxlZDogMCxcbiAgICAgICAgZWxlbWVudFNpemUsXG4gICAgICAgIHZpZXdDb25zdHJ1Y3RvcjogY3RvcixcbiAgICAgICAgcmVhZGVyVHlwZTogJ2J5b2InXG4gICAgfTtcbiAgICBpZiAoY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucHVzaChwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgICAgICAvLyBObyBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCgpIGNhbGwgc2luY2U6XG4gICAgICAgIC8vIC0gTm8gY2hhbmdlIGhhcHBlbnMgb24gZGVzaXJlZFNpemVcbiAgICAgICAgLy8gLSBUaGUgc291cmNlIGhhcyBhbHJlYWR5IGJlZW4gbm90aWZpZWQgb2YgdGhhdCB0aGVyZSdzIGF0IGxlYXN0IDEgcGVuZGluZyByZWFkKHZpZXcpXG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQWRkUmVhZEludG9SZXF1ZXN0KHN0cmVhbSwgcmVhZEludG9SZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgY29uc3QgZW1wdHlWaWV3ID0gbmV3IGN0b3IocHVsbEludG9EZXNjcmlwdG9yLmJ1ZmZlciwgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVPZmZzZXQsIDApO1xuICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Nsb3NlU3RlcHMoZW1wdHlWaWV3KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWVUb3RhbFNpemUgPiAwKSB7XG4gICAgICAgIGlmIChSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRmlsbFB1bGxJbnRvRGVzY3JpcHRvckZyb21RdWV1ZShjb250cm9sbGVyLCBwdWxsSW50b0Rlc2NyaXB0b3IpKSB7XG4gICAgICAgICAgICBjb25zdCBmaWxsZWRWaWV3ID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbnZlcnRQdWxsSW50b0Rlc2NyaXB0b3IocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJIYW5kbGVRdWV1ZURyYWluKGNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgcmVhZEludG9SZXF1ZXN0Ll9jaHVua1N0ZXBzKGZpbGxlZFZpZXcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCkge1xuICAgICAgICAgICAgY29uc3QgZSA9IG5ldyBUeXBlRXJyb3IoJ0luc3VmZmljaWVudCBieXRlcyB0byBmaWxsIGVsZW1lbnRzIGluIHRoZSBnaXZlbiBidWZmZXInKTtcbiAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKTtcbiAgICAgICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fZXJyb3JTdGVwcyhlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnB1c2gocHVsbEludG9EZXNjcmlwdG9yKTtcbiAgICBSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluQ2xvc2VkU3RhdGUoY29udHJvbGxlciwgZmlyc3REZXNjcmlwdG9yKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoUmVhZGFibGVTdHJlYW1IYXNCWU9CUmVhZGVyKHN0cmVhbSkpIHtcbiAgICAgICAgd2hpbGUgKFJlYWRhYmxlU3RyZWFtR2V0TnVtUmVhZEludG9SZXF1ZXN0cyhzdHJlYW0pID4gMCkge1xuICAgICAgICAgICAgY29uc3QgcHVsbEludG9EZXNjcmlwdG9yID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclNoaWZ0UGVuZGluZ1B1bGxJbnRvKGNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbW1pdFB1bGxJbnRvRGVzY3JpcHRvcihzdHJlYW0sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluUmVhZGFibGVTdGF0ZShjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4sIHB1bGxJbnRvRGVzY3JpcHRvcikge1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsSGVhZFB1bGxJbnRvRGVzY3JpcHRvcihjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4sIHB1bGxJbnRvRGVzY3JpcHRvcik7XG4gICAgaWYgKHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZCA8IHB1bGxJbnRvRGVzY3JpcHRvci5lbGVtZW50U2l6ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaGlmdFBlbmRpbmdQdWxsSW50byhjb250cm9sbGVyKTtcbiAgICBjb25zdCByZW1haW5kZXJTaXplID0gcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkICUgcHVsbEludG9EZXNjcmlwdG9yLmVsZW1lbnRTaXplO1xuICAgIGlmIChyZW1haW5kZXJTaXplID4gMCkge1xuICAgICAgICBjb25zdCBlbmQgPSBwdWxsSW50b0Rlc2NyaXB0b3IuYnl0ZU9mZnNldCArIHB1bGxJbnRvRGVzY3JpcHRvci5ieXRlc0ZpbGxlZDtcbiAgICAgICAgY29uc3QgcmVtYWluZGVyID0gQXJyYXlCdWZmZXJTbGljZShwdWxsSW50b0Rlc2NyaXB0b3IuYnVmZmVyLCBlbmQgLSByZW1haW5kZXJTaXplLCBlbmQpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCByZW1haW5kZXIsIDAsIHJlbWFpbmRlci5ieXRlTGVuZ3RoKTtcbiAgICB9XG4gICAgcHVsbEludG9EZXNjcmlwdG9yLmJ5dGVzRmlsbGVkIC09IHJlbWFpbmRlclNpemU7XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbW1pdFB1bGxJbnRvRGVzY3JpcHRvcihjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLCBwdWxsSW50b0Rlc2NyaXB0b3IpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJQcm9jZXNzUHVsbEludG9EZXNjcmlwdG9yc1VzaW5nUXVldWUoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEludGVybmFsKGNvbnRyb2xsZXIsIGJ5dGVzV3JpdHRlbikge1xuICAgIGNvbnN0IGZpcnN0RGVzY3JpcHRvciA9IGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucGVlaygpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJJbnZhbGlkYXRlQllPQlJlcXVlc3QoY29udHJvbGxlcik7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5DbG9zZWRTdGF0ZShjb250cm9sbGVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5SZWFkYWJsZVN0YXRlKGNvbnRyb2xsZXIsIGJ5dGVzV3JpdHRlbiwgZmlyc3REZXNjcmlwdG9yKTtcbiAgICB9XG4gICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNhbGxQdWxsSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hpZnRQZW5kaW5nUHVsbEludG8oY29udHJvbGxlcikge1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnNoaWZ0KCk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyU2hvdWxkQ2FsbFB1bGwoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fY2xvc2VSZXF1ZXN0ZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIWNvbnRyb2xsZXIuX3N0YXJ0ZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoUmVhZGFibGVTdHJlYW1IYXNEZWZhdWx0UmVhZGVyKHN0cmVhbSkgJiYgUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChSZWFkYWJsZVN0cmVhbUhhc0JZT0JSZWFkZXIoc3RyZWFtKSAmJiBSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRJbnRvUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGRlc2lyZWRTaXplID0gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldERlc2lyZWRTaXplKGNvbnRyb2xsZXIpO1xuICAgIGlmIChkZXNpcmVkU2l6ZSA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcikge1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fY2FuY2VsQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuLy8gQSBjbGllbnQgb2YgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciBtYXkgdXNlIHRoZXNlIGZ1bmN0aW9ucyBkaXJlY3RseSB0byBieXBhc3Mgc3RhdGUgY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2UoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW07XG4gICAgaWYgKGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkIHx8IHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWVUb3RhbFNpemUgPiAwKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGZpcnN0UGVuZGluZ1B1bGxJbnRvID0gY29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5wZWVrKCk7XG4gICAgICAgIGlmIChmaXJzdFBlbmRpbmdQdWxsSW50by5ieXRlc0ZpbGxlZCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGUgPSBuZXcgVHlwZUVycm9yKCdJbnN1ZmZpY2llbnQgYnl0ZXMgdG8gZmlsbCBlbGVtZW50cyBpbiB0aGUgZ2l2ZW4gYnVmZmVyJyk7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoY29udHJvbGxlciwgZSk7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWUoY29udHJvbGxlciwgY2h1bmspIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtO1xuICAgIGlmIChjb250cm9sbGVyLl9jbG9zZVJlcXVlc3RlZCB8fCBzdHJlYW0uX3N0YXRlICE9PSAncmVhZGFibGUnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYnVmZmVyID0gY2h1bmsuYnVmZmVyO1xuICAgIGNvbnN0IGJ5dGVPZmZzZXQgPSBjaHVuay5ieXRlT2Zmc2V0O1xuICAgIGNvbnN0IGJ5dGVMZW5ndGggPSBjaHVuay5ieXRlTGVuZ3RoO1xuICAgIGNvbnN0IHRyYW5zZmVycmVkQnVmZmVyID0gVHJhbnNmZXJBcnJheUJ1ZmZlcihidWZmZXIpO1xuICAgIGlmIChjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgZmlyc3RQZW5kaW5nUHVsbEludG8gPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICAgICAgaWYgKElzRGV0YWNoZWRCdWZmZXIoZmlyc3RQZW5kaW5nUHVsbEludG8uYnVmZmVyKSkgO1xuICAgICAgICBmaXJzdFBlbmRpbmdQdWxsSW50by5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKGZpcnN0UGVuZGluZ1B1bGxJbnRvLmJ1ZmZlcik7XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJJbnZhbGlkYXRlQllPQlJlcXVlc3QoY29udHJvbGxlcik7XG4gICAgaWYgKFJlYWRhYmxlU3RyZWFtSGFzRGVmYXVsdFJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIGlmIChSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pID09PSAwKSB7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZUNodW5rVG9RdWV1ZShjb250cm9sbGVyLCB0cmFuc2ZlcnJlZEJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0cmFuc2ZlcnJlZFZpZXcgPSBuZXcgVWludDhBcnJheSh0cmFuc2ZlcnJlZEJ1ZmZlciwgYnl0ZU9mZnNldCwgYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUZ1bGZpbGxSZWFkUmVxdWVzdChzdHJlYW0sIHRyYW5zZmVycmVkVmlldywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKFJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlcihzdHJlYW0pKSB7XG4gICAgICAgIC8vIFRPRE86IElkZWFsbHkgaW4gdGhpcyBicmFuY2ggZGV0YWNoaW5nIHNob3VsZCBoYXBwZW4gb25seSBpZiB0aGUgYnVmZmVyIGlzIG5vdCBjb25zdW1lZCBmdWxseS5cbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgdHJhbnNmZXJyZWRCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHJvY2Vzc1B1bGxJbnRvRGVzY3JpcHRvcnNVc2luZ1F1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVucXVldWVDaHVua1RvUXVldWUoY29udHJvbGxlciwgdHJhbnNmZXJyZWRCdWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpO1xuICAgIH1cbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSAhPT0gJ3JlYWRhYmxlJykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbGVhclBlbmRpbmdQdWxsSW50b3MoY29udHJvbGxlcik7XG4gICAgUmVzZXRRdWV1ZShjb250cm9sbGVyKTtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgIFJlYWRhYmxlU3RyZWFtRXJyb3Ioc3RyZWFtLCBlKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChjb250cm9sbGVyKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID09PSBudWxsICYmIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBmaXJzdERlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICAgICAgY29uc3QgdmlldyA9IG5ldyBVaW50OEFycmF5KGZpcnN0RGVzY3JpcHRvci5idWZmZXIsIGZpcnN0RGVzY3JpcHRvci5ieXRlT2Zmc2V0ICsgZmlyc3REZXNjcmlwdG9yLmJ5dGVzRmlsbGVkLCBmaXJzdERlc2NyaXB0b3IuYnl0ZUxlbmd0aCAtIGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCk7XG4gICAgICAgIGNvbnN0IGJ5b2JSZXF1ZXN0ID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LnByb3RvdHlwZSk7XG4gICAgICAgIFNldFVwUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdChieW9iUmVxdWVzdCwgY29udHJvbGxlciwgdmlldyk7XG4gICAgICAgIGNvbnRyb2xsZXIuX2J5b2JSZXF1ZXN0ID0gYnlvYlJlcXVlc3Q7XG4gICAgfVxuICAgIHJldHVybiBjb250cm9sbGVyLl9ieW9iUmVxdWVzdDtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNIC0gY29udHJvbGxlci5fcXVldWVUb3RhbFNpemU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZChjb250cm9sbGVyLCBieXRlc1dyaXR0ZW4pIHtcbiAgICBjb25zdCBmaXJzdERlc2NyaXB0b3IgPSBjb250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLnBlZWsoKTtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZUJ5dGVTdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgaWYgKGJ5dGVzV3JpdHRlbiAhPT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYnl0ZXNXcml0dGVuIG11c3QgYmUgMCB3aGVuIGNhbGxpbmcgcmVzcG9uZCgpIG9uIGEgY2xvc2VkIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZiAoYnl0ZXNXcml0dGVuID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdieXRlc1dyaXR0ZW4gbXVzdCBiZSBncmVhdGVyIHRoYW4gMCB3aGVuIGNhbGxpbmcgcmVzcG9uZCgpIG9uIGEgcmVhZGFibGUgc3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCArIGJ5dGVzV3JpdHRlbiA+IGZpcnN0RGVzY3JpcHRvci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYnl0ZXNXcml0dGVuIG91dCBvZiByYW5nZScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZpcnN0RGVzY3JpcHRvci5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKGZpcnN0RGVzY3JpcHRvci5idWZmZXIpO1xuICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW50ZXJuYWwoY29udHJvbGxlciwgYnl0ZXNXcml0dGVuKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcoY29udHJvbGxlciwgdmlldykge1xuICAgIGNvbnN0IGZpcnN0RGVzY3JpcHRvciA9IGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MucGVlaygpO1xuICAgIGNvbnN0IHN0YXRlID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICBpZiAodmlldy5ieXRlTGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgdmlld1xcJ3MgbGVuZ3RoIG11c3QgYmUgMCB3aGVuIGNhbGxpbmcgcmVzcG9uZFdpdGhOZXdWaWV3KCkgb24gYSBjbG9zZWQgc3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmICh2aWV3LmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSB2aWV3XFwncyBsZW5ndGggbXVzdCBiZSBncmVhdGVyIHRoYW4gMCB3aGVuIGNhbGxpbmcgcmVzcG9uZFdpdGhOZXdWaWV3KCkgb24gYSByZWFkYWJsZSBzdHJlYW0nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoZmlyc3REZXNjcmlwdG9yLmJ5dGVPZmZzZXQgKyBmaXJzdERlc2NyaXB0b3IuYnl0ZXNGaWxsZWQgIT09IHZpZXcuYnl0ZU9mZnNldCkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHJlZ2lvbiBzcGVjaWZpZWQgYnkgdmlldyBkb2VzIG5vdCBtYXRjaCBieW9iUmVxdWVzdCcpO1xuICAgIH1cbiAgICBpZiAoZmlyc3REZXNjcmlwdG9yLmJ1ZmZlckJ5dGVMZW5ndGggIT09IHZpZXcuYnVmZmVyLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBidWZmZXIgb2YgdmlldyBoYXMgZGlmZmVyZW50IGNhcGFjaXR5IHRoYW4gYnlvYlJlcXVlc3QnKTtcbiAgICB9XG4gICAgaWYgKGZpcnN0RGVzY3JpcHRvci5ieXRlc0ZpbGxlZCArIHZpZXcuYnl0ZUxlbmd0aCA+IGZpcnN0RGVzY3JpcHRvci5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgcmVnaW9uIHNwZWNpZmllZCBieSB2aWV3IGlzIGxhcmdlciB0aGFuIGJ5b2JSZXF1ZXN0Jyk7XG4gICAgfVxuICAgIGZpcnN0RGVzY3JpcHRvci5idWZmZXIgPSBUcmFuc2ZlckFycmF5QnVmZmVyKHZpZXcuYnVmZmVyKTtcbiAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEludGVybmFsKGNvbnRyb2xsZXIsIHZpZXcuYnl0ZUxlbmd0aCk7XG59XG5mdW5jdGlvbiBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBhdXRvQWxsb2NhdGVDaHVua1NpemUpIHtcbiAgICBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVCeXRlU3RyZWFtID0gc3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBZ2FpbiA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxpbmcgPSBmYWxzZTtcbiAgICBjb250cm9sbGVyLl9ieW9iUmVxdWVzdCA9IG51bGw7XG4gICAgLy8gTmVlZCB0byBzZXQgdGhlIHNsb3RzIHNvIHRoYXQgdGhlIGFzc2VydCBkb2Vzbid0IGZpcmUuIEluIHRoZSBzcGVjIHRoZSBzbG90cyBhbHJlYWR5IGV4aXN0IGltcGxpY2l0bHkuXG4gICAgY29udHJvbGxlci5fcXVldWUgPSBjb250cm9sbGVyLl9xdWV1ZVRvdGFsU2l6ZSA9IHVuZGVmaW5lZDtcbiAgICBSZXNldFF1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5SFdNID0gaGlnaFdhdGVyTWFyaztcbiAgICBjb250cm9sbGVyLl9wdWxsQWxnb3JpdGhtID0gcHVsbEFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9jYW5jZWxBbGdvcml0aG0gPSBjYW5jZWxBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fYXV0b0FsbG9jYXRlQ2h1bmtTaXplID0gYXV0b0FsbG9jYXRlQ2h1bmtTaXplO1xuICAgIGNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICBzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgY29uc3Qgc3RhcnRSZXN1bHQgPSBzdGFydEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2VSZXNvbHZlZFdpdGgoc3RhcnRSZXN1bHQpLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIHIpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2Uoc3RyZWFtLCB1bmRlcmx5aW5nQnl0ZVNvdXJjZSwgaGlnaFdhdGVyTWFyaykge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBsZXQgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlZmluZWQ7XG4gICAgbGV0IHB1bGxBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgbGV0IGNhbmNlbEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2Uuc3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdCeXRlU291cmNlLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2UucHVsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHB1bGxBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nQnl0ZVNvdXJjZS5wdWxsKGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ0J5dGVTb3VyY2UuY2FuY2VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2FuY2VsQWxnb3JpdGhtID0gcmVhc29uID0+IHVuZGVybHlpbmdCeXRlU291cmNlLmNhbmNlbChyZWFzb24pO1xuICAgIH1cbiAgICBjb25zdCBhdXRvQWxsb2NhdGVDaHVua1NpemUgPSB1bmRlcmx5aW5nQnl0ZVNvdXJjZS5hdXRvQWxsb2NhdGVDaHVua1NpemU7XG4gICAgaWYgKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdhdXRvQWxsb2NhdGVDaHVua1NpemUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCcpO1xuICAgIH1cbiAgICBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBhdXRvQWxsb2NhdGVDaHVua1NpemUpO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0KHJlcXVlc3QsIGNvbnRyb2xsZXIsIHZpZXcpIHtcbiAgICByZXF1ZXN0Ll9hc3NvY2lhdGVkUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgcmVxdWVzdC5fdmlldyA9IHZpZXc7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW1CWU9CUmVxdWVzdC5cbmZ1bmN0aW9uIGJ5b2JSZXF1ZXN0QnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3RgKTtcbn1cbi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIHRoZSBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLlxuZnVuY3Rpb24gYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcmApO1xufVxuXG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW0uXG5mdW5jdGlvbiBBY3F1aXJlUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHN0cmVhbSkge1xuICAgIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHN0cmVhbSk7XG59XG4vLyBSZWFkYWJsZVN0cmVhbSBBUEkgZXhwb3NlZCBmb3IgY29udHJvbGxlcnMuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIHJlYWRJbnRvUmVxdWVzdCkge1xuICAgIHN0cmVhbS5fcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLnB1c2gocmVhZEludG9SZXF1ZXN0KTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdChzdHJlYW0sIGNodW5rLCBkb25lKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgY29uc3QgcmVhZEludG9SZXF1ZXN0ID0gcmVhZGVyLl9yZWFkSW50b1JlcXVlc3RzLnNoaWZ0KCk7XG4gICAgaWYgKGRvbmUpIHtcbiAgICAgICAgcmVhZEludG9SZXF1ZXN0Ll9jbG9zZVN0ZXBzKGNodW5rKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlYWRJbnRvUmVxdWVzdC5fY2h1bmtTdGVwcyhjaHVuayk7XG4gICAgfVxufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkSW50b1JlcXVlc3RzKHN0cmVhbSkge1xuICAgIHJldHVybiBzdHJlYW0uX3JlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5sZW5ndGg7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUhhc0JZT0JSZWFkZXIoc3RyZWFtKSB7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIEEgQllPQiByZWFkZXIgdmVuZGVkIGJ5IGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlciB7XG4gICAgY29uc3RydWN0b3Ioc3RyZWFtKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQoc3RyZWFtLCAxLCAnUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyJyk7XG4gICAgICAgIGFzc2VydFJlYWRhYmxlU3RyZWFtKHN0cmVhbSwgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZChzdHJlYW0pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGlzIHN0cmVhbSBoYXMgYWxyZWFkeSBiZWVuIGxvY2tlZCBmb3IgZXhjbHVzaXZlIHJlYWRpbmcgYnkgYW5vdGhlciByZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIUlzUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlcihzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjb25zdHJ1Y3QgYSBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIgZm9yIGEgc3RyZWFtIG5vdCBjb25zdHJ1Y3RlZCB3aXRoIGEgYnl0ZSAnICtcbiAgICAgICAgICAgICAgICAnc291cmNlJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljSW5pdGlhbGl6ZSh0aGlzLCBzdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWFkSW50b1JlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBmdWxmaWxsZWQgd2hlbiB0aGUgc3RyZWFtIGJlY29tZXMgY2xvc2VkLCBvciByZWplY3RlZCBpZiB0aGUgc3RyZWFtIGV2ZXIgZXJyb3JzIG9yXG4gICAgICogdGhlIHJlYWRlcidzIGxvY2sgaXMgcmVsZWFzZWQgYmVmb3JlIHRoZSBzdHJlYW0gZmluaXNoZXMgY2xvc2luZy5cbiAgICAgKi9cbiAgICBnZXQgY2xvc2VkKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChieW9iUmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbignY2xvc2VkJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9zZWRQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcmVhZGVyIGlzIGFjdGl2ZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QGxpbmsgUmVhZGFibGVTdHJlYW0uY2FuY2VsIHwgc3RyZWFtLmNhbmNlbChyZWFzb24pfS5cbiAgICAgKi9cbiAgICBjYW5jZWwocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdjYW5jZWwnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbignY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNDYW5jZWwodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gcmVhZHMgYnl0ZXMgaW50byB2aWV3LCBhbmQgcmV0dXJucyBhIHByb21pc2UgcmVzb2x2ZWQgd2l0aCB0aGUgcmVzdWx0LlxuICAgICAqXG4gICAgICogSWYgcmVhZGluZyBhIGNodW5rIGNhdXNlcyB0aGUgcXVldWUgdG8gYmVjb21lIGVtcHR5LCBtb3JlIGRhdGEgd2lsbCBiZSBwdWxsZWQgZnJvbSB0aGUgdW5kZXJseWluZyBzb3VyY2UuXG4gICAgICovXG4gICAgcmVhZCh2aWV3KSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KHZpZXcpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCd2aWV3IG11c3QgYmUgYW4gYXJyYXkgYnVmZmVyIHZpZXcnKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpZXcuYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcigndmlldyBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmlldy5idWZmZXIuYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcihgdmlldydzIGJ1ZmZlciBtdXN0IGhhdmUgbm9uLXplcm8gYnl0ZUxlbmd0aGApKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoSXNEZXRhY2hlZEJ1ZmZlcih2aWV3LmJ1ZmZlcikpIDtcbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgocmVhZGVyTG9ja0V4Y2VwdGlvbigncmVhZCBmcm9tJykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXNvbHZlUHJvbWlzZTtcbiAgICAgICAgbGV0IHJlamVjdFByb21pc2U7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgIHJlamVjdFByb21pc2UgPSByZWplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZWFkSW50b1JlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4gcmVzb2x2ZVByb21pc2UoeyB2YWx1ZTogY2h1bmssIGRvbmU6IGZhbHNlIH0pLFxuICAgICAgICAgICAgX2Nsb3NlU3RlcHM6IGNodW5rID0+IHJlc29sdmVQcm9taXNlKHsgdmFsdWU6IGNodW5rLCBkb25lOiB0cnVlIH0pLFxuICAgICAgICAgICAgX2Vycm9yU3RlcHM6IGUgPT4gcmVqZWN0UHJvbWlzZShlKVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkKHRoaXMsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlcyB0aGUgcmVhZGVyJ3MgbG9jayBvbiB0aGUgY29ycmVzcG9uZGluZyBzdHJlYW0uIEFmdGVyIHRoZSBsb2NrIGlzIHJlbGVhc2VkLCB0aGUgcmVhZGVyIGlzIG5vIGxvbmdlciBhY3RpdmUuXG4gICAgICogSWYgdGhlIGFzc29jaWF0ZWQgc3RyZWFtIGlzIGVycm9yZWQgd2hlbiB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJlYWRlciB3aWxsIGFwcGVhciBlcnJvcmVkIGluIHRoZSBzYW1lIHdheVxuICAgICAqIGZyb20gbm93IG9uOyBvdGhlcndpc2UsIHRoZSByZWFkZXIgd2lsbCBhcHBlYXIgY2xvc2VkLlxuICAgICAqXG4gICAgICogQSByZWFkZXIncyBsb2NrIGNhbm5vdCBiZSByZWxlYXNlZCB3aGlsZSBpdCBzdGlsbCBoYXMgYSBwZW5kaW5nIHJlYWQgcmVxdWVzdCwgaS5lLiwgaWYgYSBwcm9taXNlIHJldHVybmVkIGJ5XG4gICAgICogdGhlIHJlYWRlcidzIHtAbGluayBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucmVhZCB8IHJlYWQoKX0gbWV0aG9kIGhhcyBub3QgeWV0IGJlZW4gc2V0dGxlZC4gQXR0ZW1wdGluZyB0b1xuICAgICAqIGRvIHNvIHdpbGwgdGhyb3cgYSBgVHlwZUVycm9yYCBhbmQgbGVhdmUgdGhlIHJlYWRlciBsb2NrZWQgdG8gdGhlIHN0cmVhbS5cbiAgICAgKi9cbiAgICByZWxlYXNlTG9jaygpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgYnlvYlJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ3JlbGVhc2VMb2NrJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX293bmVyUmVhZGFibGVTdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9yZWFkSW50b1JlcXVlc3RzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RyaWVkIHRvIHJlbGVhc2UgYSByZWFkZXIgbG9jayB3aGVuIHRoYXQgcmVhZGVyIGhhcyBwZW5kaW5nIHJlYWQoKSBjYWxscyB1bi1zZXR0bGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZSh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucHJvdG90eXBlLCB7XG4gICAgY2FuY2VsOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWFkOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWxlYXNlTG9jazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2VkOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIHJlYWRlcnMuXG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX3JlYWRJbnRvUmVxdWVzdHMnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyUmVhZChyZWFkZXIsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCkge1xuICAgIGNvbnN0IHN0cmVhbSA9IHJlYWRlci5fb3duZXJSZWFkYWJsZVN0cmVhbTtcbiAgICBzdHJlYW0uX2Rpc3R1cmJlZCA9IHRydWU7XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Vycm9yU3RlcHMoc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8oc3RyZWFtLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIHZpZXcsIHJlYWRJbnRvUmVxdWVzdCk7XG4gICAgfVxufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtQllPQlJlYWRlci5cbmZ1bmN0aW9uIGJ5b2JSZWFkZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyLnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJgKTtcbn1cblxuZnVuY3Rpb24gRXh0cmFjdEhpZ2hXYXRlck1hcmsoc3RyYXRlZ3ksIGRlZmF1bHRIV00pIHtcbiAgICBjb25zdCB7IGhpZ2hXYXRlck1hcmsgfSA9IHN0cmF0ZWd5O1xuICAgIGlmIChoaWdoV2F0ZXJNYXJrID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRIV007XG4gICAgfVxuICAgIGlmIChOdW1iZXJJc05hTihoaWdoV2F0ZXJNYXJrKSB8fCBoaWdoV2F0ZXJNYXJrIDwgMCkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCBoaWdoV2F0ZXJNYXJrJyk7XG4gICAgfVxuICAgIHJldHVybiBoaWdoV2F0ZXJNYXJrO1xufVxuZnVuY3Rpb24gRXh0cmFjdFNpemVBbGdvcml0aG0oc3RyYXRlZ3kpIHtcbiAgICBjb25zdCB7IHNpemUgfSA9IHN0cmF0ZWd5O1xuICAgIGlmICghc2l6ZSkge1xuICAgICAgICByZXR1cm4gKCkgPT4gMTtcbiAgICB9XG4gICAgcmV0dXJuIHNpemU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRRdWV1aW5nU3RyYXRlZ3koaW5pdCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkoaW5pdCwgY29udGV4dCk7XG4gICAgY29uc3QgaGlnaFdhdGVyTWFyayA9IGluaXQgPT09IG51bGwgfHwgaW5pdCA9PT0gdm9pZCAwID8gdm9pZCAwIDogaW5pdC5oaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnN0IHNpemUgPSBpbml0ID09PSBudWxsIHx8IGluaXQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGluaXQuc2l6ZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBoaWdoV2F0ZXJNYXJrOiBoaWdoV2F0ZXJNYXJrID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0VW5yZXN0cmljdGVkRG91YmxlKGhpZ2hXYXRlck1hcmspLFxuICAgICAgICBzaXplOiBzaXplID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5U2l6ZShzaXplLCBgJHtjb250ZXh0fSBoYXMgbWVtYmVyICdzaXplJyB0aGF0YClcbiAgICB9O1xufVxuZnVuY3Rpb24gY29udmVydFF1ZXVpbmdTdHJhdGVneVNpemUoZm4sIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIGNodW5rID0+IGNvbnZlcnRVbnJlc3RyaWN0ZWREb3VibGUoZm4oY2h1bmspKTtcbn1cblxuZnVuY3Rpb24gY29udmVydFVuZGVybHlpbmdTaW5rKG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShvcmlnaW5hbCwgY29udGV4dCk7XG4gICAgY29uc3QgYWJvcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuYWJvcnQ7XG4gICAgY29uc3QgY2xvc2UgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuY2xvc2U7XG4gICAgY29uc3Qgc3RhcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuc3RhcnQ7XG4gICAgY29uc3QgdHlwZSA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC50eXBlO1xuICAgIGNvbnN0IHdyaXRlID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLndyaXRlO1xuICAgIHJldHVybiB7XG4gICAgICAgIGFib3J0OiBhYm9ydCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VW5kZXJseWluZ1NpbmtBYm9ydENhbGxiYWNrKGFib3J0LCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnYWJvcnQnIHRoYXRgKSxcbiAgICAgICAgY2xvc2U6IGNsb3NlID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU2lua0Nsb3NlQ2FsbGJhY2soY2xvc2UsIG9yaWdpbmFsLCBgJHtjb250ZXh0fSBoYXMgbWVtYmVyICdjbG9zZScgdGhhdGApLFxuICAgICAgICBzdGFydDogc3RhcnQgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuZGVybHlpbmdTaW5rU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHdyaXRlOiB3cml0ZSA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VW5kZXJseWluZ1NpbmtXcml0ZUNhbGxiYWNrKHdyaXRlLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnd3JpdGUnIHRoYXRgKSxcbiAgICAgICAgdHlwZVxuICAgIH07XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtBYm9ydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKHJlYXNvbikgPT4gcHJvbWlzZUNhbGwoZm4sIG9yaWdpbmFsLCBbcmVhc29uXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtDbG9zZUNhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKCkgPT4gcHJvbWlzZUNhbGwoZm4sIG9yaWdpbmFsLCBbXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VW5kZXJseWluZ1NpbmtTdGFydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHJlZmxlY3RDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU2lua1dyaXRlQ2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAoY2h1bmssIGNvbnRyb2xsZXIpID0+IHByb21pc2VDYWxsKGZuLCBvcmlnaW5hbCwgW2NodW5rLCBjb250cm9sbGVyXSk7XG59XG5cbmZ1bmN0aW9uIGFzc2VydFdyaXRhYmxlU3RyZWFtKHgsIGNvbnRleHQpIHtcbiAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW0oeCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSBpcyBub3QgYSBXcml0YWJsZVN0cmVhbS5gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzQWJvcnRTaWduYWwodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyB8fCB2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUuYWJvcnRlZCA9PT0gJ2Jvb2xlYW4nO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgLy8gQWJvcnRTaWduYWwucHJvdG90eXBlLmFib3J0ZWQgdGhyb3dzIGlmIGl0cyBicmFuZCBjaGVjayBmYWlsc1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuY29uc3Qgc3VwcG9ydHNBYm9ydENvbnRyb2xsZXIgPSB0eXBlb2YgQWJvcnRDb250cm9sbGVyID09PSAnZnVuY3Rpb24nO1xuLyoqXG4gKiBDb25zdHJ1Y3QgYSBuZXcgQWJvcnRDb250cm9sbGVyLCBpZiBzdXBwb3J0ZWQgYnkgdGhlIHBsYXRmb3JtLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5mdW5jdGlvbiBjcmVhdGVBYm9ydENvbnRyb2xsZXIoKSB7XG4gICAgaWYgKHN1cHBvcnRzQWJvcnRDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQSB3cml0YWJsZSBzdHJlYW0gcmVwcmVzZW50cyBhIGRlc3RpbmF0aW9uIGZvciBkYXRhLCBpbnRvIHdoaWNoIHlvdSBjYW4gd3JpdGUuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBXcml0YWJsZVN0cmVhbSB7XG4gICAgY29uc3RydWN0b3IocmF3VW5kZXJseWluZ1NpbmsgPSB7fSwgcmF3U3RyYXRlZ3kgPSB7fSkge1xuICAgICAgICBpZiAocmF3VW5kZXJseWluZ1NpbmsgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmF3VW5kZXJseWluZ1NpbmsgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYXNzZXJ0T2JqZWN0KHJhd1VuZGVybHlpbmdTaW5rLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyYXRlZ3kgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5KHJhd1N0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCB1bmRlcmx5aW5nU2luayA9IGNvbnZlcnRVbmRlcmx5aW5nU2luayhyYXdVbmRlcmx5aW5nU2luaywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBJbml0aWFsaXplV3JpdGFibGVTdHJlYW0odGhpcyk7XG4gICAgICAgIGNvbnN0IHR5cGUgPSB1bmRlcmx5aW5nU2luay50eXBlO1xuICAgICAgICBpZiAodHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlIGlzIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShzdHJhdGVneSk7XG4gICAgICAgIGNvbnN0IGhpZ2hXYXRlck1hcmsgPSBFeHRyYWN0SGlnaFdhdGVyTWFyayhzdHJhdGVneSwgMSk7XG4gICAgICAgIFNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayh0aGlzLCB1bmRlcmx5aW5nU2luaywgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgd2hldGhlciBvciBub3QgdGhlIHdyaXRhYmxlIHN0cmVhbSBpcyBsb2NrZWQgdG8gYSB3cml0ZXIuXG4gICAgICovXG4gICAgZ2V0IGxvY2tlZCgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2xvY2tlZCcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBYm9ydHMgdGhlIHN0cmVhbSwgc2lnbmFsaW5nIHRoYXQgdGhlIHByb2R1Y2VyIGNhbiBubyBsb25nZXIgc3VjY2Vzc2Z1bGx5IHdyaXRlIHRvIHRoZSBzdHJlYW0gYW5kIGl0IGlzIHRvIGJlXG4gICAgICogaW1tZWRpYXRlbHkgbW92ZWQgdG8gYW4gZXJyb3JlZCBzdGF0ZSwgd2l0aCBhbnkgcXVldWVkLXVwIHdyaXRlcyBkaXNjYXJkZWQuIFRoaXMgd2lsbCBhbHNvIGV4ZWN1dGUgYW55IGFib3J0XG4gICAgICogbWVjaGFuaXNtIG9mIHRoZSB1bmRlcmx5aW5nIHNpbmsuXG4gICAgICpcbiAgICAgKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSB3aWxsIGZ1bGZpbGwgaWYgdGhlIHN0cmVhbSBzaHV0cyBkb3duIHN1Y2Nlc3NmdWxseSwgb3IgcmVqZWN0IGlmIHRoZSB1bmRlcmx5aW5nIHNpbmsgc2lnbmFsZWRcbiAgICAgKiB0aGF0IHRoZXJlIHdhcyBhbiBlcnJvciBkb2luZyBzby4gQWRkaXRpb25hbGx5LCBpdCB3aWxsIHJlamVjdCB3aXRoIGEgYFR5cGVFcnJvcmAgKHdpdGhvdXQgYXR0ZW1wdGluZyB0byBjYW5jZWxcbiAgICAgKiB0aGUgc3RyZWFtKSBpZiB0aGUgc3RyZWFtIGlzIGN1cnJlbnRseSBsb2NrZWQuXG4gICAgICovXG4gICAgYWJvcnQocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdhYm9ydCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoSXNXcml0YWJsZVN0cmVhbUxvY2tlZCh0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcignQ2Fubm90IGFib3J0IGEgc3RyZWFtIHRoYXQgYWxyZWFkeSBoYXMgYSB3cml0ZXInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtQWJvcnQodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBzdHJlYW0uIFRoZSB1bmRlcmx5aW5nIHNpbmsgd2lsbCBmaW5pc2ggcHJvY2Vzc2luZyBhbnkgcHJldmlvdXNseS13cml0dGVuIGNodW5rcywgYmVmb3JlIGludm9raW5nIGl0c1xuICAgICAqIGNsb3NlIGJlaGF2aW9yLiBEdXJpbmcgdGhpcyB0aW1lIGFueSBmdXJ0aGVyIGF0dGVtcHRzIHRvIHdyaXRlIHdpbGwgZmFpbCAod2l0aG91dCBlcnJvcmluZyB0aGUgc3RyZWFtKS5cbiAgICAgKlxuICAgICAqIFRoZSBtZXRob2QgcmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGZ1bGZpbGwgaWYgYWxsIHJlbWFpbmluZyBjaHVua3MgYXJlIHN1Y2Nlc3NmdWxseSB3cml0dGVuIGFuZCB0aGUgc3RyZWFtXG4gICAgICogc3VjY2Vzc2Z1bGx5IGNsb3Nlcywgb3IgcmVqZWN0cyBpZiBhbiBlcnJvciBpcyBlbmNvdW50ZXJlZCBkdXJpbmcgdGhpcyBwcm9jZXNzLiBBZGRpdGlvbmFsbHksIGl0IHdpbGwgcmVqZWN0IHdpdGhcbiAgICAgKiBhIGBUeXBlRXJyb3JgICh3aXRob3V0IGF0dGVtcHRpbmcgdG8gY2FuY2VsIHRoZSBzdHJlYW0pIGlmIHRoZSBzdHJlYW0gaXMgY3VycmVudGx5IGxvY2tlZC5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2xvc2UgYSBzdHJlYW0gdGhhdCBhbHJlYWR5IGhhcyBhIHdyaXRlcicpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjbG9zZSBhbiBhbHJlYWR5LWNsb3Npbmcgc3RyZWFtJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUNsb3NlKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEge0BsaW5rIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciB8IHdyaXRlcn0gYW5kIGxvY2tzIHRoZSBzdHJlYW0gdG8gdGhlIG5ldyB3cml0ZXIuIFdoaWxlIHRoZSBzdHJlYW1cbiAgICAgKiBpcyBsb2NrZWQsIG5vIG90aGVyIHdyaXRlciBjYW4gYmUgYWNxdWlyZWQgdW50aWwgdGhpcyBvbmUgaXMgcmVsZWFzZWQuXG4gICAgICpcbiAgICAgKiBUaGlzIGZ1bmN0aW9uYWxpdHkgaXMgZXNwZWNpYWxseSB1c2VmdWwgZm9yIGNyZWF0aW5nIGFic3RyYWN0aW9ucyB0aGF0IGRlc2lyZSB0aGUgYWJpbGl0eSB0byB3cml0ZSB0byBhIHN0cmVhbVxuICAgICAqIHdpdGhvdXQgaW50ZXJydXB0aW9uIG9yIGludGVybGVhdmluZy4gQnkgZ2V0dGluZyBhIHdyaXRlciBmb3IgdGhlIHN0cmVhbSwgeW91IGNhbiBlbnN1cmUgbm9ib2R5IGVsc2UgY2FuIHdyaXRlIGF0XG4gICAgICogdGhlIHNhbWUgdGltZSwgd2hpY2ggd291bGQgY2F1c2UgdGhlIHJlc3VsdGluZyB3cml0dGVuIGRhdGEgdG8gYmUgdW5wcmVkaWN0YWJsZSBhbmQgcHJvYmFibHkgdXNlbGVzcy5cbiAgICAgKi9cbiAgICBnZXRXcml0ZXIoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdnZXRXcml0ZXInKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQWNxdWlyZVdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBhYm9ydDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgY2xvc2U6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGdldFdyaXRlcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgbG9ja2VkOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnV3JpdGFibGVTdHJlYW0nLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbi8vIEFic3RyYWN0IG9wZXJhdGlvbnMgZm9yIHRoZSBXcml0YWJsZVN0cmVhbS5cbmZ1bmN0aW9uIEFjcXVpcmVXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoc3RyZWFtKSB7XG4gICAgcmV0dXJuIG5ldyBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIoc3RyZWFtKTtcbn1cbi8vIFRocm93cyBpZiBhbmQgb25seSBpZiBzdGFydEFsZ29yaXRobSB0aHJvd3MuXG5mdW5jdGlvbiBDcmVhdGVXcml0YWJsZVN0cmVhbShzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyayA9IDEsIHNpemVBbGdvcml0aG0gPSAoKSA9PiAxKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gT2JqZWN0LmNyZWF0ZShXcml0YWJsZVN0cmVhbS5wcm90b3R5cGUpO1xuICAgIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbShzdHJlYW0pO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBPYmplY3QuY3JlYXRlKFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbmZ1bmN0aW9uIEluaXRpYWxpemVXcml0YWJsZVN0cmVhbShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ3dyaXRhYmxlJztcbiAgICAvLyBUaGUgZXJyb3IgdGhhdCB3aWxsIGJlIHJlcG9ydGVkIGJ5IG5ldyBtZXRob2QgY2FsbHMgb25jZSB0aGUgc3RhdGUgYmVjb21lcyBlcnJvcmVkLiBPbmx5IHNldCB3aGVuIFtbc3RhdGVdXSBpc1xuICAgIC8vICdlcnJvcmluZycgb3IgJ2Vycm9yZWQnLiBNYXkgYmUgc2V0IHRvIGFuIHVuZGVmaW5lZCB2YWx1ZS5cbiAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fd3JpdGVyID0gdW5kZWZpbmVkO1xuICAgIC8vIEluaXRpYWxpemUgdG8gdW5kZWZpbmVkIGZpcnN0IGJlY2F1c2UgdGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBjb250cm9sbGVyIGNoZWNrcyB0aGlzXG4gICAgLy8gdmFyaWFibGUgdG8gdmFsaWRhdGUgdGhlIGNhbGxlci5cbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlciA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGlzIHF1ZXVlIGlzIHBsYWNlZCBoZXJlIGluc3RlYWQgb2YgdGhlIHdyaXRlciBjbGFzcyBpbiBvcmRlciB0byBhbGxvdyBmb3IgcGFzc2luZyBhIHdyaXRlciB0byB0aGUgbmV4dCBkYXRhXG4gICAgLy8gcHJvZHVjZXIgd2l0aG91dCB3YWl0aW5nIGZvciB0aGUgcXVldWVkIHdyaXRlcyB0byBmaW5pc2guXG4gICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgLy8gV3JpdGUgcmVxdWVzdHMgYXJlIHJlbW92ZWQgZnJvbSBfd3JpdGVSZXF1ZXN0cyB3aGVuIHdyaXRlKCkgaXMgY2FsbGVkIG9uIHRoZSB1bmRlcmx5aW5nIHNpbmsuIFRoaXMgcHJldmVudHNcbiAgICAvLyB0aGVtIGZyb20gYmVpbmcgZXJyb25lb3VzbHkgcmVqZWN0ZWQgb24gZXJyb3IuIElmIGEgd3JpdGUoKSBjYWxsIGlzIGluLWZsaWdodCwgdGhlIHJlcXVlc3QgaXMgc3RvcmVkIGhlcmUuXG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGUgcHJvbWlzZSB0aGF0IHdhcyByZXR1cm5lZCBmcm9tIHdyaXRlci5jbG9zZSgpLiBTdG9yZWQgaGVyZSBiZWNhdXNlIGl0IG1heSBiZSBmdWxmaWxsZWQgYWZ0ZXIgdGhlIHdyaXRlclxuICAgIC8vIGhhcyBiZWVuIGRldGFjaGVkLlxuICAgIHN0cmVhbS5fY2xvc2VSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIC8vIENsb3NlIHJlcXVlc3QgaXMgcmVtb3ZlZCBmcm9tIF9jbG9zZVJlcXVlc3Qgd2hlbiBjbG9zZSgpIGlzIGNhbGxlZCBvbiB0aGUgdW5kZXJseWluZyBzaW5rLiBUaGlzIHByZXZlbnRzIGl0XG4gICAgLy8gZnJvbSBiZWluZyBlcnJvbmVvdXNseSByZWplY3RlZCBvbiBlcnJvci4gSWYgYSBjbG9zZSgpIGNhbGwgaXMgaW4tZmxpZ2h0LCB0aGUgcmVxdWVzdCBpcyBzdG9yZWQgaGVyZS5cbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIC8vIFRoZSBwcm9taXNlIHRoYXQgd2FzIHJldHVybmVkIGZyb20gd3JpdGVyLmFib3J0KCkuIFRoaXMgbWF5IGFsc28gYmUgZnVsZmlsbGVkIGFmdGVyIHRoZSB3cml0ZXIgaGFzIGRldGFjaGVkLlxuICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICAvLyBUaGUgYmFja3ByZXNzdXJlIHNpZ25hbCBzZXQgYnkgdGhlIGNvbnRyb2xsZXIuXG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW0oeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ193cml0YWJsZVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgV3JpdGFibGVTdHJlYW07XG59XG5mdW5jdGlvbiBJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX3dyaXRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUFib3J0KHN0cmVhbSwgcmVhc29uKSB7XG4gICAgdmFyIF9hO1xuICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJyB8fCBzdHJlYW0uX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIuX2Fib3J0UmVhc29uID0gcmVhc29uO1xuICAgIChfYSA9IHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyLl9hYm9ydENvbnRyb2xsZXIpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5hYm9ydCgpO1xuICAgIC8vIFR5cGVTY3JpcHQgbmFycm93cyB0aGUgdHlwZSBvZiBgc3RyZWFtLl9zdGF0ZWAgZG93biB0byAnd3JpdGFibGUnIHwgJ2Vycm9yaW5nJyxcbiAgICAvLyBidXQgaXQgZG9lc24ndCBrbm93IHRoYXQgc2lnbmFsaW5nIGFib3J0IHJ1bnMgYXV0aG9yIGNvZGUgdGhhdCBtaWdodCBoYXZlIGNoYW5nZWQgdGhlIHN0YXRlLlxuICAgIC8vIFdpZGVuIHRoZSB0eXBlIGFnYWluIGJ5IGNhc3RpbmcgdG8gV3JpdGFibGVTdHJlYW1TdGF0ZS5cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnY2xvc2VkJyB8fCBzdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIGlmIChzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0Ll9wcm9taXNlO1xuICAgIH1cbiAgICBsZXQgd2FzQWxyZWFkeUVycm9yaW5nID0gZmFsc2U7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHdhc0FscmVhZHlFcnJvcmluZyA9IHRydWU7XG4gICAgICAgIC8vIHJlYXNvbiB3aWxsIG5vdCBiZSB1c2VkLCBzbyBkb24ndCBrZWVwIGEgcmVmZXJlbmNlIHRvIGl0LlxuICAgICAgICByZWFzb24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX3Byb21pc2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIF9yZXNvbHZlOiByZXNvbHZlLFxuICAgICAgICAgICAgX3JlamVjdDogcmVqZWN0LFxuICAgICAgICAgICAgX3JlYXNvbjogcmVhc29uLFxuICAgICAgICAgICAgX3dhc0FscmVhZHlFcnJvcmluZzogd2FzQWxyZWFkeUVycm9yaW5nXG4gICAgICAgIH07XG4gICAgfSk7XG4gICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0Ll9wcm9taXNlID0gcHJvbWlzZTtcbiAgICBpZiAoIXdhc0FscmVhZHlFcnJvcmluZykge1xuICAgICAgICBXcml0YWJsZVN0cmVhbVN0YXJ0RXJyb3Jpbmcoc3RyZWFtLCByZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKSB7XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcgfHwgc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKGBUaGUgc3RyZWFtIChpbiAke3N0YXRlfSBzdGF0ZSkgaXMgbm90IGluIHRoZSB3cml0YWJsZSBzdGF0ZSBhbmQgY2Fubm90IGJlIGNsb3NlZGApKTtcbiAgICB9XG4gICAgY29uc3QgcHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCBjbG9zZVJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfcmVzb2x2ZTogcmVzb2x2ZSxcbiAgICAgICAgICAgIF9yZWplY3Q6IHJlamVjdFxuICAgICAgICB9O1xuICAgICAgICBzdHJlYW0uX2Nsb3NlUmVxdWVzdCA9IGNsb3NlUmVxdWVzdDtcbiAgICB9KTtcbiAgICBjb25zdCB3cml0ZXIgPSBzdHJlYW0uX3dyaXRlcjtcbiAgICBpZiAod3JpdGVyICE9PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9iYWNrcHJlc3N1cmUgJiYgc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc29sdmUod3JpdGVyKTtcbiAgICB9XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbi8vIFdyaXRhYmxlU3RyZWFtIEFQSSBleHBvc2VkIGZvciBjb250cm9sbGVycy5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtQWRkV3JpdGVSZXF1ZXN0KHN0cmVhbSkge1xuICAgIGNvbnN0IHByb21pc2UgPSBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3Qgd3JpdGVSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX3Jlc29sdmU6IHJlc29sdmUsXG4gICAgICAgICAgICBfcmVqZWN0OiByZWplY3RcbiAgICAgICAgfTtcbiAgICAgICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzLnB1c2god3JpdGVSZXF1ZXN0KTtcbiAgICB9KTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCBlcnJvcikge1xuICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1TdGFydEVycm9yaW5nKHN0cmVhbSwgZXJyb3IpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtU3RhcnRFcnJvcmluZyhzdHJlYW0sIHJlYXNvbikge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcjtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ2Vycm9yaW5nJztcbiAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gcmVhc29uO1xuICAgIGNvbnN0IHdyaXRlciA9IHN0cmVhbS5fd3JpdGVyO1xuICAgIGlmICh3cml0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVSZWFkeVByb21pc2VSZWplY3RlZCh3cml0ZXIsIHJlYXNvbik7XG4gICAgfVxuICAgIGlmICghV3JpdGFibGVTdHJlYW1IYXNPcGVyYXRpb25NYXJrZWRJbkZsaWdodChzdHJlYW0pICYmIGNvbnRyb2xsZXIuX3N0YXJ0ZWQpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1GaW5pc2hFcnJvcmluZyhzdHJlYW0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKSB7XG4gICAgc3RyZWFtLl9zdGF0ZSA9ICdlcnJvcmVkJztcbiAgICBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcltFcnJvclN0ZXBzXSgpO1xuICAgIGNvbnN0IHN0b3JlZEVycm9yID0gc3RyZWFtLl9zdG9yZWRFcnJvcjtcbiAgICBzdHJlYW0uX3dyaXRlUmVxdWVzdHMuZm9yRWFjaCh3cml0ZVJlcXVlc3QgPT4ge1xuICAgICAgICB3cml0ZVJlcXVlc3QuX3JlamVjdChzdG9yZWRFcnJvcik7XG4gICAgfSk7XG4gICAgc3RyZWFtLl93cml0ZVJlcXVlc3RzID0gbmV3IFNpbXBsZVF1ZXVlKCk7XG4gICAgaWYgKHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBhYm9ydFJlcXVlc3QgPSBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3Q7XG4gICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIGlmIChhYm9ydFJlcXVlc3QuX3dhc0FscmVhZHlFcnJvcmluZykge1xuICAgICAgICBhYm9ydFJlcXVlc3QuX3JlamVjdChzdG9yZWRFcnJvcik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwcm9taXNlID0gc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXJbQWJvcnRTdGVwc10oYWJvcnRSZXF1ZXN0Ll9yZWFzb24pO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2UsICgpID0+IHtcbiAgICAgICAgYWJvcnRSZXF1ZXN0Ll9yZXNvbHZlKCk7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICB9LCAocmVhc29uKSA9PiB7XG4gICAgICAgIGFib3J0UmVxdWVzdC5fcmVqZWN0KHJlYXNvbik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0Ll9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdCA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZVdpdGhFcnJvcihzdHJlYW0sIGVycm9yKSB7XG4gICAgc3RyZWFtLl9pbkZsaWdodFdyaXRlUmVxdWVzdC5fcmVqZWN0KGVycm9yKTtcbiAgICBzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCBlcnJvcik7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0Q2xvc2Uoc3RyZWFtKSB7XG4gICAgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdC5fcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIHN0cmVhbS5faW5GbGlnaHRDbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yaW5nJykge1xuICAgICAgICAvLyBUaGUgZXJyb3Igd2FzIHRvbyBsYXRlIHRvIGRvIGFueXRoaW5nLCBzbyBpdCBpcyBpZ25vcmVkLlxuICAgICAgICBzdHJlYW0uX3N0b3JlZEVycm9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdC5fcmVzb2x2ZSgpO1xuICAgICAgICAgICAgc3RyZWFtLl9wZW5kaW5nQWJvcnRSZXF1ZXN0ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0cmVhbS5fc3RhdGUgPSAnY2xvc2VkJztcbiAgICBjb25zdCB3cml0ZXIgPSBzdHJlYW0uX3dyaXRlcjtcbiAgICBpZiAod3JpdGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlKHdyaXRlcik7XG4gICAgfVxufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlV2l0aEVycm9yKHN0cmVhbSwgZXJyb3IpIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0Ll9yZWplY3QoZXJyb3IpO1xuICAgIHN0cmVhbS5faW5GbGlnaHRDbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgLy8gTmV2ZXIgZXhlY3V0ZSBzaW5rIGFib3J0KCkgYWZ0ZXIgc2luayBjbG9zZSgpLlxuICAgIGlmIChzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdHJlYW0uX3BlbmRpbmdBYm9ydFJlcXVlc3QuX3JlamVjdChlcnJvcik7XG4gICAgICAgIHN0cmVhbS5fcGVuZGluZ0Fib3J0UmVxdWVzdCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgV3JpdGFibGVTdHJlYW1EZWFsV2l0aFJlamVjdGlvbihzdHJlYW0sIGVycm9yKTtcbn1cbi8vIFRPRE8ocmljZWEpOiBGaXggYWxwaGFiZXRpY2FsIG9yZGVyLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQoc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5fY2xvc2VSZXF1ZXN0ID09PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbUhhc09wZXJhdGlvbk1hcmtlZEluRmxpZ2h0KHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ID09PSB1bmRlZmluZWQgJiYgc3RyZWFtLl9pbkZsaWdodENsb3NlUmVxdWVzdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbU1hcmtDbG9zZVJlcXVlc3RJbkZsaWdodChzdHJlYW0pIHtcbiAgICBzdHJlYW0uX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0ID0gc3RyZWFtLl9jbG9zZVJlcXVlc3Q7XG4gICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbU1hcmtGaXJzdFdyaXRlUmVxdWVzdEluRmxpZ2h0KHN0cmVhbSkge1xuICAgIHN0cmVhbS5faW5GbGlnaHRXcml0ZVJlcXVlc3QgPSBzdHJlYW0uX3dyaXRlUmVxdWVzdHMuc2hpZnQoKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtUmVqZWN0Q2xvc2VBbmRDbG9zZWRQcm9taXNlSWZOZWVkZWQoc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5fY2xvc2VSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QuX3JlamVjdChzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICAgICAgc3RyZWFtLl9jbG9zZVJlcXVlc3QgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IHdyaXRlciA9IHN0cmVhbS5fd3JpdGVyO1xuICAgIGlmICh3cml0ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCh3cml0ZXIsIHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtVXBkYXRlQmFja3ByZXNzdXJlKHN0cmVhbSwgYmFja3ByZXNzdXJlKSB7XG4gICAgY29uc3Qgd3JpdGVyID0gc3RyZWFtLl93cml0ZXI7XG4gICAgaWYgKHdyaXRlciAhPT0gdW5kZWZpbmVkICYmIGJhY2twcmVzc3VyZSAhPT0gc3RyZWFtLl9iYWNrcHJlc3N1cmUpIHtcbiAgICAgICAgaWYgKGJhY2twcmVzc3VyZSkge1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0KHdyaXRlcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSh3cml0ZXIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlID0gYmFja3ByZXNzdXJlO1xufVxuLyoqXG4gKiBBIGRlZmF1bHQgd3JpdGVyIHZlbmRlZCBieSBhIHtAbGluayBXcml0YWJsZVN0cmVhbX0uXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIge1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHN0cmVhbSwgMSwgJ1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcicpO1xuICAgICAgICBhc3NlcnRXcml0YWJsZVN0cmVhbShzdHJlYW0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhpcyBzdHJlYW0gaGFzIGFscmVhZHkgYmVlbiBsb2NrZWQgZm9yIGV4Y2x1c2l2ZSB3cml0aW5nIGJ5IGFub3RoZXIgd3JpdGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgc3RyZWFtLl93cml0ZXIgPSB0aGlzO1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICAgICAgaWYgKCFXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pICYmIHN0cmVhbS5fYmFja3ByZXNzdXJlKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemUodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh0aGlzLCBzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZXNvbHZlZCh0aGlzKTtcbiAgICAgICAgICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzdG9yZWRFcnJvciA9IHN0cmVhbS5fc3RvcmVkRXJyb3I7XG4gICAgICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQodGhpcywgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh0aGlzLCBzdG9yZWRFcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBzdHJlYW0gYmVjb21lcyBjbG9zZWQsIG9yIHJlamVjdGVkIGlmIHRoZSBzdHJlYW0gZXZlciBlcnJvcnMgb3JcbiAgICAgKiB0aGUgd3JpdGVy4oCZcyBsb2NrIGlzIHJlbGVhc2VkIGJlZm9yZSB0aGUgc3RyZWFtIGZpbmlzaGVzIGNsb3NpbmcuXG4gICAgICovXG4gICAgZ2V0IGNsb3NlZCgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlZCcpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2VkUHJvbWlzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBzaXplIHRvIGZpbGwgdGhlIHN0cmVhbeKAmXMgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzIG92ZXItZnVsbC5cbiAgICAgKiBBIHByb2R1Y2VyIGNhbiB1c2UgdGhpcyBpbmZvcm1hdGlvbiB0byBkZXRlcm1pbmUgdGhlIHJpZ2h0IGFtb3VudCBvZiBkYXRhIHRvIHdyaXRlLlxuICAgICAqXG4gICAgICogSXQgd2lsbCBiZSBgbnVsbGAgaWYgdGhlIHN0cmVhbSBjYW5ub3QgYmUgc3VjY2Vzc2Z1bGx5IHdyaXR0ZW4gdG8gKGR1ZSB0byBlaXRoZXIgYmVpbmcgZXJyb3JlZCwgb3IgaGF2aW5nIGFuIGFib3J0XG4gICAgICogcXVldWVkIHVwKS4gSXQgd2lsbCByZXR1cm4gemVybyBpZiB0aGUgc3RyZWFtIGlzIGNsb3NlZC4gQW5kIHRoZSBnZXR0ZXIgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgaW52b2tlZCB3aGVuXG4gICAgICogdGhlIHdyaXRlcuKAmXMgbG9jayBpcyByZWxlYXNlZC5cbiAgICAgKi9cbiAgICBnZXQgZGVzaXJlZFNpemUoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9vd25lcldyaXRhYmxlU3RyZWFtID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJMb2NrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJHZXREZXNpcmVkU2l6ZSh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2UgdGhhdCB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgc3RyZWFt4oCZcyBpbnRlcm5hbCBxdWV1ZSB0cmFuc2l0aW9uc1xuICAgICAqIGZyb20gbm9uLXBvc2l0aXZlIHRvIHBvc2l0aXZlLCBzaWduYWxpbmcgdGhhdCBpdCBpcyBubyBsb25nZXIgYXBwbHlpbmcgYmFja3ByZXNzdXJlLiBPbmNlIHRoZSBkZXNpcmVkIHNpemUgZGlwc1xuICAgICAqIGJhY2sgdG8gemVybyBvciBiZWxvdywgdGhlIGdldHRlciB3aWxsIHJldHVybiBhIG5ldyBwcm9taXNlIHRoYXQgc3RheXMgcGVuZGluZyB1bnRpbCB0aGUgbmV4dCB0cmFuc2l0aW9uLlxuICAgICAqXG4gICAgICogSWYgdGhlIHN0cmVhbSBiZWNvbWVzIGVycm9yZWQgb3IgYWJvcnRlZCwgb3IgdGhlIHdyaXRlcuKAmXMgbG9jayBpcyByZWxlYXNlZCwgdGhlIHJldHVybmVkIHByb21pc2Ugd2lsbCBiZWNvbWVcbiAgICAgKiByZWplY3RlZC5cbiAgICAgKi9cbiAgICBnZXQgcmVhZHkoKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWFkeScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcmVhZHlQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcmVhZGVyIGlzIGFjdGl2ZSwgYmVoYXZlcyB0aGUgc2FtZSBhcyB7QGxpbmsgV3JpdGFibGVTdHJlYW0uYWJvcnQgfCBzdHJlYW0uYWJvcnQocmVhc29uKX0uXG4gICAgICovXG4gICAgYWJvcnQocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdhYm9ydCcpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbignYWJvcnQnKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckFib3J0KHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSByZWFkZXIgaXMgYWN0aXZlLCBiZWhhdmVzIHRoZSBzYW1lIGFzIHtAbGluayBXcml0YWJsZVN0cmVhbS5jbG9zZSB8IHN0cmVhbS5jbG9zZSgpfS5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcih0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24oJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgICAgIGlmIChzdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckxvY2tFeGNlcHRpb24oJ2Nsb3NlJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2xvc2UgYW4gYWxyZWFkeS1jbG9zaW5nIHN0cmVhbScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2UodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbGVhc2VzIHRoZSB3cml0ZXLigJlzIGxvY2sgb24gdGhlIGNvcnJlc3BvbmRpbmcgc3RyZWFtLiBBZnRlciB0aGUgbG9jayBpcyByZWxlYXNlZCwgdGhlIHdyaXRlciBpcyBubyBsb25nZXIgYWN0aXZlLlxuICAgICAqIElmIHRoZSBhc3NvY2lhdGVkIHN0cmVhbSBpcyBlcnJvcmVkIHdoZW4gdGhlIGxvY2sgaXMgcmVsZWFzZWQsIHRoZSB3cml0ZXIgd2lsbCBhcHBlYXIgZXJyb3JlZCBpbiB0aGUgc2FtZSB3YXkgZnJvbVxuICAgICAqIG5vdyBvbjsgb3RoZXJ3aXNlLCB0aGUgd3JpdGVyIHdpbGwgYXBwZWFyIGNsb3NlZC5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCB0aGUgbG9jayBjYW4gc3RpbGwgYmUgcmVsZWFzZWQgZXZlbiBpZiBzb21lIG9uZ29pbmcgd3JpdGVzIGhhdmUgbm90IHlldCBmaW5pc2hlZCAoaS5lLiBldmVuIGlmIHRoZVxuICAgICAqIHByb21pc2VzIHJldHVybmVkIGZyb20gcHJldmlvdXMgY2FsbHMgdG8ge0BsaW5rIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci53cml0ZSB8IHdyaXRlKCl9IGhhdmUgbm90IHlldCBzZXR0bGVkKS5cbiAgICAgKiBJdOKAmXMgbm90IG5lY2Vzc2FyeSB0byBob2xkIHRoZSBsb2NrIG9uIHRoZSB3cml0ZXIgZm9yIHRoZSBkdXJhdGlvbiBvZiB0aGUgd3JpdGU7IHRoZSBsb2NrIGluc3RlYWQgc2ltcGx5IHByZXZlbnRzXG4gICAgICogb3RoZXIgcHJvZHVjZXJzIGZyb20gd3JpdGluZyBpbiBhbiBpbnRlcmxlYXZlZCBtYW5uZXIuXG4gICAgICovXG4gICAgcmVsZWFzZUxvY2soKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdyZWxlYXNlTG9jaycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHN0cmVhbSA9IHRoaXMuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgICAgIGlmIChzdHJlYW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlclJlbGVhc2UodGhpcyk7XG4gICAgfVxuICAgIHdyaXRlKGNodW5rID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIodGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKCd3cml0ZScpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fb3duZXJXcml0YWJsZVN0cmVhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbignd3JpdGUgdG8nKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcldyaXRlKHRoaXMsIGNodW5rKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIucHJvdG90eXBlLCB7XG4gICAgYWJvcnQ6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGNsb3NlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICByZWxlYXNlTG9jazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgd3JpdGU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGNsb3NlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgZGVzaXJlZFNpemU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHJlYWR5OiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1dyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfb3duZXJXcml0YWJsZVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXI7XG59XG4vLyBBIGNsaWVudCBvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIgbWF5IHVzZSB0aGVzZSBmdW5jdGlvbnMgZGlyZWN0bHkgdG8gYnlwYXNzIHN0YXRlIGNoZWNrLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQWJvcnQod3JpdGVyLCByZWFzb24pIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgcmV0dXJuIFdyaXRhYmxlU3RyZWFtQWJvcnQoc3RyZWFtLCByZWFzb24pO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2Uod3JpdGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJDbG9zZVdpdGhFcnJvclByb3BhZ2F0aW9uKHdyaXRlcikge1xuICAgIGNvbnN0IHN0cmVhbSA9IHdyaXRlci5fb3duZXJXcml0YWJsZVN0cmVhbTtcbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKFdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkgfHwgc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yZWQnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbiAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2Uod3JpdGVyKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZUNsb3NlZFByb21pc2VSZWplY3RlZCh3cml0ZXIsIGVycm9yKSB7XG4gICAgaWYgKHdyaXRlci5fY2xvc2VkUHJvbWlzZVN0YXRlID09PSAncGVuZGluZycpIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZWplY3Qod3JpdGVyLCBlcnJvcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVSZWFkeVByb21pc2VSZWplY3RlZCh3cml0ZXIsIGVycm9yKSB7XG4gICAgaWYgKHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPT09ICdwZW5kaW5nJykge1xuICAgICAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVqZWN0KHdyaXRlciwgZXJyb3IpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJHZXREZXNpcmVkU2l6ZSh3cml0ZXIpIHtcbiAgICBjb25zdCBzdHJlYW0gPSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW07XG4gICAgY29uc3Qgc3RhdGUgPSBzdHJlYW0uX3N0YXRlO1xuICAgIGlmIChzdGF0ZSA9PT0gJ2Vycm9yZWQnIHx8IHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAoc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplKHN0cmVhbS5fd3JpdGFibGVTdHJlYW1Db250cm9sbGVyKTtcbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlclJlbGVhc2Uod3JpdGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIGNvbnN0IHJlbGVhc2VkRXJyb3IgPSBuZXcgVHlwZUVycm9yKGBXcml0ZXIgd2FzIHJlbGVhc2VkIGFuZCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgdG8gbW9uaXRvciB0aGUgc3RyZWFtJ3MgY2xvc2VkbmVzc2ApO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZVJlYWR5UHJvbWlzZVJlamVjdGVkKHdyaXRlciwgcmVsZWFzZWRFcnJvcik7XG4gICAgLy8gVGhlIHN0YXRlIHRyYW5zaXRpb25zIHRvIFwiZXJyb3JlZFwiIGJlZm9yZSB0aGUgc2luayBhYm9ydCgpIG1ldGhvZCBydW5zLCBidXQgdGhlIHdyaXRlci5jbG9zZWQgcHJvbWlzZSBpcyBub3RcbiAgICAvLyByZWplY3RlZCB1bnRpbCBhZnRlcndhcmRzLiBUaGlzIG1lYW5zIHRoYXQgc2ltcGx5IHRlc3Rpbmcgc3RhdGUgd2lsbCBub3Qgd29yay5cbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVDbG9zZWRQcm9taXNlUmVqZWN0ZWQod3JpdGVyLCByZWxlYXNlZEVycm9yKTtcbiAgICBzdHJlYW0uX3dyaXRlciA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW0gPSB1bmRlZmluZWQ7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJXcml0ZSh3cml0ZXIsIGNodW5rKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gd3JpdGVyLl9vd25lcldyaXRhYmxlU3RyZWFtO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlcjtcbiAgICBjb25zdCBjaHVua1NpemUgPSBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0Q2h1bmtTaXplKGNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICBpZiAoc3RyZWFtICE9PSB3cml0ZXIuX293bmVyV3JpdGFibGVTdHJlYW0pIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoZGVmYXVsdFdyaXRlckxvY2tFeGNlcHRpb24oJ3dyaXRlIHRvJykpO1xuICAgIH1cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgfVxuICAgIGlmIChXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pIHx8IHN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGlzIGNsb3Npbmcgb3IgY2xvc2VkIGFuZCBjYW5ub3QgYmUgd3JpdHRlbiB0bycpKTtcbiAgICB9XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbS5fc3RvcmVkRXJyb3IpO1xuICAgIH1cbiAgICBjb25zdCBwcm9taXNlID0gV3JpdGFibGVTdHJlYW1BZGRXcml0ZVJlcXVlc3Qoc3RyZWFtKTtcbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyV3JpdGUoY29udHJvbGxlciwgY2h1bmssIGNodW5rU2l6ZSk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5jb25zdCBjbG9zZVNlbnRpbmVsID0ge307XG4vKipcbiAqIEFsbG93cyBjb250cm9sIG9mIGEge0BsaW5rIFdyaXRhYmxlU3RyZWFtIHwgd3JpdGFibGUgc3RyZWFtfSdzIHN0YXRlIGFuZCBpbnRlcm5hbCBxdWV1ZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbGxlZ2FsIGNvbnN0cnVjdG9yJyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWFzb24gd2hpY2ggd2FzIHBhc3NlZCB0byBgV3JpdGFibGVTdHJlYW0uYWJvcnQocmVhc29uKWAgd2hlbiB0aGUgc3RyZWFtIHdhcyBhYm9ydGVkLlxuICAgICAqL1xuICAgIGdldCBhYm9ydFJlYXNvbigpIHtcbiAgICAgICAgaWYgKCFJc1dyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQyKCdhYm9ydFJlYXNvbicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9hYm9ydFJlYXNvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQW4gYEFib3J0U2lnbmFsYCB0aGF0IGNhbiBiZSB1c2VkIHRvIGFib3J0IHRoZSBwZW5kaW5nIHdyaXRlIG9yIGNsb3NlIG9wZXJhdGlvbiB3aGVuIHRoZSBzdHJlYW0gaXMgYWJvcnRlZC5cbiAgICAgKi9cbiAgICBnZXQgc2lnbmFsKCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIoJ3NpZ25hbCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9hYm9ydENvbnRyb2xsZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gT2xkZXIgYnJvd3NlcnMgb3Igb2xkZXIgTm9kZSB2ZXJzaW9ucyBtYXkgbm90IHN1cHBvcnQgYEFib3J0Q29udHJvbGxlcmAgb3IgYEFib3J0U2lnbmFsYC5cbiAgICAgICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gYnVuZGxlIGFuZCBzaGlwIGFuIGBBYm9ydENvbnRyb2xsZXJgIHBvbHlmaWxsIHRvZ2V0aGVyIHdpdGggb3VyIHBvbHlmaWxsLFxuICAgICAgICAgICAgLy8gc28gaW5zdGVhZCB3ZSBvbmx5IGltcGxlbWVudCBzdXBwb3J0IGZvciBgc2lnbmFsYCBpZiB3ZSBmaW5kIGEgZ2xvYmFsIGBBYm9ydENvbnRyb2xsZXJgIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUuc2lnbmFsIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fYWJvcnRDb250cm9sbGVyLnNpZ25hbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSBjb250cm9sbGVkIHdyaXRhYmxlIHN0cmVhbSwgbWFraW5nIGFsbCBmdXR1cmUgaW50ZXJhY3Rpb25zIHdpdGggaXQgZmFpbCB3aXRoIHRoZSBnaXZlbiBlcnJvciBgZWAuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyByYXJlbHkgdXNlZCwgc2luY2UgdXN1YWxseSBpdCBzdWZmaWNlcyB0byByZXR1cm4gYSByZWplY3RlZCBwcm9taXNlIGZyb20gb25lIG9mIHRoZSB1bmRlcmx5aW5nXG4gICAgICogc2luaydzIG1ldGhvZHMuIEhvd2V2ZXIsIGl0IGNhbiBiZSB1c2VmdWwgZm9yIHN1ZGRlbmx5IHNodXR0aW5nIGRvd24gYSBzdHJlYW0gaW4gcmVzcG9uc2UgdG8gYW4gZXZlbnQgb3V0c2lkZSB0aGVcbiAgICAgKiBub3JtYWwgbGlmZWN5Y2xlIG9mIGludGVyYWN0aW9ucyB3aXRoIHRoZSB1bmRlcmx5aW5nIHNpbmsuXG4gICAgICovXG4gICAgZXJyb3IoZSA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIoJ2Vycm9yJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhdGUgPSB0aGlzLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW0uX3N0YXRlO1xuICAgICAgICBpZiAoc3RhdGUgIT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgICAgIC8vIFRoZSBzdHJlYW0gaXMgY2xvc2VkLCBlcnJvcmVkIG9yIHdpbGwgYmUgc29vbi4gVGhlIHNpbmsgY2FuJ3QgZG8gYW55dGhpbmcgdXNlZnVsIGlmIGl0IGdldHMgYW4gZXJyb3IgaGVyZSwgc29cbiAgICAgICAgICAgIC8vIGp1c3QgdHJlYXQgaXQgYXMgYSBuby1vcC5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IodGhpcywgZSk7XG4gICAgfVxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBbQWJvcnRTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2Fib3J0QWxnb3JpdGhtKHJlYXNvbik7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXModGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBbRXJyb3JTdGVwc10oKSB7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBpbXBsZW1lbnRpbmcgaW50ZXJmYWNlIHJlcXVpcmVkIGJ5IHRoZSBXcml0YWJsZVN0cmVhbS5cbmZ1bmN0aW9uIElzV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih4KSB7XG4gICAgaWYgKCF0eXBlSXNPYmplY3QoeCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyO1xufVxuZnVuY3Rpb24gU2V0VXBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHdyaXRlQWxnb3JpdGhtLCBjbG9zZUFsZ29yaXRobSwgYWJvcnRBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmssIHNpemVBbGdvcml0aG0pIHtcbiAgICBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW0gPSBzdHJlYW07XG4gICAgc3RyZWFtLl93cml0YWJsZVN0cmVhbUNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuICAgIC8vIE5lZWQgdG8gc2V0IHRoZSBzbG90cyBzbyB0aGF0IHRoZSBhc3NlcnQgZG9lc24ndCBmaXJlLiBJbiB0aGUgc3BlYyB0aGUgc2xvdHMgYWxyZWFkeSBleGlzdCBpbXBsaWNpdGx5LlxuICAgIGNvbnRyb2xsZXIuX3F1ZXVlID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID0gdW5kZWZpbmVkO1xuICAgIFJlc2V0UXVldWUoY29udHJvbGxlcik7XG4gICAgY29udHJvbGxlci5fYWJvcnRSZWFzb24gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYWJvcnRDb250cm9sbGVyID0gY3JlYXRlQWJvcnRDb250cm9sbGVyKCk7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSA9IHNpemVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lIV00gPSBoaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnRyb2xsZXIuX3dyaXRlQWxnb3JpdGhtID0gd3JpdGVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fY2xvc2VBbGdvcml0aG0gPSBjbG9zZUFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9hYm9ydEFsZ29yaXRobSA9IGFib3J0QWxnb3JpdGhtO1xuICAgIGNvbnN0IGJhY2twcmVzc3VyZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRCYWNrcHJlc3N1cmUoY29udHJvbGxlcik7XG4gICAgV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpO1xuICAgIGNvbnN0IHN0YXJ0UmVzdWx0ID0gc3RhcnRBbGdvcml0aG0oKTtcbiAgICBjb25zdCBzdGFydFByb21pc2UgPSBwcm9taXNlUmVzb2x2ZWRXaXRoKHN0YXJ0UmVzdWx0KTtcbiAgICB1cG9uUHJvbWlzZShzdGFydFByb21pc2UsICgpID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJBZHZhbmNlUXVldWVJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVhbFdpdGhSZWplY3Rpb24oc3RyZWFtLCByKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayhzdHJlYW0sIHVuZGVybHlpbmdTaW5rLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUpO1xuICAgIGxldCBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBsZXQgd3JpdGVBbGdvcml0aG0gPSAoKSA9PiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgbGV0IGNsb3NlQWxnb3JpdGhtID0gKCkgPT4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIGxldCBhYm9ydEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodW5kZXJseWluZ1Npbmsuc3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdTaW5rLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1Npbmsud3JpdGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB3cml0ZUFsZ29yaXRobSA9IGNodW5rID0+IHVuZGVybHlpbmdTaW5rLndyaXRlKGNodW5rLCBjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTaW5rLmNsb3NlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2xvc2VBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nU2luay5jbG9zZSgpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1NpbmsuYWJvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhYm9ydEFsZ29yaXRobSA9IHJlYXNvbiA9PiB1bmRlcmx5aW5nU2luay5hYm9ydChyZWFzb24pO1xuICAgIH1cbiAgICBTZXRVcFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG59XG4vLyBDbGVhckFsZ29yaXRobXMgbWF5IGJlIGNhbGxlZCB0d2ljZS4gRXJyb3JpbmcgdGhlIHNhbWUgc3RyZWFtIGluIG11bHRpcGxlIHdheXMgd2lsbCBvZnRlbiByZXN1bHQgaW4gcmVkdW5kYW50IGNhbGxzLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKSB7XG4gICAgY29udHJvbGxlci5fd3JpdGVBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fY2xvc2VBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fYWJvcnRBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lTaXplQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKGNvbnRyb2xsZXIpIHtcbiAgICBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250cm9sbGVyLCBjbG9zZVNlbnRpbmVsLCAwKTtcbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0Q2h1bmtTaXplKGNvbnRyb2xsZXIsIGNodW5rKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobShjaHVuayk7XG4gICAgfVxuICAgIGNhdGNoIChjaHVua1NpemVFKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGNodW5rU2l6ZUUpO1xuICAgICAgICByZXR1cm4gMTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUoY29udHJvbGxlcikge1xuICAgIHJldHVybiBjb250cm9sbGVyLl9zdHJhdGVneUhXTSAtIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplO1xufVxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcldyaXRlKGNvbnRyb2xsZXIsIGNodW5rLCBjaHVua1NpemUpIHtcbiAgICB0cnkge1xuICAgICAgICBFbnF1ZXVlVmFsdWVXaXRoU2l6ZShjb250cm9sbGVyLCBjaHVuaywgY2h1bmtTaXplKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVucXVldWVFKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGVucXVldWVFKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW07XG4gICAgaWYgKCFXcml0YWJsZVN0cmVhbUNsb3NlUXVldWVkT3JJbkZsaWdodChzdHJlYW0pICYmIHN0cmVhbS5fc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgY29uc3QgYmFja3ByZXNzdXJlID0gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldEJhY2twcmVzc3VyZShjb250cm9sbGVyKTtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpO1xuICAgIH1cbiAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQoY29udHJvbGxlcik7XG59XG4vLyBBYnN0cmFjdCBvcGVyYXRpb25zIGZvciB0aGUgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJBZHZhbmNlUXVldWVJZk5lZWRlZChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIGlmICghY29udHJvbGxlci5fc3RhcnRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChzdHJlYW0uX2luRmxpZ2h0V3JpdGVSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzdGF0ZSA9IHN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JpbmcnKSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoRXJyb3Jpbmcoc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY29udHJvbGxlci5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdmFsdWUgPSBQZWVrUXVldWVWYWx1ZShjb250cm9sbGVyKTtcbiAgICBpZiAodmFsdWUgPT09IGNsb3NlU2VudGluZWwpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NDbG9zZShjb250cm9sbGVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQcm9jZXNzV3JpdGUoY29udHJvbGxlciwgdmFsdWUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKGNvbnRyb2xsZXIsIGVycm9yKSB7XG4gICAgaWYgKGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRXcml0YWJsZVN0cmVhbS5fc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVycm9yKTtcbiAgICB9XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc0Nsb3NlKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkV3JpdGFibGVTdHJlYW07XG4gICAgV3JpdGFibGVTdHJlYW1NYXJrQ2xvc2VSZXF1ZXN0SW5GbGlnaHQoc3RyZWFtKTtcbiAgICBEZXF1ZXVlVmFsdWUoY29udHJvbGxlcik7XG4gICAgY29uc3Qgc2lua0Nsb3NlUHJvbWlzZSA9IGNvbnRyb2xsZXIuX2Nsb3NlQWxnb3JpdGhtKCk7XG4gICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKTtcbiAgICB1cG9uUHJvbWlzZShzaW5rQ2xvc2VQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZShzdHJlYW0pO1xuICAgIH0sIHJlYXNvbiA9PiB7XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRDbG9zZVdpdGhFcnJvcihzdHJlYW0sIHJlYXNvbik7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc1dyaXRlKGNvbnRyb2xsZXIsIGNodW5rKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIFdyaXRhYmxlU3RyZWFtTWFya0ZpcnN0V3JpdGVSZXF1ZXN0SW5GbGlnaHQoc3RyZWFtKTtcbiAgICBjb25zdCBzaW5rV3JpdGVQcm9taXNlID0gY29udHJvbGxlci5fd3JpdGVBbGdvcml0aG0oY2h1bmspO1xuICAgIHVwb25Qcm9taXNlKHNpbmtXcml0ZVByb21pc2UsICgpID0+IHtcbiAgICAgICAgV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodFdyaXRlKHN0cmVhbSk7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gc3RyZWFtLl9zdGF0ZTtcbiAgICAgICAgRGVxdWV1ZVZhbHVlKGNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoIVdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KHN0cmVhbSkgJiYgc3RhdGUgPT09ICd3cml0YWJsZScpIHtcbiAgICAgICAgICAgIGNvbnN0IGJhY2twcmVzc3VyZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXRCYWNrcHJlc3N1cmUoY29udHJvbGxlcik7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbVVwZGF0ZUJhY2twcmVzc3VyZShzdHJlYW0sIGJhY2twcmVzc3VyZSk7XG4gICAgICAgIH1cbiAgICAgICAgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckFkdmFuY2VRdWV1ZUlmTmVlZGVkKGNvbnRyb2xsZXIpO1xuICAgIH0sIHJlYXNvbiA9PiB7XG4gICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnd3JpdGFibGUnKSB7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKGNvbnRyb2xsZXIpO1xuICAgICAgICB9XG4gICAgICAgIFdyaXRhYmxlU3RyZWFtRmluaXNoSW5GbGlnaHRXcml0ZVdpdGhFcnJvcihzdHJlYW0sIHJlYXNvbik7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0QmFja3ByZXNzdXJlKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBkZXNpcmVkU2l6ZSA9IFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZShjb250cm9sbGVyKTtcbiAgICByZXR1cm4gZGVzaXJlZFNpemUgPD0gMDtcbn1cbi8vIEEgY2xpZW50IG9mIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIgbWF5IHVzZSB0aGVzZSBmdW5jdGlvbnMgZGlyZWN0bHkgdG8gYnlwYXNzIHN0YXRlIGNoZWNrLlxuZnVuY3Rpb24gV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVycm9yKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgV3JpdGFibGVTdHJlYW1TdGFydEVycm9yaW5nKHN0cmVhbSwgZXJyb3IpO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQyKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW0ucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFdyaXRhYmxlU3RyZWFtYCk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5cbmZ1bmN0aW9uIGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQyKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcmApO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlci5cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyLnByb3RvdHlwZS4ke25hbWV9IGNhbiBvbmx5IGJlIHVzZWQgb24gYSBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJgKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJMb2NrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcignQ2Fubm90ICcgKyBuYW1lICsgJyBhIHN0cmVhbSB1c2luZyBhIHJlbGVhc2VkIHdyaXRlcicpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplKHdyaXRlcikge1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QgPSByZWplY3Q7XG4gICAgICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZVN0YXRlID0gJ3BlbmRpbmcnO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xuICAgIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVqZWN0KHdyaXRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlSW5pdGlhbGl6ZUFzUmVzb2x2ZWQod3JpdGVyKSB7XG4gICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplKHdyaXRlcik7XG4gICAgZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlKHdyaXRlcik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZVJlamVjdCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGlmICh3cml0ZXIuX2Nsb3NlZFByb21pc2VfcmVqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlKHdyaXRlci5fY2xvc2VkUHJvbWlzZSk7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdChyZWFzb24pO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZWplY3QgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlU3RhdGUgPSAncmVqZWN0ZWQnO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0V3JpdGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkKHdyaXRlciwgcmVhc29uKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVzb2x2ZSh3cml0ZXIpIHtcbiAgICBpZiAod3JpdGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHdyaXRlci5fY2xvc2VkUHJvbWlzZV9yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9jbG9zZWRQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX2Nsb3NlZFByb21pc2VTdGF0ZSA9ICdyZXNvbHZlZCc7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpIHtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZSA9IG5ld1Byb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID0gcmVqZWN0O1xuICAgIH0pO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPSAncGVuZGluZyc7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZUFzUmVqZWN0ZWQod3JpdGVyLCByZWFzb24pIHtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZWplY3Qod3JpdGVyLCByZWFzb24pO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkKHdyaXRlcikge1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplKHdyaXRlcik7XG4gICAgZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc29sdmUod3JpdGVyKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZWplY3Qod3JpdGVyLCByZWFzb24pIHtcbiAgICBpZiAod3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlKHdyaXRlci5fcmVhZHlQcm9taXNlKTtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZWplY3QocmVhc29uKTtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3JlamVjdCA9IHVuZGVmaW5lZDtcbiAgICB3cml0ZXIuX3JlYWR5UHJvbWlzZVN0YXRlID0gJ3JlamVjdGVkJztcbn1cbmZ1bmN0aW9uIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNldCh3cml0ZXIpIHtcbiAgICBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSh3cml0ZXIpO1xufVxuZnVuY3Rpb24gZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCh3cml0ZXIsIHJlYXNvbikge1xuICAgIGRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCh3cml0ZXIsIHJlYXNvbik7XG59XG5mdW5jdGlvbiBkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSh3cml0ZXIpIHtcbiAgICBpZiAod3JpdGVyLl9yZWFkeVByb21pc2VfcmVzb2x2ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlX3Jlc29sdmUgPSB1bmRlZmluZWQ7XG4gICAgd3JpdGVyLl9yZWFkeVByb21pc2VfcmVqZWN0ID0gdW5kZWZpbmVkO1xuICAgIHdyaXRlci5fcmVhZHlQcm9taXNlU3RhdGUgPSAnZnVsZmlsbGVkJztcbn1cblxuLy8vIDxyZWZlcmVuY2UgbGliPVwiZG9tXCIgLz5cbmNvbnN0IE5hdGl2ZURPTUV4Y2VwdGlvbiA9IHR5cGVvZiBET01FeGNlcHRpb24gIT09ICd1bmRlZmluZWQnID8gRE9NRXhjZXB0aW9uIDogdW5kZWZpbmVkO1xuXG4vLy8gPHJlZmVyZW5jZSB0eXBlcz1cIm5vZGVcIiAvPlxuZnVuY3Rpb24gaXNET01FeGNlcHRpb25Db25zdHJ1Y3RvcihjdG9yKSB7XG4gICAgaWYgKCEodHlwZW9mIGN0b3IgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGN0b3IgPT09ICdvYmplY3QnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIG5ldyBjdG9yKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjYXRjaCAoX2EpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZURPTUV4Y2VwdGlvblBvbHlmaWxsKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdCBjdG9yID0gZnVuY3Rpb24gRE9NRXhjZXB0aW9uKG1lc3NhZ2UsIG5hbWUpIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZSB8fCAnJztcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZSB8fCAnRXJyb3InO1xuICAgICAgICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICAgICAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3Rvci5wcm90b3R5cGUsICdjb25zdHJ1Y3RvcicsIHsgdmFsdWU6IGN0b3IsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSk7XG4gICAgcmV0dXJuIGN0b3I7XG59XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVkZWNsYXJlXG5jb25zdCBET01FeGNlcHRpb24kMSA9IGlzRE9NRXhjZXB0aW9uQ29uc3RydWN0b3IoTmF0aXZlRE9NRXhjZXB0aW9uKSA/IE5hdGl2ZURPTUV4Y2VwdGlvbiA6IGNyZWF0ZURPTUV4Y2VwdGlvblBvbHlmaWxsKCk7XG5cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtUGlwZVRvKHNvdXJjZSwgZGVzdCwgcHJldmVudENsb3NlLCBwcmV2ZW50QWJvcnQsIHByZXZlbnRDYW5jZWwsIHNpZ25hbCkge1xuICAgIGNvbnN0IHJlYWRlciA9IEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc291cmNlKTtcbiAgICBjb25zdCB3cml0ZXIgPSBBY3F1aXJlV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyKGRlc3QpO1xuICAgIHNvdXJjZS5fZGlzdHVyYmVkID0gdHJ1ZTtcbiAgICBsZXQgc2h1dHRpbmdEb3duID0gZmFsc2U7XG4gICAgLy8gVGhpcyBpcyB1c2VkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIHNwZWMncyByZXF1aXJlbWVudCB0aGF0IHdlIHdhaXQgZm9yIG9uZ29pbmcgd3JpdGVzIGR1cmluZyBzaHV0ZG93bi5cbiAgICBsZXQgY3VycmVudFdyaXRlID0gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIHJldHVybiBuZXdQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgbGV0IGFib3J0QWxnb3JpdGhtO1xuICAgICAgICBpZiAoc2lnbmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGFib3J0QWxnb3JpdGhtID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IERPTUV4Y2VwdGlvbiQxKCdBYm9ydGVkJywgJ0Fib3J0RXJyb3InKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3Rpb25zID0gW107XG4gICAgICAgICAgICAgICAgaWYgKCFwcmV2ZW50QWJvcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXN0Ll9zdGF0ZSA9PT0gJ3dyaXRhYmxlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBXcml0YWJsZVN0cmVhbUFib3J0KGRlc3QsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuX3N0YXRlID09PSAncmVhZGFibGUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHNvdXJjZSwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNodXRkb3duV2l0aEFjdGlvbigoKSA9PiBQcm9taXNlLmFsbChhY3Rpb25zLm1hcChhY3Rpb24gPT4gYWN0aW9uKCkpKSwgdHJ1ZSwgZXJyb3IpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgICAgICAgIGFib3J0QWxnb3JpdGhtKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnRBbGdvcml0aG0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFVzaW5nIHJlYWRlciBhbmQgd3JpdGVyLCByZWFkIGFsbCBjaHVua3MgZnJvbSB0aGlzIGFuZCB3cml0ZSB0aGVtIHRvIGRlc3RcbiAgICAgICAgLy8gLSBCYWNrcHJlc3N1cmUgbXVzdCBiZSBlbmZvcmNlZFxuICAgICAgICAvLyAtIFNodXRkb3duIG11c3Qgc3RvcCBhbGwgYWN0aXZpdHlcbiAgICAgICAgZnVuY3Rpb24gcGlwZUxvb3AoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3UHJvbWlzZSgocmVzb2x2ZUxvb3AsIHJlamVjdExvb3ApID0+IHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBuZXh0KGRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVMb29wKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgYFBlcmZvcm1Qcm9taXNlVGhlbmAgaW5zdGVhZCBvZiBgdXBvblByb21pc2VgIHRvIGF2b2lkXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhZGRpbmcgdW5uZWNlc3NhcnkgYC5jYXRjaChyZXRocm93QXNzZXJ0aW9uRXJyb3JSZWplY3Rpb24pYCBoYW5kbGVyc1xuICAgICAgICAgICAgICAgICAgICAgICAgUGVyZm9ybVByb21pc2VUaGVuKHBpcGVTdGVwKCksIG5leHQsIHJlamVjdExvb3ApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5leHQoZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gcGlwZVN0ZXAoKSB7XG4gICAgICAgICAgICBpZiAoc2h1dHRpbmdEb3duKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gUGVyZm9ybVByb21pc2VUaGVuKHdyaXRlci5fcmVhZHlQcm9taXNlLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ld1Byb21pc2UoKHJlc29sdmVSZWFkLCByZWplY3RSZWFkKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQocmVhZGVyLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRXcml0ZSA9IFBlcmZvcm1Qcm9taXNlVGhlbihXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJXcml0ZSh3cml0ZXIsIGNodW5rKSwgdW5kZWZpbmVkLCBub29wKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlUmVhZChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgX2Nsb3NlU3RlcHM6ICgpID0+IHJlc29sdmVSZWFkKHRydWUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgX2Vycm9yU3RlcHM6IHJlamVjdFJlYWRcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBFcnJvcnMgbXVzdCBiZSBwcm9wYWdhdGVkIGZvcndhcmRcbiAgICAgICAgaXNPckJlY29tZXNFcnJvcmVkKHNvdXJjZSwgcmVhZGVyLl9jbG9zZWRQcm9taXNlLCBzdG9yZWRFcnJvciA9PiB7XG4gICAgICAgICAgICBpZiAoIXByZXZlbnRBYm9ydCkge1xuICAgICAgICAgICAgICAgIHNodXRkb3duV2l0aEFjdGlvbigoKSA9PiBXcml0YWJsZVN0cmVhbUFib3J0KGRlc3QsIHN0b3JlZEVycm9yKSwgdHJ1ZSwgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd24odHJ1ZSwgc3RvcmVkRXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gRXJyb3JzIG11c3QgYmUgcHJvcGFnYXRlZCBiYWNrd2FyZFxuICAgICAgICBpc09yQmVjb21lc0Vycm9yZWQoZGVzdCwgd3JpdGVyLl9jbG9zZWRQcm9taXNlLCBzdG9yZWRFcnJvciA9PiB7XG4gICAgICAgICAgICBpZiAoIXByZXZlbnRDYW5jZWwpIHtcbiAgICAgICAgICAgICAgICBzaHV0ZG93bldpdGhBY3Rpb24oKCkgPT4gUmVhZGFibGVTdHJlYW1DYW5jZWwoc291cmNlLCBzdG9yZWRFcnJvciksIHRydWUsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNodXRkb3duKHRydWUsIHN0b3JlZEVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIENsb3NpbmcgbXVzdCBiZSBwcm9wYWdhdGVkIGZvcndhcmRcbiAgICAgICAgaXNPckJlY29tZXNDbG9zZWQoc291cmNlLCByZWFkZXIuX2Nsb3NlZFByb21pc2UsICgpID0+IHtcbiAgICAgICAgICAgIGlmICghcHJldmVudENsb3NlKSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd25XaXRoQWN0aW9uKCgpID0+IFdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckNsb3NlV2l0aEVycm9yUHJvcGFnYXRpb24od3JpdGVyKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaHV0ZG93bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQ2xvc2luZyBtdXN0IGJlIHByb3BhZ2F0ZWQgYmFja3dhcmRcbiAgICAgICAgaWYgKFdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KGRlc3QpIHx8IGRlc3QuX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgY29uc3QgZGVzdENsb3NlZCA9IG5ldyBUeXBlRXJyb3IoJ3RoZSBkZXN0aW5hdGlvbiB3cml0YWJsZSBzdHJlYW0gY2xvc2VkIGJlZm9yZSBhbGwgZGF0YSBjb3VsZCBiZSBwaXBlZCB0byBpdCcpO1xuICAgICAgICAgICAgaWYgKCFwcmV2ZW50Q2FuY2VsKSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd25XaXRoQWN0aW9uKCgpID0+IFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHNvdXJjZSwgZGVzdENsb3NlZCksIHRydWUsIGRlc3RDbG9zZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2h1dGRvd24odHJ1ZSwgZGVzdENsb3NlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShwaXBlTG9vcCgpKTtcbiAgICAgICAgZnVuY3Rpb24gd2FpdEZvcldyaXRlc1RvRmluaXNoKCkge1xuICAgICAgICAgICAgLy8gQW5vdGhlciB3cml0ZSBtYXkgaGF2ZSBzdGFydGVkIHdoaWxlIHdlIHdlcmUgd2FpdGluZyBvbiB0aGlzIGN1cnJlbnRXcml0ZSwgc28gd2UgaGF2ZSB0byBiZSBzdXJlIHRvIHdhaXRcbiAgICAgICAgICAgIC8vIGZvciB0aGF0IHRvby5cbiAgICAgICAgICAgIGNvbnN0IG9sZEN1cnJlbnRXcml0ZSA9IGN1cnJlbnRXcml0ZTtcbiAgICAgICAgICAgIHJldHVybiBQZXJmb3JtUHJvbWlzZVRoZW4oY3VycmVudFdyaXRlLCAoKSA9PiBvbGRDdXJyZW50V3JpdGUgIT09IGN1cnJlbnRXcml0ZSA/IHdhaXRGb3JXcml0ZXNUb0ZpbmlzaCgpIDogdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBpc09yQmVjb21lc0Vycm9yZWQoc3RyZWFtLCBwcm9taXNlLCBhY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb24oc3RyZWFtLl9zdG9yZWRFcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB1cG9uUmVqZWN0aW9uKHByb21pc2UsIGFjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNPckJlY29tZXNDbG9zZWQoc3RyZWFtLCBwcm9taXNlLCBhY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChzdHJlYW0uX3N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIGFjdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBvbkZ1bGZpbGxtZW50KHByb21pc2UsIGFjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gc2h1dGRvd25XaXRoQWN0aW9uKGFjdGlvbiwgb3JpZ2luYWxJc0Vycm9yLCBvcmlnaW5hbEVycm9yKSB7XG4gICAgICAgICAgICBpZiAoc2h1dHRpbmdEb3duKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2h1dHRpbmdEb3duID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChkZXN0Ll9zdGF0ZSA9PT0gJ3dyaXRhYmxlJyAmJiAhV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQoZGVzdCkpIHtcbiAgICAgICAgICAgICAgICB1cG9uRnVsZmlsbG1lbnQod2FpdEZvcldyaXRlc1RvRmluaXNoKCksIGRvVGhlUmVzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb1RoZVJlc3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZ1bmN0aW9uIGRvVGhlUmVzdCgpIHtcbiAgICAgICAgICAgICAgICB1cG9uUHJvbWlzZShhY3Rpb24oKSwgKCkgPT4gZmluYWxpemUob3JpZ2luYWxJc0Vycm9yLCBvcmlnaW5hbEVycm9yKSwgbmV3RXJyb3IgPT4gZmluYWxpemUodHJ1ZSwgbmV3RXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzaHV0ZG93bihpc0Vycm9yLCBlcnJvcikge1xuICAgICAgICAgICAgaWYgKHNodXR0aW5nRG93bikge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNodXR0aW5nRG93biA9IHRydWU7XG4gICAgICAgICAgICBpZiAoZGVzdC5fc3RhdGUgPT09ICd3cml0YWJsZScgJiYgIVdyaXRhYmxlU3RyZWFtQ2xvc2VRdWV1ZWRPckluRmxpZ2h0KGRlc3QpKSB7XG4gICAgICAgICAgICAgICAgdXBvbkZ1bGZpbGxtZW50KHdhaXRGb3JXcml0ZXNUb0ZpbmlzaCgpLCAoKSA9PiBmaW5hbGl6ZShpc0Vycm9yLCBlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZmluYWxpemUoaXNFcnJvciwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIGZpbmFsaXplKGlzRXJyb3IsIGVycm9yKSB7XG4gICAgICAgICAgICBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJSZWxlYXNlKHdyaXRlcik7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbVJlYWRlckdlbmVyaWNSZWxlYXNlKHJlYWRlcik7XG4gICAgICAgICAgICBpZiAoc2lnbmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBhYm9ydEFsZ29yaXRobSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNFcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxuLyoqXG4gKiBBbGxvd3MgY29udHJvbCBvZiBhIHtAbGluayBSZWFkYWJsZVN0cmVhbSB8IHJlYWRhYmxlIHN0cmVhbX0ncyBzdGF0ZSBhbmQgaW50ZXJuYWwgcXVldWUuXG4gKlxuICogQHB1YmxpY1xuICovXG5jbGFzcyBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgY29udHJvbGxlZCBzdHJlYW0ncyBpbnRlcm5hbCBxdWV1ZS4gSXQgY2FuIGJlIG5lZ2F0aXZlLCBpZiB0aGUgcXVldWUgaXNcbiAgICAgKiBvdmVyLWZ1bGwuIEFuIHVuZGVybHlpbmcgc291cmNlIG91Z2h0IHRvIHVzZSB0aGlzIGluZm9ybWF0aW9uIHRvIGRldGVybWluZSB3aGVuIGFuZCBob3cgdG8gYXBwbHkgYmFja3ByZXNzdXJlLlxuICAgICAqL1xuICAgIGdldCBkZXNpcmVkU2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgY29udHJvbGxlZCByZWFkYWJsZSBzdHJlYW0uIENvbnN1bWVycyB3aWxsIHN0aWxsIGJlIGFibGUgdG8gcmVhZCBhbnkgcHJldmlvdXNseS1lbnF1ZXVlZCBjaHVua3MgZnJvbVxuICAgICAqIHRoZSBzdHJlYW0sIGJ1dCBvbmNlIHRob3NlIGFyZSByZWFkLCB0aGUgc3RyZWFtIHdpbGwgYmVjb21lIGNsb3NlZC5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdjbG9zZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgc3RyZWFtIGlzIG5vdCBpbiBhIHN0YXRlIHRoYXQgcGVybWl0cyBjbG9zZScpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZSh0aGlzKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuayA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDEoJ2VucXVldWUnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIVJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYW5DbG9zZU9yRW5xdWV1ZSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIHN0cmVhbSBpcyBub3QgaW4gYSBzdGF0ZSB0aGF0IHBlcm1pdHMgZW5xdWV1ZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSh0aGlzLCBjaHVuayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVycm9ycyB0aGUgY29udHJvbGxlZCByZWFkYWJsZSBzdHJlYW0sIG1ha2luZyBhbGwgZnV0dXJlIGludGVyYWN0aW9ucyB3aXRoIGl0IGZhaWwgd2l0aCB0aGUgZ2l2ZW4gZXJyb3IgYGVgLlxuICAgICAqL1xuICAgIGVycm9yKGUgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcih0aGlzLCBlKTtcbiAgICB9XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIFtDYW5jZWxTdGVwc10ocmVhc29uKSB7XG4gICAgICAgIFJlc2V0UXVldWUodGhpcyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX2NhbmNlbEFsZ29yaXRobShyZWFzb24pO1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zKHRoaXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKiogQGludGVybmFsICovXG4gICAgW1B1bGxTdGVwc10ocmVhZFJlcXVlc3QpIHtcbiAgICAgICAgY29uc3Qgc3RyZWFtID0gdGhpcy5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgICAgICBpZiAodGhpcy5fcXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgY2h1bmsgPSBEZXF1ZXVlVmFsdWUodGhpcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5fY2xvc2VSZXF1ZXN0ZWQgJiYgdGhpcy5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyh0aGlzKTtcbiAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbUNsb3NlKHN0cmVhbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9jaHVua1N0ZXBzKGNodW5rKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtQWRkUmVhZFJlcXVlc3Qoc3RyZWFtLCByZWFkUmVxdWVzdCk7XG4gICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLCB7XG4gICAgY2xvc2U6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGVucXVldWU6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGVycm9yOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBkZXNpcmVkU2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnLCB7XG4gICAgICAgIHZhbHVlOiAnUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcicsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIuXG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19jb250cm9sbGVkUmVhZGFibGVTdHJlYW0nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzaG91bGRQdWxsID0gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsKGNvbnRyb2xsZXIpO1xuICAgIGlmICghc2hvdWxkUHVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjb250cm9sbGVyLl9wdWxsaW5nKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3B1bGxBZ2FpbiA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29udHJvbGxlci5fcHVsbGluZyA9IHRydWU7XG4gICAgY29uc3QgcHVsbFByb21pc2UgPSBjb250cm9sbGVyLl9wdWxsQWxnb3JpdGhtKCk7XG4gICAgdXBvblByb21pc2UocHVsbFByb21pc2UsICgpID0+IHtcbiAgICAgICAgY29udHJvbGxlci5fcHVsbGluZyA9IGZhbHNlO1xuICAgICAgICBpZiAoY29udHJvbGxlci5fcHVsbEFnYWluKSB7XG4gICAgICAgICAgICBjb250cm9sbGVyLl9wdWxsQWdhaW4gPSBmYWxzZTtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpO1xuICAgICAgICB9XG4gICAgfSwgZSA9PiB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJTaG91bGRDYWxsUHVsbChjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFjb250cm9sbGVyLl9zdGFydGVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKElzUmVhZGFibGVTdHJlYW1Mb2NrZWQoc3RyZWFtKSAmJiBSZWFkYWJsZVN0cmVhbUdldE51bVJlYWRSZXF1ZXN0cyhzdHJlYW0pID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgZGVzaXJlZFNpemUgPSBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUoY29udHJvbGxlcik7XG4gICAgaWYgKGRlc2lyZWRTaXplID4gMCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKSB7XG4gICAgY29udHJvbGxlci5fcHVsbEFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9jYW5jZWxBbGdvcml0aG0gPSB1bmRlZmluZWQ7XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lTaXplQWxnb3JpdGhtID0gdW5kZWZpbmVkO1xufVxuLy8gQSBjbGllbnQgb2YgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciBtYXkgdXNlIHRoZXNlIGZ1bmN0aW9ucyBkaXJlY3RseSB0byBieXBhc3Mgc3RhdGUgY2hlY2suXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UoY29udHJvbGxlcikge1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gdHJ1ZTtcbiAgICBpZiAoY29udHJvbGxlci5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgICAgIFJlYWRhYmxlU3RyZWFtQ2xvc2Uoc3RyZWFtKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtO1xuICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkgJiYgUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMoc3RyZWFtKSA+IDApIHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3Qoc3RyZWFtLCBjaHVuaywgZmFsc2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbGV0IGNodW5rU2l6ZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNodW5rU2l6ZSA9IGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobShjaHVuayk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGNodW5rU2l6ZUUpIHtcbiAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBjaHVua1NpemVFKTtcbiAgICAgICAgICAgIHRocm93IGNodW5rU2l6ZUU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIEVucXVldWVWYWx1ZVdpdGhTaXplKGNvbnRyb2xsZXIsIGNodW5rLCBjaHVua1NpemUpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlbnF1ZXVlRSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGVucXVldWVFKTtcbiAgICAgICAgICAgIHRocm93IGVucXVldWVFO1xuICAgICAgICB9XG4gICAgfVxuICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkKGNvbnRyb2xsZXIpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIGUpIHtcbiAgICBjb25zdCBzdHJlYW0gPSBjb250cm9sbGVyLl9jb250cm9sbGVkUmVhZGFibGVTdHJlYW07XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgIT09ICdyZWFkYWJsZScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBSZXNldFF1ZXVlKGNvbnRyb2xsZXIpO1xuICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcik7XG4gICAgUmVhZGFibGVTdHJlYW1FcnJvcihzdHJlYW0sIGUpO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplKGNvbnRyb2xsZXIpIHtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbS5fc3RhdGU7XG4gICAgaWYgKHN0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChzdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiBjb250cm9sbGVyLl9zdHJhdGVneUhXTSAtIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplO1xufVxuLy8gVGhpcyBpcyB1c2VkIGluIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBUcmFuc2Zvcm1TdHJlYW0uXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVySGFzQmFja3ByZXNzdXJlKGNvbnRyb2xsZXIpIHtcbiAgICBpZiAoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsKGNvbnRyb2xsZXIpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FuQ2xvc2VPckVucXVldWUoY29udHJvbGxlcikge1xuICAgIGNvbnN0IHN0YXRlID0gY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtLl9zdGF0ZTtcbiAgICBpZiAoIWNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkICYmIHN0YXRlID09PSAncmVhZGFibGUnKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBTZXRVcFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCBzdGFydEFsZ29yaXRobSwgcHVsbEFsZ29yaXRobSwgY2FuY2VsQWxnb3JpdGhtLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29udHJvbGxlci5fY29udHJvbGxlZFJlYWRhYmxlU3RyZWFtID0gc3RyZWFtO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlID0gdW5kZWZpbmVkO1xuICAgIGNvbnRyb2xsZXIuX3F1ZXVlVG90YWxTaXplID0gdW5kZWZpbmVkO1xuICAgIFJlc2V0UXVldWUoY29udHJvbGxlcik7XG4gICAgY29udHJvbGxlci5fc3RhcnRlZCA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX2Nsb3NlUmVxdWVzdGVkID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fcHVsbEFnYWluID0gZmFsc2U7XG4gICAgY29udHJvbGxlci5fcHVsbGluZyA9IGZhbHNlO1xuICAgIGNvbnRyb2xsZXIuX3N0cmF0ZWd5U2l6ZUFsZ29yaXRobSA9IHNpemVBbGdvcml0aG07XG4gICAgY29udHJvbGxlci5fc3RyYXRlZ3lIV00gPSBoaWdoV2F0ZXJNYXJrO1xuICAgIGNvbnRyb2xsZXIuX3B1bGxBbGdvcml0aG0gPSBwdWxsQWxnb3JpdGhtO1xuICAgIGNvbnRyb2xsZXIuX2NhbmNlbEFsZ29yaXRobSA9IGNhbmNlbEFsZ29yaXRobTtcbiAgICBzdHJlYW0uX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG4gICAgY29uc3Qgc3RhcnRSZXN1bHQgPSBzdGFydEFsZ29yaXRobSgpO1xuICAgIHVwb25Qcm9taXNlKHByb21pc2VSZXNvbHZlZFdpdGgoc3RhcnRSZXN1bHQpLCAoKSA9PiB7XG4gICAgICAgIGNvbnRyb2xsZXIuX3N0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZChjb250cm9sbGVyKTtcbiAgICB9LCByID0+IHtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGNvbnRyb2xsZXIsIHIpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2Uoc3RyZWFtLCB1bmRlcmx5aW5nU291cmNlLCBoaWdoV2F0ZXJNYXJrLCBzaXplQWxnb3JpdGhtKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUpO1xuICAgIGxldCBzdGFydEFsZ29yaXRobSA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICBsZXQgcHVsbEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBsZXQgY2FuY2VsQWxnb3JpdGhtID0gKCkgPT4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIGlmICh1bmRlcmx5aW5nU291cmNlLnN0YXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3RhcnRBbGdvcml0aG0gPSAoKSA9PiB1bmRlcmx5aW5nU291cmNlLnN0YXJ0KGNvbnRyb2xsZXIpO1xuICAgIH1cbiAgICBpZiAodW5kZXJseWluZ1NvdXJjZS5wdWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcHVsbEFsZ29yaXRobSA9ICgpID0+IHVuZGVybHlpbmdTb3VyY2UucHVsbChjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHVuZGVybHlpbmdTb3VyY2UuY2FuY2VsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2FuY2VsQWxnb3JpdGhtID0gcmVhc29uID0+IHVuZGVybHlpbmdTb3VyY2UuY2FuY2VsKHJlYXNvbik7XG4gICAgfVxuICAgIFNldFVwUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcihzdHJlYW0sIGNvbnRyb2xsZXIsIHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmssIHNpemVBbGdvcml0aG0pO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIuXG5mdW5jdGlvbiBkZWZhdWx0Q29udHJvbGxlckJyYW5kQ2hlY2tFeGNlcHRpb24kMShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJgKTtcbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1UZWUoc3RyZWFtLCBjbG9uZUZvckJyYW5jaDIpIHtcbiAgICBpZiAoSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKSkge1xuICAgICAgICByZXR1cm4gUmVhZGFibGVCeXRlU3RyZWFtVGVlKHN0cmVhbSk7XG4gICAgfVxuICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRUZWUoc3RyZWFtKTtcbn1cbmZ1bmN0aW9uIFJlYWRhYmxlU3RyZWFtRGVmYXVsdFRlZShzdHJlYW0sIGNsb25lRm9yQnJhbmNoMikge1xuICAgIGNvbnN0IHJlYWRlciA9IEFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIoc3RyZWFtKTtcbiAgICBsZXQgcmVhZGluZyA9IGZhbHNlO1xuICAgIGxldCBjYW5jZWxlZDEgPSBmYWxzZTtcbiAgICBsZXQgY2FuY2VsZWQyID0gZmFsc2U7XG4gICAgbGV0IHJlYXNvbjE7XG4gICAgbGV0IHJlYXNvbjI7XG4gICAgbGV0IGJyYW5jaDE7XG4gICAgbGV0IGJyYW5jaDI7XG4gICAgbGV0IHJlc29sdmVDYW5jZWxQcm9taXNlO1xuICAgIGNvbnN0IGNhbmNlbFByb21pc2UgPSBuZXdQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gICAgZnVuY3Rpb24gcHVsbEFsZ29yaXRobSgpIHtcbiAgICAgICAgaWYgKHJlYWRpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVzb2x2ZWRXaXRoKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVhZGluZyA9IHRydWU7XG4gICAgICAgIGNvbnN0IHJlYWRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgX2NodW5rU3RlcHM6IGNodW5rID0+IHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIG5lZWRzIHRvIGJlIGRlbGF5ZWQgYSBtaWNyb3Rhc2sgYmVjYXVzZSBpdCB0YWtlcyBhdCBsZWFzdCBhIG1pY3JvdGFzayB0byBkZXRlY3QgZXJyb3JzICh1c2luZ1xuICAgICAgICAgICAgICAgIC8vIHJlYWRlci5fY2xvc2VkUHJvbWlzZSBiZWxvdyksIGFuZCB3ZSB3YW50IGVycm9ycyBpbiBzdHJlYW0gdG8gZXJyb3IgYm90aCBicmFuY2hlcyBpbW1lZGlhdGVseS4gV2UgY2Fubm90IGxldFxuICAgICAgICAgICAgICAgIC8vIHN1Y2Nlc3NmdWwgc3luY2hyb25vdXNseS1hdmFpbGFibGUgcmVhZHMgZ2V0IGFoZWFkIG9mIGFzeW5jaHJvbm91c2x5LWF2YWlsYWJsZSBlcnJvcnMuXG4gICAgICAgICAgICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZWFkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNodW5rMSA9IGNodW5rO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaHVuazIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gd2F5IHRvIGFjY2VzcyB0aGUgY2xvbmluZyBjb2RlIHJpZ2h0IG5vdyBpbiB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBhZGQgb25lIHRoZW4gd2UnbGwgbmVlZCBhbiBpbXBsZW1lbnRhdGlvbiBmb3Igc2VyaWFsaXphYmxlIG9iamVjdHMuXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmICghY2FuY2VsZWQyICYmIGNsb25lRm9yQnJhbmNoMikge1xuICAgICAgICAgICAgICAgICAgICAvLyAgIGNodW5rMiA9IFN0cnVjdHVyZWREZXNlcmlhbGl6ZShTdHJ1Y3R1cmVkU2VyaWFsaXplKGNodW5rMikpO1xuICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFbnF1ZXVlKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmsyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbG9zZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDEgfHwgIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfZXJyb3JTdGVwczogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyUmVhZChyZWFkZXIsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2FuY2VsMUFsZ29yaXRobShyZWFzb24pIHtcbiAgICAgICAgY2FuY2VsZWQxID0gdHJ1ZTtcbiAgICAgICAgcmVhc29uMSA9IHJlYXNvbjtcbiAgICAgICAgaWYgKGNhbmNlbGVkMikge1xuICAgICAgICAgICAgY29uc3QgY29tcG9zaXRlUmVhc29uID0gQ3JlYXRlQXJyYXlGcm9tTGlzdChbcmVhc29uMSwgcmVhc29uMl0pO1xuICAgICAgICAgICAgY29uc3QgY2FuY2VsUmVzdWx0ID0gUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjb21wb3NpdGVSZWFzb24pO1xuICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoY2FuY2VsUmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FuY2VsUHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2FuY2VsMkFsZ29yaXRobShyZWFzb24pIHtcbiAgICAgICAgY2FuY2VsZWQyID0gdHJ1ZTtcbiAgICAgICAgcmVhc29uMiA9IHJlYXNvbjtcbiAgICAgICAgaWYgKGNhbmNlbGVkMSkge1xuICAgICAgICAgICAgY29uc3QgY29tcG9zaXRlUmVhc29uID0gQ3JlYXRlQXJyYXlGcm9tTGlzdChbcmVhc29uMSwgcmVhc29uMl0pO1xuICAgICAgICAgICAgY29uc3QgY2FuY2VsUmVzdWx0ID0gUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjb21wb3NpdGVSZWFzb24pO1xuICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoY2FuY2VsUmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FuY2VsUHJvbWlzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gc3RhcnRBbGdvcml0aG0oKSB7XG4gICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICB9XG4gICAgYnJhbmNoMSA9IENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWwxQWxnb3JpdGhtKTtcbiAgICBicmFuY2gyID0gQ3JlYXRlUmVhZGFibGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbDJBbGdvcml0aG0pO1xuICAgIHVwb25SZWplY3Rpb24ocmVhZGVyLl9jbG9zZWRQcm9taXNlLCAocikgPT4ge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IoYnJhbmNoMS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCByKTtcbiAgICAgICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgcik7XG4gICAgICAgIGlmICghY2FuY2VsZWQxIHx8ICFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gW2JyYW5jaDEsIGJyYW5jaDJdO1xufVxuZnVuY3Rpb24gUmVhZGFibGVCeXRlU3RyZWFtVGVlKHN0cmVhbSkge1xuICAgIGxldCByZWFkZXIgPSBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHN0cmVhbSk7XG4gICAgbGV0IHJlYWRpbmcgPSBmYWxzZTtcbiAgICBsZXQgY2FuY2VsZWQxID0gZmFsc2U7XG4gICAgbGV0IGNhbmNlbGVkMiA9IGZhbHNlO1xuICAgIGxldCByZWFzb24xO1xuICAgIGxldCByZWFzb24yO1xuICAgIGxldCBicmFuY2gxO1xuICAgIGxldCBicmFuY2gyO1xuICAgIGxldCByZXNvbHZlQ2FuY2VsUHJvbWlzZTtcbiAgICBjb25zdCBjYW5jZWxQcm9taXNlID0gbmV3UHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UgPSByZXNvbHZlO1xuICAgIH0pO1xuICAgIGZ1bmN0aW9uIGZvcndhcmRSZWFkZXJFcnJvcih0aGlzUmVhZGVyKSB7XG4gICAgICAgIHVwb25SZWplY3Rpb24odGhpc1JlYWRlci5fY2xvc2VkUHJvbWlzZSwgciA9PiB7XG4gICAgICAgICAgICBpZiAodGhpc1JlYWRlciAhPT0gcmVhZGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgcik7XG4gICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCByKTtcbiAgICAgICAgICAgIGlmICghY2FuY2VsZWQxIHx8ICFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbFdpdGhEZWZhdWx0UmVhZGVyKCkge1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgcmVhZGVyID0gQWNxdWlyZVJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlcihzdHJlYW0pO1xuICAgICAgICAgICAgZm9yd2FyZFJlYWRlckVycm9yKHJlYWRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVhZFJlcXVlc3QgPSB7XG4gICAgICAgICAgICBfY2h1bmtTdGVwczogY2h1bmsgPT4ge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgbmVlZHMgdG8gYmUgZGVsYXllZCBhIG1pY3JvdGFzayBiZWNhdXNlIGl0IHRha2VzIGF0IGxlYXN0IGEgbWljcm90YXNrIHRvIGRldGVjdCBlcnJvcnMgKHVzaW5nXG4gICAgICAgICAgICAgICAgLy8gcmVhZGVyLl9jbG9zZWRQcm9taXNlIGJlbG93KSwgYW5kIHdlIHdhbnQgZXJyb3JzIGluIHN0cmVhbSB0byBlcnJvciBib3RoIGJyYW5jaGVzIGltbWVkaWF0ZWx5LiBXZSBjYW5ub3QgbGV0XG4gICAgICAgICAgICAgICAgLy8gc3VjY2Vzc2Z1bCBzeW5jaHJvbm91c2x5LWF2YWlsYWJsZSByZWFkcyBnZXQgYWhlYWQgb2YgYXN5bmNocm9ub3VzbHktYXZhaWxhYmxlIGVycm9ycy5cbiAgICAgICAgICAgICAgICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2h1bmsxID0gY2h1bms7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjaHVuazIgPSBjaHVuaztcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDEgJiYgIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHVuazIgPSBDbG9uZUFzVWludDhBcnJheShjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXRjaCAoY2xvbmVFKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2xvbmVFKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRXJyb3IoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjbG9uZUUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHN0cmVhbSwgY2xvbmVFKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjYW5jZWxlZDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlKGJyYW5jaDIuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmsyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGlmICghY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZShicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMikge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2UoYnJhbmNoMi5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlci5fcGVuZGluZ1B1bGxJbnRvcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKGJyYW5jaDEuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIuX3BlbmRpbmdQdWxsSW50b3MubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWNhbmNlbGVkMSB8fCAhY2FuY2VsZWQyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXJSZWFkKHJlYWRlciwgcmVhZFJlcXVlc3QpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBwdWxsV2l0aEJZT0JSZWFkZXIodmlldywgZm9yQnJhbmNoMikge1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICAgICAgUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZShyZWFkZXIpO1xuICAgICAgICAgICAgcmVhZGVyID0gQWNxdWlyZVJlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihzdHJlYW0pO1xuICAgICAgICAgICAgZm9yd2FyZFJlYWRlckVycm9yKHJlYWRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYnlvYkJyYW5jaCA9IGZvckJyYW5jaDIgPyBicmFuY2gyIDogYnJhbmNoMTtcbiAgICAgICAgY29uc3Qgb3RoZXJCcmFuY2ggPSBmb3JCcmFuY2gyID8gYnJhbmNoMSA6IGJyYW5jaDI7XG4gICAgICAgIGNvbnN0IHJlYWRJbnRvUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIF9jaHVua1N0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBiZSBkZWxheWVkIGEgbWljcm90YXNrIGJlY2F1c2UgaXQgdGFrZXMgYXQgbGVhc3QgYSBtaWNyb3Rhc2sgdG8gZGV0ZWN0IGVycm9ycyAodXNpbmdcbiAgICAgICAgICAgICAgICAvLyByZWFkZXIuX2Nsb3NlZFByb21pc2UgYmVsb3cpLCBhbmQgd2Ugd2FudCBlcnJvcnMgaW4gc3RyZWFtIHRvIGVycm9yIGJvdGggYnJhbmNoZXMgaW1tZWRpYXRlbHkuIFdlIGNhbm5vdCBsZXRcbiAgICAgICAgICAgICAgICAvLyBzdWNjZXNzZnVsIHN5bmNocm9ub3VzbHktYXZhaWxhYmxlIHJlYWRzIGdldCBhaGVhZCBvZiBhc3luY2hyb25vdXNseS1hdmFpbGFibGUgZXJyb3JzLlxuICAgICAgICAgICAgICAgIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBieW9iQ2FuY2VsZWQgPSBmb3JCcmFuY2gyID8gY2FuY2VsZWQyIDogY2FuY2VsZWQxO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdGhlckNhbmNlbGVkID0gZm9yQnJhbmNoMiA/IGNhbmNlbGVkMSA6IGNhbmNlbGVkMjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFvdGhlckNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY2xvbmVkQ2h1bms7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lZENodW5rID0gQ2xvbmVBc1VpbnQ4QXJyYXkoY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGNsb25lRSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFcnJvcihieW9iQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNsb25lRSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yKG90aGVyQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNsb25lRSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUNhbmNlbFByb21pc2UoUmVhZGFibGVTdHJlYW1DYW5jZWwoc3RyZWFtLCBjbG9uZUUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWJ5b2JDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kV2l0aE5ld1ZpZXcoYnlvYkJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjaHVuayk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyRW5xdWV1ZShvdGhlckJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLCBjbG9uZWRDaHVuayk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWJ5b2JDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRXaXRoTmV3VmlldyhieW9iQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9jbG9zZVN0ZXBzOiBjaHVuayA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ5b2JDYW5jZWxlZCA9IGZvckJyYW5jaDIgPyBjYW5jZWxlZDIgOiBjYW5jZWxlZDE7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3RoZXJDYW5jZWxlZCA9IGZvckJyYW5jaDIgPyBjYW5jZWxlZDEgOiBjYW5jZWxlZDI7XG4gICAgICAgICAgICAgICAgaWYgKCFieW9iQ2FuY2VsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsb3NlKGJ5b2JCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghb3RoZXJDYW5jZWxlZCkge1xuICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xvc2Uob3RoZXJCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjaHVuayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghYnlvYkNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZFdpdGhOZXdWaWV3KGJ5b2JCcmFuY2guX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgY2h1bmspO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghb3RoZXJDYW5jZWxlZCAmJiBvdGhlckJyYW5jaC5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyLl9wZW5kaW5nUHVsbEludG9zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kKG90aGVyQnJhbmNoLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIsIDApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghYnlvYkNhbmNlbGVkIHx8ICFvdGhlckNhbmNlbGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVDYW5jZWxQcm9taXNlKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9lcnJvclN0ZXBzOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkKHJlYWRlciwgdmlldywgcmVhZEludG9SZXF1ZXN0KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbDFBbGdvcml0aG0oKSB7XG4gICAgICAgIGlmIChyZWFkaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJlYWRpbmcgPSB0cnVlO1xuICAgICAgICBjb25zdCBieW9iUmVxdWVzdCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChicmFuY2gxLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHB1bGxXaXRoRGVmYXVsdFJlYWRlcigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHVsbFdpdGhCWU9CUmVhZGVyKGJ5b2JSZXF1ZXN0Ll92aWV3LCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcHVsbDJBbGdvcml0aG0oKSB7XG4gICAgICAgIGlmIChyZWFkaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJlYWRpbmcgPSB0cnVlO1xuICAgICAgICBjb25zdCBieW9iUmVxdWVzdCA9IFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJHZXRCWU9CUmVxdWVzdChicmFuY2gyLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgICAgICBpZiAoYnlvYlJlcXVlc3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHB1bGxXaXRoRGVmYXVsdFJlYWRlcigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcHVsbFdpdGhCWU9CUmVhZGVyKGJ5b2JSZXF1ZXN0Ll92aWV3LCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWwxQWxnb3JpdGhtKHJlYXNvbikge1xuICAgICAgICBjYW5jZWxlZDEgPSB0cnVlO1xuICAgICAgICByZWFzb24xID0gcmVhc29uO1xuICAgICAgICBpZiAoY2FuY2VsZWQyKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wb3NpdGVSZWFzb24gPSBDcmVhdGVBcnJheUZyb21MaXN0KFtyZWFzb24xLCByZWFzb24yXSk7XG4gICAgICAgICAgICBjb25zdCBjYW5jZWxSZXN1bHQgPSBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIGNvbXBvc2l0ZVJlYXNvbik7XG4gICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZShjYW5jZWxSZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYW5jZWxQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWwyQWxnb3JpdGhtKHJlYXNvbikge1xuICAgICAgICBjYW5jZWxlZDIgPSB0cnVlO1xuICAgICAgICByZWFzb24yID0gcmVhc29uO1xuICAgICAgICBpZiAoY2FuY2VsZWQxKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wb3NpdGVSZWFzb24gPSBDcmVhdGVBcnJheUZyb21MaXN0KFtyZWFzb24xLCByZWFzb24yXSk7XG4gICAgICAgICAgICBjb25zdCBjYW5jZWxSZXN1bHQgPSBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIGNvbXBvc2l0ZVJlYXNvbik7XG4gICAgICAgICAgICByZXNvbHZlQ2FuY2VsUHJvbWlzZShjYW5jZWxSZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYW5jZWxQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzdGFydEFsZ29yaXRobSgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBicmFuY2gxID0gQ3JlYXRlUmVhZGFibGVCeXRlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsMUFsZ29yaXRobSwgY2FuY2VsMUFsZ29yaXRobSk7XG4gICAgYnJhbmNoMiA9IENyZWF0ZVJlYWRhYmxlQnl0ZVN0cmVhbShzdGFydEFsZ29yaXRobSwgcHVsbDJBbGdvcml0aG0sIGNhbmNlbDJBbGdvcml0aG0pO1xuICAgIGZvcndhcmRSZWFkZXJFcnJvcihyZWFkZXIpO1xuICAgIHJldHVybiBbYnJhbmNoMSwgYnJhbmNoMl07XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nRGVmYXVsdE9yQnl0ZVNvdXJjZShzb3VyY2UsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KHNvdXJjZSwgY29udGV4dCk7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSBzb3VyY2U7XG4gICAgY29uc3QgYXV0b0FsbG9jYXRlQ2h1bmtTaXplID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLmF1dG9BbGxvY2F0ZUNodW5rU2l6ZTtcbiAgICBjb25zdCBjYW5jZWwgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuY2FuY2VsO1xuICAgIGNvbnN0IHB1bGwgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwucHVsbDtcbiAgICBjb25zdCBzdGFydCA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5zdGFydDtcbiAgICBjb25zdCB0eXBlID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnR5cGU7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYXV0b0FsbG9jYXRlQ2h1bmtTaXplOiBhdXRvQWxsb2NhdGVDaHVua1NpemUgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuc2lnbmVkTG9uZ0xvbmdXaXRoRW5mb3JjZVJhbmdlKGF1dG9BbGxvY2F0ZUNodW5rU2l6ZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnYXV0b0FsbG9jYXRlQ2h1bmtTaXplJyB0aGF0YCksXG4gICAgICAgIGNhbmNlbDogY2FuY2VsID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlQ2FuY2VsQ2FsbGJhY2soY2FuY2VsLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnY2FuY2VsJyB0aGF0YCksXG4gICAgICAgIHB1bGw6IHB1bGwgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFVuZGVybHlpbmdTb3VyY2VQdWxsQ2FsbGJhY2socHVsbCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3B1bGwnIHRoYXRgKSxcbiAgICAgICAgc3RhcnQ6IHN0YXJ0ID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHR5cGU6IHR5cGUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGNvbnZlcnRSZWFkYWJsZVN0cmVhbVR5cGUodHlwZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAndHlwZScgdGhhdGApXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlQ2FuY2VsQ2FsbGJhY2soZm4sIG9yaWdpbmFsLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RnVuY3Rpb24oZm4sIGNvbnRleHQpO1xuICAgIHJldHVybiAocmVhc29uKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtyZWFzb25dKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlUHVsbENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHByb21pc2VDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRVbmRlcmx5aW5nU291cmNlU3RhcnRDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjb250cm9sbGVyKSA9PiByZWZsZWN0Q2FsbChmbiwgb3JpZ2luYWwsIFtjb250cm9sbGVyXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0UmVhZGFibGVTdHJlYW1UeXBlKHR5cGUsIGNvbnRleHQpIHtcbiAgICB0eXBlID0gYCR7dHlwZX1gO1xuICAgIGlmICh0eXBlICE9PSAnYnl0ZXMnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7Y29udGV4dH0gJyR7dHlwZX0nIGlzIG5vdCBhIHZhbGlkIGVudW1lcmF0aW9uIHZhbHVlIGZvciBSZWFkYWJsZVN0cmVhbVR5cGVgKTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGU7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWFkZXJPcHRpb25zKG9wdGlvbnMsIGNvbnRleHQpIHtcbiAgICBhc3NlcnREaWN0aW9uYXJ5KG9wdGlvbnMsIGNvbnRleHQpO1xuICAgIGNvbnN0IG1vZGUgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubW9kZTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtb2RlOiBtb2RlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjb252ZXJ0UmVhZGFibGVTdHJlYW1SZWFkZXJNb2RlKG1vZGUsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ21vZGUnIHRoYXRgKVxuICAgIH07XG59XG5mdW5jdGlvbiBjb252ZXJ0UmVhZGFibGVTdHJlYW1SZWFkZXJNb2RlKG1vZGUsIGNvbnRleHQpIHtcbiAgICBtb2RlID0gYCR7bW9kZX1gO1xuICAgIGlmIChtb2RlICE9PSAnYnlvYicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtjb250ZXh0fSAnJHttb2RlfScgaXMgbm90IGEgdmFsaWQgZW51bWVyYXRpb24gdmFsdWUgZm9yIFJlYWRhYmxlU3RyZWFtUmVhZGVyTW9kZWApO1xuICAgIH1cbiAgICByZXR1cm4gbW9kZTtcbn1cblxuZnVuY3Rpb24gY29udmVydEl0ZXJhdG9yT3B0aW9ucyhvcHRpb25zLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShvcHRpb25zLCBjb250ZXh0KTtcbiAgICBjb25zdCBwcmV2ZW50Q2FuY2VsID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDYW5jZWw7XG4gICAgcmV0dXJuIHsgcHJldmVudENhbmNlbDogQm9vbGVhbihwcmV2ZW50Q2FuY2VsKSB9O1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0UGlwZU9wdGlvbnMob3B0aW9ucywgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkob3B0aW9ucywgY29udGV4dCk7XG4gICAgY29uc3QgcHJldmVudEFib3J0ID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRBYm9ydDtcbiAgICBjb25zdCBwcmV2ZW50Q2FuY2VsID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDYW5jZWw7XG4gICAgY29uc3QgcHJldmVudENsb3NlID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZXZlbnRDbG9zZTtcbiAgICBjb25zdCBzaWduYWwgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMuc2lnbmFsO1xuICAgIGlmIChzaWduYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhc3NlcnRBYm9ydFNpZ25hbChzaWduYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3NpZ25hbCcgdGhhdGApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBwcmV2ZW50QWJvcnQ6IEJvb2xlYW4ocHJldmVudEFib3J0KSxcbiAgICAgICAgcHJldmVudENhbmNlbDogQm9vbGVhbihwcmV2ZW50Q2FuY2VsKSxcbiAgICAgICAgcHJldmVudENsb3NlOiBCb29sZWFuKHByZXZlbnRDbG9zZSksXG4gICAgICAgIHNpZ25hbFxuICAgIH07XG59XG5mdW5jdGlvbiBhc3NlcnRBYm9ydFNpZ25hbChzaWduYWwsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzQWJvcnRTaWduYWwoc2lnbmFsKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2NvbnRleHR9IGlzIG5vdCBhbiBBYm9ydFNpZ25hbC5gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpcihwYWlyLCBjb250ZXh0KSB7XG4gICAgYXNzZXJ0RGljdGlvbmFyeShwYWlyLCBjb250ZXh0KTtcbiAgICBjb25zdCByZWFkYWJsZSA9IHBhaXIgPT09IG51bGwgfHwgcGFpciA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFpci5yZWFkYWJsZTtcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKHJlYWRhYmxlLCAncmVhZGFibGUnLCAnUmVhZGFibGVXcml0YWJsZVBhaXInKTtcbiAgICBhc3NlcnRSZWFkYWJsZVN0cmVhbShyZWFkYWJsZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAncmVhZGFibGUnIHRoYXRgKTtcbiAgICBjb25zdCB3cml0YWJsZSA9IHBhaXIgPT09IG51bGwgfHwgcGFpciA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFpci53cml0YWJsZTtcbiAgICBhc3NlcnRSZXF1aXJlZEZpZWxkKHdyaXRhYmxlLCAnd3JpdGFibGUnLCAnUmVhZGFibGVXcml0YWJsZVBhaXInKTtcbiAgICBhc3NlcnRXcml0YWJsZVN0cmVhbSh3cml0YWJsZSwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnd3JpdGFibGUnIHRoYXRgKTtcbiAgICByZXR1cm4geyByZWFkYWJsZSwgd3JpdGFibGUgfTtcbn1cblxuLyoqXG4gKiBBIHJlYWRhYmxlIHN0cmVhbSByZXByZXNlbnRzIGEgc291cmNlIG9mIGRhdGEsIGZyb20gd2hpY2ggeW91IGNhbiByZWFkLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuY2xhc3MgUmVhZGFibGVTdHJlYW0ge1xuICAgIGNvbnN0cnVjdG9yKHJhd1VuZGVybHlpbmdTb3VyY2UgPSB7fSwgcmF3U3RyYXRlZ3kgPSB7fSkge1xuICAgICAgICBpZiAocmF3VW5kZXJseWluZ1NvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByYXdVbmRlcmx5aW5nU291cmNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFzc2VydE9iamVjdChyYXdVbmRlcmx5aW5nU291cmNlLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RyYXRlZ3kgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5KHJhd1N0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCB1bmRlcmx5aW5nU291cmNlID0gY29udmVydFVuZGVybHlpbmdEZWZhdWx0T3JCeXRlU291cmNlKHJhd1VuZGVybHlpbmdTb3VyY2UsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgSW5pdGlhbGl6ZVJlYWRhYmxlU3RyZWFtKHRoaXMpO1xuICAgICAgICBpZiAodW5kZXJseWluZ1NvdXJjZS50eXBlID09PSAnYnl0ZXMnKSB7XG4gICAgICAgICAgICBpZiAoc3RyYXRlZ3kuc2l6ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSBzdHJhdGVneSBmb3IgYSBieXRlIHN0cmVhbSBjYW5ub3QgaGF2ZSBhIHNpemUgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGhpZ2hXYXRlck1hcmsgPSBFeHRyYWN0SGlnaFdhdGVyTWFyayhzdHJhdGVneSwgMCk7XG4gICAgICAgICAgICBTZXRVcFJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGcm9tVW5kZXJseWluZ1NvdXJjZSh0aGlzLCB1bmRlcmx5aW5nU291cmNlLCBoaWdoV2F0ZXJNYXJrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShzdHJhdGVneSk7XG4gICAgICAgICAgICBjb25zdCBoaWdoV2F0ZXJNYXJrID0gRXh0cmFjdEhpZ2hXYXRlck1hcmsoc3RyYXRlZ3ksIDEpO1xuICAgICAgICAgICAgU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2UodGhpcywgdW5kZXJseWluZ1NvdXJjZSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hldGhlciBvciBub3QgdGhlIHJlYWRhYmxlIHN0cmVhbSBpcyBsb2NrZWQgdG8gYSB7QGxpbmsgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyIHwgcmVhZGVyfS5cbiAgICAgKi9cbiAgICBnZXQgbG9ja2VkKCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnbG9ja2VkJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIElzUmVhZGFibGVTdHJlYW1Mb2NrZWQodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgdGhlIHN0cmVhbSwgc2lnbmFsaW5nIGEgbG9zcyBvZiBpbnRlcmVzdCBpbiB0aGUgc3RyZWFtIGJ5IGEgY29uc3VtZXIuXG4gICAgICpcbiAgICAgKiBUaGUgc3VwcGxpZWQgYHJlYXNvbmAgYXJndW1lbnQgd2lsbCBiZSBnaXZlbiB0byB0aGUgdW5kZXJseWluZyBzb3VyY2UncyB7QGxpbmsgVW5kZXJseWluZ1NvdXJjZS5jYW5jZWwgfCBjYW5jZWwoKX1cbiAgICAgKiBtZXRob2QsIHdoaWNoIG1pZ2h0IG9yIG1pZ2h0IG5vdCB1c2UgaXQuXG4gICAgICovXG4gICAgY2FuY2VsKHJlYXNvbiA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgnY2FuY2VsJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FuY2VsIGEgc3RyZWFtIHRoYXQgYWxyZWFkeSBoYXMgYSByZWFkZXInKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWRhYmxlU3RyZWFtQ2FuY2VsKHRoaXMsIHJlYXNvbik7XG4gICAgfVxuICAgIGdldFJlYWRlcihyYXdPcHRpb25zID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNSZWFkYWJsZVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbiQxKCdnZXRSZWFkZXInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvcHRpb25zID0gY29udmVydFJlYWRlck9wdGlvbnMocmF3T3B0aW9ucywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAob3B0aW9ucy5tb2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBBY3F1aXJlUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBBY3F1aXJlUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyKHRoaXMpO1xuICAgIH1cbiAgICBwaXBlVGhyb3VnaChyYXdUcmFuc2Zvcm0sIHJhd09wdGlvbnMgPSB7fSkge1xuICAgICAgICBpZiAoIUlzUmVhZGFibGVTdHJlYW0odGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IHN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMSgncGlwZVRocm91Z2gnKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NlcnRSZXF1aXJlZEFyZ3VtZW50KHJhd1RyYW5zZm9ybSwgMSwgJ3BpcGVUaHJvdWdoJyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGNvbnZlcnRSZWFkYWJsZVdyaXRhYmxlUGFpcihyYXdUcmFuc2Zvcm0sICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbnZlcnRQaXBlT3B0aW9ucyhyYXdPcHRpb25zLCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbUxvY2tlZCh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUaHJvdWdoIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFJlYWRhYmxlU3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKElzV3JpdGFibGVTdHJlYW1Mb2NrZWQodHJhbnNmb3JtLndyaXRhYmxlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUaHJvdWdoIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFdyaXRhYmxlU3RyZWFtJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IFJlYWRhYmxlU3RyZWFtUGlwZVRvKHRoaXMsIHRyYW5zZm9ybS53cml0YWJsZSwgb3B0aW9ucy5wcmV2ZW50Q2xvc2UsIG9wdGlvbnMucHJldmVudEFib3J0LCBvcHRpb25zLnByZXZlbnRDYW5jZWwsIG9wdGlvbnMuc2lnbmFsKTtcbiAgICAgICAgc2V0UHJvbWlzZUlzSGFuZGxlZFRvVHJ1ZShwcm9taXNlKTtcbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybS5yZWFkYWJsZTtcbiAgICB9XG4gICAgcGlwZVRvKGRlc3RpbmF0aW9uLCByYXdPcHRpb25zID0ge30pIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3BpcGVUbycpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVzdGluYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgoYFBhcmFtZXRlciAxIGlzIHJlcXVpcmVkIGluICdwaXBlVG8nLmApO1xuICAgICAgICB9XG4gICAgICAgIGlmICghSXNXcml0YWJsZVN0cmVhbShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKG5ldyBUeXBlRXJyb3IoYFJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZS5waXBlVG8ncyBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgV3JpdGFibGVTdHJlYW1gKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBvcHRpb25zID0gY29udmVydFBpcGVPcHRpb25zKHJhd09wdGlvbnMsICdTZWNvbmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlUmVqZWN0ZWRXaXRoKGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChuZXcgVHlwZUVycm9yKCdSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUucGlwZVRvIGNhbm5vdCBiZSB1c2VkIG9uIGEgbG9ja2VkIFJlYWRhYmxlU3RyZWFtJykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChJc1dyaXRhYmxlU3RyZWFtTG9ja2VkKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgobmV3IFR5cGVFcnJvcignUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnBpcGVUbyBjYW5ub3QgYmUgdXNlZCBvbiBhIGxvY2tlZCBXcml0YWJsZVN0cmVhbScpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhZGFibGVTdHJlYW1QaXBlVG8odGhpcywgZGVzdGluYXRpb24sIG9wdGlvbnMucHJldmVudENsb3NlLCBvcHRpb25zLnByZXZlbnRBYm9ydCwgb3B0aW9ucy5wcmV2ZW50Q2FuY2VsLCBvcHRpb25zLnNpZ25hbCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRlZXMgdGhpcyByZWFkYWJsZSBzdHJlYW0sIHJldHVybmluZyBhIHR3by1lbGVtZW50IGFycmF5IGNvbnRhaW5pbmcgdGhlIHR3byByZXN1bHRpbmcgYnJhbmNoZXMgYXNcbiAgICAgKiBuZXcge0BsaW5rIFJlYWRhYmxlU3RyZWFtfSBpbnN0YW5jZXMuXG4gICAgICpcbiAgICAgKiBUZWVpbmcgYSBzdHJlYW0gd2lsbCBsb2NrIGl0LCBwcmV2ZW50aW5nIGFueSBvdGhlciBjb25zdW1lciBmcm9tIGFjcXVpcmluZyBhIHJlYWRlci5cbiAgICAgKiBUbyBjYW5jZWwgdGhlIHN0cmVhbSwgY2FuY2VsIGJvdGggb2YgdGhlIHJlc3VsdGluZyBicmFuY2hlczsgYSBjb21wb3NpdGUgY2FuY2VsbGF0aW9uIHJlYXNvbiB3aWxsIHRoZW4gYmVcbiAgICAgKiBwcm9wYWdhdGVkIHRvIHRoZSBzdHJlYW0ncyB1bmRlcmx5aW5nIHNvdXJjZS5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCB0aGUgY2h1bmtzIHNlZW4gaW4gZWFjaCBicmFuY2ggd2lsbCBiZSB0aGUgc2FtZSBvYmplY3QuIElmIHRoZSBjaHVua3MgYXJlIG5vdCBpbW11dGFibGUsXG4gICAgICogdGhpcyBjb3VsZCBhbGxvdyBpbnRlcmZlcmVuY2UgYmV0d2VlbiB0aGUgdHdvIGJyYW5jaGVzLlxuICAgICAqL1xuICAgIHRlZSgpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3RlZScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJyYW5jaGVzID0gUmVhZGFibGVTdHJlYW1UZWUodGhpcyk7XG4gICAgICAgIHJldHVybiBDcmVhdGVBcnJheUZyb21MaXN0KGJyYW5jaGVzKTtcbiAgICB9XG4gICAgdmFsdWVzKHJhd09wdGlvbnMgPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKCFJc1JlYWRhYmxlU3RyZWFtKHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEoJ3ZhbHVlcycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb252ZXJ0SXRlcmF0b3JPcHRpb25zKHJhd09wdGlvbnMsICdGaXJzdCBwYXJhbWV0ZXInKTtcbiAgICAgICAgcmV0dXJuIEFjcXVpcmVSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IodGhpcywgb3B0aW9ucy5wcmV2ZW50Q2FuY2VsKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBjYW5jZWw6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGdldFJlYWRlcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgcGlwZVRocm91Z2g6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIHBpcGVUbzogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgdGVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB2YWx1ZXM6IHsgZW51bWVyYWJsZTogdHJ1ZSB9LFxuICAgIGxvY2tlZDogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1JlYWRhYmxlU3RyZWFtJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLmFzeW5jSXRlcmF0b3IgPT09ICdzeW1ib2wnKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlYWRhYmxlU3RyZWFtLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwuYXN5bmNJdGVyYXRvciwge1xuICAgICAgICB2YWx1ZTogUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlLnZhbHVlcyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pO1xufVxuLy8gQWJzdHJhY3Qgb3BlcmF0aW9ucyBmb3IgdGhlIFJlYWRhYmxlU3RyZWFtLlxuLy8gVGhyb3dzIGlmIGFuZCBvbmx5IGlmIHN0YXJ0QWxnb3JpdGhtIHRocm93cy5cbmZ1bmN0aW9uIENyZWF0ZVJlYWRhYmxlU3RyZWFtKHN0YXJ0QWxnb3JpdGhtLCBwdWxsQWxnb3JpdGhtLCBjYW5jZWxBbGdvcml0aG0sIGhpZ2hXYXRlck1hcmsgPSAxLCBzaXplQWxnb3JpdGhtID0gKCkgPT4gMSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlKTtcbiAgICBJbml0aWFsaXplUmVhZGFibGVTdHJlYW0oc3RyZWFtKTtcbiAgICBjb25zdCBjb250cm9sbGVyID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLnByb3RvdHlwZSk7XG4gICAgU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgaGlnaFdhdGVyTWFyaywgc2l6ZUFsZ29yaXRobSk7XG4gICAgcmV0dXJuIHN0cmVhbTtcbn1cbi8vIFRocm93cyBpZiBhbmQgb25seSBpZiBzdGFydEFsZ29yaXRobSB0aHJvd3MuXG5mdW5jdGlvbiBDcmVhdGVSZWFkYWJsZUJ5dGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSkge1xuICAgIGNvbnN0IHN0cmVhbSA9IE9iamVjdC5jcmVhdGUoUmVhZGFibGVTdHJlYW0ucHJvdG90eXBlKTtcbiAgICBJbml0aWFsaXplUmVhZGFibGVTdHJlYW0oc3RyZWFtKTtcbiAgICBjb25zdCBjb250cm9sbGVyID0gT2JqZWN0LmNyZWF0ZShSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLnByb3RvdHlwZSk7XG4gICAgU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyKHN0cmVhbSwgY29udHJvbGxlciwgc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgMCwgdW5kZWZpbmVkKTtcbiAgICByZXR1cm4gc3RyZWFtO1xufVxuZnVuY3Rpb24gSW5pdGlhbGl6ZVJlYWRhYmxlU3RyZWFtKHN0cmVhbSkge1xuICAgIHN0cmVhbS5fc3RhdGUgPSAncmVhZGFibGUnO1xuICAgIHN0cmVhbS5fcmVhZGVyID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fc3RvcmVkRXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgc3RyZWFtLl9kaXN0dXJiZWQgPSBmYWxzZTtcbn1cbmZ1bmN0aW9uIElzUmVhZGFibGVTdHJlYW0oeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXInKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW07XG59XG5mdW5jdGlvbiBJc1JlYWRhYmxlU3RyZWFtTG9ja2VkKHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uX3JlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vLyBSZWFkYWJsZVN0cmVhbSBBUEkgZXhwb3NlZCBmb3IgY29udHJvbGxlcnMuXG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUNhbmNlbChzdHJlYW0sIHJlYXNvbikge1xuICAgIHN0cmVhbS5fZGlzdHVyYmVkID0gdHJ1ZTtcbiAgICBpZiAoc3RyZWFtLl9zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICB9XG4gICAgaWYgKHN0cmVhbS5fc3RhdGUgPT09ICdlcnJvcmVkJykge1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlamVjdGVkV2l0aChzdHJlYW0uX3N0b3JlZEVycm9yKTtcbiAgICB9XG4gICAgUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pO1xuICAgIGNvbnN0IHJlYWRlciA9IHN0cmVhbS5fcmVhZGVyO1xuICAgIGlmIChyZWFkZXIgIT09IHVuZGVmaW5lZCAmJiBJc1JlYWRhYmxlU3RyZWFtQllPQlJlYWRlcihyZWFkZXIpKSB7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5mb3JFYWNoKHJlYWRJbnRvUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Nsb3NlU3RlcHModW5kZWZpbmVkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cyA9IG5ldyBTaW1wbGVRdWV1ZSgpO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2VDYW5jZWxQcm9taXNlID0gc3RyZWFtLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXJbQ2FuY2VsU3RlcHNdKHJlYXNvbik7XG4gICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKHNvdXJjZUNhbmNlbFByb21pc2UsIG5vb3ApO1xufVxuZnVuY3Rpb24gUmVhZGFibGVTdHJlYW1DbG9zZShzdHJlYW0pIHtcbiAgICBzdHJlYW0uX3N0YXRlID0gJ2Nsb3NlZCc7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNvbHZlKHJlYWRlcik7XG4gICAgaWYgKElzUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyKHJlYWRlcikpIHtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMuZm9yRWFjaChyZWFkUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkUmVxdWVzdC5fY2xvc2VTdGVwcygpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG59XG5mdW5jdGlvbiBSZWFkYWJsZVN0cmVhbUVycm9yKHN0cmVhbSwgZSkge1xuICAgIHN0cmVhbS5fc3RhdGUgPSAnZXJyb3JlZCc7XG4gICAgc3RyZWFtLl9zdG9yZWRFcnJvciA9IGU7XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLl9yZWFkZXI7XG4gICAgaWYgKHJlYWRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZWplY3QocmVhZGVyLCBlKTtcbiAgICBpZiAoSXNSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIocmVhZGVyKSkge1xuICAgICAgICByZWFkZXIuX3JlYWRSZXF1ZXN0cy5mb3JFYWNoKHJlYWRSZXF1ZXN0ID0+IHtcbiAgICAgICAgICAgIHJlYWRSZXF1ZXN0Ll9lcnJvclN0ZXBzKGUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZGVyLl9yZWFkUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlYWRlci5fcmVhZEludG9SZXF1ZXN0cy5mb3JFYWNoKHJlYWRJbnRvUmVxdWVzdCA9PiB7XG4gICAgICAgICAgICByZWFkSW50b1JlcXVlc3QuX2Vycm9yU3RlcHMoZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZWFkZXIuX3JlYWRJbnRvUmVxdWVzdHMgPSBuZXcgU2ltcGxlUXVldWUoKTtcbiAgICB9XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgUmVhZGFibGVTdHJlYW0uXG5mdW5jdGlvbiBzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEobmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBSZWFkYWJsZVN0cmVhbS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgUmVhZGFibGVTdHJlYW1gKTtcbn1cblxuZnVuY3Rpb24gY29udmVydFF1ZXVpbmdTdHJhdGVneUluaXQoaW5pdCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkoaW5pdCwgY29udGV4dCk7XG4gICAgY29uc3QgaGlnaFdhdGVyTWFyayA9IGluaXQgPT09IG51bGwgfHwgaW5pdCA9PT0gdm9pZCAwID8gdm9pZCAwIDogaW5pdC5oaWdoV2F0ZXJNYXJrO1xuICAgIGFzc2VydFJlcXVpcmVkRmllbGQoaGlnaFdhdGVyTWFyaywgJ2hpZ2hXYXRlck1hcmsnLCAnUXVldWluZ1N0cmF0ZWd5SW5pdCcpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGhpZ2hXYXRlck1hcms6IGNvbnZlcnRVbnJlc3RyaWN0ZWREb3VibGUoaGlnaFdhdGVyTWFyaylcbiAgICB9O1xufVxuXG4vLyBUaGUgc2l6ZSBmdW5jdGlvbiBtdXN0IG5vdCBoYXZlIGEgcHJvdG90eXBlIHByb3BlcnR5IG5vciBiZSBhIGNvbnN0cnVjdG9yXG5jb25zdCBieXRlTGVuZ3RoU2l6ZUZ1bmN0aW9uID0gKGNodW5rKSA9PiB7XG4gICAgcmV0dXJuIGNodW5rLmJ5dGVMZW5ndGg7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGJ5dGVMZW5ndGhTaXplRnVuY3Rpb24sICduYW1lJywge1xuICAgIHZhbHVlOiAnc2l6ZScsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG59KTtcbi8qKlxuICogQSBxdWV1aW5nIHN0cmF0ZWd5IHRoYXQgY291bnRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gZWFjaCBjaHVuay5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgYXNzZXJ0UmVxdWlyZWRBcmd1bWVudChvcHRpb25zLCAxLCAnQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneScpO1xuICAgICAgICBvcHRpb25zID0gY29udmVydFF1ZXVpbmdTdHJhdGVneUluaXQob3B0aW9ucywgJ0ZpcnN0IHBhcmFtZXRlcicpO1xuICAgICAgICB0aGlzLl9ieXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGlnaCB3YXRlciBtYXJrIHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBnZXQgaGlnaFdhdGVyTWFyaygpIHtcbiAgICAgICAgaWYgKCFJc0J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKCdoaWdoV2F0ZXJNYXJrJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNZWFzdXJlcyB0aGUgc2l6ZSBvZiBgY2h1bmtgIGJ5IHJldHVybmluZyB0aGUgdmFsdWUgb2YgaXRzIGBieXRlTGVuZ3RoYCBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc0J5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3kodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKCdzaXplJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJ5dGVMZW5ndGhTaXplRnVuY3Rpb247XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUsIHtcbiAgICBoaWdoV2F0ZXJNYXJrOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBzaXplOiB7IGVudW1lcmFibGU6IHRydWUgfVxufSk7XG5pZiAodHlwZW9mIFN5bWJvbFBvbHlmaWxsLnRvU3RyaW5nVGFnID09PSAnc3ltYm9sJykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5LnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneWApO1xufVxuZnVuY3Rpb24gSXNCeXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5KHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfYnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneTtcbn1cblxuLy8gVGhlIHNpemUgZnVuY3Rpb24gbXVzdCBub3QgaGF2ZSBhIHByb3RvdHlwZSBwcm9wZXJ0eSBub3IgYmUgYSBjb25zdHJ1Y3RvclxuY29uc3QgY291bnRTaXplRnVuY3Rpb24gPSAoKSA9PiB7XG4gICAgcmV0dXJuIDE7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvdW50U2l6ZUZ1bmN0aW9uLCAnbmFtZScsIHtcbiAgICB2YWx1ZTogJ3NpemUnLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxufSk7XG4vKipcbiAqIEEgcXVldWluZyBzdHJhdGVneSB0aGF0IGNvdW50cyB0aGUgbnVtYmVyIG9mIGNodW5rcy5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIENvdW50UXVldWluZ1N0cmF0ZWd5IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIGFzc2VydFJlcXVpcmVkQXJndW1lbnQob3B0aW9ucywgMSwgJ0NvdW50UXVldWluZ1N0cmF0ZWd5Jyk7XG4gICAgICAgIG9wdGlvbnMgPSBjb252ZXJ0UXVldWluZ1N0cmF0ZWd5SW5pdChvcHRpb25zLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIHRoaXMuX2NvdW50UXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaGlnaCB3YXRlciBtYXJrIHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBnZXQgaGlnaFdhdGVyTWFyaygpIHtcbiAgICAgICAgaWYgKCFJc0NvdW50UXVldWluZ1N0cmF0ZWd5KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24oJ2hpZ2hXYXRlck1hcmsnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fY291bnRRdWV1aW5nU3RyYXRlZ3lIaWdoV2F0ZXJNYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNZWFzdXJlcyB0aGUgc2l6ZSBvZiBgY2h1bmtgIGJ5IGFsd2F5cyByZXR1cm5pbmcgMS5cbiAgICAgKiBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgdG90YWwgcXVldWUgc2l6ZSBpcyBhIGNvdW50IG9mIHRoZSBudW1iZXIgb2YgY2h1bmtzIGluIHRoZSBxdWV1ZS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgaWYgKCFJc0NvdW50UXVldWluZ1N0cmF0ZWd5KHRoaXMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24oJ3NpemUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY291bnRTaXplRnVuY3Rpb247XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQ291bnRRdWV1aW5nU3RyYXRlZ3kucHJvdG90eXBlLCB7XG4gICAgaGlnaFdhdGVyTWFyazogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgc2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ291bnRRdWV1aW5nU3RyYXRlZ3kucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ0NvdW50UXVldWluZ1N0cmF0ZWd5JyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgQ291bnRRdWV1aW5nU3RyYXRlZ3kuXG5mdW5jdGlvbiBjb3VudEJyYW5kQ2hlY2tFeGNlcHRpb24obmFtZSkge1xuICAgIHJldHVybiBuZXcgVHlwZUVycm9yKGBDb3VudFF1ZXVpbmdTdHJhdGVneS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgQ291bnRRdWV1aW5nU3RyYXRlZ3lgKTtcbn1cbmZ1bmN0aW9uIElzQ291bnRRdWV1aW5nU3RyYXRlZ3koeCkge1xuICAgIGlmICghdHlwZUlzT2JqZWN0KHgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoeCwgJ19jb3VudFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB4IGluc3RhbmNlb2YgQ291bnRRdWV1aW5nU3RyYXRlZ3k7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2Zvcm1lcihvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydERpY3Rpb25hcnkob3JpZ2luYWwsIGNvbnRleHQpO1xuICAgIGNvbnN0IGZsdXNoID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLmZsdXNoO1xuICAgIGNvbnN0IHJlYWRhYmxlVHlwZSA9IG9yaWdpbmFsID09PSBudWxsIHx8IG9yaWdpbmFsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcmlnaW5hbC5yZWFkYWJsZVR5cGU7XG4gICAgY29uc3Qgc3RhcnQgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwuc3RhcnQ7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gb3JpZ2luYWwgPT09IG51bGwgfHwgb3JpZ2luYWwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9yaWdpbmFsLnRyYW5zZm9ybTtcbiAgICBjb25zdCB3cml0YWJsZVR5cGUgPSBvcmlnaW5hbCA9PT0gbnVsbCB8fCBvcmlnaW5hbCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3JpZ2luYWwud3JpdGFibGVUeXBlO1xuICAgIHJldHVybiB7XG4gICAgICAgIGZsdXNoOiBmbHVzaCA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICAgIHVuZGVmaW5lZCA6XG4gICAgICAgICAgICBjb252ZXJ0VHJhbnNmb3JtZXJGbHVzaENhbGxiYWNrKGZsdXNoLCBvcmlnaW5hbCwgYCR7Y29udGV4dH0gaGFzIG1lbWJlciAnZmx1c2gnIHRoYXRgKSxcbiAgICAgICAgcmVhZGFibGVUeXBlLFxuICAgICAgICBzdGFydDogc3RhcnQgPT09IHVuZGVmaW5lZCA/XG4gICAgICAgICAgICB1bmRlZmluZWQgOlxuICAgICAgICAgICAgY29udmVydFRyYW5zZm9ybWVyU3RhcnRDYWxsYmFjayhzdGFydCwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3N0YXJ0JyB0aGF0YCksXG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNmb3JtID09PSB1bmRlZmluZWQgP1xuICAgICAgICAgICAgdW5kZWZpbmVkIDpcbiAgICAgICAgICAgIGNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrKHRyYW5zZm9ybSwgb3JpZ2luYWwsIGAke2NvbnRleHR9IGhhcyBtZW1iZXIgJ3RyYW5zZm9ybScgdGhhdGApLFxuICAgICAgICB3cml0YWJsZVR5cGVcbiAgICB9O1xufVxuZnVuY3Rpb24gY29udmVydFRyYW5zZm9ybWVyRmx1c2hDYWxsYmFjayhmbiwgb3JpZ2luYWwsIGNvbnRleHQpIHtcbiAgICBhc3NlcnRGdW5jdGlvbihmbiwgY29udGV4dCk7XG4gICAgcmV0dXJuIChjb250cm9sbGVyKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtjb250cm9sbGVyXSk7XG59XG5mdW5jdGlvbiBjb252ZXJ0VHJhbnNmb3JtZXJTdGFydENhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNvbnRyb2xsZXIpID0+IHJlZmxlY3RDYWxsKGZuLCBvcmlnaW5hbCwgW2NvbnRyb2xsZXJdKTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2Zvcm1lclRyYW5zZm9ybUNhbGxiYWNrKGZuLCBvcmlnaW5hbCwgY29udGV4dCkge1xuICAgIGFzc2VydEZ1bmN0aW9uKGZuLCBjb250ZXh0KTtcbiAgICByZXR1cm4gKGNodW5rLCBjb250cm9sbGVyKSA9PiBwcm9taXNlQ2FsbChmbiwgb3JpZ2luYWwsIFtjaHVuaywgY29udHJvbGxlcl0pO1xufVxuXG4vLyBDbGFzcyBUcmFuc2Zvcm1TdHJlYW1cbi8qKlxuICogQSB0cmFuc2Zvcm0gc3RyZWFtIGNvbnNpc3RzIG9mIGEgcGFpciBvZiBzdHJlYW1zOiBhIHtAbGluayBXcml0YWJsZVN0cmVhbSB8IHdyaXRhYmxlIHN0cmVhbX0sXG4gKiBrbm93biBhcyBpdHMgd3JpdGFibGUgc2lkZSwgYW5kIGEge0BsaW5rIFJlYWRhYmxlU3RyZWFtIHwgcmVhZGFibGUgc3RyZWFtfSwga25vd24gYXMgaXRzIHJlYWRhYmxlIHNpZGUuXG4gKiBJbiBhIG1hbm5lciBzcGVjaWZpYyB0byB0aGUgdHJhbnNmb3JtIHN0cmVhbSBpbiBxdWVzdGlvbiwgd3JpdGVzIHRvIHRoZSB3cml0YWJsZSBzaWRlIHJlc3VsdCBpbiBuZXcgZGF0YSBiZWluZ1xuICogbWFkZSBhdmFpbGFibGUgZm9yIHJlYWRpbmcgZnJvbSB0aGUgcmVhZGFibGUgc2lkZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFRyYW5zZm9ybVN0cmVhbSB7XG4gICAgY29uc3RydWN0b3IocmF3VHJhbnNmb3JtZXIgPSB7fSwgcmF3V3JpdGFibGVTdHJhdGVneSA9IHt9LCByYXdSZWFkYWJsZVN0cmF0ZWd5ID0ge30pIHtcbiAgICAgICAgaWYgKHJhd1RyYW5zZm9ybWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJhd1RyYW5zZm9ybWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3cml0YWJsZVN0cmF0ZWd5ID0gY29udmVydFF1ZXVpbmdTdHJhdGVneShyYXdXcml0YWJsZVN0cmF0ZWd5LCAnU2Vjb25kIHBhcmFtZXRlcicpO1xuICAgICAgICBjb25zdCByZWFkYWJsZVN0cmF0ZWd5ID0gY29udmVydFF1ZXVpbmdTdHJhdGVneShyYXdSZWFkYWJsZVN0cmF0ZWd5LCAnVGhpcmQgcGFyYW1ldGVyJyk7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gY29udmVydFRyYW5zZm9ybWVyKHJhd1RyYW5zZm9ybWVyLCAnRmlyc3QgcGFyYW1ldGVyJyk7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci5yZWFkYWJsZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgcmVhZGFibGVUeXBlIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci53cml0YWJsZVR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgd3JpdGFibGVUeXBlIHNwZWNpZmllZCcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlSGlnaFdhdGVyTWFyayA9IEV4dHJhY3RIaWdoV2F0ZXJNYXJrKHJlYWRhYmxlU3RyYXRlZ3ksIDApO1xuICAgICAgICBjb25zdCByZWFkYWJsZVNpemVBbGdvcml0aG0gPSBFeHRyYWN0U2l6ZUFsZ29yaXRobShyZWFkYWJsZVN0cmF0ZWd5KTtcbiAgICAgICAgY29uc3Qgd3JpdGFibGVIaWdoV2F0ZXJNYXJrID0gRXh0cmFjdEhpZ2hXYXRlck1hcmsod3JpdGFibGVTdHJhdGVneSwgMSk7XG4gICAgICAgIGNvbnN0IHdyaXRhYmxlU2l6ZUFsZ29yaXRobSA9IEV4dHJhY3RTaXplQWxnb3JpdGhtKHdyaXRhYmxlU3RyYXRlZ3kpO1xuICAgICAgICBsZXQgc3RhcnRQcm9taXNlX3Jlc29sdmU7XG4gICAgICAgIGNvbnN0IHN0YXJ0UHJvbWlzZSA9IG5ld1Byb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBJbml0aWFsaXplVHJhbnNmb3JtU3RyZWFtKHRoaXMsIHN0YXJ0UHJvbWlzZSwgd3JpdGFibGVIaWdoV2F0ZXJNYXJrLCB3cml0YWJsZVNpemVBbGdvcml0aG0sIHJlYWRhYmxlSGlnaFdhdGVyTWFyaywgcmVhZGFibGVTaXplQWxnb3JpdGhtKTtcbiAgICAgICAgU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21UcmFuc2Zvcm1lcih0aGlzLCB0cmFuc2Zvcm1lcik7XG4gICAgICAgIGlmICh0cmFuc2Zvcm1lci5zdGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSh0cmFuc2Zvcm1lci5zdGFydCh0aGlzLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGFydFByb21pc2VfcmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByZWFkYWJsZSBzaWRlIG9mIHRoZSB0cmFuc2Zvcm0gc3RyZWFtLlxuICAgICAqL1xuICAgIGdldCByZWFkYWJsZSgpIHtcbiAgICAgICAgaWYgKCFJc1RyYW5zZm9ybVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbigncmVhZGFibGUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcmVhZGFibGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB3cml0YWJsZSBzaWRlIG9mIHRoZSB0cmFuc2Zvcm0gc3RyZWFtLlxuICAgICAqL1xuICAgIGdldCB3cml0YWJsZSgpIHtcbiAgICAgICAgaWYgKCFJc1RyYW5zZm9ybVN0cmVhbSh0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbignd3JpdGFibGUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fd3JpdGFibGU7XG4gICAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoVHJhbnNmb3JtU3RyZWFtLnByb3RvdHlwZSwge1xuICAgIHJlYWRhYmxlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICB3cml0YWJsZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVHJhbnNmb3JtU3RyZWFtLnByb3RvdHlwZSwgU3ltYm9sUG9seWZpbGwudG9TdHJpbmdUYWcsIHtcbiAgICAgICAgdmFsdWU6ICdUcmFuc2Zvcm1TdHJlYW0nLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIEluaXRpYWxpemVUcmFuc2Zvcm1TdHJlYW0oc3RyZWFtLCBzdGFydFByb21pc2UsIHdyaXRhYmxlSGlnaFdhdGVyTWFyaywgd3JpdGFibGVTaXplQWxnb3JpdGhtLCByZWFkYWJsZUhpZ2hXYXRlck1hcmssIHJlYWRhYmxlU2l6ZUFsZ29yaXRobSkge1xuICAgIGZ1bmN0aW9uIHN0YXJ0QWxnb3JpdGhtKCkge1xuICAgICAgICByZXR1cm4gc3RhcnRQcm9taXNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiB3cml0ZUFsZ29yaXRobShjaHVuaykge1xuICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtXcml0ZUFsZ29yaXRobShzdHJlYW0sIGNodW5rKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYWJvcnRBbGdvcml0aG0ocmVhc29uKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua0Fib3J0QWxnb3JpdGhtKHN0cmVhbSwgcmVhc29uKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY2xvc2VBbGdvcml0aG0oKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua0Nsb3NlQWxnb3JpdGhtKHN0cmVhbSk7XG4gICAgfVxuICAgIHN0cmVhbS5fd3JpdGFibGUgPSBDcmVhdGVXcml0YWJsZVN0cmVhbShzdGFydEFsZ29yaXRobSwgd3JpdGVBbGdvcml0aG0sIGNsb3NlQWxnb3JpdGhtLCBhYm9ydEFsZ29yaXRobSwgd3JpdGFibGVIaWdoV2F0ZXJNYXJrLCB3cml0YWJsZVNpemVBbGdvcml0aG0pO1xuICAgIGZ1bmN0aW9uIHB1bGxBbGdvcml0aG0oKSB7XG4gICAgICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U291cmNlUHVsbEFsZ29yaXRobShzdHJlYW0pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5jZWxBbGdvcml0aG0ocmVhc29uKSB7XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUoc3RyZWFtLCByZWFzb24pO1xuICAgICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xuICAgIH1cbiAgICBzdHJlYW0uX3JlYWRhYmxlID0gQ3JlYXRlUmVhZGFibGVTdHJlYW0oc3RhcnRBbGdvcml0aG0sIHB1bGxBbGdvcml0aG0sIGNhbmNlbEFsZ29yaXRobSwgcmVhZGFibGVIaWdoV2F0ZXJNYXJrLCByZWFkYWJsZVNpemVBbGdvcml0aG0pO1xuICAgIC8vIFRoZSBbW2JhY2twcmVzc3VyZV1dIHNsb3QgaXMgc2V0IHRvIHVuZGVmaW5lZCBzbyB0aGF0IGl0IGNhbiBiZSBpbml0aWFsaXNlZCBieSBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUuXG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSB1bmRlZmluZWQ7XG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgIHN0cmVhbS5fYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZV9yZXNvbHZlID0gdW5kZWZpbmVkO1xuICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIHRydWUpO1xuICAgIHN0cmVhbS5fdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlciA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIElzVHJhbnNmb3JtU3RyZWFtKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlcicpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBUcmFuc2Zvcm1TdHJlYW07XG59XG4vLyBUaGlzIGlzIGEgbm8tb3AgaWYgYm90aCBzaWRlcyBhcmUgYWxyZWFkeSBlcnJvcmVkLlxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRXJyb3Ioc3RyZWFtLCBlKSB7XG4gICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVycm9yKHN0cmVhbS5fcmVhZGFibGUuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlciwgZSk7XG4gICAgVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZShzdHJlYW0sIGUpO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZShzdHJlYW0sIGUpIHtcbiAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXIpO1xuICAgIFdyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkKHN0cmVhbS5fd3JpdGFibGUuX3dyaXRhYmxlU3RyZWFtQ29udHJvbGxlciwgZSk7XG4gICAgaWYgKHN0cmVhbS5fYmFja3ByZXNzdXJlKSB7XG4gICAgICAgIC8vIFByZXRlbmQgdGhhdCBwdWxsKCkgd2FzIGNhbGxlZCB0byBwZXJtaXQgYW55IHBlbmRpbmcgd3JpdGUoKSBjYWxscyB0byBjb21wbGV0ZS4gVHJhbnNmb3JtU3RyZWFtU2V0QmFja3ByZXNzdXJlKClcbiAgICAgICAgLy8gY2Fubm90IGJlIGNhbGxlZCBmcm9tIGVucXVldWUoKSBvciBwdWxsKCkgb25jZSB0aGUgUmVhZGFibGVTdHJlYW0gaXMgZXJyb3JlZCwgc28gdGhpcyB3aWxsIHdpbGwgYmUgdGhlIGZpbmFsIHRpbWVcbiAgICAgICAgLy8gX2JhY2twcmVzc3VyZSBpcyBzZXQuXG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIGZhbHNlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1TZXRCYWNrcHJlc3N1cmUoc3RyZWFtLCBiYWNrcHJlc3N1cmUpIHtcbiAgICAvLyBQYXNzZXMgYWxzbyB3aGVuIGNhbGxlZCBkdXJpbmcgY29uc3RydWN0aW9uLlxuICAgIGlmIChzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSgpO1xuICAgIH1cbiAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2UgPSBuZXdQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBzdHJlYW0uX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gICAgc3RyZWFtLl9iYWNrcHJlc3N1cmUgPSBiYWNrcHJlc3N1cmU7XG59XG4vLyBDbGFzcyBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclxuLyoqXG4gKiBBbGxvd3MgY29udHJvbCBvZiB0aGUge0BsaW5rIFJlYWRhYmxlU3RyZWFtfSBhbmQge0BsaW5rIFdyaXRhYmxlU3RyZWFtfSBvZiB0aGUgYXNzb2NpYXRlZCB7QGxpbmsgVHJhbnNmb3JtU3RyZWFtfS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmNsYXNzIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSWxsZWdhbCBjb25zdHJ1Y3RvcicpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIHNpemUgdG8gZmlsbCB0aGUgcmVhZGFibGUgc2lkZeKAmXMgaW50ZXJuYWwgcXVldWUuIEl0IGNhbiBiZSBuZWdhdGl2ZSwgaWYgdGhlIHF1ZXVlIGlzIG92ZXItZnVsbC5cbiAgICAgKi9cbiAgICBnZXQgZGVzaXJlZFNpemUoKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdkZXNpcmVkU2l6ZScpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRhYmxlQ29udHJvbGxlciA9IHRoaXMuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW0uX3JlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgICAgIHJldHVybiBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyR2V0RGVzaXJlZFNpemUocmVhZGFibGVDb250cm9sbGVyKTtcbiAgICB9XG4gICAgZW5xdWV1ZShjaHVuayA9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoIUlzVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIodGhpcykpIHtcbiAgICAgICAgICAgIHRocm93IGRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbignZW5xdWV1ZScpO1xuICAgICAgICB9XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSh0aGlzLCBjaHVuayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVycm9ycyBib3RoIHRoZSByZWFkYWJsZSBzaWRlIGFuZCB0aGUgd3JpdGFibGUgc2lkZSBvZiB0aGUgY29udHJvbGxlZCB0cmFuc2Zvcm0gc3RyZWFtLCBtYWtpbmcgYWxsIGZ1dHVyZVxuICAgICAqIGludGVyYWN0aW9ucyB3aXRoIGl0IGZhaWwgd2l0aCB0aGUgZ2l2ZW4gZXJyb3IgYGVgLiBBbnkgY2h1bmtzIHF1ZXVlZCBmb3IgdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBkaXNjYXJkZWQuXG4gICAgICovXG4gICAgZXJyb3IocmVhc29uID0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IodGhpcywgcmVhc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2VzIHRoZSByZWFkYWJsZSBzaWRlIGFuZCBlcnJvcnMgdGhlIHdyaXRhYmxlIHNpZGUgb2YgdGhlIGNvbnRyb2xsZWQgdHJhbnNmb3JtIHN0cmVhbS4gVGhpcyBpcyB1c2VmdWwgd2hlbiB0aGVcbiAgICAgKiB0cmFuc2Zvcm1lciBvbmx5IG5lZWRzIHRvIGNvbnN1bWUgYSBwb3J0aW9uIG9mIHRoZSBjaHVua3Mgd3JpdHRlbiB0byB0aGUgd3JpdGFibGUgc2lkZS5cbiAgICAgKi9cbiAgICB0ZXJtaW5hdGUoKSB7XG4gICAgICAgIGlmICghSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcih0aGlzKSkge1xuICAgICAgICAgICAgdGhyb3cgZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKCd0ZXJtaW5hdGUnKTtcbiAgICAgICAgfVxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclRlcm1pbmF0ZSh0aGlzKTtcbiAgICB9XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlci5wcm90b3R5cGUsIHtcbiAgICBlbnF1ZXVlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBlcnJvcjogeyBlbnVtZXJhYmxlOiB0cnVlIH0sXG4gICAgdGVybWluYXRlOiB7IGVudW1lcmFibGU6IHRydWUgfSxcbiAgICBkZXNpcmVkU2l6ZTogeyBlbnVtZXJhYmxlOiB0cnVlIH1cbn0pO1xuaWYgKHR5cGVvZiBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCcpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLCBTeW1ib2xQb2x5ZmlsbC50b1N0cmluZ1RhZywge1xuICAgICAgICB2YWx1ZTogJ1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyJyxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG59XG4vLyBUcmFuc2Zvcm0gU3RyZWFtIERlZmF1bHQgQ29udHJvbGxlciBBYnN0cmFjdCBPcGVyYXRpb25zXG5mdW5jdGlvbiBJc1RyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyKHgpIHtcbiAgICBpZiAoIXR5cGVJc09iamVjdCh4KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHgsICdfY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbScpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHggaW5zdGFuY2VvZiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcjtcbn1cbmZ1bmN0aW9uIFNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIoc3RyZWFtLCBjb250cm9sbGVyLCB0cmFuc2Zvcm1BbGdvcml0aG0sIGZsdXNoQWxnb3JpdGhtKSB7XG4gICAgY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSA9IHN0cmVhbTtcbiAgICBzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuICAgIGNvbnRyb2xsZXIuX3RyYW5zZm9ybUFsZ29yaXRobSA9IHRyYW5zZm9ybUFsZ29yaXRobTtcbiAgICBjb250cm9sbGVyLl9mbHVzaEFsZ29yaXRobSA9IGZsdXNoQWxnb3JpdGhtO1xufVxuZnVuY3Rpb24gU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21UcmFuc2Zvcm1lcihzdHJlYW0sIHRyYW5zZm9ybWVyKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IE9iamVjdC5jcmVhdGUoVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlKTtcbiAgICBsZXQgdHJhbnNmb3JtQWxnb3JpdGhtID0gKGNodW5rKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUoY29udHJvbGxlciwgY2h1bmspO1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAodHJhbnNmb3JtUmVzdWx0RSkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VSZWplY3RlZFdpdGgodHJhbnNmb3JtUmVzdWx0RSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGxldCBmbHVzaEFsZ29yaXRobSA9ICgpID0+IHByb21pc2VSZXNvbHZlZFdpdGgodW5kZWZpbmVkKTtcbiAgICBpZiAodHJhbnNmb3JtZXIudHJhbnNmb3JtICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHJhbnNmb3JtQWxnb3JpdGhtID0gY2h1bmsgPT4gdHJhbnNmb3JtZXIudHJhbnNmb3JtKGNodW5rLCBjb250cm9sbGVyKTtcbiAgICB9XG4gICAgaWYgKHRyYW5zZm9ybWVyLmZsdXNoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZmx1c2hBbGdvcml0aG0gPSAoKSA9PiB0cmFuc2Zvcm1lci5mbHVzaChjb250cm9sbGVyKTtcbiAgICB9XG4gICAgU2V0VXBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlcihzdHJlYW0sIGNvbnRyb2xsZXIsIHRyYW5zZm9ybUFsZ29yaXRobSwgZmx1c2hBbGdvcml0aG0pO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDbGVhckFsZ29yaXRobXMoY29udHJvbGxlcikge1xuICAgIGNvbnRyb2xsZXIuX3RyYW5zZm9ybUFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbiAgICBjb250cm9sbGVyLl9mbHVzaEFsZ29yaXRobSA9IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShjb250cm9sbGVyLCBjaHVuaykge1xuICAgIGNvbnN0IHN0cmVhbSA9IGNvbnRyb2xsZXIuX2NvbnRyb2xsZWRUcmFuc2Zvcm1TdHJlYW07XG4gICAgY29uc3QgcmVhZGFibGVDb250cm9sbGVyID0gc3RyZWFtLl9yZWFkYWJsZS5fcmVhZGFibGVTdHJlYW1Db250cm9sbGVyO1xuICAgIGlmICghUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlKHJlYWRhYmxlQ29udHJvbGxlcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUmVhZGFibGUgc2lkZSBpcyBub3QgaW4gYSBzdGF0ZSB0aGF0IHBlcm1pdHMgZW5xdWV1ZScpO1xuICAgIH1cbiAgICAvLyBXZSB0aHJvdHRsZSB0cmFuc2Zvcm0gaW52b2NhdGlvbnMgYmFzZWQgb24gdGhlIGJhY2twcmVzc3VyZSBvZiB0aGUgUmVhZGFibGVTdHJlYW0sIGJ1dCB3ZSBzdGlsbFxuICAgIC8vIGFjY2VwdCBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUoKSBjYWxscy5cbiAgICB0cnkge1xuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZShyZWFkYWJsZUNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICB9XG4gICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gVGhpcyBoYXBwZW5zIHdoZW4gcmVhZGFibGVTdHJhdGVneS5zaXplKCkgdGhyb3dzLlxuICAgICAgICBUcmFuc2Zvcm1TdHJlYW1FcnJvcldyaXRhYmxlQW5kVW5ibG9ja1dyaXRlKHN0cmVhbSwgZSk7XG4gICAgICAgIHRocm93IHN0cmVhbS5fcmVhZGFibGUuX3N0b3JlZEVycm9yO1xuICAgIH1cbiAgICBjb25zdCBiYWNrcHJlc3N1cmUgPSBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVySGFzQmFja3ByZXNzdXJlKHJlYWRhYmxlQ29udHJvbGxlcik7XG4gICAgaWYgKGJhY2twcmVzc3VyZSAhPT0gc3RyZWFtLl9iYWNrcHJlc3N1cmUpIHtcbiAgICAgICAgVHJhbnNmb3JtU3RyZWFtU2V0QmFja3ByZXNzdXJlKHN0cmVhbSwgdHJ1ZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcihjb250cm9sbGVyLCBlKSB7XG4gICAgVHJhbnNmb3JtU3RyZWFtRXJyb3IoY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSwgZSk7XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclBlcmZvcm1UcmFuc2Zvcm0oY29udHJvbGxlciwgY2h1bmspIHtcbiAgICBjb25zdCB0cmFuc2Zvcm1Qcm9taXNlID0gY29udHJvbGxlci5fdHJhbnNmb3JtQWxnb3JpdGhtKGNodW5rKTtcbiAgICByZXR1cm4gdHJhbnNmb3JtUHJvbWlzZVdpdGgodHJhbnNmb3JtUHJvbWlzZSwgdW5kZWZpbmVkLCByID0+IHtcbiAgICAgICAgVHJhbnNmb3JtU3RyZWFtRXJyb3IoY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbSwgcik7XG4gICAgICAgIHRocm93IHI7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclRlcm1pbmF0ZShjb250cm9sbGVyKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY29udHJvbGxlci5fY29udHJvbGxlZFRyYW5zZm9ybVN0cmVhbTtcbiAgICBjb25zdCByZWFkYWJsZUNvbnRyb2xsZXIgPSBzdHJlYW0uX3JlYWRhYmxlLl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlKHJlYWRhYmxlQ29udHJvbGxlcik7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgVHlwZUVycm9yKCdUcmFuc2Zvcm1TdHJlYW0gdGVybWluYXRlZCcpO1xuICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yV3JpdGFibGVBbmRVbmJsb2NrV3JpdGUoc3RyZWFtLCBlcnJvcik7XG59XG4vLyBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2luayBBbGdvcml0aG1zXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0U2lua1dyaXRlQWxnb3JpdGhtKHN0cmVhbSwgY2h1bmspIHtcbiAgICBjb25zdCBjb250cm9sbGVyID0gc3RyZWFtLl90cmFuc2Zvcm1TdHJlYW1Db250cm9sbGVyO1xuICAgIGlmIChzdHJlYW0uX2JhY2twcmVzc3VyZSkge1xuICAgICAgICBjb25zdCBiYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlID0gc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlO1xuICAgICAgICByZXR1cm4gdHJhbnNmb3JtUHJvbWlzZVdpdGgoYmFja3ByZXNzdXJlQ2hhbmdlUHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgd3JpdGFibGUgPSBzdHJlYW0uX3dyaXRhYmxlO1xuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSB3cml0YWJsZS5fc3RhdGU7XG4gICAgICAgICAgICBpZiAoc3RhdGUgPT09ICdlcnJvcmluZycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyB3cml0YWJsZS5fc3RvcmVkRXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQZXJmb3JtVHJhbnNmb3JtKGNvbnRyb2xsZXIsIGNodW5rKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlclBlcmZvcm1UcmFuc2Zvcm0oY29udHJvbGxlciwgY2h1bmspO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtBYm9ydEFsZ29yaXRobShzdHJlYW0sIHJlYXNvbikge1xuICAgIC8vIGFib3J0KCkgaXMgbm90IGNhbGxlZCBzeW5jaHJvbm91c2x5LCBzbyBpdCBpcyBwb3NzaWJsZSBmb3IgYWJvcnQoKSB0byBiZSBjYWxsZWQgd2hlbiB0aGUgc3RyZWFtIGlzIGFscmVhZHlcbiAgICAvLyBlcnJvcmVkLlxuICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yKHN0cmVhbSwgcmVhc29uKTtcbiAgICByZXR1cm4gcHJvbWlzZVJlc29sdmVkV2l0aCh1bmRlZmluZWQpO1xufVxuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtDbG9zZUFsZ29yaXRobShzdHJlYW0pIHtcbiAgICAvLyBzdHJlYW0uX3JlYWRhYmxlIGNhbm5vdCBjaGFuZ2UgYWZ0ZXIgY29uc3RydWN0aW9uLCBzbyBjYWNoaW5nIGl0IGFjcm9zcyBhIGNhbGwgdG8gdXNlciBjb2RlIGlzIHNhZmUuXG4gICAgY29uc3QgcmVhZGFibGUgPSBzdHJlYW0uX3JlYWRhYmxlO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBzdHJlYW0uX3RyYW5zZm9ybVN0cmVhbUNvbnRyb2xsZXI7XG4gICAgY29uc3QgZmx1c2hQcm9taXNlID0gY29udHJvbGxlci5fZmx1c2hBbGdvcml0aG0oKTtcbiAgICBUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsZWFyQWxnb3JpdGhtcyhjb250cm9sbGVyKTtcbiAgICAvLyBSZXR1cm4gYSBwcm9taXNlIHRoYXQgaXMgZnVsZmlsbGVkIHdpdGggdW5kZWZpbmVkIG9uIHN1Y2Nlc3MuXG4gICAgcmV0dXJuIHRyYW5zZm9ybVByb21pc2VXaXRoKGZsdXNoUHJvbWlzZSwgKCkgPT4ge1xuICAgICAgICBpZiAocmVhZGFibGUuX3N0YXRlID09PSAnZXJyb3JlZCcpIHtcbiAgICAgICAgICAgIHRocm93IHJlYWRhYmxlLl9zdG9yZWRFcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xvc2UocmVhZGFibGUuX3JlYWRhYmxlU3RyZWFtQ29udHJvbGxlcik7XG4gICAgfSwgciA9PiB7XG4gICAgICAgIFRyYW5zZm9ybVN0cmVhbUVycm9yKHN0cmVhbSwgcik7XG4gICAgICAgIHRocm93IHJlYWRhYmxlLl9zdG9yZWRFcnJvcjtcbiAgICB9KTtcbn1cbi8vIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRTb3VyY2UgQWxnb3JpdGhtc1xuZnVuY3Rpb24gVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNvdXJjZVB1bGxBbGdvcml0aG0oc3RyZWFtKSB7XG4gICAgLy8gSW52YXJpYW50LiBFbmZvcmNlZCBieSB0aGUgcHJvbWlzZXMgcmV0dXJuZWQgYnkgc3RhcnQoKSBhbmQgcHVsbCgpLlxuICAgIFRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZShzdHJlYW0sIGZhbHNlKTtcbiAgICAvLyBQcmV2ZW50IHRoZSBuZXh0IHB1bGwoKSBjYWxsIHVudGlsIHRoZXJlIGlzIGJhY2twcmVzc3VyZS5cbiAgICByZXR1cm4gc3RyZWFtLl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlO1xufVxuLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgdGhlIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyLlxuZnVuY3Rpb24gZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFR5cGVFcnJvcihgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIucHJvdG90eXBlLiR7bmFtZX0gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyYCk7XG59XG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciB0aGUgVHJhbnNmb3JtU3RyZWFtLlxuZnVuY3Rpb24gc3RyZWFtQnJhbmRDaGVja0V4Y2VwdGlvbihuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoYFRyYW5zZm9ybVN0cmVhbS5wcm90b3R5cGUuJHtuYW1lfSBjYW4gb25seSBiZSB1c2VkIG9uIGEgVHJhbnNmb3JtU3RyZWFtYCk7XG59XG5cbmV4cG9ydCB7IEJ5dGVMZW5ndGhRdWV1aW5nU3RyYXRlZ3ksIENvdW50UXVldWluZ1N0cmF0ZWd5LCBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyLCBSZWFkYWJsZVN0cmVhbSwgUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyLCBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0LCBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLCBSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIsIFRyYW5zZm9ybVN0cmVhbSwgVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIsIFdyaXRhYmxlU3RyZWFtLCBXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyLCBXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXIgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBvbnlmaWxsLmVzMjAxOC5tanMubWFwXG4iLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdGlkOiBtb2R1bGVJZCxcblx0XHRsb2FkZWQ6IGZhbHNlLFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcblx0bW9kdWxlLmxvYWRlZCA9IHRydWU7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9ucyBmb3IgaGFybW9ueSBleHBvcnRzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSAoZXhwb3J0cywgZGVmaW5pdGlvbikgPT4ge1xuXHRmb3IodmFyIGtleSBpbiBkZWZpbml0aW9uKSB7XG5cdFx0aWYoX193ZWJwYWNrX3JlcXVpcmVfXy5vKGRlZmluaXRpb24sIGtleSkgJiYgIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBrZXkpKSB7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywga2V5LCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZGVmaW5pdGlvbltrZXldIH0pO1xuXHRcdH1cblx0fVxufTsiLCJfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSAob2JqLCBwcm9wKSA9PiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpIiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5ubWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZS5wYXRocyA9IFtdO1xuXHRpZiAoIW1vZHVsZS5jaGlsZHJlbikgbW9kdWxlLmNoaWxkcmVuID0gW107XG5cdHJldHVybiBtb2R1bGU7XG59OyIsIi8vIHN0YXJ0dXBcbi8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLy8gVGhpcyBlbnRyeSBtb2R1bGUgaXMgcmVmZXJlbmNlZCBieSBvdGhlciBtb2R1bGVzIHNvIGl0IGNhbid0IGJlIGlubGluZWRcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0OCk7XG4iXSwibmFtZXMiOlsicm9vdCIsImZhY3RvcnkiLCJleHBvcnRzIiwibW9kdWxlIiwiZGVmaW5lIiwiYW1kIiwidGhpcyIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwidmFsdWUiLCJldmVudFRhcmdldFNoaW0iLCJBYm9ydFNpZ25hbCIsIkV2ZW50VGFyZ2V0IiwiY29uc3RydWN0b3IiLCJzdXBlciIsIlR5cGVFcnJvciIsImFib3J0ZWQiLCJhYm9ydGVkRmxhZ3MiLCJnZXQiLCJkZWZpbmVFdmVudEF0dHJpYnV0ZSIsInByb3RvdHlwZSIsIldlYWtNYXAiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiZW51bWVyYWJsZSIsIlN5bWJvbCIsInRvU3RyaW5nVGFnIiwiY29uZmlndXJhYmxlIiwiQWJvcnRDb250cm9sbGVyIiwic2lnbmFscyIsInNldCIsInNpZ25hbCIsImNyZWF0ZSIsImNhbGwiLCJjcmVhdGVBYm9ydFNpZ25hbCIsImdldFNpZ25hbCIsImFib3J0IiwiZGlzcGF0Y2hFdmVudCIsInR5cGUiLCJjb250cm9sbGVyIiwiRm9ybURhdGEiLCJmb3JtRGF0YSIsImNsaWVudCIsIm9wdGlvbnMiLCJNYWlsZ3VuIiwiY29uZmlnIiwidXJsIiwidXNlcm5hbWUiLCJFcnJvciIsImtleSIsInJlcXVlc3QiLCJtYWlsTGlzdHNNZW1iZXJzIiwiZG9tYWlucyIsIndlYmhvb2tzIiwiZXZlbnRzIiwic3RhdHMiLCJzdXBwcmVzc2lvbnMiLCJtZXNzYWdlcyIsInJvdXRlcyIsImlwcyIsImlwX3Bvb2xzIiwibGlzdHMiLCJwdWJsaWNfa2V5IiwicHVibGljX3JlcXVlc3QiLCJ2YWxpZGF0ZSIsInBhcnNlIiwiZGF0YSIsInJlY2VpdmluZyIsInNlbmRpbmciLCJuYW1lIiwicmVxdWlyZV90bHMiLCJza2lwX3ZlcmlmaWNhdGlvbiIsInN0YXRlIiwid2lsZGNhcmQiLCJzcGFtX2FjdGlvbiIsImNyZWF0ZWRfYXQiLCJzbXRwX3Bhc3N3b3JkIiwic210cF9sb2dpbiIsInJlY2VpdmluZ19kbnNfcmVjb3JkcyIsInNlbmRpbmdfZG5zX3JlY29yZHMiLCJfcGFyc2VNZXNzYWdlIiwicmVzcG9uc2UiLCJib2R5IiwiX3BhcnNlRG9tYWluTGlzdCIsIml0ZW1zIiwibWFwIiwiaXRlbSIsIkRvbWFpbiIsIl9wYXJzZURvbWFpbiIsImRvbWFpbiIsIl9wYXJzZVRyYWNraW5nU2V0dGluZ3MiLCJ0cmFja2luZyIsIl9wYXJzZVRyYWNraW5nVXBkYXRlIiwibGlzdCIsInF1ZXJ5IiwidGhlbiIsInJlcyIsInBvc3RXaXRoRkQiLCJkZXN0cm95IiwiZGVsZXRlIiwiZ2V0VHJhY2tpbmciLCJ1cGRhdGVUcmFja2luZyIsImFjdGl2ZSIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJtZXNzYWdlIiwicHV0V2l0aEZEIiwiZ2V0SXBzIiwiYXNzaWduSXAiLCJpcCIsImRlbGV0ZUlwIiwibGlua0lwUG9vbCIsInBvb2xfaWQiLCJ1bmxpbmtJcFBvbGwiLCJib2R5TWVzc2FnZSIsImVycm9yIiwic3RhY2siLCJkZXRhaWxzIiwiX3BhcnNlUGFnZU51bWJlciIsInNwbGl0IiwicG9wIiwiX3BhcnNlUGFnZSIsImlkIiwibnVtYmVyIiwiX3BhcnNlUGFnZUxpbmtzIiwiZW50cmllcyIsInBhZ2luZyIsInJlZHVjZSIsImFjYyIsImVudHJpZSIsIl9wYXJzZUV2ZW50TGlzdCIsInBhZ2VzIiwicXVlcnlDb3B5IiwicGFnZSIsInBhcnNlSXBQb29sc1Jlc3BvbnNlIiwicG9zdCIsInVwZGF0ZSIsInBvb2xJZCIsInBhdGNoIiwicGFyc2VJcHNSZXNwb25zZSIsIm1lbWJlcnMiLCJiYXNlUm91dGUiLCJtYWlsTGlzdEFkZHJlc3MiLCJjaGVja0FuZFVwZGF0ZURhdGEiLCJuZXdEYXRhIiwidmFycyIsIkpTT04iLCJzdHJpbmdpZnkiLCJzdWJzY3JpYmVkIiwibGlzdE1lbWJlcnMiLCJnZXRNZW1iZXIiLCJtYWlsTGlzdE1lbWJlckFkZHJlc3MiLCJjcmVhdGVNZW1iZXIiLCJyZXFEYXRhIiwiY3JlYXRlTWVtYmVycyIsIkFycmF5IiwiaXNBcnJheSIsInVwc2VydCIsInVwZGF0ZU1lbWJlciIsImRlc3Ryb3lNZW1iZXIiLCJfcGFyc2VSZXNwb25zZSIsImFkZHJlc3NlcyIsImVuYWJsZURuc0VzcENoZWNrcyIsImpvaW4iLCJzeW50YXhfb25seSIsImlzU3RyZWFtIiwiYXR0YWNobWVudCIsInBpcGUiLCJ0aW1lb3V0IiwiaGVhZGVycyIsIm1ldGhvZCIsImlucHV0T3B0aW9ucyIsImJhc2ljIiwiZW5jb2RlIiwiQXV0aG9yaXphdGlvbiIsInBhcmFtcyIsImdldE93blByb3BlcnR5TmFtZXMiLCJsZW5ndGgiLCJzZWFyY2hQYXJhbXMiLCJ0b0xvY2FsZVVwcGVyQ2FzZSIsInRocm93SHR0cEVycm9ycyIsIm9rIiwic3RyZWFtIiwiY2h1bmtzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJvbiIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsInRvU3RyaW5nIiwianNvbiIsImNvbW1hbmQiLCJoZWFkIiwiY3JlYXRlRm9ybURhdGEiLCJhcHBlbmRGaWxlVG9GRCIsIm9iaiIsImZvcm1EYXRhSW5zdGFuY2UiLCJvYmpEYXRhIiwiZmlsZW5hbWUiLCJjb250ZW50VHlwZSIsImtub3duTGVuZ3RoIiwiZ2V0QXR0YWNobWVudE9wdGlvbnMiLCJ1bmRlZmluZWQiLCJnZXRIZWFkZXJzIiwiaXNOb2RlRm9ybURhdGEiLCJhcHBlbmQiLCJrZXlzIiwiZmlsdGVyIiwiZm9ybURhdGFBY2MiLCJmb3JFYWNoIiwicHV0IiwiUmVxdWVzdCIsInN0YXJ0IiwiRGF0ZSIsImVuZCIsInJlc29sdXRpb24iLCJzdGF0IiwidGltZSIsIl9wYXJzZVN0YXRzIiwiU3RhdHMiLCJnZXREb21haW4iLCJnZXRBY2NvdW50IiwiY3JlYXRlT3B0aW9ucyIsImFkZHJlc3MiLCJjb2RlIiwidGFncyIsIm1vZGVscyIsImJvdW5jZXMiLCJCb3VuY2UiLCJjb21wbGFpbnRzIiwiQ29tcGxhaW50IiwidW5zdWJzY3JpYmVzIiwiVW5zdWJzY3JpYmUiLCJwYWdlVXJsIiwiX3BhcnNlTGlzdCIsIk1vZGVsIiwiZCIsIl9wYXJzZUl0ZW0iLCJtb2RlbCIsImVuY29kZVVSSUNvbXBvbmVudCIsInBvc3REYXRhIiwiU3VwcHJlc3Npb25DbGllbnQiLCJfcGFyc2VXZWJob29rTGlzdCIsIl9wYXJzZVdlYmhvb2tXaXRoSUQiLCJ3ZWJob29rUmVzcG9uc2UiLCJ3ZWJob29rIiwidXJscyIsIldlYmhvb2siLCJfcGFyc2VXZWJob29rVGVzdCIsInRlc3QiLCJmcmVlRXhwb3J0cyIsImZyZWVHbG9iYWwiLCJnbG9iYWwiLCJ3aW5kb3ciLCJJbnZhbGlkQ2hhcmFjdGVyRXJyb3IiLCJUQUJMRSIsIlJFR0VYX1NQQUNFX0NIQVJBQ1RFUlMiLCJiYXNlNjQiLCJpbnB1dCIsIlN0cmluZyIsImEiLCJiIiwiYyIsImJ1ZmZlciIsInBhZGRpbmciLCJvdXRwdXQiLCJwb3NpdGlvbiIsImNoYXJDb2RlQXQiLCJjaGFyQXQiLCJyZXBsYWNlIiwiYml0U3RvcmFnZSIsImJpdENvdW50ZXIiLCJpbmRleE9mIiwiZnJvbUNoYXJDb2RlIiwidXJpIiwiZmlyc3RDb21tYSIsIm1ldGEiLCJzdWJzdHJpbmciLCJjaGFyc2V0IiwidHlwZUZ1bGwiLCJpIiwiZW5jb2RpbmciLCJ1bmVzY2FwZSIsImZyb20iLCJwcml2YXRlRGF0YSIsIndyYXBwZXJzIiwicGQiLCJldmVudCIsInJldHYiLCJjb25zb2xlIiwiYXNzZXJ0Iiwic2V0Q2FuY2VsRmxhZyIsInBhc3NpdmVMaXN0ZW5lciIsImNhbmNlbGFibGUiLCJjYW5jZWxlZCIsInByZXZlbnREZWZhdWx0IiwiRXZlbnQiLCJldmVudFRhcmdldCIsImV2ZW50UGhhc2UiLCJjdXJyZW50VGFyZ2V0Iiwic3RvcHBlZCIsImltbWVkaWF0ZVN0b3BwZWQiLCJ0aW1lU3RhbXAiLCJub3ciLCJkZWZpbmVSZWRpcmVjdERlc2NyaXB0b3IiLCJkZWZpbmVDYWxsRGVzY3JpcHRvciIsImFwcGx5IiwiYXJndW1lbnRzIiwiZ2V0V3JhcHBlciIsInByb3RvIiwid3JhcHBlciIsIkJhc2VFdmVudCIsIkN1c3RvbUV2ZW50Iiwid3JpdGFibGUiLCJpc0Z1bmMiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJkZWZpbmVXcmFwcGVyIiwiZ2V0UHJvdG90eXBlT2YiLCJpc1N0b3BwZWQiLCJzZXRQYXNzaXZlTGlzdGVuZXIiLCJ0YXJnZXQiLCJjb21wb3NlZFBhdGgiLCJOT05FIiwiQ0FQVFVSSU5HX1BIQVNFIiwiQVRfVEFSR0VUIiwiQlVCQkxJTkdfUEhBU0UiLCJzdG9wUHJvcGFnYXRpb24iLCJzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24iLCJidWJibGVzIiwiQm9vbGVhbiIsImRlZmF1bHRQcmV2ZW50ZWQiLCJjb21wb3NlZCIsInNyY0VsZW1lbnQiLCJjYW5jZWxCdWJibGUiLCJyZXR1cm5WYWx1ZSIsImluaXRFdmVudCIsInNldFByb3RvdHlwZU9mIiwibGlzdGVuZXJzTWFwIiwiaXNPYmplY3QiLCJ4IiwiZ2V0TGlzdGVuZXJzIiwibGlzdGVuZXJzIiwiZXZlbnRUYXJnZXRQcm90b3R5cGUiLCJldmVudE5hbWUiLCJub2RlIiwibGlzdGVuZXJUeXBlIiwibGlzdGVuZXIiLCJuZXh0IiwicHJldiIsIm5ld05vZGUiLCJwYXNzaXZlIiwib25jZSIsImRlZmluZUV2ZW50QXR0cmlidXRlRGVzY3JpcHRvciIsImRlZmluZUN1c3RvbUV2ZW50VGFyZ2V0IiwiZXZlbnROYW1lcyIsIkN1c3RvbUV2ZW50VGFyZ2V0IiwidHlwZXMiLCJNYXAiLCJhZGRFdmVudExpc3RlbmVyIiwib3B0aW9uc0lzT2JqIiwiY2FwdHVyZSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJ3cmFwcGVkRXZlbnQiLCJ3cmFwRXZlbnQiLCJlcnIiLCJoYW5kbGVFdmVudCIsInNldEV2ZW50UGhhc2UiLCJzZXRDdXJyZW50VGFyZ2V0IiwiUmVhZGFibGUiLCJ3bSIsIkJsb2IiLCJibG9iUGFydHMiLCJzaXplIiwicGFydHMiLCJlbGVtZW50IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJieXRlT2Zmc2V0IiwiYnl0ZUxlbmd0aCIsInRvTG93ZXJDYXNlIiwiYXN5bmMiLCJhcnJheUJ1ZmZlciIsIlVpbnQ4QXJyYXkiLCJvZmZzZXQiLCJwYXJ0IiwicmVhZCIsInNsaWNlIiwicmVsYXRpdmVTdGFydCIsIk1hdGgiLCJtYXgiLCJtaW4iLCJyZWxhdGl2ZUVuZCIsInNwYW4iLCJ2YWx1ZXMiLCJhZGRlZCIsImJsb2IiLCJhc3NpZ24iLCJzdGF0aWMiLCJoYXNJbnN0YW5jZSIsIm9iamVjdCIsImZldGNoIiwiaGlnaFdhdGVyTWFyayIsIkhlYWRlcnMiLCJSZXNwb25zZSIsIlJlYWRhYmxlU3RyZWFtIiwiXyIsImdsb2JhbHMiLCJnZXRHbG9iYWwiLCJwcm9wZXJ0eSIsInNlbGYiLCJnbG9iYWxUaGlzIiwiZ2xvYmFsUHJvcGVydGllcyIsImdsb2JhbE9iamVjdCIsImJpbmQiLCJzdXBwb3J0c0Fib3J0Q29udHJvbGxlciIsInN1cHBvcnRzU3RyZWFtcyIsInN1cHBvcnRzRm9ybURhdGEiLCJtZXJnZUhlYWRlcnMiLCJzb3VyY2UxIiwic291cmNlMiIsInJlc3VsdCIsImlzSGVhZGVyc0luc3RhbmNlIiwic291cmNlIiwiZGVlcE1lcmdlIiwic291cmNlcyIsInJlcXVlc3RNZXRob2RzIiwicmVzcG9uc2VUeXBlcyIsInRleHQiLCJyZXRyeUFmdGVyU3RhdHVzQ29kZXMiLCJzdG9wIiwiSFRUUEVycm9yIiwiVGltZW91dEVycm9yIiwiZGVsYXkiLCJtcyIsInNldFRpbWVvdXQiLCJub3JtYWxpemVSZXF1ZXN0TWV0aG9kIiwiaW5jbHVkZXMiLCJ0b1VwcGVyQ2FzZSIsImRlZmF1bHRSZXRyeU9wdGlvbnMiLCJsaW1pdCIsIm1ldGhvZHMiLCJzdGF0dXNDb2RlcyIsImFmdGVyU3RhdHVzQ29kZXMiLCJub3JtYWxpemVSZXRyeU9wdGlvbnMiLCJyZXRyeSIsIm1heFNhZmVUaW1lb3V0IiwiS3kiLCJfcmV0cnlDb3VudCIsIl9pbnB1dCIsIl9vcHRpb25zIiwiY3JlZGVudGlhbHMiLCJob29rcyIsImJlZm9yZVJlcXVlc3QiLCJiZWZvcmVSZXRyeSIsImFmdGVyUmVzcG9uc2UiLCJwcmVmaXhVcmwiLCJVUkwiLCJzdGFydHNXaXRoIiwiZW5kc1dpdGgiLCJhYm9ydENvbnRyb2xsZXIiLCJVUkxTZWFyY2hQYXJhbXMiLCJmbiIsIlJhbmdlRXJyb3IiLCJfZmV0Y2giLCJob29rIiwibW9kaWZpZWRSZXNwb25zZSIsIl9kZWNvcmF0ZVJlc3BvbnNlIiwiY2xvbmUiLCJvbkRvd25sb2FkUHJvZ3Jlc3MiLCJfc3RyZWFtIiwiX3JldHJ5IiwibWltZVR5cGUiLCJwYXJzZUpzb24iLCJfY2FsY3VsYXRlUmV0cnlEZWxheSIsInJldHJ5QWZ0ZXIiLCJhZnRlciIsIk51bWJlciIsImlzTmFOIiwibWF4UmV0cnlBZnRlciIsInJldHJ5Q291bnQiLCJ0aW1lb3V0SUQiLCJjYXRjaCIsImNsZWFyVGltZW91dCIsInRvdGFsQnl0ZXMiLCJ0cmFuc2ZlcnJlZEJ5dGVzIiwicmVhZGVyIiwiZ2V0UmVhZGVyIiwicGVyY2VudCIsImRvbmUiLCJjbG9zZSIsImVucXVldWUiLCJ2YWxpZGF0ZUFuZE1lcmdlIiwiY3JlYXRlSW5zdGFuY2UiLCJkZWZhdWx0cyIsImt5IiwibmV3RGVmYXVsdHMiLCJleHRlbmQiLCJub3JtYWxpemUiLCJzdHIiLCJqb2luZWQiLCJyZXF1aXJlIiwiaHR0cCIsImh0dHBzIiwiemxpYiIsIlN0cmVhbSIsImRhdGFVcmlUb0J1ZmZlciIsInV0aWwiLCJjcnlwdG8iLCJGZXRjaEJhc2VFcnJvciIsImNhcHR1cmVTdGFja1RyYWNlIiwiRmV0Y2hFcnJvciIsInN5c3RlbUVycm9yIiwiZXJybm8iLCJlcnJvcmVkU3lzQ2FsbCIsInN5c2NhbGwiLCJOQU1FIiwiaXNVUkxTZWFyY2hQYXJhbWV0ZXJzIiwiZ2V0QWxsIiwiaGFzIiwic29ydCIsImlzQmxvYiIsImlzRm9ybURhdGEiLCJjYXJyaWFnZSIsImRhc2hlcyIsInJlcGVhdCIsImNhcnJpYWdlTGVuZ3RoIiwiZ2V0Rm9vdGVyIiwiYm91bmRhcnkiLCJnZXRIZWFkZXIiLCJmaWVsZCIsImhlYWRlciIsIklOVEVSTkFMUyIsIkJvZHkiLCJpc0J1ZmZlciIsImlzQW55QXJyYXlCdWZmZXIiLCJyYW5kb21CeXRlcyIsImZvcm0iLCJmb3JtRGF0YUl0ZXJhdG9yIiwiZGlzdHVyYmVkIiwiYm9keVVzZWQiLCJjb25zdW1lQm9keSIsImN0IiwiYnVmIiwiYWxsb2MiLCJhY2N1bSIsImFjY3VtQnl0ZXMiLCJyZWFkYWJsZUVuZGVkIiwiX3JlYWRhYmxlU3RhdGUiLCJlbmRlZCIsImV2ZXJ5IiwiaW5zdGFuY2UiLCJwMSIsInAyIiwiZ2V0Qm91bmRhcnkiLCJQYXNzVGhyb3VnaCIsImV4dHJhY3RDb250ZW50VHlwZSIsImdldFRvdGFsQnl0ZXMiLCJnZXRMZW5ndGhTeW5jIiwiaGFzS25vd25MZW5ndGgiLCJnZXRGb3JtRGF0YUxlbmd0aCIsInZhbGlkYXRlSGVhZGVyTmFtZSIsInZhbGlkYXRlSGVhZGVyVmFsdWUiLCJpbml0IiwicmF3IiwiaXNCb3hlZFByaW1pdGl2ZSIsIml0ZXJhdG9yIiwicGFpciIsIlByb3h5IiwicCIsInJlY2VpdmVyIiwiU2V0IiwiUmVmbGVjdCIsImNhbGxiYWNrIiwiZm9yIiwicmVkaXJlY3RTdGF0dXMiLCJpc1JlZGlyZWN0IiwiSU5URVJOQUxTJDEiLCJjb3VudGVyIiwicmVkaXJlY3RlZCIsImxvY2F0aW9uIiwiSU5URVJOQUxTJDIiLCJpc1JlcXVlc3QiLCJwYXJzZWRVUkwiLCJpbnB1dEJvZHkiLCJyZWRpcmVjdCIsImZvbGxvdyIsImNvbXByZXNzIiwiYWdlbnQiLCJpbnNlY3VyZUhUVFBQYXJzZXIiLCJmb3JtYXQiLCJBYm9ydEVycm9yIiwic3VwcG9ydGVkU2NoZW1hcyIsIm9wdGlvbnNfIiwiY29udGVudExlbmd0aFZhbHVlIiwic2VhcmNoIiwibGFzdE9mZnNldCIsImhyZWYiLCJoYXNoIiwiZ2V0U2VhcmNoIiwicGF0aCIsInBhdGhuYW1lIiwiaG9zdG5hbWUiLCJwcm90b2NvbCIsInBvcnQiLCJnZXROb2RlUmVxdWVzdE9wdGlvbnMiLCJzZW5kIiwiZW1pdCIsImFib3J0QW5kRmluYWxpemUiLCJmaW5hbGl6ZSIsInJlcXVlc3RfIiwicmVzcG9uc2VfIiwiaW5kZXgiLCJhcnJheSIsImZyb21SYXdIZWFkZXJzIiwicmF3SGVhZGVycyIsInN0YXR1c0NvZGUiLCJsb2NhdGlvblVSTCIsInJlcXVlc3RPcHRpb25zIiwicGlwZWxpbmUiLCJwcm9jZXNzIiwidmVyc2lvbiIsInJlc3BvbnNlT3B0aW9ucyIsInN0YXR1c01lc3NhZ2UiLCJjb2RpbmdzIiwiemxpYk9wdGlvbnMiLCJmbHVzaCIsIlpfU1lOQ19GTFVTSCIsImZpbmlzaEZsdXNoIiwiY3JlYXRlR3VuemlwIiwiY3JlYXRlQnJvdGxpRGVjb21wcmVzcyIsImNyZWF0ZUluZmxhdGUiLCJjcmVhdGVJbmZsYXRlUmF3IiwiZGVzdCIsIndyaXRlIiwid3JpdGVUb1N0cmVhbSIsIlN5bWJvbFBvbHlmaWxsIiwiZGVzY3JpcHRpb24iLCJub29wIiwidHlwZUlzT2JqZWN0IiwicmV0aHJvd0Fzc2VydGlvbkVycm9yUmVqZWN0aW9uIiwib3JpZ2luYWxQcm9taXNlIiwib3JpZ2luYWxQcm9taXNlVGhlbiIsIm9yaWdpbmFsUHJvbWlzZVJlc29sdmUiLCJvcmlnaW5hbFByb21pc2VSZWplY3QiLCJuZXdQcm9taXNlIiwiZXhlY3V0b3IiLCJwcm9taXNlUmVzb2x2ZWRXaXRoIiwicHJvbWlzZVJlamVjdGVkV2l0aCIsInJlYXNvbiIsIlBlcmZvcm1Qcm9taXNlVGhlbiIsInByb21pc2UiLCJvbkZ1bGZpbGxlZCIsIm9uUmVqZWN0ZWQiLCJ1cG9uUHJvbWlzZSIsInVwb25GdWxmaWxsbWVudCIsInVwb25SZWplY3Rpb24iLCJ0cmFuc2Zvcm1Qcm9taXNlV2l0aCIsImZ1bGZpbGxtZW50SGFuZGxlciIsInJlamVjdGlvbkhhbmRsZXIiLCJzZXRQcm9taXNlSXNIYW5kbGVkVG9UcnVlIiwicXVldWVNaWNyb3Rhc2siLCJnbG9iYWxRdWV1ZU1pY3JvdGFzayIsInJlc29sdmVkUHJvbWlzZSIsInJlZmxlY3RDYWxsIiwiRiIsIlYiLCJhcmdzIiwiRnVuY3Rpb24iLCJwcm9taXNlQ2FsbCIsIlNpbXBsZVF1ZXVlIiwiX2N1cnNvciIsIl9zaXplIiwiX2Zyb250IiwiX2VsZW1lbnRzIiwiX25leHQiLCJfYmFjayIsIm9sZEJhY2siLCJuZXdCYWNrIiwiUVVFVUVfTUFYX0FSUkFZX1NJWkUiLCJzaGlmdCIsIm9sZEZyb250IiwibmV3RnJvbnQiLCJvbGRDdXJzb3IiLCJuZXdDdXJzb3IiLCJlbGVtZW50cyIsInBlZWsiLCJmcm9udCIsImN1cnNvciIsIlJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0luaXRpYWxpemUiLCJfb3duZXJSZWFkYWJsZVN0cmVhbSIsIl9yZWFkZXIiLCJfc3RhdGUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZVJlc29sdmUiLCJkZWZhdWx0UmVhZGVyQ2xvc2VkUHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkIiwiZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCIsIl9zdG9yZWRFcnJvciIsIlJlYWRhYmxlU3RyZWFtUmVhZGVyR2VuZXJpY0NhbmNlbCIsIlJlYWRhYmxlU3RyZWFtQ2FuY2VsIiwiUmVhZGFibGVTdHJlYW1SZWFkZXJHZW5lcmljUmVsZWFzZSIsImRlZmF1bHRSZWFkZXJDbG9zZWRQcm9taXNlUmVqZWN0IiwiZGVmYXVsdFJlYWRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQiLCJyZWFkZXJMb2NrRXhjZXB0aW9uIiwiX2Nsb3NlZFByb21pc2UiLCJfY2xvc2VkUHJvbWlzZV9yZXNvbHZlIiwiX2Nsb3NlZFByb21pc2VfcmVqZWN0IiwiQWJvcnRTdGVwcyIsIkVycm9yU3RlcHMiLCJDYW5jZWxTdGVwcyIsIlB1bGxTdGVwcyIsIk51bWJlcklzRmluaXRlIiwiaXNGaW5pdGUiLCJNYXRoVHJ1bmMiLCJ0cnVuYyIsInYiLCJjZWlsIiwiZmxvb3IiLCJhc3NlcnREaWN0aW9uYXJ5IiwiY29udGV4dCIsImFzc2VydEZ1bmN0aW9uIiwiYXNzZXJ0T2JqZWN0IiwiYXNzZXJ0UmVxdWlyZWRBcmd1bWVudCIsImFzc2VydFJlcXVpcmVkRmllbGQiLCJjb252ZXJ0VW5yZXN0cmljdGVkRG91YmxlIiwiY2Vuc29yTmVnYXRpdmVaZXJvIiwiY29udmVydFVuc2lnbmVkTG9uZ0xvbmdXaXRoRW5mb3JjZVJhbmdlIiwidXBwZXJCb3VuZCIsIk1BWF9TQUZFX0lOVEVHRVIiLCJpbnRlZ2VyUGFydCIsImFzc2VydFJlYWRhYmxlU3RyZWFtIiwiSXNSZWFkYWJsZVN0cmVhbSIsIkFjcXVpcmVSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUFkZFJlYWRSZXF1ZXN0IiwicmVhZFJlcXVlc3QiLCJfcmVhZFJlcXVlc3RzIiwiUmVhZGFibGVTdHJlYW1GdWxmaWxsUmVhZFJlcXVlc3QiLCJfY2xvc2VTdGVwcyIsIl9jaHVua1N0ZXBzIiwiUmVhZGFibGVTdHJlYW1HZXROdW1SZWFkUmVxdWVzdHMiLCJSZWFkYWJsZVN0cmVhbUhhc0RlZmF1bHRSZWFkZXIiLCJJc1JlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlciIsIklzUmVhZGFibGVTdHJlYW1Mb2NrZWQiLCJjbG9zZWQiLCJkZWZhdWx0UmVhZGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsImNhbmNlbCIsInJlc29sdmVQcm9taXNlIiwicmVqZWN0UHJvbWlzZSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdFJlYWRlclJlYWQiLCJfZXJyb3JTdGVwcyIsImUiLCJyZWxlYXNlTG9jayIsImhhc093blByb3BlcnR5IiwiX2Rpc3R1cmJlZCIsIl9yZWFkYWJsZVN0cmVhbUNvbnRyb2xsZXIiLCJBc3luY0l0ZXJhdG9yUHJvdG90eXBlIiwiUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9ySW1wbCIsInByZXZlbnRDYW5jZWwiLCJfb25nb2luZ1Byb21pc2UiLCJfaXNGaW5pc2hlZCIsIl9wcmV2ZW50Q2FuY2VsIiwibmV4dFN0ZXBzIiwiX25leHRTdGVwcyIsInJldHVybiIsInJldHVyblN0ZXBzIiwiX3JldHVyblN0ZXBzIiwiUmVhZGFibGVTdHJlYW1Bc3luY0l0ZXJhdG9yUHJvdG90eXBlIiwiSXNSZWFkYWJsZVN0cmVhbUFzeW5jSXRlcmF0b3IiLCJfYXN5bmNJdGVyYXRvckltcGwiLCJzdHJlYW1Bc3luY0l0ZXJhdG9yQnJhbmRDaGVja0V4Y2VwdGlvbiIsIl9hIiwiTnVtYmVySXNOYU4iLCJDcmVhdGVBcnJheUZyb21MaXN0IiwiQ29weURhdGFCbG9ja0J5dGVzIiwiZGVzdE9mZnNldCIsInNyYyIsInNyY09mZnNldCIsIm4iLCJBcnJheUJ1ZmZlclNsaWNlIiwiYmVnaW4iLCJDbG9uZUFzVWludDhBcnJheSIsIk8iLCJEZXF1ZXVlVmFsdWUiLCJjb250YWluZXIiLCJfcXVldWUiLCJfcXVldWVUb3RhbFNpemUiLCJFbnF1ZXVlVmFsdWVXaXRoU2l6ZSIsIkluZmluaXR5IiwiUmVzZXRRdWV1ZSIsIlJlYWRhYmxlU3RyZWFtQllPQlJlcXVlc3QiLCJ2aWV3IiwiSXNSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IiwiYnlvYlJlcXVlc3RCcmFuZENoZWNrRXhjZXB0aW9uIiwiX3ZpZXciLCJyZXNwb25kIiwiYnl0ZXNXcml0dGVuIiwiX2Fzc29jaWF0ZWRSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmQiLCJyZXNwb25kV2l0aE5ld1ZpZXciLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZFdpdGhOZXdWaWV3IiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlciIsImJ5b2JSZXF1ZXN0IiwiSXNSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwiYnl0ZVN0cmVhbUNvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckdldEJZT0JSZXF1ZXN0IiwiZGVzaXJlZFNpemUiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyR2V0RGVzaXJlZFNpemUiLCJfY2xvc2VSZXF1ZXN0ZWQiLCJfY29udHJvbGxlZFJlYWRhYmxlQnl0ZVN0cmVhbSIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDbG9zZSIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckVycm9yIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNsZWFyUGVuZGluZ1B1bGxJbnRvcyIsIl9jYW5jZWxBbGdvcml0aG0iLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiZW50cnkiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVySGFuZGxlUXVldWVEcmFpbiIsImF1dG9BbGxvY2F0ZUNodW5rU2l6ZSIsIl9hdXRvQWxsb2NhdGVDaHVua1NpemUiLCJidWZmZXJFIiwicHVsbEludG9EZXNjcmlwdG9yIiwiYnVmZmVyQnl0ZUxlbmd0aCIsImJ5dGVzRmlsbGVkIiwiZWxlbWVudFNpemUiLCJ2aWV3Q29uc3RydWN0b3IiLCJyZWFkZXJUeXBlIiwiX3BlbmRpbmdQdWxsSW50b3MiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyQ2FsbFB1bGxJZk5lZWRlZCIsInNob3VsZFB1bGwiLCJfc3RhcnRlZCIsIlJlYWRhYmxlU3RyZWFtSGFzQllPQlJlYWRlciIsIlJlYWRhYmxlU3RyZWFtR2V0TnVtUmVhZEludG9SZXF1ZXN0cyIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJTaG91bGRDYWxsUHVsbCIsIl9wdWxsaW5nIiwiX3B1bGxBZ2FpbiIsIl9wdWxsQWxnb3JpdGhtIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckludmFsaWRhdGVCWU9CUmVxdWVzdCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJDb21taXRQdWxsSW50b0Rlc2NyaXB0b3IiLCJmaWxsZWRWaWV3IiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckNvbnZlcnRQdWxsSW50b0Rlc2NyaXB0b3IiLCJyZWFkSW50b1JlcXVlc3QiLCJfcmVhZEludG9SZXF1ZXN0cyIsIlJlYWRhYmxlU3RyZWFtRnVsZmlsbFJlYWRJbnRvUmVxdWVzdCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJFbnF1ZXVlQ2h1bmtUb1F1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZpbGxQdWxsSW50b0Rlc2NyaXB0b3JGcm9tUXVldWUiLCJjdXJyZW50QWxpZ25lZEJ5dGVzIiwibWF4Qnl0ZXNUb0NvcHkiLCJtYXhCeXRlc0ZpbGxlZCIsIm1heEFsaWduZWRCeXRlcyIsInRvdGFsQnl0ZXNUb0NvcHlSZW1haW5pbmciLCJyZWFkeSIsInF1ZXVlIiwiaGVhZE9mUXVldWUiLCJieXRlc1RvQ29weSIsImRlc3RTdGFydCIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJGaWxsSGVhZFB1bGxJbnRvRGVzY3JpcHRvciIsIlJlYWRhYmxlU3RyZWFtQ2xvc2UiLCJfYnlvYlJlcXVlc3QiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHJvY2Vzc1B1bGxJbnRvRGVzY3JpcHRvcnNVc2luZ1F1ZXVlIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclNoaWZ0UGVuZGluZ1B1bGxJbnRvIiwiUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlclJlc3BvbmRJbnRlcm5hbCIsImZpcnN0RGVzY3JpcHRvciIsIlJlYWRhYmxlQnl0ZVN0cmVhbUNvbnRyb2xsZXJSZXNwb25kSW5DbG9zZWRTdGF0ZSIsInJlbWFpbmRlclNpemUiLCJyZW1haW5kZXIiLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUmVzcG9uZEluUmVhZGFibGVTdGF0ZSIsInRyYW5zZmVycmVkQnVmZmVyIiwiZmlyc3RQZW5kaW5nUHVsbEludG8iLCJSZWFkYWJsZVN0cmVhbUVycm9yIiwiU2V0VXBSZWFkYWJsZVN0cmVhbUJZT0JSZXF1ZXN0IiwiX3N0cmF0ZWd5SFdNIiwiU2V0VXBSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyIiwic3RhcnRBbGdvcml0aG0iLCJwdWxsQWxnb3JpdGhtIiwiY2FuY2VsQWxnb3JpdGhtIiwiciIsIkFjcXVpcmVSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXIiLCJSZWFkYWJsZVN0cmVhbUFkZFJlYWRJbnRvUmVxdWVzdCIsIklzUmVhZGFibGVTdHJlYW1CWU9CUmVhZGVyIiwiYnlvYlJlYWRlckJyYW5kQ2hlY2tFeGNlcHRpb24iLCJSZWFkYWJsZVN0cmVhbUJZT0JSZWFkZXJSZWFkIiwiRGF0YVZpZXciLCJCWVRFU19QRVJfRUxFTUVOVCIsImN0b3IiLCJlbXB0eVZpZXciLCJSZWFkYWJsZUJ5dGVTdHJlYW1Db250cm9sbGVyUHVsbEludG8iLCJFeHRyYWN0SGlnaFdhdGVyTWFyayIsInN0cmF0ZWd5IiwiZGVmYXVsdEhXTSIsIkV4dHJhY3RTaXplQWxnb3JpdGhtIiwiY29udmVydFF1ZXVpbmdTdHJhdGVneSIsImNvbnZlcnRRdWV1aW5nU3RyYXRlZ3lTaXplIiwiY29udmVydFVuZGVybHlpbmdTaW5rQWJvcnRDYWxsYmFjayIsIm9yaWdpbmFsIiwiY29udmVydFVuZGVybHlpbmdTaW5rQ2xvc2VDYWxsYmFjayIsImNvbnZlcnRVbmRlcmx5aW5nU2lua1N0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0VW5kZXJseWluZ1NpbmtXcml0ZUNhbGxiYWNrIiwiYXNzZXJ0V3JpdGFibGVTdHJlYW0iLCJJc1dyaXRhYmxlU3RyZWFtIiwiV3JpdGFibGVTdHJlYW0iLCJyYXdVbmRlcmx5aW5nU2luayIsInJhd1N0cmF0ZWd5IiwidW5kZXJseWluZ1NpbmsiLCJjb252ZXJ0VW5kZXJseWluZ1NpbmsiLCJJbml0aWFsaXplV3JpdGFibGVTdHJlYW0iLCJzaXplQWxnb3JpdGhtIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIndyaXRlQWxnb3JpdGhtIiwiY2xvc2VBbGdvcml0aG0iLCJhYm9ydEFsZ29yaXRobSIsIlNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIlNldFVwV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckZyb21VbmRlcmx5aW5nU2luayIsImxvY2tlZCIsInN0cmVhbUJyYW5kQ2hlY2tFeGNlcHRpb24kMiIsIklzV3JpdGFibGVTdHJlYW1Mb2NrZWQiLCJXcml0YWJsZVN0cmVhbUFib3J0IiwiV3JpdGFibGVTdHJlYW1DbG9zZVF1ZXVlZE9ySW5GbGlnaHQiLCJXcml0YWJsZVN0cmVhbUNsb3NlIiwiZ2V0V3JpdGVyIiwiQWNxdWlyZVdyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlciIsIl93cml0ZXIiLCJfd3JpdGFibGVTdHJlYW1Db250cm9sbGVyIiwiX3dyaXRlUmVxdWVzdHMiLCJfaW5GbGlnaHRXcml0ZVJlcXVlc3QiLCJfY2xvc2VSZXF1ZXN0IiwiX2luRmxpZ2h0Q2xvc2VSZXF1ZXN0IiwiX3BlbmRpbmdBYm9ydFJlcXVlc3QiLCJfYmFja3ByZXNzdXJlIiwiX2Fib3J0UmVhc29uIiwiX2Fib3J0Q29udHJvbGxlciIsIl9wcm9taXNlIiwid2FzQWxyZWFkeUVycm9yaW5nIiwiX3Jlc29sdmUiLCJfcmVqZWN0IiwiX3JlYXNvbiIsIl93YXNBbHJlYWR5RXJyb3JpbmciLCJXcml0YWJsZVN0cmVhbVN0YXJ0RXJyb3JpbmciLCJjbG9zZVJlcXVlc3QiLCJ3cml0ZXIiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVzb2x2ZSIsImNsb3NlU2VudGluZWwiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQWR2YW5jZVF1ZXVlSWZOZWVkZWQiLCJXcml0YWJsZVN0cmVhbURlYWxXaXRoUmVqZWN0aW9uIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hFcnJvcmluZyIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckVuc3VyZVJlYWR5UHJvbWlzZVJlamVjdGVkIiwiV3JpdGFibGVTdHJlYW1IYXNPcGVyYXRpb25NYXJrZWRJbkZsaWdodCIsInN0b3JlZEVycm9yIiwid3JpdGVSZXF1ZXN0IiwiV3JpdGFibGVTdHJlYW1SZWplY3RDbG9zZUFuZENsb3NlZFByb21pc2VJZk5lZWRlZCIsImFib3J0UmVxdWVzdCIsImRlZmF1bHRXcml0ZXJDbG9zZWRQcm9taXNlUmVqZWN0IiwiV3JpdGFibGVTdHJlYW1VcGRhdGVCYWNrcHJlc3N1cmUiLCJiYWNrcHJlc3N1cmUiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlSW5pdGlhbGl6ZSIsImRlZmF1bHRXcml0ZXJSZWFkeVByb21pc2VSZXNldCIsIl9vd25lcldyaXRhYmxlU3RyZWFtIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1Jlc29sdmVkIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplIiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZUluaXRpYWxpemVBc1JlamVjdGVkIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNvbHZlIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VJbml0aWFsaXplQXNSZWplY3RlZCIsIklzV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyIiwiZGVmYXVsdFdyaXRlckJyYW5kQ2hlY2tFeGNlcHRpb24iLCJkZWZhdWx0V3JpdGVyTG9ja0V4Y2VwdGlvbiIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJHZXREZXNpcmVkU2l6ZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckdldERlc2lyZWRTaXplIiwiX3JlYWR5UHJvbWlzZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdFdyaXRlckFib3J0IiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2UiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJSZWxlYXNlIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyV3JpdGUiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRXcml0ZXJFbnN1cmVDbG9zZWRQcm9taXNlUmVqZWN0ZWQiLCJfY2xvc2VkUHJvbWlzZVN0YXRlIiwiZGVmYXVsdFdyaXRlckNsb3NlZFByb21pc2VSZXNldFRvUmVqZWN0ZWQiLCJfcmVhZHlQcm9taXNlU3RhdGUiLCJkZWZhdWx0V3JpdGVyUmVhZHlQcm9taXNlUmVqZWN0IiwiZGVmYXVsdFdyaXRlclJlYWR5UHJvbWlzZVJlc2V0VG9SZWplY3RlZCIsInJlbGVhc2VkRXJyb3IiLCJjaHVua1NpemUiLCJfc3RyYXRlZ3lTaXplQWxnb3JpdGhtIiwiY2h1bmtTaXplRSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJFcnJvcklmTmVlZGVkIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldENodW5rU2l6ZSIsIldyaXRhYmxlU3RyZWFtQWRkV3JpdGVSZXF1ZXN0IiwiZW5xdWV1ZUUiLCJfY29udHJvbGxlZFdyaXRhYmxlU3RyZWFtIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldEJhY2twcmVzc3VyZSIsIldyaXRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJXcml0ZSIsImFib3J0UmVhc29uIiwiSXNXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIiwiZGVmYXVsdENvbnRyb2xsZXJCcmFuZENoZWNrRXhjZXB0aW9uJDIiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IiLCJfYWJvcnRBbGdvcml0aG0iLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiY3JlYXRlQWJvcnRDb250cm9sbGVyIiwiX3dyaXRlQWxnb3JpdGhtIiwiX2Nsb3NlQWxnb3JpdGhtIiwiV3JpdGFibGVTdHJlYW1NYXJrQ2xvc2VSZXF1ZXN0SW5GbGlnaHQiLCJzaW5rQ2xvc2VQcm9taXNlIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlIiwiV3JpdGFibGVTdHJlYW1GaW5pc2hJbkZsaWdodENsb3NlV2l0aEVycm9yIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclByb2Nlc3NDbG9zZSIsIldyaXRhYmxlU3RyZWFtTWFya0ZpcnN0V3JpdGVSZXF1ZXN0SW5GbGlnaHQiLCJXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0V3JpdGUiLCJXcml0YWJsZVN0cmVhbUZpbmlzaEluRmxpZ2h0V3JpdGVXaXRoRXJyb3IiLCJXcml0YWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyUHJvY2Vzc1dyaXRlIiwiX3JlYWR5UHJvbWlzZV9yZXNvbHZlIiwiX3JlYWR5UHJvbWlzZV9yZWplY3QiLCJOYXRpdmVET01FeGNlcHRpb24iLCJET01FeGNlcHRpb24iLCJET01FeGNlcHRpb24kMSIsImlzRE9NRXhjZXB0aW9uQ29uc3RydWN0b3IiLCJjcmVhdGVET01FeGNlcHRpb25Qb2x5ZmlsbCIsIlJlYWRhYmxlU3RyZWFtUGlwZVRvIiwicHJldmVudENsb3NlIiwicHJldmVudEFib3J0Iiwic2h1dHRpbmdEb3duIiwiY3VycmVudFdyaXRlIiwiYWN0aW9ucyIsInNodXRkb3duV2l0aEFjdGlvbiIsImFsbCIsImFjdGlvbiIsImlzT3JCZWNvbWVzRXJyb3JlZCIsInNodXRkb3duIiwiV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyQ2xvc2VXaXRoRXJyb3JQcm9wYWdhdGlvbiIsImRlc3RDbG9zZWQiLCJ3YWl0Rm9yV3JpdGVzVG9GaW5pc2giLCJvbGRDdXJyZW50V3JpdGUiLCJvcmlnaW5hbElzRXJyb3IiLCJvcmlnaW5hbEVycm9yIiwiZG9UaGVSZXN0IiwibmV3RXJyb3IiLCJpc0Vycm9yIiwicmVzb2x2ZUxvb3AiLCJyZWplY3RMb29wIiwicmVzb2x2ZVJlYWQiLCJyZWplY3RSZWFkIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsIklzUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsImRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiQxIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckdldERlc2lyZWRTaXplIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNhbkNsb3NlT3JFbnF1ZXVlIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckNsb3NlIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckVucXVldWUiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRXJyb3IiLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiX2NvbnRyb2xsZWRSZWFkYWJsZVN0cmVhbSIsIlJlYWRhYmxlU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJDYWxsUHVsbElmTmVlZGVkIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlclNob3VsZENhbGxQdWxsIiwiU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyIiwiUmVhZGFibGVTdHJlYW1UZWUiLCJjbG9uZUZvckJyYW5jaDIiLCJyZWFzb24xIiwicmVhc29uMiIsImJyYW5jaDEiLCJicmFuY2gyIiwicmVzb2x2ZUNhbmNlbFByb21pc2UiLCJyZWFkaW5nIiwiY2FuY2VsZWQxIiwiY2FuY2VsZWQyIiwiY2FuY2VsUHJvbWlzZSIsImZvcndhcmRSZWFkZXJFcnJvciIsInRoaXNSZWFkZXIiLCJwdWxsV2l0aERlZmF1bHRSZWFkZXIiLCJjaHVuazEiLCJjaHVuazIiLCJjbG9uZUUiLCJwdWxsV2l0aEJZT0JSZWFkZXIiLCJmb3JCcmFuY2gyIiwiYnlvYkJyYW5jaCIsIm90aGVyQnJhbmNoIiwiYnlvYkNhbmNlbGVkIiwiY2xvbmVkQ2h1bmsiLCJvdGhlckNhbmNlbGVkIiwicHVsbDFBbGdvcml0aG0iLCJwdWxsMkFsZ29yaXRobSIsImNhbmNlbDFBbGdvcml0aG0iLCJjb21wb3NpdGVSZWFzb24iLCJjYW5jZWxSZXN1bHQiLCJjYW5jZWwyQWxnb3JpdGhtIiwiQ3JlYXRlUmVhZGFibGVCeXRlU3RyZWFtIiwiUmVhZGFibGVCeXRlU3RyZWFtVGVlIiwiQ3JlYXRlUmVhZGFibGVTdHJlYW0iLCJSZWFkYWJsZVN0cmVhbURlZmF1bHRUZWUiLCJjb252ZXJ0VW5kZXJseWluZ1NvdXJjZUNhbmNlbENhbGxiYWNrIiwiY29udmVydFVuZGVybHlpbmdTb3VyY2VQdWxsQ2FsbGJhY2siLCJjb252ZXJ0VW5kZXJseWluZ1NvdXJjZVN0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0UmVhZGFibGVTdHJlYW1UeXBlIiwiY29udmVydFJlYWRhYmxlU3RyZWFtUmVhZGVyTW9kZSIsIm1vZGUiLCJjb252ZXJ0UGlwZU9wdGlvbnMiLCJpc0Fib3J0U2lnbmFsIiwiYXNzZXJ0QWJvcnRTaWduYWwiLCJyYXdVbmRlcmx5aW5nU291cmNlIiwidW5kZXJseWluZ1NvdXJjZSIsInB1bGwiLCJjb252ZXJ0VW5kZXJseWluZ0RlZmF1bHRPckJ5dGVTb3VyY2UiLCJJbml0aWFsaXplUmVhZGFibGVTdHJlYW0iLCJ1bmRlcmx5aW5nQnl0ZVNvdXJjZSIsIlNldFVwUmVhZGFibGVCeXRlU3RyZWFtQ29udHJvbGxlckZyb21VbmRlcmx5aW5nU291cmNlIiwiU2V0VXBSZWFkYWJsZVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVVuZGVybHlpbmdTb3VyY2UiLCJzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uJDEiLCJyYXdPcHRpb25zIiwiY29udmVydFJlYWRlck9wdGlvbnMiLCJwaXBlVGhyb3VnaCIsInJhd1RyYW5zZm9ybSIsInRyYW5zZm9ybSIsInJlYWRhYmxlIiwiY29udmVydFJlYWRhYmxlV3JpdGFibGVQYWlyIiwicGlwZVRvIiwiZGVzdGluYXRpb24iLCJ0ZWUiLCJpbXBsIiwiQWNxdWlyZVJlYWRhYmxlU3RyZWFtQXN5bmNJdGVyYXRvciIsImNvbnZlcnRJdGVyYXRvck9wdGlvbnMiLCJjb252ZXJ0UXVldWluZ1N0cmF0ZWd5SW5pdCIsImFzeW5jSXRlcmF0b3IiLCJieXRlTGVuZ3RoU2l6ZUZ1bmN0aW9uIiwiQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneSIsIl9ieXRlTGVuZ3RoUXVldWluZ1N0cmF0ZWd5SGlnaFdhdGVyTWFyayIsIklzQnl0ZUxlbmd0aFF1ZXVpbmdTdHJhdGVneSIsImJ5dGVMZW5ndGhCcmFuZENoZWNrRXhjZXB0aW9uIiwiY291bnRTaXplRnVuY3Rpb24iLCJDb3VudFF1ZXVpbmdTdHJhdGVneSIsIl9jb3VudFF1ZXVpbmdTdHJhdGVneUhpZ2hXYXRlck1hcmsiLCJJc0NvdW50UXVldWluZ1N0cmF0ZWd5IiwiY291bnRCcmFuZENoZWNrRXhjZXB0aW9uIiwiY29udmVydFRyYW5zZm9ybWVyRmx1c2hDYWxsYmFjayIsImNvbnZlcnRUcmFuc2Zvcm1lclN0YXJ0Q2FsbGJhY2siLCJjb252ZXJ0VHJhbnNmb3JtZXJUcmFuc2Zvcm1DYWxsYmFjayIsIlRyYW5zZm9ybVN0cmVhbSIsInJhd1RyYW5zZm9ybWVyIiwicmF3V3JpdGFibGVTdHJhdGVneSIsInJhd1JlYWRhYmxlU3RyYXRlZ3kiLCJ3cml0YWJsZVN0cmF0ZWd5IiwicmVhZGFibGVTdHJhdGVneSIsInRyYW5zZm9ybWVyIiwicmVhZGFibGVUeXBlIiwid3JpdGFibGVUeXBlIiwiY29udmVydFRyYW5zZm9ybWVyIiwicmVhZGFibGVIaWdoV2F0ZXJNYXJrIiwicmVhZGFibGVTaXplQWxnb3JpdGhtIiwid3JpdGFibGVIaWdoV2F0ZXJNYXJrIiwid3JpdGFibGVTaXplQWxnb3JpdGhtIiwic3RhcnRQcm9taXNlX3Jlc29sdmUiLCJzdGFydFByb21pc2UiLCJfdHJhbnNmb3JtU3RyZWFtQ29udHJvbGxlciIsIl9iYWNrcHJlc3N1cmVDaGFuZ2VQcm9taXNlIiwiX3dyaXRhYmxlIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXJQZXJmb3JtVHJhbnNmb3JtIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtXcml0ZUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbUVycm9yIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtBYm9ydEFsZ29yaXRobSIsIl9yZWFkYWJsZSIsImZsdXNoUHJvbWlzZSIsIl9mbHVzaEFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyQ2xlYXJBbGdvcml0aG1zIiwiVHJhbnNmb3JtU3RyZWFtRGVmYXVsdFNpbmtDbG9zZUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbVNldEJhY2twcmVzc3VyZSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRTb3VyY2VQdWxsQWxnb3JpdGhtIiwiVHJhbnNmb3JtU3RyZWFtRXJyb3JXcml0YWJsZUFuZFVuYmxvY2tXcml0ZSIsIkNyZWF0ZVdyaXRhYmxlU3RyZWFtIiwiX2JhY2twcmVzc3VyZUNoYW5nZVByb21pc2VfcmVzb2x2ZSIsIkluaXRpYWxpemVUcmFuc2Zvcm1TdHJlYW0iLCJUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsInRyYW5zZm9ybUFsZ29yaXRobSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRW5xdWV1ZSIsInRyYW5zZm9ybVJlc3VsdEUiLCJmbHVzaEFsZ29yaXRobSIsIl9jb250cm9sbGVkVHJhbnNmb3JtU3RyZWFtIiwiX3RyYW5zZm9ybUFsZ29yaXRobSIsIlNldFVwVHJhbnNmb3JtU3RyZWFtRGVmYXVsdENvbnRyb2xsZXIiLCJTZXRVcFRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyRnJvbVRyYW5zZm9ybWVyIiwiSXNUcmFuc2Zvcm1TdHJlYW0iLCJzdHJlYW1CcmFuZENoZWNrRXhjZXB0aW9uIiwiSXNUcmFuc2Zvcm1TdHJlYW1EZWZhdWx0Q29udHJvbGxlciIsImRlZmF1bHRDb250cm9sbGVyQnJhbmRDaGVja0V4Y2VwdGlvbiIsInRlcm1pbmF0ZSIsIlRyYW5zZm9ybVN0cmVhbURlZmF1bHRDb250cm9sbGVyVGVybWluYXRlIiwicmVhZGFibGVDb250cm9sbGVyIiwiUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlckhhc0JhY2twcmVzc3VyZSIsIl9fd2VicGFja19tb2R1bGVfY2FjaGVfXyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsImNhY2hlZE1vZHVsZSIsImxvYWRlZCIsIl9fd2VicGFja19tb2R1bGVzX18iLCJkZWZpbml0aW9uIiwibyIsInByb3AiLCJubWQiLCJwYXRocyIsImNoaWxkcmVuIl0sInNvdXJjZVJvb3QiOiIifQ== - -/***/ }), - -/***/ 4294: +/***/ 4812: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -module.exports = __nccwpck_require__(4219); +module.exports = +{ + parallel : __nccwpck_require__(8210), + serial : __nccwpck_require__(445), + serialOrdered : __nccwpck_require__(3578) +}; /***/ }), -/***/ 4219: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - -"use strict"; +/***/ 1700: +/***/ ((module) => { +// API +module.exports = abort; -var net = __nccwpck_require__(1808); -var tls = __nccwpck_require__(4404); -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var events = __nccwpck_require__(2361); -var assert = __nccwpck_require__(9491); -var util = __nccwpck_require__(3837); +/** + * Aborts leftover active jobs + * + * @param {object} state - current state object + */ +function abort(state) +{ + Object.keys(state.jobs).forEach(clean.bind(state)); + // reset leftover jobs + state.jobs = {}; +} -exports.httpOverHttp = httpOverHttp; -exports.httpsOverHttp = httpsOverHttp; -exports.httpOverHttps = httpOverHttps; -exports.httpsOverHttps = httpsOverHttps; +/** + * Cleans up leftover job by invoking abort function for the provided job id + * + * @this state + * @param {string|number} key - job id to abort + */ +function clean(key) +{ + if (typeof this.jobs[key] == 'function') + { + this.jobs[key](); + } +} -function httpOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - return agent; -} +/***/ }), -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} +/***/ 2794: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -function httpOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - return agent; -} +var defer = __nccwpck_require__(5295); -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - agent.createSocket = createSecureSocket; - agent.defaultPort = 443; - return agent; -} +// API +module.exports = async; +/** + * Runs provided callback asynchronously + * even if callback itself is not + * + * @param {function} callback - callback to invoke + * @returns {function} - augmented callback + */ +function async(callback) +{ + var isAsync = false; -function TunnelingAgent(options) { - var self = this; - self.options = options || {}; - self.proxyOptions = self.options.proxy || {}; - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; - self.requests = []; - self.sockets = []; + // check if async happened + defer(function() { isAsync = true; }); - self.on('free', function onFree(socket, host, port, localAddress) { - var options = toOptions(host, port, localAddress); - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i]; - if (pending.host === options.host && pending.port === options.port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1); - pending.request.onSocket(socket); - return; - } + return function async_callback(err, result) + { + if (isAsync) + { + callback(err, result); } - socket.destroy(); - self.removeSocket(socket); - }); + else + { + defer(function nextTick_callback() + { + callback(err, result); + }); + } + }; } -util.inherits(TunnelingAgent, events.EventEmitter); -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { - var self = this; - var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push(options); - return; - } - // If we are under maxSockets create a new one. - self.createSocket(options, function(socket) { - socket.on('free', onFree); - socket.on('close', onCloseOrRemove); - socket.on('agentRemove', onCloseOrRemove); - req.onSocket(socket); +/***/ }), - function onFree() { - self.emit('free', socket, options); - } +/***/ 5295: +/***/ ((module) => { - function onCloseOrRemove(err) { - self.removeSocket(socket); - socket.removeListener('free', onFree); - socket.removeListener('close', onCloseOrRemove); - socket.removeListener('agentRemove', onCloseOrRemove); - } - }); -}; +module.exports = defer; -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this; - var placeholder = {}; - self.sockets.push(placeholder); +/** + * Runs provided function on next iteration of the event loop + * + * @param {function} fn - function to run + */ +function defer(fn) +{ + var nextTick = typeof setImmediate == 'function' + ? setImmediate + : ( + typeof process == 'object' && typeof process.nextTick == 'function' + ? process.nextTick + : null + ); - var connectOptions = mergeOptions({}, self.proxyOptions, { - method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false, - headers: { - host: options.host + ':' + options.port - } - }); - if (options.localAddress) { - connectOptions.localAddress = options.localAddress; + if (nextTick) + { + nextTick(fn); } - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {}; - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64'); + else + { + setTimeout(fn, 0); } +} - debug('making CONNECT request'); - var connectReq = self.request(connectOptions); - connectReq.useChunkedEncodingByDefault = false; // for v0.6 - connectReq.once('response', onResponse); // for v0.6 - connectReq.once('upgrade', onUpgrade); // for v0.6 - connectReq.once('connect', onConnect); // for v0.7 or later - connectReq.once('error', onError); - connectReq.end(); - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true; - } +/***/ }), - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head); - }); - } +/***/ 9023: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - function onConnect(res, socket, head) { - connectReq.removeAllListeners(); - socket.removeAllListeners(); +var async = __nccwpck_require__(2794) + , abort = __nccwpck_require__(1700) + ; - if (res.statusCode !== 200) { - debug('tunneling socket could not be established, statusCode=%d', - res.statusCode); - socket.destroy(); - var error = new Error('tunneling socket could not be established, ' + - 'statusCode=' + res.statusCode); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); +// API +module.exports = iterate; + +/** + * Iterates over each job object + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {object} state - current job status + * @param {function} callback - invoked when all elements processed + */ +function iterate(list, iterator, state, callback) +{ + // store current index + var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + + state.jobs[key] = runJob(iterator, key, list[key], function(error, output) + { + // don't repeat yourself + // skip secondary callbacks + if (!(key in state.jobs)) + { return; } - if (head.length > 0) { - debug('got illegal response body from proxy'); - socket.destroy(); - var error = new Error('got illegal response body from proxy'); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - return; + + // clean up jobs + delete state.jobs[key]; + + if (error) + { + // don't process rest of the results + // stop still active jobs + // and reset the list + abort(state); + } + else + { + state.results[key] = output; } - debug('tunneling connection has established'); - self.sockets[self.sockets.indexOf(placeholder)] = socket; - return cb(socket); - } - function onError(cause) { - connectReq.removeAllListeners(); + // return salvaged results + callback(error, state.results); + }); +} - debug('tunneling socket could not be established, cause=%s\n', - cause.message, cause.stack); - var error = new Error('tunneling socket could not be established, ' + - 'cause=' + cause.message); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } -}; +/** + * Runs iterator over provided job element + * + * @param {function} iterator - iterator to invoke + * @param {string|number} key - key/index of the element in the list of jobs + * @param {mixed} item - job description + * @param {function} callback - invoked after iterator is done with the job + * @returns {function|mixed} - job abort function or something else + */ +function runJob(iterator, key, item, callback) +{ + var aborter; -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) { - return; + // allow shortcut if iterator expects only two arguments + if (iterator.length == 2) + { + aborter = iterator(item, async(callback)); } - this.sockets.splice(pos, 1); - - var pending = this.requests.shift(); - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket); - }); + // otherwise go with full three arguments + else + { + aborter = iterator(item, key, async(callback)); } -}; - -function createSecureSocket(options, cb) { - var self = this; - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - var hostHeader = options.request.getHeader('host'); - var tlsOptions = mergeOptions({}, self.options, { - socket: socket, - servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host - }); - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, tlsOptions); - self.sockets[self.sockets.indexOf(socket)] = secureSocket; - cb(secureSocket); - }); + return aborter; } -function toOptions(host, port, localAddress) { - if (typeof host === 'string') { // since v0.10 - return { - host: host, - port: port, - localAddress: localAddress - }; - } - return host; // for v0.11 or later -} +/***/ }), -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i]; - if (typeof overrides === 'object') { - var keys = Object.keys(overrides); - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j]; - if (overrides[k] !== undefined) { - target[k] = overrides[k]; - } - } - } - } - return target; -} +/***/ 2474: +/***/ ((module) => { +// API +module.exports = state; -var debug; -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments); - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0]; - } else { - args.unshift('TUNNEL:'); +/** + * Creates initial state object + * for iteration over list + * + * @param {array|object} list - list to iterate over + * @param {function|null} sortMethod - function to use for keys sort, + * or `null` to keep them as is + * @returns {object} - initial state object + */ +function state(list, sortMethod) +{ + var isNamedList = !Array.isArray(list) + , initState = + { + index : 0, + keyedList: isNamedList || sortMethod ? Object.keys(list) : null, + jobs : {}, + results : isNamedList ? {} : [], + size : isNamedList ? Object.keys(list).length : list.length } - console.error.apply(console, args); + ; + + if (sortMethod) + { + // sort array keys based on it's values + // sort object's keys just on own merit + initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) + { + return sortMethod(list[a], list[b]); + }); } -} else { - debug = function() {}; + + return initState; } -exports.debug = debug; // for test /***/ }), -/***/ 1773: +/***/ 7942: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +var abort = __nccwpck_require__(1700) + , async = __nccwpck_require__(2794) + ; +// API +module.exports = terminator; -const Client = __nccwpck_require__(3598) -const Dispatcher = __nccwpck_require__(412) -const errors = __nccwpck_require__(8045) -const Pool = __nccwpck_require__(4634) -const BalancedPool = __nccwpck_require__(7931) -const Agent = __nccwpck_require__(7890) -const util = __nccwpck_require__(3983) -const { InvalidArgumentError } = errors -const api = __nccwpck_require__(4059) -const buildConnector = __nccwpck_require__(2067) -const MockClient = __nccwpck_require__(8687) -const MockAgent = __nccwpck_require__(6771) -const MockPool = __nccwpck_require__(6193) -const mockErrors = __nccwpck_require__(888) -const ProxyAgent = __nccwpck_require__(7858) -const RetryHandler = __nccwpck_require__(2286) -const { getGlobalDispatcher, setGlobalDispatcher } = __nccwpck_require__(1892) -const DecoratorHandler = __nccwpck_require__(6930) -const RedirectHandler = __nccwpck_require__(2860) -const createRedirectInterceptor = __nccwpck_require__(8861) +/** + * Terminates jobs in the attached state context + * + * @this AsyncKitState# + * @param {function} callback - final callback to invoke after termination + */ +function terminator(callback) +{ + if (!Object.keys(this.jobs).length) + { + return; + } -let hasCrypto -try { - __nccwpck_require__(6113) - hasCrypto = true -} catch { - hasCrypto = false -} + // fast forward iteration index + this.index = this.size; -Object.assign(Dispatcher.prototype, api) + // abort jobs + abort(this); -module.exports.Dispatcher = Dispatcher -module.exports.Client = Client -module.exports.Pool = Pool -module.exports.BalancedPool = BalancedPool -module.exports.Agent = Agent -module.exports.ProxyAgent = ProxyAgent -module.exports.RetryHandler = RetryHandler + // send back results we have so far + async(callback)(null, this.results); +} -module.exports.DecoratorHandler = DecoratorHandler -module.exports.RedirectHandler = RedirectHandler -module.exports.createRedirectInterceptor = createRedirectInterceptor -module.exports.buildConnector = buildConnector -module.exports.errors = errors +/***/ }), -function makeDispatcher (fn) { - return (url, opts, handler) => { - if (typeof opts === 'function') { - handler = opts - opts = null - } +/***/ 8210: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { - throw new InvalidArgumentError('invalid url') - } +var iterate = __nccwpck_require__(9023) + , initState = __nccwpck_require__(2474) + , terminator = __nccwpck_require__(7942) + ; - if (opts != null && typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } +// Public API +module.exports = parallel; - if (opts && opts.path != null) { - if (typeof opts.path !== 'string') { - throw new InvalidArgumentError('invalid opts.path') - } +/** + * Runs iterator over provided array elements in parallel + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function parallel(list, iterator, callback) +{ + var state = initState(list); - let path = opts.path - if (!opts.path.startsWith('/')) { - path = `/${path}` + while (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, function(error, result) + { + if (error) + { + callback(error, result); + return; } - url = new URL(util.parseOrigin(url).origin + path) - } else { - if (!opts) { - opts = typeof url === 'object' ? url : {} + // looks like it's the last one + if (Object.keys(state.jobs).length === 0) + { + callback(null, state.results); + return; } + }); - url = util.parseURL(url) - } + state.index++; + } - const { agent, dispatcher = getGlobalDispatcher() } = opts + return terminator.bind(state, callback); +} - if (agent) { - throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') - } - return fn.call(dispatcher, { - ...opts, - origin: url.origin, - path: url.search ? `${url.pathname}${url.search}` : url.pathname, - method: opts.method || (opts.body ? 'PUT' : 'GET') - }, handler) - } -} +/***/ }), -module.exports.setGlobalDispatcher = setGlobalDispatcher -module.exports.getGlobalDispatcher = getGlobalDispatcher +/***/ 445: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) { - let fetchImpl = null - module.exports.fetch = async function fetch (resource) { - if (!fetchImpl) { - fetchImpl = (__nccwpck_require__(4881).fetch) - } +var serialOrdered = __nccwpck_require__(3578); - try { - return await fetchImpl(...arguments) - } catch (err) { - if (typeof err === 'object') { - Error.captureStackTrace(err, this) - } +// Public API +module.exports = serial; - throw err - } - } - module.exports.Headers = __nccwpck_require__(554).Headers - module.exports.Response = __nccwpck_require__(7823).Response - module.exports.Request = __nccwpck_require__(8359).Request - module.exports.FormData = __nccwpck_require__(2015).FormData - module.exports.File = __nccwpck_require__(8511).File - module.exports.FileReader = __nccwpck_require__(1446).FileReader +/** + * Runs iterator over provided array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serial(list, iterator, callback) +{ + return serialOrdered(list, iterator, null, callback); +} - const { setGlobalOrigin, getGlobalOrigin } = __nccwpck_require__(1246) - module.exports.setGlobalOrigin = setGlobalOrigin - module.exports.getGlobalOrigin = getGlobalOrigin +/***/ }), - const { CacheStorage } = __nccwpck_require__(7907) - const { kConstruct } = __nccwpck_require__(9174) +/***/ 3578: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // Cache & CacheStorage are tightly coupled with fetch. Even if it may run - // in an older version of Node, it doesn't have any use without fetch. - module.exports.caches = new CacheStorage(kConstruct) -} +var iterate = __nccwpck_require__(9023) + , initState = __nccwpck_require__(2474) + , terminator = __nccwpck_require__(7942) + ; -if (util.nodeMajor >= 16) { - const { deleteCookie, getCookies, getSetCookies, setCookie } = __nccwpck_require__(1724) +// Public API +module.exports = serialOrdered; +// sorting helpers +module.exports.ascending = ascending; +module.exports.descending = descending; - module.exports.deleteCookie = deleteCookie - module.exports.getCookies = getCookies - module.exports.getSetCookies = getSetCookies - module.exports.setCookie = setCookie +/** + * Runs iterator over provided sorted array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serialOrdered(list, iterator, sortMethod, callback) +{ + var state = initState(list, sortMethod); - const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) + iterate(list, iterator, state, function iteratorHandler(error, result) + { + if (error) + { + callback(error, result); + return; + } - module.exports.parseMIMEType = parseMIMEType - module.exports.serializeAMimeType = serializeAMimeType -} + state.index++; -if (util.nodeMajor >= 18 && hasCrypto) { - const { WebSocket } = __nccwpck_require__(4284) + // are we there yet? + if (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, iteratorHandler); + return; + } - module.exports.WebSocket = WebSocket + // done here + callback(null, state.results); + }); + + return terminator.bind(state, callback); } -module.exports.request = makeDispatcher(api.request) -module.exports.stream = makeDispatcher(api.stream) -module.exports.pipeline = makeDispatcher(api.pipeline) -module.exports.connect = makeDispatcher(api.connect) -module.exports.upgrade = makeDispatcher(api.upgrade) +/* + * -- Sort methods + */ -module.exports.MockClient = MockClient -module.exports.MockPool = MockPool -module.exports.MockAgent = MockAgent -module.exports.mockErrors = mockErrors +/** + * sort helper to sort array elements in ascending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function ascending(a, b) +{ + return a < b ? -1 : a > b ? 1 : 0; +} + +/** + * sort helper to sort array elements in descending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function descending(a, b) +{ + return -1 * ascending(a, b); +} /***/ }), -/***/ 7890: +/***/ 5443: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +var util = __nccwpck_require__(3837); +var Stream = (__nccwpck_require__(2781).Stream); +var DelayedStream = __nccwpck_require__(8611); +module.exports = CombinedStream; +function CombinedStream() { + this.writable = false; + this.readable = true; + this.dataSize = 0; + this.maxDataSize = 2 * 1024 * 1024; + this.pauseStreams = true; -const { InvalidArgumentError } = __nccwpck_require__(8045) -const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = __nccwpck_require__(2785) -const DispatcherBase = __nccwpck_require__(4839) -const Pool = __nccwpck_require__(4634) -const Client = __nccwpck_require__(3598) -const util = __nccwpck_require__(3983) -const createRedirectInterceptor = __nccwpck_require__(8861) -const { WeakRef, FinalizationRegistry } = __nccwpck_require__(6436)() + this._released = false; + this._streams = []; + this._currentStream = null; + this._insideLoop = false; + this._pendingNext = false; +} +util.inherits(CombinedStream, Stream); -const kOnConnect = Symbol('onConnect') -const kOnDisconnect = Symbol('onDisconnect') -const kOnConnectionError = Symbol('onConnectionError') -const kMaxRedirections = Symbol('maxRedirections') -const kOnDrain = Symbol('onDrain') -const kFactory = Symbol('factory') -const kFinalizer = Symbol('finalizer') -const kOptions = Symbol('options') +CombinedStream.create = function(options) { + var combinedStream = new this(); -function defaultFactory (origin, opts) { - return opts && opts.connections === 1 - ? new Client(origin, opts) - : new Pool(origin, opts) -} + options = options || {}; + for (var option in options) { + combinedStream[option] = options[option]; + } -class Agent extends DispatcherBase { - constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { - super() + return combinedStream; +}; - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') - } +CombinedStream.isStreamLike = function(stream) { + return (typeof stream !== 'function') + && (typeof stream !== 'string') + && (typeof stream !== 'boolean') + && (typeof stream !== 'number') + && (!Buffer.isBuffer(stream)); +}; - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } +CombinedStream.prototype.append = function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); - if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { - throw new InvalidArgumentError('maxRedirections must be a positive number') + if (isStreamLike) { + if (!(stream instanceof DelayedStream)) { + var newStream = DelayedStream.create(stream, { + maxDataSize: Infinity, + pauseStream: this.pauseStreams, + }); + stream.on('data', this._checkDataSize.bind(this)); + stream = newStream; } - if (connect && typeof connect !== 'function') { - connect = { ...connect } + this._handleErrors(stream); + + if (this.pauseStreams) { + stream.pause(); } + } - this[kInterceptors] = options.interceptors && options.interceptors.Agent && Array.isArray(options.interceptors.Agent) - ? options.interceptors.Agent - : [createRedirectInterceptor({ maxRedirections })] + this._streams.push(stream); + return this; +}; - this[kOptions] = { ...util.deepClone(options), connect } - this[kOptions].interceptors = options.interceptors - ? { ...options.interceptors } - : undefined - this[kMaxRedirections] = maxRedirections - this[kFactory] = factory - this[kClients] = new Map() - this[kFinalizer] = new FinalizationRegistry(/* istanbul ignore next: gc is undeterministic */ key => { - const ref = this[kClients].get(key) - if (ref !== undefined && ref.deref() === undefined) { - this[kClients].delete(key) - } - }) +CombinedStream.prototype.pipe = function(dest, options) { + Stream.prototype.pipe.call(this, dest, options); + this.resume(); + return dest; +}; - const agent = this +CombinedStream.prototype._getNext = function() { + this._currentStream = null; - this[kOnDrain] = (origin, targets) => { - agent.emit('drain', origin, [agent, ...targets]) - } + if (this._insideLoop) { + this._pendingNext = true; + return; // defer call + } - this[kOnConnect] = (origin, targets) => { - agent.emit('connect', origin, [agent, ...targets]) - } + this._insideLoop = true; + try { + do { + this._pendingNext = false; + this._realGetNext(); + } while (this._pendingNext); + } finally { + this._insideLoop = false; + } +}; - this[kOnDisconnect] = (origin, targets, err) => { - agent.emit('disconnect', origin, [agent, ...targets], err) - } +CombinedStream.prototype._realGetNext = function() { + var stream = this._streams.shift(); - this[kOnConnectionError] = (origin, targets, err) => { - agent.emit('connectionError', origin, [agent, ...targets], err) - } + + if (typeof stream == 'undefined') { + this.end(); + return; } - get [kRunning] () { - let ret = 0 - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore next: gc is undeterministic */ - if (client) { - ret += client[kRunning] - } - } - return ret + if (typeof stream !== 'function') { + this._pipeNext(stream); + return; } - [kDispatch] (opts, handler) { - let key - if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { - key = String(opts.origin) - } else { - throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') + var getStream = stream; + getStream(function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('data', this._checkDataSize.bind(this)); + this._handleErrors(stream); } - const ref = this[kClients].get(key) - - let dispatcher = ref ? ref.deref() : null - if (!dispatcher) { - dispatcher = this[kFactory](opts.origin, this[kOptions]) - .on('drain', this[kOnDrain]) - .on('connect', this[kOnConnect]) - .on('disconnect', this[kOnDisconnect]) - .on('connectionError', this[kOnConnectionError]) + this._pipeNext(stream); + }.bind(this)); +}; - this[kClients].set(key, new WeakRef(dispatcher)) - this[kFinalizer].register(dispatcher, key) - } +CombinedStream.prototype._pipeNext = function(stream) { + this._currentStream = stream; - return dispatcher.dispatch(opts, handler) + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('end', this._getNext.bind(this)); + stream.pipe(this, {end: false}); + return; } - async [kClose] () { - const closePromises = [] - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore else: gc is undeterministic */ - if (client) { - closePromises.push(client.close()) - } - } + var value = stream; + this.write(value); + this._getNext(); +}; - await Promise.all(closePromises) - } +CombinedStream.prototype._handleErrors = function(stream) { + var self = this; + stream.on('error', function(err) { + self._emitError(err); + }); +}; - async [kDestroy] (err) { - const destroyPromises = [] - for (const ref of this[kClients].values()) { - const client = ref.deref() - /* istanbul ignore else: gc is undeterministic */ - if (client) { - destroyPromises.push(client.destroy(err)) - } - } +CombinedStream.prototype.write = function(data) { + this.emit('data', data); +}; - await Promise.all(destroyPromises) +CombinedStream.prototype.pause = function() { + if (!this.pauseStreams) { + return; } -} - -module.exports = Agent + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); + this.emit('pause'); +}; -/***/ }), - -/***/ 7032: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +CombinedStream.prototype.resume = function() { + if (!this._released) { + this._released = true; + this.writable = true; + this._getNext(); + } -const { addAbortListener } = __nccwpck_require__(3983) -const { RequestAbortedError } = __nccwpck_require__(8045) + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); + this.emit('resume'); +}; -const kListener = Symbol('kListener') -const kSignal = Symbol('kSignal') +CombinedStream.prototype.end = function() { + this._reset(); + this.emit('end'); +}; -function abort (self) { - if (self.abort) { - self.abort() - } else { - self.onError(new RequestAbortedError()) - } -} +CombinedStream.prototype.destroy = function() { + this._reset(); + this.emit('close'); +}; -function addSignal (self, signal) { - self[kSignal] = null - self[kListener] = null +CombinedStream.prototype._reset = function() { + this.writable = false; + this._streams = []; + this._currentStream = null; +}; - if (!signal) { - return +CombinedStream.prototype._checkDataSize = function() { + this._updateDataSize(); + if (this.dataSize <= this.maxDataSize) { + return; } - if (signal.aborted) { - abort(self) - return - } + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; + this._emitError(new Error(message)); +}; - self[kSignal] = signal - self[kListener] = () => { - abort(self) - } +CombinedStream.prototype._updateDataSize = function() { + this.dataSize = 0; - addAbortListener(self[kSignal], self[kListener]) -} + var self = this; + this._streams.forEach(function(stream) { + if (!stream.dataSize) { + return; + } -function removeSignal (self) { - if (!self[kSignal]) { - return - } + self.dataSize += stream.dataSize; + }); - if ('removeEventListener' in self[kSignal]) { - self[kSignal].removeEventListener('abort', self[kListener]) - } else { - self[kSignal].removeListener('abort', self[kListener]) + if (this._currentStream && this._currentStream.dataSize) { + this.dataSize += this._currentStream.dataSize; } +}; - self[kSignal] = null - self[kListener] = null -} - -module.exports = { - addSignal, - removeSignal -} +CombinedStream.prototype._emitError = function(err) { + this._reset(); + this.emit('error', err); +}; /***/ }), -/***/ 9744: +/***/ 8611: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; - +var Stream = (__nccwpck_require__(2781).Stream); +var util = __nccwpck_require__(3837); -const { AsyncResource } = __nccwpck_require__(852) -const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { addSignal, removeSignal } = __nccwpck_require__(7032) +module.exports = DelayedStream; +function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; -class ConnectHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; +} +util.inherits(DelayedStream, Stream); - const { signal, opaque, responseHeaders } = opts +DelayedStream.create = function(source, options) { + var delayedStream = new this(); - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; + } - super('UNDICI_CONNECT') + delayedStream.source = source; - this.opaque = opaque || null - this.responseHeaders = responseHeaders || null - this.callback = callback - this.abort = null + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; - addSignal(this, signal) + source.on('error', function() {}); + if (delayedStream.pauseStream) { + source.pause(); } - onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() - } + return delayedStream; +}; - this.abort = abort - this.context = context +Object.defineProperty(DelayedStream.prototype, 'readable', { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; } +}); - onHeaders () { - throw new SocketError('bad connect', null) - } +DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); +}; - onUpgrade (statusCode, rawHeaders, socket) { - const { callback, opaque, context } = this +DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } - removeSignal(this) + this.source.resume(); +}; - this.callback = null +DelayedStream.prototype.pause = function() { + this.source.pause(); +}; - let headers = rawHeaders - // Indicates is an HTTP2Session - if (headers != null) { - headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - } +DelayedStream.prototype.release = function() { + this._released = true; - this.runInAsyncScope(callback, null, null, { - statusCode, - headers, - socket, - opaque, - context - }) - } + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; +}; - onError (err) { - const { callback, opaque } = this +DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; +}; - removeSignal(this) +DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; + } - if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } + if (args[0] === 'data') { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); } -} -function connect (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - connect.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) + this._bufferedEvents.push(args); +}; + +DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; } - try { - const connectHandler = new ConnectHandler(opts, callback) - this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler) - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts && opts.opaque - queueMicrotask(() => callback(err, { opaque })) + if (this.dataSize <= this.maxDataSize) { + return; } -} -module.exports = connect + this._maxDataSizeExceeded = true; + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' + this.emit('error', new Error(message)); +}; /***/ }), -/***/ 8752: +/***/ 4334: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +var CombinedStream = __nccwpck_require__(5443); +var util = __nccwpck_require__(3837); +var path = __nccwpck_require__(1017); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var parseUrl = (__nccwpck_require__(7310).parse); +var fs = __nccwpck_require__(7147); +var Stream = (__nccwpck_require__(2781).Stream); +var mime = __nccwpck_require__(3583); +var asynckit = __nccwpck_require__(4812); +var populate = __nccwpck_require__(7142); +// Public API +module.exports = FormData; -const { - Readable, - Duplex, - PassThrough -} = __nccwpck_require__(2781) -const { - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError -} = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { AsyncResource } = __nccwpck_require__(852) -const { addSignal, removeSignal } = __nccwpck_require__(7032) -const assert = __nccwpck_require__(9491) +// make it a Stream +util.inherits(FormData, CombinedStream); -const kResume = Symbol('resume') +/** + * Create readable "multipart/form-data" streams. + * Can be used to submit forms + * and file uploads to other web applications. + * + * @constructor + * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream + */ +function FormData(options) { + if (!(this instanceof FormData)) { + return new FormData(options); + } -class PipelineRequest extends Readable { - constructor () { - super({ autoDestroy: true }) + this._overheadLength = 0; + this._valueLength = 0; + this._valuesToMeasure = []; - this[kResume] = null + CombinedStream.call(this); + + options = options || {}; + for (var option in options) { + this[option] = options[option]; } +} - _read () { - const { [kResume]: resume } = this +FormData.LINE_BREAK = '\r\n'; +FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; - if (resume) { - this[kResume] = null - resume() - } - } +FormData.prototype.append = function(field, value, options) { - _destroy (err, callback) { - this._read() + options = options || {}; - callback(err) + // allow filename as single option + if (typeof options == 'string') { + options = {filename: options}; } -} -class PipelineResponse extends Readable { - constructor (resume) { - super({ autoDestroy: true }) - this[kResume] = resume - } + var append = CombinedStream.prototype.append.bind(this); - _read () { - this[kResume]() + // all that streamy business can't handle numbers + if (typeof value == 'number') { + value = '' + value; } - _destroy (err, callback) { - if (!err && !this._readableState.endEmitted) { - err = new RequestAbortedError() - } - - callback(err) + // https://github.com/felixge/node-form-data/issues/38 + if (util.isArray(value)) { + // Please convert your array into string + // the way web server expects it + this._error(new Error('Arrays are not supported.')); + return; } -} -class PipelineHandler extends AsyncResource { - constructor (opts, handler) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } + var header = this._multiPartHeader(field, value, options); + var footer = this._multiPartFooter(); - if (typeof handler !== 'function') { - throw new InvalidArgumentError('invalid handler') - } + append(header); + append(value); + append(footer); - const { signal, method, opaque, onInfo, responseHeaders } = opts + // pass along options.knownLength + this._trackLength(header, value, options); +}; - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } +FormData.prototype._trackLength = function(header, value, options) { + var valueLength = 0; - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } + // used w/ getLengthSync(), when length is known. + // e.g. for streaming directly from a remote server, + // w/ a known file a size, and not wanting to wait for + // incoming file to finish to get its size. + if (options.knownLength != null) { + valueLength += +options.knownLength; + } else if (Buffer.isBuffer(value)) { + valueLength = value.length; + } else if (typeof value === 'string') { + valueLength = Buffer.byteLength(value); + } - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } + this._valueLength += valueLength; - super('UNDICI_PIPELINE') + // @check why add CRLF? does this account for custom/multiple CRLFs? + this._overheadLength += + Buffer.byteLength(header) + + FormData.LINE_BREAK.length; - this.opaque = opaque || null - this.responseHeaders = responseHeaders || null - this.handler = handler - this.abort = null - this.context = null - this.onInfo = onInfo || null + // empty or either doesn't have path or not an http response or not a stream + if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) && !(value instanceof Stream))) { + return; + } - this.req = new PipelineRequest().on('error', util.nop) + // no need to bother with the length + if (!options.knownLength) { + this._valuesToMeasure.push(value); + } +}; - this.ret = new Duplex({ - readableObjectMode: opts.objectMode, - autoDestroy: true, - read: () => { - const { body } = this +FormData.prototype._lengthRetriever = function(value, callback) { - if (body && body.resume) { - body.resume() - } - }, - write: (chunk, encoding, callback) => { - const { req } = this + if (value.hasOwnProperty('fd')) { - if (req.push(chunk, encoding) || req._readableState.destroyed) { - callback() - } else { - req[kResume] = callback - } - }, - destroy: (err, callback) => { - const { body, req, res, ret, abort } = this + // take read range into a account + // `end` = Infinity –> read file till the end + // + // TODO: Looks like there is bug in Node fs.createReadStream + // it doesn't respect `end` options without `start` options + // Fix it when node fixes it. + // https://github.com/joyent/node/issues/7819 + if (value.end != undefined && value.end != Infinity && value.start != undefined) { - if (!err && !ret._readableState.endEmitted) { - err = new RequestAbortedError() - } + // when end specified + // no need to calculate range + // inclusive, starts with 0 + callback(null, value.end + 1 - (value.start ? value.start : 0)); - if (abort && err) { - abort() - } + // not that fast snoopy + } else { + // still need to fetch file size from fs + fs.stat(value.path, function(err, stat) { - util.destroy(body, err) - util.destroy(req, err) - util.destroy(res, err) + var fileSize; - removeSignal(this) + if (err) { + callback(err); + return; + } - callback(err) - } - }).on('prefinish', () => { - const { req } = this + // update final size based on the range options + fileSize = stat.size - (value.start ? value.start : 0); + callback(null, fileSize); + }); + } - // Node < 15 does not call _final in same tick. - req.push(null) - }) + // or http response + } else if (value.hasOwnProperty('httpVersion')) { + callback(null, +value.headers['content-length']); - this.res = null + // or request stream http://github.com/mikeal/request + } else if (value.hasOwnProperty('httpModule')) { + // wait till response come back + value.on('response', function(response) { + value.pause(); + callback(null, +response.headers['content-length']); + }); + value.resume(); - addSignal(this, signal) + // something else + } else { + callback('Unknown stream'); } +}; - onConnect (abort, context) { - const { ret, res } = this +FormData.prototype._multiPartHeader = function(field, value, options) { + // custom header specified (as string)? + // it becomes responsible for boundary + // (e.g. to handle extra CRLFs on .NET servers) + if (typeof options.header == 'string') { + return options.header; + } - assert(!res, 'pipeline cannot be retried') + var contentDisposition = this._getContentDisposition(value, options); + var contentType = this._getContentType(value, options); - if (ret.destroyed) { - throw new RequestAbortedError() - } + var contents = ''; + var headers = { + // add custom disposition as third element or keep it two elements if not + 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), + // if no content type. allow it to be empty array + 'Content-Type': [].concat(contentType || []) + }; - this.abort = abort - this.context = context + // allow custom headers. + if (typeof options.header == 'object') { + populate(headers, options.header); } - onHeaders (statusCode, rawHeaders, resume) { - const { opaque, handler, context } = this + var header; + for (var prop in headers) { + if (!headers.hasOwnProperty(prop)) continue; + header = headers[prop]; - if (statusCode < 200) { - if (this.onInfo) { - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - this.onInfo({ statusCode, headers }) - } - return + // skip nullish headers. + if (header == null) { + continue; } - this.res = new PipelineResponse(resume) - - let body - try { - this.handler = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - body = this.runInAsyncScope(handler, null, { - statusCode, - headers, - opaque, - body: this.res, - context - }) - } catch (err) { - this.res.on('error', util.nop) - throw err + // convert all headers to arrays. + if (!Array.isArray(header)) { + header = [header]; } - if (!body || typeof body.on !== 'function') { - throw new InvalidReturnValueError('expected Readable') + // add non-empty headers. + if (header.length) { + contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; } + } - body - .on('data', (chunk) => { - const { ret, body } = this + return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; +}; - if (!ret.push(chunk) && body.pause) { - body.pause() - } - }) - .on('error', (err) => { - const { ret } = this +FormData.prototype._getContentDisposition = function(value, options) { - util.destroy(ret, err) - }) - .on('end', () => { - const { ret } = this + var filename + , contentDisposition + ; - ret.push(null) - }) - .on('close', () => { - const { ret } = this + if (typeof options.filepath === 'string') { + // custom filepath for relative paths + filename = path.normalize(options.filepath).replace(/\\/g, '/'); + } else if (options.filename || value.name || value.path) { + // custom filename take precedence + // formidable and the browser add a name property + // fs- and request- streams have path property + filename = path.basename(options.filename || value.name || value.path); + } else if (value.readable && value.hasOwnProperty('httpVersion')) { + // or try http response + filename = path.basename(value.client._httpMessage.path || ''); + } - if (!ret._readableState.ended) { - util.destroy(ret, new RequestAbortedError()) - } - }) + if (filename) { + contentDisposition = 'filename="' + filename + '"'; + } - this.body = body + return contentDisposition; +}; + +FormData.prototype._getContentType = function(value, options) { + + // use custom content-type above all + var contentType = options.contentType; + + // or try `name` from formidable, browser + if (!contentType && value.name) { + contentType = mime.lookup(value.name); } - onData (chunk) { - const { res } = this - return res.push(chunk) + // or try `path` from fs-, request- streams + if (!contentType && value.path) { + contentType = mime.lookup(value.path); } - onComplete (trailers) { - const { res } = this - res.push(null) + // or if it's http-reponse + if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { + contentType = value.headers['content-type']; } - onError (err) { - const { ret } = this - this.handler = null - util.destroy(ret, err) + // or guess it from the filepath or filename + if (!contentType && (options.filepath || options.filename)) { + contentType = mime.lookup(options.filepath || options.filename); } -} -function pipeline (opts, handler) { - try { - const pipelineHandler = new PipelineHandler(opts, handler) - this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler) - return pipelineHandler.ret - } catch (err) { - return new PassThrough().destroy(err) + // fallback to the default content type if `value` is not simple value + if (!contentType && typeof value == 'object') { + contentType = FormData.DEFAULT_CONTENT_TYPE; } -} - -module.exports = pipeline + return contentType; +}; -/***/ }), +FormData.prototype._multiPartFooter = function() { + return function(next) { + var footer = FormData.LINE_BREAK; -/***/ 5448: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + var lastPart = (this._streams.length === 0); + if (lastPart) { + footer += this._lastBoundary(); + } -"use strict"; + next(footer); + }.bind(this); +}; +FormData.prototype._lastBoundary = function() { + return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; +}; -const Readable = __nccwpck_require__(3858) -const { - InvalidArgumentError, - RequestAbortedError -} = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) -const { AsyncResource } = __nccwpck_require__(852) -const { addSignal, removeSignal } = __nccwpck_require__(7032) +FormData.prototype.getHeaders = function(userHeaders) { + var header; + var formHeaders = { + 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() + }; -class RequestHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') + for (header in userHeaders) { + if (userHeaders.hasOwnProperty(header)) { + formHeaders[header.toLowerCase()] = userHeaders[header]; } + } - const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts + return formHeaders; +}; - try { - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } +FormData.prototype.setBoundary = function(boundary) { + this._boundary = boundary; +}; - if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) { - throw new InvalidArgumentError('invalid highWaterMark') - } +FormData.prototype.getBoundary = function() { + if (!this._boundary) { + this._generateBoundary(); + } - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + return this._boundary; +}; - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } +FormData.prototype.getBuffer = function() { + var dataBuffer = new Buffer.alloc( 0 ); + var boundary = this.getBoundary(); - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } + // Create the form content. Add Line breaks to the end of data. + for (var i = 0, len = this._streams.length; i < len; i++) { + if (typeof this._streams[i] !== 'function') { - super('UNDICI_REQUEST') - } catch (err) { - if (util.isStream(body)) { - util.destroy(body.on('error', util.nop), err) + // Add content to the buffer. + if(Buffer.isBuffer(this._streams[i])) { + dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); + }else { + dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); } - throw err - } - - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.callback = callback - this.res = null - this.abort = null - this.body = body - this.trailers = {} - this.context = null - this.onInfo = onInfo || null - this.throwOnError = throwOnError - this.highWaterMark = highWaterMark - if (util.isStream(body)) { - body.on('error', (err) => { - this.onError(err) - }) + // Add break after content. + if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { + dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); + } } - - addSignal(this, signal) } - onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() - } + // Add the footer and return the Buffer object. + return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); +}; - this.abort = abort - this.context = context +FormData.prototype._generateBoundary = function() { + // This generates a 50 character boundary similar to those used by Firefox. + // They are optimized for boyer-moore parsing. + var boundary = '--------------------------'; + for (var i = 0; i < 24; i++) { + boundary += Math.floor(Math.random() * 10).toString(16); } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this - - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - - if (statusCode < 200) { - if (this.onInfo) { - this.onInfo({ statusCode, headers }) - } - return - } + this._boundary = boundary; +}; - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers - const contentType = parsedHeaders['content-type'] - const body = new Readable({ resume, abort, contentType, highWaterMark }) +// Note: getLengthSync DOESN'T calculate streams length +// As workaround one can calculate file size manually +// and add it as knownLength option +FormData.prototype.getLengthSync = function() { + var knownLength = this._overheadLength + this._valueLength; - this.callback = null - this.res = body - if (callback !== null) { - if (this.throwOnError && statusCode >= 400) { - this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body, contentType, statusCode, statusMessage, headers } - ) - } else { - this.runInAsyncScope(callback, null, null, { - statusCode, - headers, - trailers: this.trailers, - opaque, - body, - context - }) - } - } + // Don't get confused, there are 3 "internal" streams for each keyval pair + // so it basically checks if there is any value added to the form + if (this._streams.length) { + knownLength += this._lastBoundary().length; } - onData (chunk) { - const { res } = this - return res.push(chunk) + // https://github.com/form-data/form-data/issues/40 + if (!this.hasKnownLength()) { + // Some async length retrievers are present + // therefore synchronous length calculation is false. + // Please use getLength(callback) to get proper length + this._error(new Error('Cannot calculate proper length in synchronous way.')); } - onComplete (trailers) { - const { res } = this - - removeSignal(this) + return knownLength; +}; - util.parseHeaders(trailers, this.trailers) +// Public API to check if length of added values is known +// https://github.com/form-data/form-data/issues/196 +// https://github.com/form-data/form-data/issues/262 +FormData.prototype.hasKnownLength = function() { + var hasKnownLength = true; - res.push(null) + if (this._valuesToMeasure.length) { + hasKnownLength = false; } - onError (err) { - const { res, callback, body, opaque } = this - - removeSignal(this) - - if (callback) { - // TODO: Does this need queueMicrotask? - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } + return hasKnownLength; +}; - if (res) { - this.res = null - // Ensure all queued handlers are invoked before destroying res. - queueMicrotask(() => { - util.destroy(res, err) - }) - } +FormData.prototype.getLength = function(cb) { + var knownLength = this._overheadLength + this._valueLength; - if (body) { - this.body = null - util.destroy(body, err) - } + if (this._streams.length) { + knownLength += this._lastBoundary().length; } -} -function request (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - request.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) + if (!this._valuesToMeasure.length) { + process.nextTick(cb.bind(this, null, knownLength)); + return; } - try { - this.dispatch(opts, new RequestHandler(opts, callback)) - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts && opts.opaque - queueMicrotask(() => callback(err, { opaque })) - } -} - -module.exports = request -module.exports.RequestHandler = RequestHandler + asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { + if (err) { + cb(err); + return; + } + values.forEach(function(length) { + knownLength += length; + }); -/***/ }), + cb(null, knownLength); + }); +}; -/***/ 5395: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +FormData.prototype.submit = function(params, cb) { + var request + , options + , defaults = {method: 'post'} + ; -"use strict"; + // parse provided url if it's string + // or treat it as options object + if (typeof params == 'string') { + params = parseUrl(params); + options = populate({ + port: params.port, + path: params.pathname, + host: params.hostname, + protocol: params.protocol + }, defaults); -const { finished, PassThrough } = __nccwpck_require__(2781) -const { - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError -} = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) -const { AsyncResource } = __nccwpck_require__(852) -const { addSignal, removeSignal } = __nccwpck_require__(7032) + // use custom params + } else { -class StreamHandler extends AsyncResource { - constructor (opts, factory, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') + options = populate(params, defaults); + // if no port provided use default one + if (!options.port) { + options.port = options.protocol == 'https:' ? 443 : 80; } + } - const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts + // put that good code in getHeaders to some use + options.headers = this.getHeaders(params.headers); - try { - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + // https if specified, fallback to http in any other case + if (options.protocol == 'https:') { + request = https.request(options); + } else { + request = http.request(options); + } - if (typeof factory !== 'function') { - throw new InvalidArgumentError('invalid factory') - } + // get content length and fire away + this.getLength(function(err, length) { + if (err && err !== 'Unknown stream') { + this._error(err); + return; + } - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + // add content length + if (length) { + request.setHeader('Content-Length', length); + } - if (method === 'CONNECT') { - throw new InvalidArgumentError('invalid method') - } + this.pipe(request); + if (cb) { + var onResponse; - if (onInfo && typeof onInfo !== 'function') { - throw new InvalidArgumentError('invalid onInfo callback') - } + var callback = function (error, responce) { + request.removeListener('error', callback); + request.removeListener('response', onResponse); - super('UNDICI_STREAM') - } catch (err) { - if (util.isStream(body)) { - util.destroy(body.on('error', util.nop), err) - } - throw err - } + return cb.call(this, error, responce); + }; - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.factory = factory - this.callback = callback - this.res = null - this.abort = null - this.context = null - this.trailers = null - this.body = body - this.onInfo = onInfo || null - this.throwOnError = throwOnError || false + onResponse = callback.bind(this, null); - if (util.isStream(body)) { - body.on('error', (err) => { - this.onError(err) - }) + request.on('error', callback); + request.on('response', onResponse); } + }.bind(this)); - addSignal(this, signal) - } - - onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() - } + return request; +}; - this.abort = abort - this.context = context +FormData.prototype._error = function(err) { + if (!this.error) { + this.error = err; + this.pause(); + this.emit('error', err); } +}; - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const { factory, opaque, context, callback, responseHeaders } = this - - const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) +FormData.prototype.toString = function () { + return '[object FormData]'; +}; - if (statusCode < 200) { - if (this.onInfo) { - this.onInfo({ statusCode, headers }) - } - return - } - this.factory = null +/***/ }), - let res +/***/ 7142: +/***/ ((module) => { - if (this.throwOnError && statusCode >= 400) { - const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers - const contentType = parsedHeaders['content-type'] - res = new PassThrough() +// populates missing values +module.exports = function(dst, src) { - this.callback = null - this.runInAsyncScope(getResolveErrorBodyCallback, null, - { callback, body: res, contentType, statusCode, statusMessage, headers } - ) - } else { - if (factory === null) { - return - } + Object.keys(src).forEach(function(prop) + { + dst[prop] = dst[prop] || src[prop]; + }); - res = this.runInAsyncScope(factory, null, { - statusCode, - headers, - opaque, - context - }) + return dst; +}; - if ( - !res || - typeof res.write !== 'function' || - typeof res.end !== 'function' || - typeof res.on !== 'function' - ) { - throw new InvalidReturnValueError('expected Writable') - } - // TODO: Avoid finished. It registers an unnecessary amount of listeners. - finished(res, { readable: false }, (err) => { - const { callback, res, opaque, trailers, abort } = this +/***/ }), - this.res = null - if (err || !res.readable) { - util.destroy(res, err) - } +/***/ 4274: +/***/ (function(module, __unused_webpack_exports, __nccwpck_require__) { - this.callback = null - this.runInAsyncScope(callback, null, err || null, { opaque, trailers }) +/*! For license information please see mailgun.node.js.LICENSE.txt */ +!function(e,t){ true?module.exports=t():0}(this,(()=>(()=>{var e={9118:(e,t,n)=>{e.exports={parallel:n(9162),serial:n(1357),serialOrdered:n(9087)}},7651:e=>{function t(e){"function"==typeof this.jobs[e]&&this.jobs[e]()}e.exports=function(e){Object.keys(e.jobs).forEach(t.bind(e)),e.jobs={}}},5912:(e,t,n)=>{var a=n(9265);e.exports=function(e){var t=!1;return a((function(){t=!0})),function(n,i){t?e(n,i):a((function(){e(n,i)}))}}},9265:e=>{e.exports=function(e){var t="function"==typeof setImmediate?setImmediate:"object"==typeof process&&"function"==typeof process.nextTick?process.nextTick:null;t?t(e):setTimeout(e,0)}},7594:(e,t,n)=>{var a=n(5912),i=n(7651);e.exports=function(e,t,n,o){var s=n.keyedList?n.keyedList[n.index]:n.index;n.jobs[s]=function(e,t,n,i){var o;o=2==e.length?e(n,a(i)):e(n,t,a(i));return o}(t,s,e[s],(function(e,t){s in n.jobs&&(delete n.jobs[s],e?i(n):n.results[s]=t,o(e,n.results))}))}},4528:e=>{e.exports=function(e,t){var n=!Array.isArray(e),a={index:0,keyedList:n||t?Object.keys(e):null,jobs:{},results:n?{}:[],size:n?Object.keys(e).length:e.length};t&&a.keyedList.sort(n?t:function(n,a){return t(e[n],e[a])});return a}},5353:(e,t,n)=>{var a=n(7651),i=n(5912);e.exports=function(e){if(!Object.keys(this.jobs).length)return;this.index=this.size,a(this),i(e)(null,this.results)}},9162:(e,t,n)=>{var a=n(7594),i=n(4528),o=n(5353);e.exports=function(e,t,n){var s=i(e);for(;s.index<(s.keyedList||e).length;)a(e,t,s,(function(e,t){e?n(e,t):0!==Object.keys(s.jobs).length||n(null,s.results)})),s.index++;return o.bind(s,n)}},1357:(e,t,n)=>{var a=n(9087);e.exports=function(e,t,n){return a(e,t,null,n)}},9087:(e,t,n)=>{var a=n(7594),i=n(4528),o=n(5353);function s(e,t){return et?1:0}e.exports=function(e,t,n,s){var r=i(e,n);return a(e,t,r,(function n(i,o){i?s(i,o):(r.index++,r.index<(r.keyedList||e).length?a(e,t,r,n):s(null,r.results))})),o.bind(r,s)},e.exports.ascending=s,e.exports.descending=function(e,t){return-1*s(e,t)}},4106:(e,t,n)=>{var a=n(9779),i=n(3837),o=n(1017),s=n(3685),r=n(5687),c=n(7310).parse,p=n(7147),u=n(2781).Stream,l=n(983),d=n(9118),m=n(5469);function f(e){if(!(this instanceof f))return new f(e);for(var t in this._overheadLength=0,this._valueLength=0,this._valuesToMeasure=[],a.call(this),e=e||{})this[t]=e[t]}e.exports=f,i.inherits(f,a),f.LINE_BREAK="\r\n",f.DEFAULT_CONTENT_TYPE="application/octet-stream",f.prototype.append=function(e,t,n){"string"==typeof(n=n||{})&&(n={filename:n});var o=a.prototype.append.bind(this);if("number"==typeof t&&(t=""+t),i.isArray(t))this._error(new Error("Arrays are not supported."));else{var s=this._multiPartHeader(e,t,n),r=this._multiPartFooter();o(s),o(t),o(r),this._trackLength(s,t,n)}},f.prototype._trackLength=function(e,t,n){var a=0;null!=n.knownLength?a+=+n.knownLength:Buffer.isBuffer(t)?a=t.length:"string"==typeof t&&(a=Buffer.byteLength(t)),this._valueLength+=a,this._overheadLength+=Buffer.byteLength(e)+f.LINE_BREAK.length,t&&(t.path||t.readable&&t.hasOwnProperty("httpVersion")||t instanceof u)&&(n.knownLength||this._valuesToMeasure.push(t))},f.prototype._lengthRetriever=function(e,t){e.hasOwnProperty("fd")?null!=e.end&&e.end!=1/0&&null!=e.start?t(null,e.end+1-(e.start?e.start:0)):p.stat(e.path,(function(n,a){var i;n?t(n):(i=a.size-(e.start?e.start:0),t(null,i))})):e.hasOwnProperty("httpVersion")?t(null,+e.headers["content-length"]):e.hasOwnProperty("httpModule")?(e.on("response",(function(n){e.pause(),t(null,+n.headers["content-length"])})),e.resume()):t("Unknown stream")},f.prototype._multiPartHeader=function(e,t,n){if("string"==typeof n.header)return n.header;var a,i=this._getContentDisposition(t,n),o=this._getContentType(t,n),s="",r={"Content-Disposition":["form-data",'name="'+e+'"'].concat(i||[]),"Content-Type":[].concat(o||[])};for(var c in"object"==typeof n.header&&m(r,n.header),r)r.hasOwnProperty(c)&&null!=(a=r[c])&&(Array.isArray(a)||(a=[a]),a.length&&(s+=c+": "+a.join("; ")+f.LINE_BREAK));return"--"+this.getBoundary()+f.LINE_BREAK+s+f.LINE_BREAK},f.prototype._getContentDisposition=function(e,t){var n,a;return"string"==typeof t.filepath?n=o.normalize(t.filepath).replace(/\\/g,"/"):t.filename||e.name||e.path?n=o.basename(t.filename||e.name||e.path):e.readable&&e.hasOwnProperty("httpVersion")&&(n=o.basename(e.client._httpMessage.path||"")),n&&(a='filename="'+n+'"'),a},f.prototype._getContentType=function(e,t){var n=t.contentType;return!n&&e.name&&(n=l.lookup(e.name)),!n&&e.path&&(n=l.lookup(e.path)),!n&&e.readable&&e.hasOwnProperty("httpVersion")&&(n=e.headers["content-type"]),n||!t.filepath&&!t.filename||(n=l.lookup(t.filepath||t.filename)),n||"object"!=typeof e||(n=f.DEFAULT_CONTENT_TYPE),n},f.prototype._multiPartFooter=function(){return function(e){var t=f.LINE_BREAK;0===this._streams.length&&(t+=this._lastBoundary()),e(t)}.bind(this)},f.prototype._lastBoundary=function(){return"--"+this.getBoundary()+"--"+f.LINE_BREAK},f.prototype.getHeaders=function(e){var t,n={"content-type":"multipart/form-data; boundary="+this.getBoundary()};for(t in e)e.hasOwnProperty(t)&&(n[t.toLowerCase()]=e[t]);return n},f.prototype.setBoundary=function(e){this._boundary=e},f.prototype.getBoundary=function(){return this._boundary||this._generateBoundary(),this._boundary},f.prototype.getBuffer=function(){for(var e=new Buffer.alloc(0),t=this.getBoundary(),n=0,a=this._streams.length;n{e.exports=function(e,t){return Object.keys(t).forEach((function(n){e[n]=e[n]||t[n]})),e}},5205:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e,t,n){this.name=e.name,this.require_tls=e.require_tls,this.skip_verification=e.skip_verification,this.state=e.state,this.wildcard=e.wildcard,this.spam_action=e.spam_action,this.created_at=e.created_at,this.smtp_password=e.smtp_password,this.smtp_login=e.smtp_login,this.type=e.type,this.receiving_dns_records=t||null,this.sending_dns_records=n||null;var a=["id","is_disabled","web_prefix","web_scheme"].reduce((function(t,n){return n in e&&(t[n]=e[n]),t}),{});Object.assign(this,a)};t.default=n},8127:function(e,t,n){"use strict";var a=this&&this.__assign||function(){return a=Object.assign||function(e){for(var t,n=1,a=arguments.length;n0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e){this.request=e}return e.prototype.list=function(e){return this.request.get("/v3/routes",e).then((function(e){return e.body.items}))},e.prototype.get=function(e){return this.request.get("/v3/routes/".concat(e)).then((function(e){return e.body.route}))},e.prototype.create=function(e){return this.request.postWithFD("/v3/routes",e).then((function(e){return e.body.route}))},e.prototype.update=function(e,t){return this.request.putWithFD("/v3/routes/".concat(e),t).then((function(e){return e.body}))},e.prototype.destroy=function(e){return this.request.delete("/v3/routes/".concat(e)).then((function(e){return e.body}))},e}();t.default=n},8165:function(e,t,n){"use strict";var a=this&&this.__spreadArray||function(e,t,n){if(n||2===arguments.length)for(var a,i=0,o=t.length;i{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e){this.request=e}return e.prototype.list=function(e){return this.request.get("/v5/accounts/subaccounts",e).then((function(e){return e.body}))},e.prototype.get=function(e){return this.request.get("/v5/accounts/subaccounts/".concat(e)).then((function(e){return e.body}))},e.prototype.create=function(e){return this.request.postWithFD("/v5/accounts/subaccounts",{name:e}).then((function(e){return e.body}))},e.prototype.enable=function(e){return this.request.post("/v5/accounts/subaccounts/".concat(e,"/enable")).then((function(e){return e.body}))},e.prototype.disable=function(e){return this.request.post("/v5/accounts/subaccounts/".concat(e,"/disable")).then((function(e){return e.body}))},e.SUBACCOUNT_HEADER="X-Mailgun-On-Behalf-Of",e}();t.default=n},7002:function(e,t,n){"use strict";var a,i=this&&this.__extends||(a=function(e,t){return a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},a(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var s=n(8089),r=function(e){function t(t){var n=e.call(this,s.SuppressionModels.BOUNCES)||this;return n.address=t.address,n.code=+t.code,n.error=t.error,n.created_at=new Date(t.created_at),n}return i(t,e),t}(o(n(9013)).default);t.default=r},9601:function(e,t,n){"use strict";var a,i=this&&this.__extends||(a=function(e,t){return a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},a(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var s=n(8089),r=function(e){function t(t){var n=e.call(this,s.SuppressionModels.COMPLAINTS)||this;return n.address=t.address,n.created_at=new Date(t.created_at),n}return i(t,e),t}(o(n(9013)).default);t.default=r},9013:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){this.type=e};t.default=n},1481:function(e,t,n){"use strict";var a,i=this&&this.__extends||(a=function(e,t){return a=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},a(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}a(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),o=this&&this.__awaiter||function(e,t,n,a){return new(n||(n=Promise))((function(i,o){function s(e){try{c(a.next(e))}catch(e){o(e)}}function r(e){try{c(a.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,r)}c((a=a.apply(e,t||[])).next())}))},s=this&&this.__generator||function(e,t){var n,a,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:r(0),throw:r(1),return:r(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function r(r){return function(c){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,r[0]&&(s=0)),s;)try{if(n=1,a&&(i=2&r[0]?a.return:r[0]?a.throw||((i=a.return)&&i.call(a),0):a.next)&&!(i=i.call(a,r[1])).done)return i;switch(a=0,i&&(r=[2&r[0],i.value]),r[0]){case 0:case 1:i=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,a=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&i[i.length-1])||6!==r[0]&&2!==r[0])){s=0;continue}if(3===r[0]&&(!i||r[1]>i[0]&&r[1]0&&(u.params=new URLSearchParams(r.query),delete u.query),(null==r?void 0:r.body)&&(f=null==r?void 0:r.body,u.data=f,delete u.body),v=(0,l.default)(this.url,t),c.label=1;case 1:return c.trys.push([1,3,,4]),[4,d.default.request(a(a({method:e.toLocaleUpperCase(),timeout:this.timeout,url:v,headers:p},u),{maxBodyLength:this.maxBodyLength,proxy:this.proxy}))];case 2:return h=c.sent(),[3,4];case 3:throw x=c.sent(),b=x,new m.default({status:(null===(i=null==b?void 0:b.response)||void 0===i?void 0:i.status)||400,statusText:(null===(o=null==b?void 0:b.response)||void 0===o?void 0:o.statusText)||b.code,body:(null===(s=null==b?void 0:b.response)||void 0===s?void 0:s.data)||b.message});case 4:return[4,this.getResponseBody(h)];case 5:return[2,c.sent()]}}))}))},e.prototype.getResponseBody=function(e){return r(this,void 0,void 0,(function(){var t;return c(this,(function(n){if(t={body:{},status:null==e?void 0:e.status},"string"==typeof e.data){if("Mailgun Magnificent API"===e.data)throw new m.default({status:400,statusText:"Incorrect url",body:e.data});t.body={message:e.data}}else t.body=e.data;return[2,t]}))}))},e.prototype.joinAndTransformHeaders=function(e){var t=new d.AxiosHeaders,n=u.encode("".concat(this.username,":").concat(this.key));t.setAuthorization("Basic ".concat(n)),t.set(this.headers);var a=e&&e.headers,i=this.makeHeadersFromObject(a);return t.set(i),t},e.prototype.makeHeadersFromObject=function(e){void 0===e&&(e={});var t=new d.AxiosHeaders;return t=Object.entries(e).reduce((function(e,t){var n=t[0],a=t[1];return e.set(n,a),e}),t)},e.prototype.setSubaccountHeader=function(e){var t,n=this.makeHeadersFromObject(a(a({},this.headers),((t={})[h.default.SUBACCOUNT_HEADER]=e,t)));this.headers.set(n)},e.prototype.resetSubaccountHeader=function(){this.headers.delete(h.default.SUBACCOUNT_HEADER)},e.prototype.query=function(e,t,n,i){return this.request(e,t,a({query:n},i))},e.prototype.command=function(e,t,n,i,o){void 0===o&&(o=!0);var s={};o&&(s={"Content-Type":"application/x-www-form-urlencoded"});var r=a(a(a({},s),{body:n}),i);return this.request(e,t,r)},e.prototype.get=function(e,t,n){return this.query("get",e,t,n)},e.prototype.post=function(e,t,n){return this.command("post",e,t,n)},e.prototype.postWithFD=function(e,t){var n=this.formDataBuilder.createFormData(t);return this.command("post",e,n,{headers:{"Content-Type":"multipart/form-data"}},!1)},e.prototype.putWithFD=function(e,t){var n=this.formDataBuilder.createFormData(t);return this.command("put",e,n,{headers:{"Content-Type":"multipart/form-data"}},!1)},e.prototype.patchWithFD=function(e,t){var n=this.formDataBuilder.createFormData(t);return this.command("patch",e,n,{headers:{"Content-Type":"multipart/form-data"}},!1)},e.prototype.put=function(e,t,n){return this.command("put",e,t,n)},e.prototype.delete=function(e,t){return this.command("delete",e,t)},e}();t.default=v},8089:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.YesNo=t.WebhooksIds=t.SuppressionModels=t.Resolution=void 0,function(e){e.HOUR="hour",e.DAY="day",e.MONTH="month"}(t.Resolution||(t.Resolution={})),function(e){e.BOUNCES="bounces",e.COMPLAINTS="complaints",e.UNSUBSCRIBES="unsubscribes",e.WHITELISTS="whitelists"}(t.SuppressionModels||(t.SuppressionModels={})),function(e){e.CLICKED="clicked",e.COMPLAINED="complained",e.DELIVERED="delivered",e.OPENED="opened",e.PERMANENT_FAIL="permanent_fail",e.TEMPORARY_FAIL="temporary_fail",e.UNSUBSCRIBED="unsubscribe"}(t.WebhooksIds||(t.WebhooksIds={})),function(e){e.YES="yes",e.NO="no"}(t.YesNo||(t.YesNo={}))},7471:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},466:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7471),t)},7647:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7546:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1358:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2236:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9483:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7647),t),i(n(7546),t),i(n(1358),t),i(n(2236),t)},4251:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},896:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(4251),t)},9798:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},188:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(9798),t)},7677:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2685:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7677),t)},7913:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1094:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7913),t)},3446:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1225:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2570:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(3446),t),i(n(1225),t)},7104:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4005:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7104),t)},6115:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},848:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(6115),t)},4012:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1574:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9923:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(4012),t),i(n(1574),t)},3748:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2220:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(3748),t)},5129:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},157:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2818:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},504:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},3740:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2043:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(5129),t),i(n(157),t),i(n(504),t),i(n(3740),t),i(n(2818),t)},6233:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4826:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7272:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(6233),t),i(n(4826),t)},1034:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2955:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(1034),t)},799:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(466),t),i(n(9483),t),i(n(1094),t),i(n(2570),t),i(n(9923),t),i(n(2043),t),i(n(7272),t),i(n(896),t),i(n(2955),t),i(n(4005),t),i(n(848),t),i(n(2685),t),i(n(188),t),i(n(2220),t)},4859:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7843:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2755:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4994:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},643:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4886:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7843),t),i(n(4859),t),i(n(2755),t),i(n(4994),t),i(n(643),t)},8011:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},1409:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},3627:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},970:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2179:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9543:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(8011),t),i(n(2179),t),i(n(1409),t),i(n(3627),t),i(n(970),t)},8483:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4385:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(8483),t)},3097:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},720:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(3097),t)},2409:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5986:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(2409),t)},7666:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4553:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(7666),t)},5560:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5810:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9977:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(5560),t),i(n(5810),t)},9348:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7313:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(9348),t)},9006:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5006:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(9006),t)},2144:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4744:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(2144),t)},9040:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9700:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(9040),t)},8275:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5451:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7935:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4205:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},4312:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2267:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(8275),t),i(n(5451),t),i(n(7935),t),i(n(4205),t),i(n(4312),t)},4090:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},202:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7587:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(4090),t),i(n(202),t)},771:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},8042:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(771),t)},8615:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(4886),t),i(n(9543),t),i(n(4385),t),i(n(720),t),i(n(5986),t),i(n(4553),t),i(n(9977),t),i(n(7313),t),i(n(5006),t),i(n(4744),t),i(n(9700),t),i(n(2267),t),i(n(7587),t),i(n(8042),t)},7530:function(e,t,n){"use strict";var a=this&&this.__createBinding||(Object.create?function(e,t,n,a){void 0===a&&(a=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,a,i)}:function(e,t,n,a){void 0===a&&(a=n),e[a]=t[n]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&a(t,e,n);return i(t,e),t},s=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||a(t,e,n)},r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.Interfaces=t.Enums=void 0;var c=r(n(5558));t.Enums=o(n(8089)),s(n(8615),t),t.Interfaces=o(n(799));var p=function(){function e(e){this.formData=e}return Object.defineProperty(e,"default",{get:function(){return this},enumerable:!1,configurable:!0}),e.prototype.client=function(e){return new c.default(e,this.formData)},e}();t.default=p},7501:function(e,t,n){var a;e=n.nmd(e),function(i){var o=t,s=(e&&e.exports,"object"==typeof global&&global);s.global!==s&&s.window;var r=function(e){this.message=e};(r.prototype=new Error).name="InvalidCharacterError";var c=function(e){throw new r(e)},p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=/[\t\n\f\r ]/g,l={encode:function(e){e=String(e),/[^\0-\xFF]/.test(e)&&c("The string to be encoded contains characters outside of the Latin1 range.");for(var t,n,a,i,o=e.length%3,s="",r=-1,u=e.length-o;++r>18&63)+p.charAt(i>>12&63)+p.charAt(i>>6&63)+p.charAt(63&i);return 2==o?(t=e.charCodeAt(r)<<8,n=e.charCodeAt(++r),s+=p.charAt((i=t+n)>>10)+p.charAt(i>>4&63)+p.charAt(i<<2&63)+"="):1==o&&(i=e.charCodeAt(r),s+=p.charAt(i>>2)+p.charAt(i<<4&63)+"=="),s},decode:function(e){var t=(e=String(e).replace(u,"")).length;t%4==0&&(t=(e=e.replace(/==?$/,"")).length),(t%4==1||/[^+a-zA-Z0-9/]/.test(e))&&c("Invalid character: the string to be decoded is not correctly encoded.");for(var n,a,i=0,o="",s=-1;++s>(-2*i&6)));return o},version:"1.0.0"};void 0===(a=function(){return l}.call(t,n,t,e))||(e.exports=a)}()},9779:(e,t,n)=>{var a=n(3837),i=n(2781).Stream,o=n(3463);function s(){this.writable=!1,this.readable=!0,this.dataSize=0,this.maxDataSize=2097152,this.pauseStreams=!0,this._released=!1,this._streams=[],this._currentStream=null,this._insideLoop=!1,this._pendingNext=!1}e.exports=s,a.inherits(s,i),s.create=function(e){var t=new this;for(var n in e=e||{})t[n]=e[n];return t},s.isStreamLike=function(e){return"function"!=typeof e&&"string"!=typeof e&&"boolean"!=typeof e&&"number"!=typeof e&&!Buffer.isBuffer(e)},s.prototype.append=function(e){if(s.isStreamLike(e)){if(!(e instanceof o)){var t=o.create(e,{maxDataSize:1/0,pauseStream:this.pauseStreams});e.on("data",this._checkDataSize.bind(this)),e=t}this._handleErrors(e),this.pauseStreams&&e.pause()}return this._streams.push(e),this},s.prototype.pipe=function(e,t){return i.prototype.pipe.call(this,e,t),this.resume(),e},s.prototype._getNext=function(){if(this._currentStream=null,this._insideLoop)this._pendingNext=!0;else{this._insideLoop=!0;try{do{this._pendingNext=!1,this._realGetNext()}while(this._pendingNext)}finally{this._insideLoop=!1}}},s.prototype._realGetNext=function(){var e=this._streams.shift();void 0!==e?"function"==typeof e?e(function(e){s.isStreamLike(e)&&(e.on("data",this._checkDataSize.bind(this)),this._handleErrors(e)),this._pipeNext(e)}.bind(this)):this._pipeNext(e):this.end()},s.prototype._pipeNext=function(e){if(this._currentStream=e,s.isStreamLike(e))return e.on("end",this._getNext.bind(this)),void e.pipe(this,{end:!1});var t=e;this.write(t),this._getNext()},s.prototype._handleErrors=function(e){var t=this;e.on("error",(function(e){t._emitError(e)}))},s.prototype.write=function(e){this.emit("data",e)},s.prototype.pause=function(){this.pauseStreams&&(this.pauseStreams&&this._currentStream&&"function"==typeof this._currentStream.pause&&this._currentStream.pause(),this.emit("pause"))},s.prototype.resume=function(){this._released||(this._released=!0,this.writable=!0,this._getNext()),this.pauseStreams&&this._currentStream&&"function"==typeof this._currentStream.resume&&this._currentStream.resume(),this.emit("resume")},s.prototype.end=function(){this._reset(),this.emit("end")},s.prototype.destroy=function(){this._reset(),this.emit("close")},s.prototype._reset=function(){this.writable=!1,this._streams=[],this._currentStream=null},s.prototype._checkDataSize=function(){if(this._updateDataSize(),!(this.dataSize<=this.maxDataSize)){var e="DelayedStream#maxDataSize of "+this.maxDataSize+" bytes exceeded.";this._emitError(new Error(e))}},s.prototype._updateDataSize=function(){this.dataSize=0;var e=this;this._streams.forEach((function(t){t.dataSize&&(e.dataSize+=t.dataSize)})),this._currentStream&&this._currentStream.dataSize&&(this.dataSize+=this._currentStream.dataSize)},s.prototype._emitError=function(e){this._reset(),this.emit("error",e)}},1227:(e,t,n)=>{t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let a=0,i=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(a++,"%c"===e&&(i=a))})),t.splice(i,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG);return e},t.useColors=function(){if("undefined"!=typeof window&&window.process&&("renderer"===window.process.type||window.process.__nwjs))return!0;if("undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))return!1;return"undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=n(2447)(t);const{formatters:a}=e.exports;a.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}},2447:(e,t,n)=>{e.exports=function(e){function t(e){let n,i,o,s=null;function r(...e){if(!r.enabled)return;const a=r,i=Number(new Date),o=i-(n||i);a.diff=o,a.prev=n,a.curr=i,n=i,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let s=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((n,i)=>{if("%%"===n)return"%";s++;const o=t.formatters[i];if("function"==typeof o){const t=e[s];n=o.call(a,t),e.splice(s,1),s--}return n})),t.formatArgs.call(a,e);(a.log||t.log).apply(a,e)}return r.namespace=e,r.useColors=t.useColors(),r.color=t.selectColor(e),r.extend=a,r.destroy=t.destroy,Object.defineProperty(r,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==s?s:(i!==t.namespaces&&(i=t.namespaces,o=t.enabled(e)),o),set:e=>{s=e}}),"function"==typeof t.init&&t.init(r),r}function a(e,n){const a=t(this.namespace+(void 0===n?":":n)+e);return a.log=this.log,a}function i(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(i),...t.skips.map(i).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const a=("string"==typeof e?e:"").split(/[\s,]+/),i=a.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?e.exports=n(1227):e.exports=n(39)},39:(e,t,n)=>{const a=n(6224),i=n(3837);t.init=function(e){e.inspectOpts={};const n=Object.keys(t.inspectOpts);for(let a=0;a{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=n(2130);e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let a=process.env[t];return a=!!/^(yes|on|true|enabled)$/i.test(a)||!/^(no|off|false|disabled)$/i.test(a)&&("null"===a?null:Number(a)),e[n]=a,e}),{}),e.exports=n(2447)(t);const{formatters:o}=e.exports;o.o=function(e){return this.inspectOpts.colors=this.useColors,i.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},o.O=function(e){return this.inspectOpts.colors=this.useColors,i.inspect(e,this.inspectOpts)}},3463:(e,t,n)=>{var a=n(2781).Stream,i=n(3837);function o(){this.source=null,this.dataSize=0,this.maxDataSize=1048576,this.pauseStream=!0,this._maxDataSizeExceeded=!1,this._released=!1,this._bufferedEvents=[]}e.exports=o,i.inherits(o,a),o.create=function(e,t){var n=new this;for(var a in t=t||{})n[a]=t[a];n.source=e;var i=e.emit;return e.emit=function(){return n._handleEmit(arguments),i.apply(e,arguments)},e.on("error",(function(){})),n.pauseStream&&e.pause(),n},Object.defineProperty(o.prototype,"readable",{configurable:!0,enumerable:!0,get:function(){return this.source.readable}}),o.prototype.setEncoding=function(){return this.source.setEncoding.apply(this.source,arguments)},o.prototype.resume=function(){this._released||this.release(),this.source.resume()},o.prototype.pause=function(){this.source.pause()},o.prototype.release=function(){this._released=!0,this._bufferedEvents.forEach(function(e){this.emit.apply(this,e)}.bind(this)),this._bufferedEvents=[]},o.prototype.pipe=function(){var e=a.prototype.pipe.apply(this,arguments);return this.resume(),e},o.prototype._handleEmit=function(e){this._released?this.emit.apply(this,e):("data"===e[0]&&(this.dataSize+=e[1].length,this._checkIfMaxDataSizeExceeded()),this._bufferedEvents.push(e))},o.prototype._checkIfMaxDataSizeExceeded=function(){if(!(this._maxDataSizeExceeded||this.dataSize<=this.maxDataSize)){this._maxDataSizeExceeded=!0;var e="DelayedStream#maxDataSize of "+this.maxDataSize+" bytes exceeded.";this.emit("error",new Error(e))}}},2261:(e,t,n)=>{var a;e.exports=function(){if(!a){try{a=n(5158)("follow-redirects")}catch(e){}"function"!=typeof a&&(a=function(){})}a.apply(null,arguments)}},938:(e,t,n)=>{var a=n(7310),i=a.URL,o=n(3685),s=n(5687),r=n(2781).Writable,c=n(9491),p=n(2261),u=!1;try{c(new i)}catch(e){u="ERR_INVALID_URL"===e.code}var l=["auth","host","hostname","href","path","pathname","port","protocol","query","search","hash"],d=["abort","aborted","connect","error","socket","timeout"],m=Object.create(null);d.forEach((function(e){m[e]=function(t,n,a){this._redirectable.emit(e,t,n,a)}}));var f=R("ERR_INVALID_URL","Invalid URL",TypeError),h=R("ERR_FR_REDIRECTION_FAILURE","Redirected request failed"),v=R("ERR_FR_TOO_MANY_REDIRECTS","Maximum number of redirects exceeded",h),x=R("ERR_FR_MAX_BODY_LENGTH_EXCEEDED","Request body larger than maxBodyLength limit"),b=R("ERR_STREAM_WRITE_AFTER_END","write after end"),g=r.prototype.destroy||w;function y(e,t){r.call(this),this._sanitizeOptions(e),this._options=e,this._ended=!1,this._ending=!1,this._redirectCount=0,this._redirects=[],this._requestBodyLength=0,this._requestBodyBuffers=[],t&&this.on("response",t);var n=this;this._onNativeResponse=function(e){try{n._processResponse(e)}catch(e){n.emit("error",e instanceof h?e:new h({cause:e}))}},this._performRequest()}function _(e){var t={maxRedirects:21,maxBodyLength:10485760},n={};return Object.keys(e).forEach((function(a){var o=a+":",s=n[o]=e[a],r=t[a]=Object.create(s);Object.defineProperties(r,{request:{value:function(e,a,s){var r;return r=e,i&&r instanceof i?e=k(e):E(e)?e=k(j(e)):(s=a,a=O(e),e={protocol:o}),C(a)&&(s=a,a=null),(a=Object.assign({maxRedirects:t.maxRedirects,maxBodyLength:t.maxBodyLength},e,a)).nativeProtocols=n,E(a.host)||E(a.hostname)||(a.hostname="::1"),c.equal(a.protocol,o,"protocol mismatch"),p("options",a),new y(a,s)},configurable:!0,enumerable:!0,writable:!0},get:{value:function(e,t,n){var a=r.request(e,t,n);return a.end(),a},configurable:!0,enumerable:!0,writable:!0}})})),t}function w(){}function j(e){var t;if(u)t=new i(e);else if(!E((t=O(a.parse(e))).protocol))throw new f({input:e});return t}function O(e){if(/^\[/.test(e.hostname)&&!/^\[[:0-9a-f]+\]$/i.test(e.hostname))throw new f({input:e.href||e});if(/^\[/.test(e.host)&&!/^\[[:0-9a-f]+\](:\d+)?$/i.test(e.host))throw new f({input:e.href||e});return e}function k(e,t){var n=t||{};for(var a of l)n[a]=e[a];return n.hostname.startsWith("[")&&(n.hostname=n.hostname.slice(1,-1)),""!==n.port&&(n.port=Number(n.port)),n.path=n.search?n.pathname+n.search:n.pathname,n}function P(e,t){var n;for(var a in t)e.test(a)&&(n=t[a],delete t[a]);return null==n?void 0:String(n).trim()}function R(e,t,n){function a(n){Error.captureStackTrace(this,this.constructor),Object.assign(this,n||{}),this.code=e,this.message=this.cause?t+": "+this.cause.message:t}return a.prototype=new(n||Error),Object.defineProperties(a.prototype,{constructor:{value:a,enumerable:!1},name:{value:"Error ["+e+"]",enumerable:!1}}),a}function S(e,t){for(var n of d)e.removeListener(n,m[n]);e.on("error",w),e.destroy(t)}function E(e){return"string"==typeof e||e instanceof String}function C(e){return"function"==typeof e}y.prototype=Object.create(r.prototype),y.prototype.abort=function(){S(this._currentRequest),this._currentRequest.abort(),this.emit("abort")},y.prototype.destroy=function(e){return S(this._currentRequest,e),g.call(this,e),this},y.prototype.write=function(e,t,n){if(this._ending)throw new b;if(!E(e)&&("object"!=typeof(a=e)||!("length"in a)))throw new TypeError("data should be a string, Buffer or Uint8Array");var a;C(t)&&(n=t,t=null),0!==e.length?this._requestBodyLength+e.length<=this._options.maxBodyLength?(this._requestBodyLength+=e.length,this._requestBodyBuffers.push({data:e,encoding:t}),this._currentRequest.write(e,t,n)):(this.emit("error",new x),this.abort()):n&&n()},y.prototype.end=function(e,t,n){if(C(e)?(n=e,e=t=null):C(t)&&(n=t,t=null),e){var a=this,i=this._currentRequest;this.write(e,t,(function(){a._ended=!0,i.end(null,null,n)})),this._ending=!0}else this._ended=this._ending=!0,this._currentRequest.end(null,null,n)},y.prototype.setHeader=function(e,t){this._options.headers[e]=t,this._currentRequest.setHeader(e,t)},y.prototype.removeHeader=function(e){delete this._options.headers[e],this._currentRequest.removeHeader(e)},y.prototype.setTimeout=function(e,t){var n=this;function a(t){t.setTimeout(e),t.removeListener("timeout",t.destroy),t.addListener("timeout",t.destroy)}function i(t){n._timeout&&clearTimeout(n._timeout),n._timeout=setTimeout((function(){n.emit("timeout"),o()}),e),a(t)}function o(){n._timeout&&(clearTimeout(n._timeout),n._timeout=null),n.removeListener("abort",o),n.removeListener("error",o),n.removeListener("response",o),n.removeListener("close",o),t&&n.removeListener("timeout",t),n.socket||n._currentRequest.removeListener("socket",i)}return t&&this.on("timeout",t),this.socket?i(this.socket):this._currentRequest.once("socket",i),this.on("socket",a),this.on("abort",o),this.on("error",o),this.on("response",o),this.on("close",o),this},["flushHeaders","getHeader","setNoDelay","setSocketKeepAlive"].forEach((function(e){y.prototype[e]=function(t,n){return this._currentRequest[e](t,n)}})),["aborted","connection","socket"].forEach((function(e){Object.defineProperty(y.prototype,e,{get:function(){return this._currentRequest[e]}})})),y.prototype._sanitizeOptions=function(e){if(e.headers||(e.headers={}),e.host&&(e.hostname||(e.hostname=e.host),delete e.host),!e.pathname&&e.path){var t=e.path.indexOf("?");t<0?e.pathname=e.path:(e.pathname=e.path.substring(0,t),e.search=e.path.substring(t))}},y.prototype._performRequest=function(){var e=this._options.protocol,t=this._options.nativeProtocols[e];if(!t)throw new TypeError("Unsupported protocol "+e);if(this._options.agents){var n=e.slice(0,-1);this._options.agent=this._options.agents[n]}var i=this._currentRequest=t.request(this._options,this._onNativeResponse);for(var o of(i._redirectable=this,d))i.on(o,m[o]);if(this._currentUrl=/^\//.test(this._options.path)?a.format(this._options):this._options.path,this._isRedirect){var s=0,r=this,c=this._requestBodyBuffers;!function e(t){if(i===r._currentRequest)if(t)r.emit("error",t);else if(s=400)return e.responseUrl=this._currentUrl,e.redirects=this._redirects,this.emit("response",e),void(this._requestBodyBuffers=[]);if(S(this._currentRequest),e.destroy(),++this._redirectCount>this._options.maxRedirects)throw new v;var s=this._options.beforeRedirect;s&&(n=Object.assign({Host:e.req.getHeader("host")},this._options.headers));var r=this._options.method;((301===t||302===t)&&"POST"===this._options.method||303===t&&!/^(?:GET|HEAD)$/.test(this._options.method))&&(this._options.method="GET",this._requestBodyBuffers=[],P(/^content-/i,this._options.headers));var l,d,m=P(/^host$/i,this._options.headers),f=j(this._currentUrl),h=m||f.host,x=/^\w+:/.test(o)?this._currentUrl:a.format(Object.assign(f,{host:h})),b=(l=o,d=x,u?new i(l,d):j(a.resolve(d,l)));if(p("redirecting to",b.href),this._isRedirect=!0,k(b,this._options),(b.protocol!==f.protocol&&"https:"!==b.protocol||b.host!==h&&!function(e,t){c(E(e)&&E(t));var n=e.length-t.length-1;return n>0&&"."===e[n]&&e.endsWith(t)}(b.host,h))&&P(/^(?:authorization|cookie)$/i,this._options.headers),C(s)){var g={headers:e.headers,statusCode:t},y={url:x,method:r,headers:n};s(this._options,g,y),this._sanitizeOptions(this._options)}this._performRequest()},e.exports=_({http:o,https:s}),e.exports.wrap=_},6560:e=>{"use strict";e.exports=(e,t)=>{t=t||process.argv;const n=e.startsWith("-")?"":1===e.length?"-":"--",a=t.indexOf(n+e),i=t.indexOf("--");return-1!==a&&(-1===i||a{e.exports=n(3765)},983:(e,t,n)=>{"use strict";var a,i,o,s=n(5234),r=n(1017).extname,c=/^\s*([^;\s]*)(?:;|\s|$)/,p=/^text\//i;function u(e){if(!e||"string"!=typeof e)return!1;var t=c.exec(e),n=t&&s[t[1].toLowerCase()];return n&&n.charset?n.charset:!(!t||!p.test(t[1]))&&"UTF-8"}t.charset=u,t.charsets={lookup:u},t.contentType=function(e){if(!e||"string"!=typeof e)return!1;var n=-1===e.indexOf("/")?t.lookup(e):e;if(!n)return!1;if(-1===n.indexOf("charset")){var a=t.charset(n);a&&(n+="; charset="+a.toLowerCase())}return n},t.extension=function(e){if(!e||"string"!=typeof e)return!1;var n=c.exec(e),a=n&&t.extensions[n[1].toLowerCase()];if(!a||!a.length)return!1;return a[0]},t.extensions=Object.create(null),t.lookup=function(e){if(!e||"string"!=typeof e)return!1;var n=r("x."+e).toLowerCase().substr(1);if(!n)return!1;return t.types[n]||!1},t.types=Object.create(null),a=t.extensions,i=t.types,o=["nginx","apache",void 0,"iana"],Object.keys(s).forEach((function(e){var t=s[e],n=t.extensions;if(n&&n.length){a[e]=n;for(var r=0;ru||p===u&&"application/"===i[c].substr(0,12)))continue}i[c]=e}}}))},7824:e=>{var t=1e3,n=60*t,a=60*n,i=24*a,o=7*i,s=365.25*i;function r(e,t,n,a){var i=t>=1.5*n;return Math.round(e/n)+" "+a+(i?"s":"")}e.exports=function(e,c){c=c||{};var p=typeof e;if("string"===p&&e.length>0)return function(e){if((e=String(e)).length>100)return;var r=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(e);if(!r)return;var c=parseFloat(r[1]);switch((r[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*s;case"weeks":case"week":case"w":return c*o;case"days":case"day":case"d":return c*i;case"hours":case"hour":case"hrs":case"hr":case"h":return c*a;case"minutes":case"minute":case"mins":case"min":case"m":return c*n;case"seconds":case"second":case"secs":case"sec":case"s":return c*t;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(e);if("number"===p&&isFinite(e))return c.long?function(e){var o=Math.abs(e);if(o>=i)return r(e,o,i,"day");if(o>=a)return r(e,o,a,"hour");if(o>=n)return r(e,o,n,"minute");if(o>=t)return r(e,o,t,"second");return e+" ms"}(e):function(e){var o=Math.abs(e);if(o>=i)return Math.round(e/i)+"d";if(o>=a)return Math.round(e/a)+"h";if(o>=n)return Math.round(e/n)+"m";if(o>=t)return Math.round(e/t)+"s";return e+"ms"}(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}},1394:(e,t,n)=>{"use strict";var a=n(7310).parse,i={ftp:21,gopher:70,http:80,https:443,ws:80,wss:443},o=String.prototype.endsWith||function(e){return e.length<=this.length&&-1!==this.indexOf(e,this.length-e.length)};function s(e){return process.env[e.toLowerCase()]||process.env[e.toUpperCase()]||""}t.getProxyForUrl=function(e){var t="string"==typeof e?a(e):e||{},n=t.protocol,r=t.host,c=t.port;if("string"!=typeof r||!r||"string"!=typeof n)return"";if(n=n.split(":",1)[0],!function(e,t){var n=(s("npm_config_no_proxy")||s("no_proxy")).toLowerCase();if(!n)return!0;if("*"===n)return!1;return n.split(/[,\s]/).every((function(n){if(!n)return!0;var a=n.match(/^(.+):(\d+)$/),i=a?a[1]:n,s=a?parseInt(a[2]):0;return!(!s||s===t)||(/^[.*]/.test(i)?("*"===i.charAt(0)&&(i=i.slice(1)),!o.call(e,i)):e!==i)}))}(r=r.replace(/:\d*$/,""),c=parseInt(c)||i[n]||0))return"";var p=s("npm_config_"+n+"_proxy")||s(n+"_proxy")||s("npm_config_proxy")||s("all_proxy");return p&&-1===p.indexOf("://")&&(p=n+"://"+p),p}},2130:(e,t,n)=>{"use strict";const a=n(2037),i=n(6560),o=process.env;let s;function r(e){const t=function(e){if(!1===s)return 0;if(i("color=16m")||i("color=full")||i("color=truecolor"))return 3;if(i("color=256"))return 2;if(e&&!e.isTTY&&!0!==s)return 0;const t=s?1:0;if("win32"===process.platform){const e=a.release().split(".");return Number(process.versions.node.split(".")[0])>=8&&Number(e[0])>=10&&Number(e[2])>=10586?Number(e[2])>=14931?3:2:1}if("CI"in o)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI"].some((e=>e in o))||"codeship"===o.CI_NAME?1:t;if("TEAMCITY_VERSION"in o)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(o.TEAMCITY_VERSION)?1:0;if("truecolor"===o.COLORTERM)return 3;if("TERM_PROGRAM"in o){const e=parseInt((o.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(o.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(o.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(o.TERM)||"COLORTERM"in o?1:(o.TERM,t)}(e);return function(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}(t)}i("no-color")||i("no-colors")||i("color=false")?s=!1:(i("color")||i("colors")||i("color=true")||i("color=always"))&&(s=!0),"FORCE_COLOR"in o&&(s=0===o.FORCE_COLOR.length||0!==parseInt(o.FORCE_COLOR,10)),e.exports={supportsColor:r,stdout:r(process.stdout),stderr:r(process.stderr)}},4078:function(e,t,n){var a,i,o;o=function(){function e(e){var t=[];if(0===e.length)return"";if("string"!=typeof e[0])throw new TypeError("Url must be a string. Received "+e[0]);if(e[0].match(/^[^/:]+:\/*$/)&&e.length>1){var n=e.shift();e[0]=n+e[0]}e[0].match(/^file:\/\/\//)?e[0]=e[0].replace(/^([^/:]+):\/*/,"$1:///"):e[0]=e[0].replace(/^([^/:]+):\/*/,"$1://");for(var a=0;a0&&(i=i.replace(/^[\/]+/,"")),i=a0?"?":"")+s.join("&")}return function(){return e("object"==typeof arguments[0]?arguments[0]:[].slice.call(arguments))}},e.exports?e.exports=o():void 0===(i="function"==typeof(a=o)?a.call(t,n,t,e):a)||(e.exports=i)},9491:e=>{"use strict";e.exports=__nccwpck_require__(9491)},2361:e=>{"use strict";e.exports=__nccwpck_require__(2361)},7147:e=>{"use strict";e.exports=__nccwpck_require__(7147)},3685:e=>{"use strict";e.exports=__nccwpck_require__(3685)},5687:e=>{"use strict";e.exports=__nccwpck_require__(5687)},2037:e=>{"use strict";e.exports=__nccwpck_require__(2037)},1017:e=>{"use strict";e.exports=__nccwpck_require__(1017)},2781:e=>{"use strict";e.exports=__nccwpck_require__(2781)},6224:e=>{"use strict";e.exports=__nccwpck_require__(6224)},7310:e=>{"use strict";e.exports=__nccwpck_require__(7310)},3837:e=>{"use strict";e.exports=__nccwpck_require__(3837)},9796:e=>{"use strict";e.exports=__nccwpck_require__(9796)},3306:(e,t,n)=>{"use strict";const a=n(4106),i=n(7310),o=n(1394),s=n(3685),r=n(5687),c=n(3837),p=n(938),u=n(9796),l=n(2781),d=n(2361);function m(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}const f=m(a),h=m(i),v=m(s),x=m(r),b=m(c),g=m(p),y=m(u),_=m(l),w=m(d);function j(e,t){return function(){return e.apply(t,arguments)}}const{toString:O}=Object.prototype,{getPrototypeOf:k}=Object,P=(R=Object.create(null),e=>{const t=O.call(e);return R[t]||(R[t]=t.slice(8,-1).toLowerCase())});var R;const S=e=>(e=e.toLowerCase(),t=>P(t)===e),E=e=>t=>typeof t===e,{isArray:C}=Array,T=E("undefined");const q=S("ArrayBuffer");const A=E("string"),D=E("function"),M=E("number"),F=e=>null!==e&&"object"==typeof e,L=e=>{if("object"!==P(e))return!1;const t=k(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||Symbol.toStringTag in e||Symbol.iterator in e)},B=S("Date"),z=S("File"),U=S("Blob"),N=S("FileList"),I=S("URLSearchParams");function W(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let a,i;if("object"!=typeof e&&(e=[e]),C(e))for(a=0,i=e.length;a0;)if(a=n[i],t===a.toLowerCase())return a;return null}const V="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,$=e=>!T(e)&&e!==V;const G=(J="undefined"!=typeof Uint8Array&&k(Uint8Array),e=>J&&e instanceof J);var J;const K=S("HTMLFormElement"),Y=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),Q=S("RegExp"),Z=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),a={};W(n,((n,i)=>{let o;!1!==(o=t(n,i,e))&&(a[i]=o||n)})),Object.defineProperties(e,a)},X="abcdefghijklmnopqrstuvwxyz",ee="0123456789",te={DIGIT:ee,ALPHA:X,ALPHA_DIGIT:X+X.toUpperCase()+ee};const ne=S("AsyncFunction"),ae={isArray:C,isArrayBuffer:q,isBuffer:function(e){return null!==e&&!T(e)&&null!==e.constructor&&!T(e.constructor)&&D(e.constructor.isBuffer)&&e.constructor.isBuffer(e)},isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||D(e.append)&&("formdata"===(t=P(e))||"object"===t&&D(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&q(e.buffer),t},isString:A,isNumber:M,isBoolean:e=>!0===e||!1===e,isObject:F,isPlainObject:L,isUndefined:T,isDate:B,isFile:z,isBlob:U,isRegExp:Q,isFunction:D,isStream:e=>F(e)&&D(e.pipe),isURLSearchParams:I,isTypedArray:G,isFileList:N,forEach:W,merge:function e(){const{caseless:t}=$(this)&&this||{},n={},a=(a,i)=>{const o=t&&H(n,i)||i;L(n[o])&&L(a)?n[o]=e(n[o],a):L(a)?n[o]=e({},a):C(a)?n[o]=a.slice():n[o]=a};for(let e=0,t=arguments.length;e(W(t,((t,a)=>{n&&D(t)?e[a]=j(t,n):e[a]=t}),{allOwnKeys:a}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,a)=>{e.prototype=Object.create(t.prototype,a),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,a)=>{let i,o,s;const r={};if(t=t||{},null==e)return t;do{for(i=Object.getOwnPropertyNames(e),o=i.length;o-- >0;)s=i[o],a&&!a(s,e,t)||r[s]||(t[s]=e[s],r[s]=!0);e=!1!==n&&k(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:P,kindOfTest:S,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const a=e.indexOf(t,n);return-1!==a&&a===n},toArray:e=>{if(!e)return null;if(C(e))return e;let t=e.length;if(!M(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[Symbol.iterator]).call(e);let a;for(;(a=n.next())&&!a.done;){const n=a.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const a=[];for(;null!==(n=e.exec(t));)a.push(n);return a},isHTMLForm:K,hasOwnProperty:Y,hasOwnProp:Y,reduceDescriptors:Z,freezeMethods:e=>{Z(e,((t,n)=>{if(D(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const a=e[n];D(a)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))}))},toObjectSet:(e,t)=>{const n={},a=e=>{e.forEach((e=>{n[e]=!0}))};return C(e)?a(e):a(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,n){return t.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(e,t)=>(e=+e,Number.isFinite(e)?e:t),findKey:H,global:V,isContextDefined:$,ALPHABET:te,generateString:(e=16,t=te.ALPHA_DIGIT)=>{let n="";const{length:a}=t;for(;e--;)n+=t[Math.random()*a|0];return n},isSpecCompliantForm:function(e){return!!(e&&D(e.append)&&"FormData"===e[Symbol.toStringTag]&&e[Symbol.iterator])},toJSONObject:e=>{const t=new Array(10),n=(e,a)=>{if(F(e)){if(t.indexOf(e)>=0)return;if(!("toJSON"in e)){t[a]=e;const i=C(e)?[]:{};return W(e,((e,t)=>{const o=n(e,a+1);!T(o)&&(i[t]=o)})),t[a]=void 0,i}}return e};return n(e,0)},isAsyncFn:ne,isThenable:e=>e&&(F(e)||D(e))&&D(e.then)&&D(e.catch)};function ie(e,t,n,a,i){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),a&&(this.request=a),i&&(this.response=i)}ae.inherits(ie,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:ae.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const oe=ie.prototype,se={};function re(e){return ae.isPlainObject(e)||ae.isArray(e)}function ce(e){return ae.endsWith(e,"[]")?e.slice(0,-2):e}function pe(e,t,n){return e?e.concat(t).map((function(e,t){return e=ce(e),!n&&t?"["+e+"]":e})).join(n?".":""):t}["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((e=>{se[e]={value:e}})),Object.defineProperties(ie,se),Object.defineProperty(oe,"isAxiosError",{value:!0}),ie.from=(e,t,n,a,i,o)=>{const s=Object.create(oe);return ae.toFlatObject(e,s,(function(e){return e!==Error.prototype}),(e=>"isAxiosError"!==e)),ie.call(s,e.message,t,n,a,i),s.cause=e,s.name=e.name,o&&Object.assign(s,o),s};const ue=ae.toFlatObject(ae,{},null,(function(e){return/^is[A-Z]/.test(e)}));function le(e,t,n){if(!ae.isObject(e))throw new TypeError("target must be an object");t=t||new(f.default||FormData);const a=(n=ae.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!ae.isUndefined(t[e])}))).metaTokens,i=n.visitor||p,o=n.dots,s=n.indexes,r=(n.Blob||"undefined"!=typeof Blob&&Blob)&&ae.isSpecCompliantForm(t);if(!ae.isFunction(i))throw new TypeError("visitor must be a function");function c(e){if(null===e)return"";if(ae.isDate(e))return e.toISOString();if(!r&&ae.isBlob(e))throw new ie("Blob is not supported. Use a Buffer instead.");return ae.isArrayBuffer(e)||ae.isTypedArray(e)?r&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function p(e,n,i){let r=e;if(e&&!i&&"object"==typeof e)if(ae.endsWith(n,"{}"))n=a?n:n.slice(0,-2),e=JSON.stringify(e);else if(ae.isArray(e)&&function(e){return ae.isArray(e)&&!e.some(re)}(e)||(ae.isFileList(e)||ae.endsWith(n,"[]"))&&(r=ae.toArray(e)))return n=ce(n),r.forEach((function(e,a){!ae.isUndefined(e)&&null!==e&&t.append(!0===s?pe([n],a,o):null===s?n:n+"[]",c(e))})),!1;return!!re(e)||(t.append(pe(i,n,o),c(e)),!1)}const u=[],l=Object.assign(ue,{defaultVisitor:p,convertValue:c,isVisitable:re});if(!ae.isObject(e))throw new TypeError("data must be an object");return function e(n,a){if(!ae.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+a.join("."));u.push(n),ae.forEach(n,(function(n,o){!0===(!(ae.isUndefined(n)||null===n)&&i.call(t,n,ae.isString(o)?o.trim():o,a,l))&&e(n,a?a.concat(o):[o])})),u.pop()}}(e),t}function de(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function me(e,t){this._pairs=[],e&&le(e,this,t)}const fe=me.prototype;function he(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function ve(e,t,n){if(!t)return e;const a=n&&n.encode||he,i=n&&n.serialize;let o;if(o=i?i(t,n):ae.isURLSearchParams(t)?t.toString():new me(t,n).toString(a),o){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+o}return e}fe.append=function(e,t){this._pairs.push([e,t])},fe.toString=function(e){const t=e?function(t){return e.call(this,t,de)}:de;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};const xe=class InterceptorManager{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){ae.forEach(this.handlers,(function(t){null!==t&&e(t)}))}},be={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},ge={isNode:!0,classes:{URLSearchParams:h.default.URLSearchParams,FormData:f.default,Blob:"undefined"!=typeof Blob&&Blob||null},protocols:["http","https","file","data"]};function ye(e){function t(e,n,a,i){let o=e[i++];const s=Number.isFinite(+o),r=i>=e.length;if(o=!o&&ae.isArray(a)?a.length:o,r)return ae.hasOwnProp(a,o)?a[o]=[a[o],n]:a[o]=n,!s;a[o]&&ae.isObject(a[o])||(a[o]=[]);return t(e,n,a[o],i)&&ae.isArray(a[o])&&(a[o]=function(e){const t={},n=Object.keys(e);let a;const i=n.length;let o;for(a=0;a{t(function(e){return ae.matchAll(/\w+|\[(\w*)]/g,e).map((e=>"[]"===e[0]?"":e[1]||e[0]))}(e),a,n,0)})),n}return null}const _e={transitional:be,adapter:["xhr","http"],transformRequest:[function(e,t){const n=t.getContentType()||"",a=n.indexOf("application/json")>-1,i=ae.isObject(e);i&&ae.isHTMLForm(e)&&(e=new FormData(e));if(ae.isFormData(e))return a&&a?JSON.stringify(ye(e)):e;if(ae.isArrayBuffer(e)||ae.isBuffer(e)||ae.isStream(e)||ae.isFile(e)||ae.isBlob(e))return e;if(ae.isArrayBufferView(e))return e.buffer;if(ae.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let o;if(i){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return le(e,new ge.classes.URLSearchParams,Object.assign({visitor:function(e,t,n,a){return ae.isBuffer(e)?(this.append(t,e.toString("base64")),!1):a.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((o=ae.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return le(o?{"files[]":e}:e,t&&new t,this.formSerializer)}}return i||a?(t.setContentType("application/json",!1),function(e,t,n){if(ae.isString(e))try{return(t||JSON.parse)(e),ae.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(n||JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||_e.transitional,n=t&&t.forcedJSONParsing,a="json"===this.responseType;if(e&&ae.isString(e)&&(n&&!this.responseType||a)){const n=!(t&&t.silentJSONParsing)&&a;try{return JSON.parse(e)}catch(e){if(n){if("SyntaxError"===e.name)throw ie.from(e,ie.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:ge.classes.FormData,Blob:ge.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};ae.forEach(["delete","get","head","post","put","patch"],(e=>{_e.headers[e]={}}));const we=_e,je=ae.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Oe=Symbol("internals");function ke(e){return e&&String(e).trim().toLowerCase()}function Pe(e){return!1===e||null==e?e:ae.isArray(e)?e.map(Pe):String(e)}function Re(e,t,n,a,i){return ae.isFunction(a)?a.call(this,t,n):(i&&(t=n),ae.isString(t)?ae.isString(a)?-1!==t.indexOf(a):ae.isRegExp(a)?a.test(t):void 0:void 0)}class AxiosHeaders{constructor(e){e&&this.set(e)}set(e,t,n){const a=this;function i(e,t,n){const i=ke(t);if(!i)throw new Error("header name must be a non-empty string");const o=ae.findKey(a,i);(!o||void 0===a[o]||!0===n||void 0===n&&!1!==a[o])&&(a[o||t]=Pe(e))}const o=(e,t)=>ae.forEach(e,((e,n)=>i(e,n,t)));return ae.isPlainObject(e)||e instanceof this.constructor?o(e,t):ae.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim())?o((e=>{const t={};let n,a,i;return e&&e.split("\n").forEach((function(e){i=e.indexOf(":"),n=e.substring(0,i).trim().toLowerCase(),a=e.substring(i+1).trim(),!n||t[n]&&je[n]||("set-cookie"===n?t[n]?t[n].push(a):t[n]=[a]:t[n]=t[n]?t[n]+", "+a:a)})),t})(e),t):null!=e&&i(t,e,n),this}get(e,t){if(e=ke(e)){const n=ae.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let a;for(;a=n.exec(e);)t[a[1]]=a[2];return t}(e);if(ae.isFunction(t))return t.call(this,e,n);if(ae.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=ke(e)){const n=ae.findKey(this,e);return!(!n||void 0===this[n]||t&&!Re(0,this[n],n,t))}return!1}delete(e,t){const n=this;let a=!1;function i(e){if(e=ke(e)){const i=ae.findKey(n,e);!i||t&&!Re(0,n[i],i,t)||(delete n[i],a=!0)}}return ae.isArray(e)?e.forEach(i):i(e),a}clear(e){const t=Object.keys(this);let n=t.length,a=!1;for(;n--;){const i=t[n];e&&!Re(0,this[i],i,e,!0)||(delete this[i],a=!0)}return a}normalize(e){const t=this,n={};return ae.forEach(this,((a,i)=>{const o=ae.findKey(n,i);if(o)return t[o]=Pe(a),void delete t[i];const s=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((e,t,n)=>t.toUpperCase()+n))}(i):String(i).trim();s!==i&&delete t[i],t[s]=Pe(a),n[s]=!0})),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return ae.forEach(this,((n,a)=>{null!=n&&!1!==n&&(t[a]=e&&ae.isArray(n)?n.join(", "):n)})),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map((([e,t])=>e+": "+t)).join("\n")}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach((e=>n.set(e))),n}static accessor(e){const t=(this[Oe]=this[Oe]={accessors:{}}).accessors,n=this.prototype;function a(e){const a=ke(e);t[a]||(!function(e,t){const n=ae.toCamelCase(" "+t);["get","set","has"].forEach((a=>{Object.defineProperty(e,a+n,{value:function(e,n,i){return this[a].call(this,t,e,n,i)},configurable:!0})}))}(n,e),t[a]=!0)}return ae.isArray(e)?e.forEach(a):a(e),this}}AxiosHeaders.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),ae.reduceDescriptors(AxiosHeaders.prototype,(({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}})),ae.freezeMethods(AxiosHeaders);const Se=AxiosHeaders;function Ee(e,t){const n=this||we,a=t||n,i=Se.from(a.headers);let o=a.data;return ae.forEach(e,(function(e){o=e.call(n,o,i.normalize(),t?t.status:void 0)})),i.normalize(),o}function Ce(e){return!(!e||!e.__CANCEL__)}function Te(e,t,n){ie.call(this,null==e?"canceled":e,ie.ERR_CANCELED,t,n),this.name="CanceledError"}function qe(e,t,n){const a=n.config.validateStatus;n.status&&a&&!a(n.status)?t(new ie("Request failed with status code "+n.status,[ie.ERR_BAD_REQUEST,ie.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}function Ae(e,t){return e&&!function(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}(t)?function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}ae.inherits(Te,ie,{__CANCEL__:!0});const De="1.6.0";function Me(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}const Fe=/^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/;function Le(e,t){e=e||10;const n=new Array(e),a=new Array(e);let i,o=0,s=0;return t=void 0!==t?t:1e3,function(r){const c=Date.now(),p=a[s];i||(i=c),n[o]=r,a[o]=c;let u=s,l=0;for(;u!==o;)l+=n[u++],u%=e;if(o=(o+1)%e,o===s&&(s=(s+1)%e),c-i!ae.isUndefined(t[e])))).chunkSize});const t=this,n=this[Be]={length:e.length,timeWindow:e.timeWindow,ticksRate:e.ticksRate,chunkSize:e.chunkSize,maxRate:e.maxRate,minChunkSize:e.minChunkSize,bytesSeen:0,isCaptured:!1,notifiedBytesLoaded:0,ts:Date.now(),bytes:0,onReadCallback:null},a=Le(n.ticksRate*e.samplesCount,n.timeWindow);this.on("newListener",(e=>{"progress"===e&&(n.isCaptured||(n.isCaptured=!0))}));let i=0;n.updateProgress=function(e,t){let n=0;const a=1e3/t;let i=null;return function(t,o){const s=Date.now();if(t||s-n>a)return i&&(clearTimeout(i),i=null),n=s,e.apply(null,o);i||(i=setTimeout((()=>(i=null,n=Date.now(),e.apply(null,o))),a-(s-n)))}}((function(){const e=n.length,o=n.bytesSeen,s=o-i;if(!s||t.destroyed)return;const r=a(s);i=o,process.nextTick((()=>{t.emit("progress",{loaded:o,total:e,progress:e?o/e:void 0,bytes:s,rate:r||void 0,estimated:r&&e&&o<=e?(e-o)/r:void 0})}))}),n.ticksRate);const o=()=>{n.updateProgress(!0)};this.once("end",o),this.once("error",o)}_read(e){const t=this[Be];return t.onReadCallback&&t.onReadCallback(),super._read(e)}_transform(e,t,n){const a=this,i=this[Be],o=i.maxRate,s=this.readableHighWaterMark,r=i.timeWindow,c=o/(1e3/r),p=!1!==i.minChunkSize?Math.max(i.minChunkSize,.01*c):0;const u=(e,t)=>{const n=Buffer.byteLength(e);let u,l=null,d=s,m=0;if(o){const e=Date.now();(!i.ts||(m=e-i.ts)>=r)&&(i.ts=e,u=c-i.bytes,i.bytes=u<0?-u:0,m=0),u=c-i.bytes}if(o){if(u<=0)return setTimeout((()=>{t(null,e)}),r-m);ud&&n-d>p&&(l=e.subarray(d),e=e.subarray(0,d)),function(e,t){const n=Buffer.byteLength(e);i.bytesSeen+=n,i.bytes+=n,i.isCaptured&&i.updateProgress(),a.push(e)?process.nextTick(t):i.onReadCallback=()=>{i.onReadCallback=null,process.nextTick(t)}}(e,l?()=>{process.nextTick(t,null,l)}:t)};u(e,(function e(t,a){if(t)return n(t);a?u(a,e):n(null)}))}setLength(e){return this[Be].length=+e,this}}const ze=AxiosTransformStream,{asyncIterator:Ue}=Symbol,Ne=async function*(e){e.stream?yield*e.stream():e.arrayBuffer?yield await e.arrayBuffer():e[Ue]?yield*e[Ue]():yield e},Ie=ae.ALPHABET.ALPHA_DIGIT+"-_",We=new c.TextEncoder,He="\r\n",Ve=We.encode(He);class FormDataPart{constructor(e,t){const{escapeName:n}=this.constructor,a=ae.isString(t);let i=`Content-Disposition: form-data; name="${n(e)}"${!a&&t.name?`; filename="${n(t.name)}"`:""}\r\n`;a?t=We.encode(String(t).replace(/\r?\n|\r\n?/g,He)):i+=`Content-Type: ${t.type||"application/octet-stream"}\r\n`,this.headers=We.encode(i+He),this.contentLength=a?t.byteLength:t.size,this.size=this.headers.byteLength+this.contentLength+2,this.name=e,this.value=t}async*encode(){yield this.headers;const{value:e}=this;ae.isTypedArray(e)?yield e:yield*Ne(e),yield Ve}static escapeName(e){return String(e).replace(/[\r\n"]/g,(e=>({"\r":"%0D","\n":"%0A",'"':"%22"}[e])))}}const $e=(e,t,n)=>{const{tag:a="form-data-boundary",size:i=25,boundary:o=a+"-"+ae.generateString(i,Ie)}=n||{};if(!ae.isFormData(e))throw TypeError("FormData instance required");if(o.length<1||o.length>70)throw Error("boundary must be 10-70 characters long");const s=We.encode("--"+o+He),r=We.encode("--"+o+"--"+He+He);let c=r.byteLength;const p=Array.from(e.entries()).map((([e,t])=>{const n=new FormDataPart(e,t);return c+=n.size,n}));c+=s.byteLength*p.length,c=ae.toFiniteNumber(c);const u={"Content-Type":`multipart/form-data; boundary=${o}`};return Number.isFinite(c)&&(u["Content-Length"]=c),t&&t(u),l.Readable.from(async function*(){for(const e of p)yield s,yield*e.encode();yield r}())};class ZlibHeaderTransformStream extends _.default.Transform{__transform(e,t,n){this.push(e),n()}_transform(e,t,n){if(0!==e.length&&(this._transform=this.__transform,120!==e[0])){const e=Buffer.alloc(2);e[0]=120,e[1]=156,this.push(e,t)}this.__transform(e,t,n)}}const Ge=ZlibHeaderTransformStream,Je=(e,t)=>ae.isAsyncFn(e)?function(...n){const a=n.pop();e.apply(this,n).then((e=>{try{t?a(null,...t(e)):a(null,e)}catch(e){a(e)}}),a)}:e,Ke={flush:y.default.constants.Z_SYNC_FLUSH,finishFlush:y.default.constants.Z_SYNC_FLUSH},Ye={flush:y.default.constants.BROTLI_OPERATION_FLUSH,finishFlush:y.default.constants.BROTLI_OPERATION_FLUSH},Qe=ae.isFunction(y.default.createBrotliDecompress),{http:Ze,https:Xe}=g.default,et=/https:?/,tt=ge.protocols.map((e=>e+":"));function nt(e){e.beforeRedirects.proxy&&e.beforeRedirects.proxy(e),e.beforeRedirects.config&&e.beforeRedirects.config(e)}function at(e,t,n){let a=t;if(!a&&!1!==a){const e=o.getProxyForUrl(n);e&&(a=new URL(e))}if(a){if(a.username&&(a.auth=(a.username||"")+":"+(a.password||"")),a.auth){(a.auth.username||a.auth.password)&&(a.auth=(a.auth.username||"")+":"+(a.auth.password||""));const t=Buffer.from(a.auth,"utf8").toString("base64");e.headers["Proxy-Authorization"]="Basic "+t}e.headers.host=e.hostname+(e.port?":"+e.port:"");const t=a.hostname||a.host;e.hostname=t,e.host=t,e.port=a.port,e.path=n,a.protocol&&(e.protocol=a.protocol.includes(":")?a.protocol:`${a.protocol}:`)}e.beforeRedirects.proxy=function(e){at(e,t,e.href)}}const it="undefined"!=typeof process&&"process"===ae.kindOf(process),ot=(e,t)=>(({address:e,family:t})=>{if(!ae.isString(e))throw TypeError("address must be a string");return{address:e,family:t||(e.indexOf(".")<0?6:4)}})(ae.isObject(e)?e:{address:e,family:t}),st=it&&function(e){return t=async function(t,n,a){let{data:i,lookup:o,family:s}=e;const{responseType:r,responseEncoding:c}=e,p=e.method.toUpperCase();let u,l,d=!1;if(o){const e=Je(o,(e=>ae.isArray(e)?e:[e]));o=(t,n,a)=>{e(t,n,((e,t,i)=>{const o=ae.isArray(t)?t.map((e=>ot(e))):[ot(t,i)];n.all?a(e,o):a(e,o[0].address,o[0].family)}))}}const m=new w.default,f=()=>{e.cancelToken&&e.cancelToken.unsubscribe(h),e.signal&&e.signal.removeEventListener("abort",h),m.removeAllListeners()};function h(t){m.emit("abort",!t||t.type?new Te(null,e,l):t)}a(((e,t)=>{u=!0,t&&(d=!0,f())})),m.once("abort",n),(e.cancelToken||e.signal)&&(e.cancelToken&&e.cancelToken.subscribe(h),e.signal&&(e.signal.aborted?h():e.signal.addEventListener("abort",h)));const g=Ae(e.baseURL,e.url),j=new URL(g,"http://localhost"),O=j.protocol||tt[0];if("data:"===O){let a;if("GET"!==p)return qe(t,n,{status:405,statusText:"method not allowed",headers:{},config:e});try{a=function(e,t,n){const a=n&&n.Blob||ge.classes.Blob,i=Me(e);if(void 0===t&&a&&(t=!0),"data"===i){e=i.length?e.slice(i.length+1):e;const n=Fe.exec(e);if(!n)throw new ie("Invalid URL",ie.ERR_INVALID_URL);const o=n[1],s=n[2],r=n[3],c=Buffer.from(decodeURIComponent(r),s?"base64":"utf8");if(t){if(!a)throw new ie("Blob is not supported",ie.ERR_NOT_SUPPORT);return new a([c],{type:o})}return c}throw new ie("Unsupported protocol "+i,ie.ERR_NOT_SUPPORT)}(e.url,"blob"===r,{Blob:e.env&&e.env.Blob})}catch(t){throw ie.from(t,ie.ERR_BAD_REQUEST,e)}return"text"===r?(a=a.toString(c),c&&"utf8"!==c||(a=ae.stripBOM(a))):"stream"===r&&(a=_.default.Readable.from(a)),qe(t,n,{data:a,status:200,statusText:"OK",headers:new Se,config:e})}if(-1===tt.indexOf(O))return n(new ie("Unsupported protocol "+O,ie.ERR_BAD_REQUEST,e));const k=Se.from(e.headers).normalize();k.set("User-Agent","axios/1.6.0",!1);const P=e.onDownloadProgress,R=e.onUploadProgress,S=e.maxRate;let E,C;if(ae.isSpecCompliantForm(i)){const e=k.getContentType(/boundary=([-_\w\d]{10,70})/i);i=$e(i,(e=>{k.set(e)}),{tag:"axios-1.6.0-boundary",boundary:e&&e[1]||void 0})}else if(ae.isFormData(i)&&ae.isFunction(i.getHeaders)){if(k.set(i.getHeaders()),!k.hasContentLength())try{const e=await b.default.promisify(i.getLength).call(i);Number.isFinite(e)&&e>=0&&k.setContentLength(e)}catch(e){}}else if(ae.isBlob(i))i.size&&k.setContentType(i.type||"application/octet-stream"),k.setContentLength(i.size||0),i=_.default.Readable.from(Ne(i));else if(i&&!ae.isStream(i)){if(Buffer.isBuffer(i));else if(ae.isArrayBuffer(i))i=Buffer.from(new Uint8Array(i));else{if(!ae.isString(i))return n(new ie("Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream",ie.ERR_BAD_REQUEST,e));i=Buffer.from(i,"utf-8")}if(k.setContentLength(i.length,!1),e.maxBodyLength>-1&&i.length>e.maxBodyLength)return n(new ie("Request body larger than maxBodyLength limit",ie.ERR_BAD_REQUEST,e))}const T=ae.toFiniteNumber(k.getContentLength());let q,A;ae.isArray(S)?(E=S[0],C=S[1]):E=C=S,i&&(R||E)&&(ae.isStream(i)||(i=_.default.Readable.from(i,{objectMode:!1})),i=_.default.pipeline([i,new ze({length:T,maxRate:ae.toFiniteNumber(E)})],ae.noop),R&&i.on("progress",(e=>{R(Object.assign(e,{upload:!0}))}))),e.auth&&(q=(e.auth.username||"")+":"+(e.auth.password||"")),!q&&j.username&&(q=j.username+":"+j.password),q&&k.delete("authorization");try{A=ve(j.pathname+j.search,e.params,e.paramsSerializer).replace(/^\?/,"")}catch(t){const a=new Error(t.message);return a.config=e,a.url=e.url,a.exists=!0,n(a)}k.set("Accept-Encoding","gzip, compress, deflate"+(Qe?", br":""),!1);const D={path:A,method:p,headers:k.toJSON(),agents:{http:e.httpAgent,https:e.httpsAgent},auth:q,protocol:O,family:s,beforeRedirect:nt,beforeRedirects:{}};let M;!ae.isUndefined(o)&&(D.lookup=o),e.socketPath?D.socketPath=e.socketPath:(D.hostname=j.hostname,D.port=j.port,at(D,e.proxy,O+"//"+j.hostname+(j.port?":"+j.port:"")+D.path));const F=et.test(D.protocol);if(D.agent=F?e.httpsAgent:e.httpAgent,e.transport?M=e.transport:0===e.maxRedirects?M=F?x.default:v.default:(e.maxRedirects&&(D.maxRedirects=e.maxRedirects),e.beforeRedirect&&(D.beforeRedirects.config=e.beforeRedirect),M=F?Xe:Ze),e.maxBodyLength>-1?D.maxBodyLength=e.maxBodyLength:D.maxBodyLength=1/0,e.insecureHTTPParser&&(D.insecureHTTPParser=e.insecureHTTPParser),l=M.request(D,(function(a){if(l.destroyed)return;const i=[a],o=+a.headers["content-length"];if(P){const e=new ze({length:ae.toFiniteNumber(o),maxRate:ae.toFiniteNumber(C)});P&&e.on("progress",(e=>{P(Object.assign(e,{download:!0}))})),i.push(e)}let s=a;const u=a.req||l;if(!1!==e.decompress&&a.headers["content-encoding"])switch("HEAD"!==p&&204!==a.statusCode||delete a.headers["content-encoding"],(a.headers["content-encoding"]||"").toLowerCase()){case"gzip":case"x-gzip":case"compress":case"x-compress":i.push(y.default.createUnzip(Ke)),delete a.headers["content-encoding"];break;case"deflate":i.push(new Ge),i.push(y.default.createUnzip(Ke)),delete a.headers["content-encoding"];break;case"br":Qe&&(i.push(y.default.createBrotliDecompress(Ye)),delete a.headers["content-encoding"])}s=i.length>1?_.default.pipeline(i,ae.noop):i[0];const h=_.default.finished(s,(()=>{h(),f()})),v={status:a.statusCode,statusText:a.statusMessage,headers:new Se(a.headers),config:e,request:u};if("stream"===r)v.data=s,qe(t,n,v);else{const a=[];let i=0;s.on("data",(function(t){a.push(t),i+=t.length,e.maxContentLength>-1&&i>e.maxContentLength&&(d=!0,s.destroy(),n(new ie("maxContentLength size of "+e.maxContentLength+" exceeded",ie.ERR_BAD_RESPONSE,e,u)))})),s.on("aborted",(function(){if(d)return;const t=new ie("maxContentLength size of "+e.maxContentLength+" exceeded",ie.ERR_BAD_RESPONSE,e,u);s.destroy(t),n(t)})),s.on("error",(function(t){l.destroyed||n(ie.from(t,null,e,u))})),s.on("end",(function(){try{let e=1===a.length?a[0]:Buffer.concat(a);"arraybuffer"!==r&&(e=e.toString(c),c&&"utf8"!==c||(e=ae.stripBOM(e))),v.data=e}catch(t){return n(ie.from(t,null,e,v.request,v))}qe(t,n,v)}))}m.once("abort",(e=>{s.destroyed||(s.emit("error",e),s.destroy())}))})),m.once("abort",(e=>{n(e),l.destroy(e)})),l.on("error",(function(t){n(ie.from(t,null,e,l))})),l.on("socket",(function(e){e.setKeepAlive(!0,6e4)})),e.timeout){const t=parseInt(e.timeout,10);if(Number.isNaN(t))return void n(new ie("error trying to parse `config.timeout` to int",ie.ERR_BAD_OPTION_VALUE,e,l));l.setTimeout(t,(function(){if(u)return;let t=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const a=e.transitional||be;e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(new ie(t,a.clarifyTimeoutError?ie.ETIMEDOUT:ie.ECONNABORTED,e,l)),h()}))}if(ae.isStream(i)){let t=!1,n=!1;i.on("end",(()=>{t=!0})),i.once("error",(e=>{n=!0,l.destroy(e)})),i.on("close",(()=>{t||n||h(new Te("Request stream has been aborted",e,l))})),i.pipe(l)}else l.end(i)},new Promise(((e,n)=>{let a,i;const o=(e,t)=>{i||(i=!0,a&&a(e,t))},s=e=>{o(e,!0),n(e)};t((t=>{o(t),e(t)}),s,(e=>a=e)).catch(s)}));var t},rt=ge.isStandardBrowserEnv?{write:function(e,t,n,a,i,o){const s=[];s.push(e+"="+encodeURIComponent(t)),ae.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),ae.isString(a)&&s.push("path="+a),ae.isString(i)&&s.push("domain="+i),!0===o&&s.push("secure"),document.cookie=s.join("; ")},read:function(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}},ct=ge.isStandardBrowserEnv?function(){const e=/(msie|trident)/i.test(navigator.userAgent),t=document.createElement("a");let n;function a(n){let a=n;return e&&(t.setAttribute("href",a),a=t.href),t.setAttribute("href",a),{href:t.href,protocol:t.protocol?t.protocol.replace(/:$/,""):"",host:t.host,search:t.search?t.search.replace(/^\?/,""):"",hash:t.hash?t.hash.replace(/^#/,""):"",hostname:t.hostname,port:t.port,pathname:"/"===t.pathname.charAt(0)?t.pathname:"/"+t.pathname}}return n=a(window.location.href),function(e){const t=ae.isString(e)?a(e):e;return t.protocol===n.protocol&&t.host===n.host}}():function(){return!0};function pt(e,t){let n=0;const a=Le(50,250);return i=>{const o=i.loaded,s=i.lengthComputable?i.total:void 0,r=o-n,c=a(r);n=o;const p={loaded:o,total:s,progress:s?o/s:void 0,bytes:r,rate:c||void 0,estimated:c&&s&&o<=s?(s-o)/c:void 0,event:i};p[t?"download":"upload"]=!0,e(p)}}const ut={http:st,xhr:"undefined"!=typeof XMLHttpRequest&&function(e){return new Promise((function(t,n){let a=e.data;const i=Se.from(e.headers).normalize(),o=e.responseType;let s,r;function c(){e.cancelToken&&e.cancelToken.unsubscribe(s),e.signal&&e.signal.removeEventListener("abort",s)}ae.isFormData(a)&&(ge.isStandardBrowserEnv||ge.isStandardBrowserWebWorkerEnv?i.setContentType(!1):i.getContentType(/^\s*multipart\/form-data/)?ae.isString(r=i.getContentType())&&i.setContentType(r.replace(/^\s*(multipart\/form-data);+/,"$1")):i.setContentType("multipart/form-data"));let p=new XMLHttpRequest;if(e.auth){const t=e.auth.username||"",n=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";i.set("Authorization","Basic "+btoa(t+":"+n))}const u=Ae(e.baseURL,e.url);function l(){if(!p)return;const a=Se.from("getAllResponseHeaders"in p&&p.getAllResponseHeaders());qe((function(e){t(e),c()}),(function(e){n(e),c()}),{data:o&&"text"!==o&&"json"!==o?p.response:p.responseText,status:p.status,statusText:p.statusText,headers:a,config:e,request:p}),p=null}if(p.open(e.method.toUpperCase(),ve(u,e.params,e.paramsSerializer),!0),p.timeout=e.timeout,"onloadend"in p?p.onloadend=l:p.onreadystatechange=function(){p&&4===p.readyState&&(0!==p.status||p.responseURL&&0===p.responseURL.indexOf("file:"))&&setTimeout(l)},p.onabort=function(){p&&(n(new ie("Request aborted",ie.ECONNABORTED,e,p)),p=null)},p.onerror=function(){n(new ie("Network Error",ie.ERR_NETWORK,e,p)),p=null},p.ontimeout=function(){let t=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const a=e.transitional||be;e.timeoutErrorMessage&&(t=e.timeoutErrorMessage),n(new ie(t,a.clarifyTimeoutError?ie.ETIMEDOUT:ie.ECONNABORTED,e,p)),p=null},ge.isStandardBrowserEnv){const t=ct(u)&&e.xsrfCookieName&&rt.read(e.xsrfCookieName);t&&i.set(e.xsrfHeaderName,t)}void 0===a&&i.setContentType(null),"setRequestHeader"in p&&ae.forEach(i.toJSON(),(function(e,t){p.setRequestHeader(t,e)})),ae.isUndefined(e.withCredentials)||(p.withCredentials=!!e.withCredentials),o&&"json"!==o&&(p.responseType=e.responseType),"function"==typeof e.onDownloadProgress&&p.addEventListener("progress",pt(e.onDownloadProgress,!0)),"function"==typeof e.onUploadProgress&&p.upload&&p.upload.addEventListener("progress",pt(e.onUploadProgress)),(e.cancelToken||e.signal)&&(s=t=>{p&&(n(!t||t.type?new Te(null,e,p):t),p.abort(),p=null)},e.cancelToken&&e.cancelToken.subscribe(s),e.signal&&(e.signal.aborted?s():e.signal.addEventListener("abort",s)));const d=Me(u);d&&-1===ge.protocols.indexOf(d)?n(new ie("Unsupported protocol "+d+":",ie.ERR_BAD_REQUEST,e)):p.send(a||null)}))}};ae.forEach(ut,((e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}}));const lt=e=>`- ${e}`,dt=e=>ae.isFunction(e)||null===e||!1===e,mt=e=>{e=ae.isArray(e)?e:[e];const{length:t}=e;let n,a;const i={};for(let o=0;o`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build")));throw new ie("There is no suitable adapter to dispatch the request "+(t?e.length>1?"since :\n"+e.map(lt).join("\n"):" "+lt(e[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return a};function ft(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Te(null,e)}function ht(e){ft(e),e.headers=Se.from(e.headers),e.data=Ee.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1);return mt(e.adapter||we.adapter)(e).then((function(t){return ft(e),t.data=Ee.call(e,e.transformResponse,t),t.headers=Se.from(t.headers),t}),(function(t){return Ce(t)||(ft(e),t&&t.response&&(t.response.data=Ee.call(e,e.transformResponse,t.response),t.response.headers=Se.from(t.response.headers))),Promise.reject(t)}))}const vt=e=>e instanceof Se?e.toJSON():e;function xt(e,t){t=t||{};const n={};function a(e,t,n){return ae.isPlainObject(e)&&ae.isPlainObject(t)?ae.merge.call({caseless:n},e,t):ae.isPlainObject(t)?ae.merge({},t):ae.isArray(t)?t.slice():t}function i(e,t,n){return ae.isUndefined(t)?ae.isUndefined(e)?void 0:a(void 0,e,n):a(e,t,n)}function o(e,t){if(!ae.isUndefined(t))return a(void 0,t)}function s(e,t){return ae.isUndefined(t)?ae.isUndefined(e)?void 0:a(void 0,e):a(void 0,t)}function r(n,i,o){return o in t?a(n,i):o in e?a(void 0,n):void 0}const c={url:o,method:o,data:o,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:r,headers:(e,t)=>i(vt(e),vt(t),!0)};return ae.forEach(Object.keys(Object.assign({},e,t)),(function(a){const o=c[a]||i,s=o(e[a],t[a],a);ae.isUndefined(s)&&o!==r||(n[a]=s)})),n}const bt={};["object","boolean","number","function","string","symbol"].forEach(((e,t)=>{bt[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}}));const gt={};bt.transitional=function(e,t,n){function a(e,t){return"[Axios v1.6.0] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,i,o)=>{if(!1===e)throw new ie(a(i," has been removed"+(t?" in "+t:"")),ie.ERR_DEPRECATED);return t&&!gt[i]&&(gt[i]=!0,console.warn(a(i," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,i,o)}};const yt={assertOptions:function(e,t,n){if("object"!=typeof e)throw new ie("options must be an object",ie.ERR_BAD_OPTION_VALUE);const a=Object.keys(e);let i=a.length;for(;i-- >0;){const o=a[i],s=t[o];if(s){const t=e[o],n=void 0===t||s(t,o,e);if(!0!==n)throw new ie("option "+o+" must be "+n,ie.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new ie("Unknown option "+o,ie.ERR_BAD_OPTION)}},validators:bt},_t=yt.validators;class Axios{constructor(e){this.defaults=e,this.interceptors={request:new xe,response:new xe}}request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=xt(this.defaults,t);const{transitional:n,paramsSerializer:a,headers:i}=t;void 0!==n&&yt.assertOptions(n,{silentJSONParsing:_t.transitional(_t.boolean),forcedJSONParsing:_t.transitional(_t.boolean),clarifyTimeoutError:_t.transitional(_t.boolean)},!1),null!=a&&(ae.isFunction(a)?t.paramsSerializer={serialize:a}:yt.assertOptions(a,{encode:_t.function,serialize:_t.function},!0)),t.method=(t.method||this.defaults.method||"get").toLowerCase();let o=i&&ae.merge(i.common,i[t.method]);i&&ae.forEach(["delete","get","head","post","put","patch","common"],(e=>{delete i[e]})),t.headers=Se.concat(o,i);const s=[];let r=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(r=r&&e.synchronous,s.unshift(e.fulfilled,e.rejected))}));const c=[];let p;this.interceptors.response.forEach((function(e){c.push(e.fulfilled,e.rejected)}));let u,l=0;if(!r){const e=[ht.bind(this),void 0];for(e.unshift.apply(e,s),e.push.apply(e,c),u=e.length,p=Promise.resolve(t);l{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null})),this.promise.then=e=>{let t;const a=new Promise((e=>{n.subscribe(e),t=e})).then(e);return a.cancel=function(){n.unsubscribe(t)},a},e((function(e,a,i){n.reason||(n.reason=new Te(e,a,i),t(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}static source(){let e;return{token:new CancelToken((function(t){e=t})),cancel:e}}}const jt=CancelToken;const Ot={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ot).forEach((([e,t])=>{Ot[t]=e}));const kt=Ot;const Pt=function e(t){const n=new wt(t),a=j(wt.prototype.request,n);return ae.extend(a,wt.prototype,n,{allOwnKeys:!0}),ae.extend(a,n,null,{allOwnKeys:!0}),a.create=function(n){return e(xt(t,n))},a}(we);Pt.Axios=wt,Pt.CanceledError=Te,Pt.CancelToken=jt,Pt.isCancel=Ce,Pt.VERSION=De,Pt.toFormData=le,Pt.AxiosError=ie,Pt.Cancel=Pt.CanceledError,Pt.all=function(e){return Promise.all(e)},Pt.spread=function(e){return function(t){return e.apply(null,t)}},Pt.isAxiosError=function(e){return ae.isObject(e)&&!0===e.isAxiosError},Pt.mergeConfig=xt,Pt.AxiosHeaders=Se,Pt.formToJSON=e=>ye(ae.isHTMLForm(e)?new FormData(e):e),Pt.getAdapter=mt,Pt.HttpStatusCode=kt,Pt.default=Pt,e.exports=Pt},3765:e=>{"use strict";e.exports=JSON.parse('{"application/1d-interleaved-parityfec":{"source":"iana"},"application/3gpdash-qoe-report+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/3gpp-ims+xml":{"source":"iana","compressible":true},"application/3gpphal+json":{"source":"iana","compressible":true},"application/3gpphalforms+json":{"source":"iana","compressible":true},"application/a2l":{"source":"iana"},"application/ace+cbor":{"source":"iana"},"application/activemessage":{"source":"iana"},"application/activity+json":{"source":"iana","compressible":true},"application/alto-costmap+json":{"source":"iana","compressible":true},"application/alto-costmapfilter+json":{"source":"iana","compressible":true},"application/alto-directory+json":{"source":"iana","compressible":true},"application/alto-endpointcost+json":{"source":"iana","compressible":true},"application/alto-endpointcostparams+json":{"source":"iana","compressible":true},"application/alto-endpointprop+json":{"source":"iana","compressible":true},"application/alto-endpointpropparams+json":{"source":"iana","compressible":true},"application/alto-error+json":{"source":"iana","compressible":true},"application/alto-networkmap+json":{"source":"iana","compressible":true},"application/alto-networkmapfilter+json":{"source":"iana","compressible":true},"application/alto-updatestreamcontrol+json":{"source":"iana","compressible":true},"application/alto-updatestreamparams+json":{"source":"iana","compressible":true},"application/aml":{"source":"iana"},"application/andrew-inset":{"source":"iana","extensions":["ez"]},"application/applefile":{"source":"iana"},"application/applixware":{"source":"apache","extensions":["aw"]},"application/at+jwt":{"source":"iana"},"application/atf":{"source":"iana"},"application/atfx":{"source":"iana"},"application/atom+xml":{"source":"iana","compressible":true,"extensions":["atom"]},"application/atomcat+xml":{"source":"iana","compressible":true,"extensions":["atomcat"]},"application/atomdeleted+xml":{"source":"iana","compressible":true,"extensions":["atomdeleted"]},"application/atomicmail":{"source":"iana"},"application/atomsvc+xml":{"source":"iana","compressible":true,"extensions":["atomsvc"]},"application/atsc-dwd+xml":{"source":"iana","compressible":true,"extensions":["dwd"]},"application/atsc-dynamic-event-message":{"source":"iana"},"application/atsc-held+xml":{"source":"iana","compressible":true,"extensions":["held"]},"application/atsc-rdt+json":{"source":"iana","compressible":true},"application/atsc-rsat+xml":{"source":"iana","compressible":true,"extensions":["rsat"]},"application/atxml":{"source":"iana"},"application/auth-policy+xml":{"source":"iana","compressible":true},"application/bacnet-xdd+zip":{"source":"iana","compressible":false},"application/batch-smtp":{"source":"iana"},"application/bdoc":{"compressible":false,"extensions":["bdoc"]},"application/beep+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/calendar+json":{"source":"iana","compressible":true},"application/calendar+xml":{"source":"iana","compressible":true,"extensions":["xcs"]},"application/call-completion":{"source":"iana"},"application/cals-1840":{"source":"iana"},"application/captive+json":{"source":"iana","compressible":true},"application/cbor":{"source":"iana"},"application/cbor-seq":{"source":"iana"},"application/cccex":{"source":"iana"},"application/ccmp+xml":{"source":"iana","compressible":true},"application/ccxml+xml":{"source":"iana","compressible":true,"extensions":["ccxml"]},"application/cdfx+xml":{"source":"iana","compressible":true,"extensions":["cdfx"]},"application/cdmi-capability":{"source":"iana","extensions":["cdmia"]},"application/cdmi-container":{"source":"iana","extensions":["cdmic"]},"application/cdmi-domain":{"source":"iana","extensions":["cdmid"]},"application/cdmi-object":{"source":"iana","extensions":["cdmio"]},"application/cdmi-queue":{"source":"iana","extensions":["cdmiq"]},"application/cdni":{"source":"iana"},"application/cea":{"source":"iana"},"application/cea-2018+xml":{"source":"iana","compressible":true},"application/cellml+xml":{"source":"iana","compressible":true},"application/cfw":{"source":"iana"},"application/city+json":{"source":"iana","compressible":true},"application/clr":{"source":"iana"},"application/clue+xml":{"source":"iana","compressible":true},"application/clue_info+xml":{"source":"iana","compressible":true},"application/cms":{"source":"iana"},"application/cnrp+xml":{"source":"iana","compressible":true},"application/coap-group+json":{"source":"iana","compressible":true},"application/coap-payload":{"source":"iana"},"application/commonground":{"source":"iana"},"application/conference-info+xml":{"source":"iana","compressible":true},"application/cose":{"source":"iana"},"application/cose-key":{"source":"iana"},"application/cose-key-set":{"source":"iana"},"application/cpl+xml":{"source":"iana","compressible":true,"extensions":["cpl"]},"application/csrattrs":{"source":"iana"},"application/csta+xml":{"source":"iana","compressible":true},"application/cstadata+xml":{"source":"iana","compressible":true},"application/csvm+json":{"source":"iana","compressible":true},"application/cu-seeme":{"source":"apache","extensions":["cu"]},"application/cwt":{"source":"iana"},"application/cybercash":{"source":"iana"},"application/dart":{"compressible":true},"application/dash+xml":{"source":"iana","compressible":true,"extensions":["mpd"]},"application/dash-patch+xml":{"source":"iana","compressible":true,"extensions":["mpp"]},"application/dashdelta":{"source":"iana"},"application/davmount+xml":{"source":"iana","compressible":true,"extensions":["davmount"]},"application/dca-rft":{"source":"iana"},"application/dcd":{"source":"iana"},"application/dec-dx":{"source":"iana"},"application/dialog-info+xml":{"source":"iana","compressible":true},"application/dicom":{"source":"iana"},"application/dicom+json":{"source":"iana","compressible":true},"application/dicom+xml":{"source":"iana","compressible":true},"application/dii":{"source":"iana"},"application/dit":{"source":"iana"},"application/dns":{"source":"iana"},"application/dns+json":{"source":"iana","compressible":true},"application/dns-message":{"source":"iana"},"application/docbook+xml":{"source":"apache","compressible":true,"extensions":["dbk"]},"application/dots+cbor":{"source":"iana"},"application/dskpp+xml":{"source":"iana","compressible":true},"application/dssc+der":{"source":"iana","extensions":["dssc"]},"application/dssc+xml":{"source":"iana","compressible":true,"extensions":["xdssc"]},"application/dvcs":{"source":"iana"},"application/ecmascript":{"source":"iana","compressible":true,"extensions":["es","ecma"]},"application/edi-consent":{"source":"iana"},"application/edi-x12":{"source":"iana","compressible":false},"application/edifact":{"source":"iana","compressible":false},"application/efi":{"source":"iana"},"application/elm+json":{"source":"iana","charset":"UTF-8","compressible":true},"application/elm+xml":{"source":"iana","compressible":true},"application/emergencycalldata.cap+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/emergencycalldata.comment+xml":{"source":"iana","compressible":true},"application/emergencycalldata.control+xml":{"source":"iana","compressible":true},"application/emergencycalldata.deviceinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.ecall.msd":{"source":"iana"},"application/emergencycalldata.providerinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.serviceinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.subscriberinfo+xml":{"source":"iana","compressible":true},"application/emergencycalldata.veds+xml":{"source":"iana","compressible":true},"application/emma+xml":{"source":"iana","compressible":true,"extensions":["emma"]},"application/emotionml+xml":{"source":"iana","compressible":true,"extensions":["emotionml"]},"application/encaprtp":{"source":"iana"},"application/epp+xml":{"source":"iana","compressible":true},"application/epub+zip":{"source":"iana","compressible":false,"extensions":["epub"]},"application/eshop":{"source":"iana"},"application/exi":{"source":"iana","extensions":["exi"]},"application/expect-ct-report+json":{"source":"iana","compressible":true},"application/express":{"source":"iana","extensions":["exp"]},"application/fastinfoset":{"source":"iana"},"application/fastsoap":{"source":"iana"},"application/fdt+xml":{"source":"iana","compressible":true,"extensions":["fdt"]},"application/fhir+json":{"source":"iana","charset":"UTF-8","compressible":true},"application/fhir+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/fido.trusted-apps+json":{"compressible":true},"application/fits":{"source":"iana"},"application/flexfec":{"source":"iana"},"application/font-sfnt":{"source":"iana"},"application/font-tdpfr":{"source":"iana","extensions":["pfr"]},"application/font-woff":{"source":"iana","compressible":false},"application/framework-attributes+xml":{"source":"iana","compressible":true},"application/geo+json":{"source":"iana","compressible":true,"extensions":["geojson"]},"application/geo+json-seq":{"source":"iana"},"application/geopackage+sqlite3":{"source":"iana"},"application/geoxacml+xml":{"source":"iana","compressible":true},"application/gltf-buffer":{"source":"iana"},"application/gml+xml":{"source":"iana","compressible":true,"extensions":["gml"]},"application/gpx+xml":{"source":"apache","compressible":true,"extensions":["gpx"]},"application/gxf":{"source":"apache","extensions":["gxf"]},"application/gzip":{"source":"iana","compressible":false,"extensions":["gz"]},"application/h224":{"source":"iana"},"application/held+xml":{"source":"iana","compressible":true},"application/hjson":{"extensions":["hjson"]},"application/http":{"source":"iana"},"application/hyperstudio":{"source":"iana","extensions":["stk"]},"application/ibe-key-request+xml":{"source":"iana","compressible":true},"application/ibe-pkg-reply+xml":{"source":"iana","compressible":true},"application/ibe-pp-data":{"source":"iana"},"application/iges":{"source":"iana"},"application/im-iscomposing+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/index":{"source":"iana"},"application/index.cmd":{"source":"iana"},"application/index.obj":{"source":"iana"},"application/index.response":{"source":"iana"},"application/index.vnd":{"source":"iana"},"application/inkml+xml":{"source":"iana","compressible":true,"extensions":["ink","inkml"]},"application/iotp":{"source":"iana"},"application/ipfix":{"source":"iana","extensions":["ipfix"]},"application/ipp":{"source":"iana"},"application/isup":{"source":"iana"},"application/its+xml":{"source":"iana","compressible":true,"extensions":["its"]},"application/java-archive":{"source":"apache","compressible":false,"extensions":["jar","war","ear"]},"application/java-serialized-object":{"source":"apache","compressible":false,"extensions":["ser"]},"application/java-vm":{"source":"apache","compressible":false,"extensions":["class"]},"application/javascript":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["js","mjs"]},"application/jf2feed+json":{"source":"iana","compressible":true},"application/jose":{"source":"iana"},"application/jose+json":{"source":"iana","compressible":true},"application/jrd+json":{"source":"iana","compressible":true},"application/jscalendar+json":{"source":"iana","compressible":true},"application/json":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["json","map"]},"application/json-patch+json":{"source":"iana","compressible":true},"application/json-seq":{"source":"iana"},"application/json5":{"extensions":["json5"]},"application/jsonml+json":{"source":"apache","compressible":true,"extensions":["jsonml"]},"application/jwk+json":{"source":"iana","compressible":true},"application/jwk-set+json":{"source":"iana","compressible":true},"application/jwt":{"source":"iana"},"application/kpml-request+xml":{"source":"iana","compressible":true},"application/kpml-response+xml":{"source":"iana","compressible":true},"application/ld+json":{"source":"iana","compressible":true,"extensions":["jsonld"]},"application/lgr+xml":{"source":"iana","compressible":true,"extensions":["lgr"]},"application/link-format":{"source":"iana"},"application/load-control+xml":{"source":"iana","compressible":true},"application/lost+xml":{"source":"iana","compressible":true,"extensions":["lostxml"]},"application/lostsync+xml":{"source":"iana","compressible":true},"application/lpf+zip":{"source":"iana","compressible":false},"application/lxf":{"source":"iana"},"application/mac-binhex40":{"source":"iana","extensions":["hqx"]},"application/mac-compactpro":{"source":"apache","extensions":["cpt"]},"application/macwriteii":{"source":"iana"},"application/mads+xml":{"source":"iana","compressible":true,"extensions":["mads"]},"application/manifest+json":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["webmanifest"]},"application/marc":{"source":"iana","extensions":["mrc"]},"application/marcxml+xml":{"source":"iana","compressible":true,"extensions":["mrcx"]},"application/mathematica":{"source":"iana","extensions":["ma","nb","mb"]},"application/mathml+xml":{"source":"iana","compressible":true,"extensions":["mathml"]},"application/mathml-content+xml":{"source":"iana","compressible":true},"application/mathml-presentation+xml":{"source":"iana","compressible":true},"application/mbms-associated-procedure-description+xml":{"source":"iana","compressible":true},"application/mbms-deregister+xml":{"source":"iana","compressible":true},"application/mbms-envelope+xml":{"source":"iana","compressible":true},"application/mbms-msk+xml":{"source":"iana","compressible":true},"application/mbms-msk-response+xml":{"source":"iana","compressible":true},"application/mbms-protection-description+xml":{"source":"iana","compressible":true},"application/mbms-reception-report+xml":{"source":"iana","compressible":true},"application/mbms-register+xml":{"source":"iana","compressible":true},"application/mbms-register-response+xml":{"source":"iana","compressible":true},"application/mbms-schedule+xml":{"source":"iana","compressible":true},"application/mbms-user-service-description+xml":{"source":"iana","compressible":true},"application/mbox":{"source":"iana","extensions":["mbox"]},"application/media-policy-dataset+xml":{"source":"iana","compressible":true,"extensions":["mpf"]},"application/media_control+xml":{"source":"iana","compressible":true},"application/mediaservercontrol+xml":{"source":"iana","compressible":true,"extensions":["mscml"]},"application/merge-patch+json":{"source":"iana","compressible":true},"application/metalink+xml":{"source":"apache","compressible":true,"extensions":["metalink"]},"application/metalink4+xml":{"source":"iana","compressible":true,"extensions":["meta4"]},"application/mets+xml":{"source":"iana","compressible":true,"extensions":["mets"]},"application/mf4":{"source":"iana"},"application/mikey":{"source":"iana"},"application/mipc":{"source":"iana"},"application/missing-blocks+cbor-seq":{"source":"iana"},"application/mmt-aei+xml":{"source":"iana","compressible":true,"extensions":["maei"]},"application/mmt-usd+xml":{"source":"iana","compressible":true,"extensions":["musd"]},"application/mods+xml":{"source":"iana","compressible":true,"extensions":["mods"]},"application/moss-keys":{"source":"iana"},"application/moss-signature":{"source":"iana"},"application/mosskey-data":{"source":"iana"},"application/mosskey-request":{"source":"iana"},"application/mp21":{"source":"iana","extensions":["m21","mp21"]},"application/mp4":{"source":"iana","extensions":["mp4s","m4p"]},"application/mpeg4-generic":{"source":"iana"},"application/mpeg4-iod":{"source":"iana"},"application/mpeg4-iod-xmt":{"source":"iana"},"application/mrb-consumer+xml":{"source":"iana","compressible":true},"application/mrb-publish+xml":{"source":"iana","compressible":true},"application/msc-ivr+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/msc-mixer+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/msword":{"source":"iana","compressible":false,"extensions":["doc","dot"]},"application/mud+json":{"source":"iana","compressible":true},"application/multipart-core":{"source":"iana"},"application/mxf":{"source":"iana","extensions":["mxf"]},"application/n-quads":{"source":"iana","extensions":["nq"]},"application/n-triples":{"source":"iana","extensions":["nt"]},"application/nasdata":{"source":"iana"},"application/news-checkgroups":{"source":"iana","charset":"US-ASCII"},"application/news-groupinfo":{"source":"iana","charset":"US-ASCII"},"application/news-transmission":{"source":"iana"},"application/nlsml+xml":{"source":"iana","compressible":true},"application/node":{"source":"iana","extensions":["cjs"]},"application/nss":{"source":"iana"},"application/oauth-authz-req+jwt":{"source":"iana"},"application/oblivious-dns-message":{"source":"iana"},"application/ocsp-request":{"source":"iana"},"application/ocsp-response":{"source":"iana"},"application/octet-stream":{"source":"iana","compressible":false,"extensions":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]},"application/oda":{"source":"iana","extensions":["oda"]},"application/odm+xml":{"source":"iana","compressible":true},"application/odx":{"source":"iana"},"application/oebps-package+xml":{"source":"iana","compressible":true,"extensions":["opf"]},"application/ogg":{"source":"iana","compressible":false,"extensions":["ogx"]},"application/omdoc+xml":{"source":"apache","compressible":true,"extensions":["omdoc"]},"application/onenote":{"source":"apache","extensions":["onetoc","onetoc2","onetmp","onepkg"]},"application/opc-nodeset+xml":{"source":"iana","compressible":true},"application/oscore":{"source":"iana"},"application/oxps":{"source":"iana","extensions":["oxps"]},"application/p21":{"source":"iana"},"application/p21+zip":{"source":"iana","compressible":false},"application/p2p-overlay+xml":{"source":"iana","compressible":true,"extensions":["relo"]},"application/parityfec":{"source":"iana"},"application/passport":{"source":"iana"},"application/patch-ops-error+xml":{"source":"iana","compressible":true,"extensions":["xer"]},"application/pdf":{"source":"iana","compressible":false,"extensions":["pdf"]},"application/pdx":{"source":"iana"},"application/pem-certificate-chain":{"source":"iana"},"application/pgp-encrypted":{"source":"iana","compressible":false,"extensions":["pgp"]},"application/pgp-keys":{"source":"iana","extensions":["asc"]},"application/pgp-signature":{"source":"iana","extensions":["asc","sig"]},"application/pics-rules":{"source":"apache","extensions":["prf"]},"application/pidf+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/pidf-diff+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/pkcs10":{"source":"iana","extensions":["p10"]},"application/pkcs12":{"source":"iana"},"application/pkcs7-mime":{"source":"iana","extensions":["p7m","p7c"]},"application/pkcs7-signature":{"source":"iana","extensions":["p7s"]},"application/pkcs8":{"source":"iana","extensions":["p8"]},"application/pkcs8-encrypted":{"source":"iana"},"application/pkix-attr-cert":{"source":"iana","extensions":["ac"]},"application/pkix-cert":{"source":"iana","extensions":["cer"]},"application/pkix-crl":{"source":"iana","extensions":["crl"]},"application/pkix-pkipath":{"source":"iana","extensions":["pkipath"]},"application/pkixcmp":{"source":"iana","extensions":["pki"]},"application/pls+xml":{"source":"iana","compressible":true,"extensions":["pls"]},"application/poc-settings+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/postscript":{"source":"iana","compressible":true,"extensions":["ai","eps","ps"]},"application/ppsp-tracker+json":{"source":"iana","compressible":true},"application/problem+json":{"source":"iana","compressible":true},"application/problem+xml":{"source":"iana","compressible":true},"application/provenance+xml":{"source":"iana","compressible":true,"extensions":["provx"]},"application/prs.alvestrand.titrax-sheet":{"source":"iana"},"application/prs.cww":{"source":"iana","extensions":["cww"]},"application/prs.cyn":{"source":"iana","charset":"7-BIT"},"application/prs.hpub+zip":{"source":"iana","compressible":false},"application/prs.nprend":{"source":"iana"},"application/prs.plucker":{"source":"iana"},"application/prs.rdf-xml-crypt":{"source":"iana"},"application/prs.xsf+xml":{"source":"iana","compressible":true},"application/pskc+xml":{"source":"iana","compressible":true,"extensions":["pskcxml"]},"application/pvd+json":{"source":"iana","compressible":true},"application/qsig":{"source":"iana"},"application/raml+yaml":{"compressible":true,"extensions":["raml"]},"application/raptorfec":{"source":"iana"},"application/rdap+json":{"source":"iana","compressible":true},"application/rdf+xml":{"source":"iana","compressible":true,"extensions":["rdf","owl"]},"application/reginfo+xml":{"source":"iana","compressible":true,"extensions":["rif"]},"application/relax-ng-compact-syntax":{"source":"iana","extensions":["rnc"]},"application/remote-printing":{"source":"iana"},"application/reputon+json":{"source":"iana","compressible":true},"application/resource-lists+xml":{"source":"iana","compressible":true,"extensions":["rl"]},"application/resource-lists-diff+xml":{"source":"iana","compressible":true,"extensions":["rld"]},"application/rfc+xml":{"source":"iana","compressible":true},"application/riscos":{"source":"iana"},"application/rlmi+xml":{"source":"iana","compressible":true},"application/rls-services+xml":{"source":"iana","compressible":true,"extensions":["rs"]},"application/route-apd+xml":{"source":"iana","compressible":true,"extensions":["rapd"]},"application/route-s-tsid+xml":{"source":"iana","compressible":true,"extensions":["sls"]},"application/route-usd+xml":{"source":"iana","compressible":true,"extensions":["rusd"]},"application/rpki-ghostbusters":{"source":"iana","extensions":["gbr"]},"application/rpki-manifest":{"source":"iana","extensions":["mft"]},"application/rpki-publication":{"source":"iana"},"application/rpki-roa":{"source":"iana","extensions":["roa"]},"application/rpki-updown":{"source":"iana"},"application/rsd+xml":{"source":"apache","compressible":true,"extensions":["rsd"]},"application/rss+xml":{"source":"apache","compressible":true,"extensions":["rss"]},"application/rtf":{"source":"iana","compressible":true,"extensions":["rtf"]},"application/rtploopback":{"source":"iana"},"application/rtx":{"source":"iana"},"application/samlassertion+xml":{"source":"iana","compressible":true},"application/samlmetadata+xml":{"source":"iana","compressible":true},"application/sarif+json":{"source":"iana","compressible":true},"application/sarif-external-properties+json":{"source":"iana","compressible":true},"application/sbe":{"source":"iana"},"application/sbml+xml":{"source":"iana","compressible":true,"extensions":["sbml"]},"application/scaip+xml":{"source":"iana","compressible":true},"application/scim+json":{"source":"iana","compressible":true},"application/scvp-cv-request":{"source":"iana","extensions":["scq"]},"application/scvp-cv-response":{"source":"iana","extensions":["scs"]},"application/scvp-vp-request":{"source":"iana","extensions":["spq"]},"application/scvp-vp-response":{"source":"iana","extensions":["spp"]},"application/sdp":{"source":"iana","extensions":["sdp"]},"application/secevent+jwt":{"source":"iana"},"application/senml+cbor":{"source":"iana"},"application/senml+json":{"source":"iana","compressible":true},"application/senml+xml":{"source":"iana","compressible":true,"extensions":["senmlx"]},"application/senml-etch+cbor":{"source":"iana"},"application/senml-etch+json":{"source":"iana","compressible":true},"application/senml-exi":{"source":"iana"},"application/sensml+cbor":{"source":"iana"},"application/sensml+json":{"source":"iana","compressible":true},"application/sensml+xml":{"source":"iana","compressible":true,"extensions":["sensmlx"]},"application/sensml-exi":{"source":"iana"},"application/sep+xml":{"source":"iana","compressible":true},"application/sep-exi":{"source":"iana"},"application/session-info":{"source":"iana"},"application/set-payment":{"source":"iana"},"application/set-payment-initiation":{"source":"iana","extensions":["setpay"]},"application/set-registration":{"source":"iana"},"application/set-registration-initiation":{"source":"iana","extensions":["setreg"]},"application/sgml":{"source":"iana"},"application/sgml-open-catalog":{"source":"iana"},"application/shf+xml":{"source":"iana","compressible":true,"extensions":["shf"]},"application/sieve":{"source":"iana","extensions":["siv","sieve"]},"application/simple-filter+xml":{"source":"iana","compressible":true},"application/simple-message-summary":{"source":"iana"},"application/simplesymbolcontainer":{"source":"iana"},"application/sipc":{"source":"iana"},"application/slate":{"source":"iana"},"application/smil":{"source":"iana"},"application/smil+xml":{"source":"iana","compressible":true,"extensions":["smi","smil"]},"application/smpte336m":{"source":"iana"},"application/soap+fastinfoset":{"source":"iana"},"application/soap+xml":{"source":"iana","compressible":true},"application/sparql-query":{"source":"iana","extensions":["rq"]},"application/sparql-results+xml":{"source":"iana","compressible":true,"extensions":["srx"]},"application/spdx+json":{"source":"iana","compressible":true},"application/spirits-event+xml":{"source":"iana","compressible":true},"application/sql":{"source":"iana"},"application/srgs":{"source":"iana","extensions":["gram"]},"application/srgs+xml":{"source":"iana","compressible":true,"extensions":["grxml"]},"application/sru+xml":{"source":"iana","compressible":true,"extensions":["sru"]},"application/ssdl+xml":{"source":"apache","compressible":true,"extensions":["ssdl"]},"application/ssml+xml":{"source":"iana","compressible":true,"extensions":["ssml"]},"application/stix+json":{"source":"iana","compressible":true},"application/swid+xml":{"source":"iana","compressible":true,"extensions":["swidtag"]},"application/tamp-apex-update":{"source":"iana"},"application/tamp-apex-update-confirm":{"source":"iana"},"application/tamp-community-update":{"source":"iana"},"application/tamp-community-update-confirm":{"source":"iana"},"application/tamp-error":{"source":"iana"},"application/tamp-sequence-adjust":{"source":"iana"},"application/tamp-sequence-adjust-confirm":{"source":"iana"},"application/tamp-status-query":{"source":"iana"},"application/tamp-status-response":{"source":"iana"},"application/tamp-update":{"source":"iana"},"application/tamp-update-confirm":{"source":"iana"},"application/tar":{"compressible":true},"application/taxii+json":{"source":"iana","compressible":true},"application/td+json":{"source":"iana","compressible":true},"application/tei+xml":{"source":"iana","compressible":true,"extensions":["tei","teicorpus"]},"application/tetra_isi":{"source":"iana"},"application/thraud+xml":{"source":"iana","compressible":true,"extensions":["tfi"]},"application/timestamp-query":{"source":"iana"},"application/timestamp-reply":{"source":"iana"},"application/timestamped-data":{"source":"iana","extensions":["tsd"]},"application/tlsrpt+gzip":{"source":"iana"},"application/tlsrpt+json":{"source":"iana","compressible":true},"application/tnauthlist":{"source":"iana"},"application/token-introspection+jwt":{"source":"iana"},"application/toml":{"compressible":true,"extensions":["toml"]},"application/trickle-ice-sdpfrag":{"source":"iana"},"application/trig":{"source":"iana","extensions":["trig"]},"application/ttml+xml":{"source":"iana","compressible":true,"extensions":["ttml"]},"application/tve-trigger":{"source":"iana"},"application/tzif":{"source":"iana"},"application/tzif-leap":{"source":"iana"},"application/ubjson":{"compressible":false,"extensions":["ubj"]},"application/ulpfec":{"source":"iana"},"application/urc-grpsheet+xml":{"source":"iana","compressible":true},"application/urc-ressheet+xml":{"source":"iana","compressible":true,"extensions":["rsheet"]},"application/urc-targetdesc+xml":{"source":"iana","compressible":true,"extensions":["td"]},"application/urc-uisocketdesc+xml":{"source":"iana","compressible":true},"application/vcard+json":{"source":"iana","compressible":true},"application/vcard+xml":{"source":"iana","compressible":true},"application/vemmi":{"source":"iana"},"application/vividence.scriptfile":{"source":"apache"},"application/vnd.1000minds.decision-model+xml":{"source":"iana","compressible":true,"extensions":["1km"]},"application/vnd.3gpp-prose+xml":{"source":"iana","compressible":true},"application/vnd.3gpp-prose-pc3ch+xml":{"source":"iana","compressible":true},"application/vnd.3gpp-v2x-local-service-information":{"source":"iana"},"application/vnd.3gpp.5gnas":{"source":"iana"},"application/vnd.3gpp.access-transfer-events+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.bsf+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.gmop+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.gtpc":{"source":"iana"},"application/vnd.3gpp.interworking-data":{"source":"iana"},"application/vnd.3gpp.lpp":{"source":"iana"},"application/vnd.3gpp.mc-signalling-ear":{"source":"iana"},"application/vnd.3gpp.mcdata-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-payload":{"source":"iana"},"application/vnd.3gpp.mcdata-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-signalling":{"source":"iana"},"application/vnd.3gpp.mcdata-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcdata-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-floor-request+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-location-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-mbms-usage-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-signed+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-ue-init-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcptt-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-affiliation-command+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-affiliation-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-location-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-mbms-usage-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-service-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-transmission-request+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-ue-config+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mcvideo-user-profile+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.mid-call+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.ngap":{"source":"iana"},"application/vnd.3gpp.pfcp":{"source":"iana"},"application/vnd.3gpp.pic-bw-large":{"source":"iana","extensions":["plb"]},"application/vnd.3gpp.pic-bw-small":{"source":"iana","extensions":["psb"]},"application/vnd.3gpp.pic-bw-var":{"source":"iana","extensions":["pvb"]},"application/vnd.3gpp.s1ap":{"source":"iana"},"application/vnd.3gpp.sms":{"source":"iana"},"application/vnd.3gpp.sms+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.srvcc-ext+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.srvcc-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.state-and-event-info+xml":{"source":"iana","compressible":true},"application/vnd.3gpp.ussd+xml":{"source":"iana","compressible":true},"application/vnd.3gpp2.bcmcsinfo+xml":{"source":"iana","compressible":true},"application/vnd.3gpp2.sms":{"source":"iana"},"application/vnd.3gpp2.tcap":{"source":"iana","extensions":["tcap"]},"application/vnd.3lightssoftware.imagescal":{"source":"iana"},"application/vnd.3m.post-it-notes":{"source":"iana","extensions":["pwn"]},"application/vnd.accpac.simply.aso":{"source":"iana","extensions":["aso"]},"application/vnd.accpac.simply.imp":{"source":"iana","extensions":["imp"]},"application/vnd.acucobol":{"source":"iana","extensions":["acu"]},"application/vnd.acucorp":{"source":"iana","extensions":["atc","acutc"]},"application/vnd.adobe.air-application-installer-package+zip":{"source":"apache","compressible":false,"extensions":["air"]},"application/vnd.adobe.flash.movie":{"source":"iana"},"application/vnd.adobe.formscentral.fcdt":{"source":"iana","extensions":["fcdt"]},"application/vnd.adobe.fxp":{"source":"iana","extensions":["fxp","fxpl"]},"application/vnd.adobe.partial-upload":{"source":"iana"},"application/vnd.adobe.xdp+xml":{"source":"iana","compressible":true,"extensions":["xdp"]},"application/vnd.adobe.xfdf":{"source":"iana","extensions":["xfdf"]},"application/vnd.aether.imp":{"source":"iana"},"application/vnd.afpc.afplinedata":{"source":"iana"},"application/vnd.afpc.afplinedata-pagedef":{"source":"iana"},"application/vnd.afpc.cmoca-cmresource":{"source":"iana"},"application/vnd.afpc.foca-charset":{"source":"iana"},"application/vnd.afpc.foca-codedfont":{"source":"iana"},"application/vnd.afpc.foca-codepage":{"source":"iana"},"application/vnd.afpc.modca":{"source":"iana"},"application/vnd.afpc.modca-cmtable":{"source":"iana"},"application/vnd.afpc.modca-formdef":{"source":"iana"},"application/vnd.afpc.modca-mediummap":{"source":"iana"},"application/vnd.afpc.modca-objectcontainer":{"source":"iana"},"application/vnd.afpc.modca-overlay":{"source":"iana"},"application/vnd.afpc.modca-pagesegment":{"source":"iana"},"application/vnd.age":{"source":"iana","extensions":["age"]},"application/vnd.ah-barcode":{"source":"iana"},"application/vnd.ahead.space":{"source":"iana","extensions":["ahead"]},"application/vnd.airzip.filesecure.azf":{"source":"iana","extensions":["azf"]},"application/vnd.airzip.filesecure.azs":{"source":"iana","extensions":["azs"]},"application/vnd.amadeus+json":{"source":"iana","compressible":true},"application/vnd.amazon.ebook":{"source":"apache","extensions":["azw"]},"application/vnd.amazon.mobi8-ebook":{"source":"iana"},"application/vnd.americandynamics.acc":{"source":"iana","extensions":["acc"]},"application/vnd.amiga.ami":{"source":"iana","extensions":["ami"]},"application/vnd.amundsen.maze+xml":{"source":"iana","compressible":true},"application/vnd.android.ota":{"source":"iana"},"application/vnd.android.package-archive":{"source":"apache","compressible":false,"extensions":["apk"]},"application/vnd.anki":{"source":"iana"},"application/vnd.anser-web-certificate-issue-initiation":{"source":"iana","extensions":["cii"]},"application/vnd.anser-web-funds-transfer-initiation":{"source":"apache","extensions":["fti"]},"application/vnd.antix.game-component":{"source":"iana","extensions":["atx"]},"application/vnd.apache.arrow.file":{"source":"iana"},"application/vnd.apache.arrow.stream":{"source":"iana"},"application/vnd.apache.thrift.binary":{"source":"iana"},"application/vnd.apache.thrift.compact":{"source":"iana"},"application/vnd.apache.thrift.json":{"source":"iana"},"application/vnd.api+json":{"source":"iana","compressible":true},"application/vnd.aplextor.warrp+json":{"source":"iana","compressible":true},"application/vnd.apothekende.reservation+json":{"source":"iana","compressible":true},"application/vnd.apple.installer+xml":{"source":"iana","compressible":true,"extensions":["mpkg"]},"application/vnd.apple.keynote":{"source":"iana","extensions":["key"]},"application/vnd.apple.mpegurl":{"source":"iana","extensions":["m3u8"]},"application/vnd.apple.numbers":{"source":"iana","extensions":["numbers"]},"application/vnd.apple.pages":{"source":"iana","extensions":["pages"]},"application/vnd.apple.pkpass":{"compressible":false,"extensions":["pkpass"]},"application/vnd.arastra.swi":{"source":"iana"},"application/vnd.aristanetworks.swi":{"source":"iana","extensions":["swi"]},"application/vnd.artisan+json":{"source":"iana","compressible":true},"application/vnd.artsquare":{"source":"iana"},"application/vnd.astraea-software.iota":{"source":"iana","extensions":["iota"]},"application/vnd.audiograph":{"source":"iana","extensions":["aep"]},"application/vnd.autopackage":{"source":"iana"},"application/vnd.avalon+json":{"source":"iana","compressible":true},"application/vnd.avistar+xml":{"source":"iana","compressible":true},"application/vnd.balsamiq.bmml+xml":{"source":"iana","compressible":true,"extensions":["bmml"]},"application/vnd.balsamiq.bmpr":{"source":"iana"},"application/vnd.banana-accounting":{"source":"iana"},"application/vnd.bbf.usp.error":{"source":"iana"},"application/vnd.bbf.usp.msg":{"source":"iana"},"application/vnd.bbf.usp.msg+json":{"source":"iana","compressible":true},"application/vnd.bekitzur-stech+json":{"source":"iana","compressible":true},"application/vnd.bint.med-content":{"source":"iana"},"application/vnd.biopax.rdf+xml":{"source":"iana","compressible":true},"application/vnd.blink-idb-value-wrapper":{"source":"iana"},"application/vnd.blueice.multipass":{"source":"iana","extensions":["mpm"]},"application/vnd.bluetooth.ep.oob":{"source":"iana"},"application/vnd.bluetooth.le.oob":{"source":"iana"},"application/vnd.bmi":{"source":"iana","extensions":["bmi"]},"application/vnd.bpf":{"source":"iana"},"application/vnd.bpf3":{"source":"iana"},"application/vnd.businessobjects":{"source":"iana","extensions":["rep"]},"application/vnd.byu.uapi+json":{"source":"iana","compressible":true},"application/vnd.cab-jscript":{"source":"iana"},"application/vnd.canon-cpdl":{"source":"iana"},"application/vnd.canon-lips":{"source":"iana"},"application/vnd.capasystems-pg+json":{"source":"iana","compressible":true},"application/vnd.cendio.thinlinc.clientconf":{"source":"iana"},"application/vnd.century-systems.tcp_stream":{"source":"iana"},"application/vnd.chemdraw+xml":{"source":"iana","compressible":true,"extensions":["cdxml"]},"application/vnd.chess-pgn":{"source":"iana"},"application/vnd.chipnuts.karaoke-mmd":{"source":"iana","extensions":["mmd"]},"application/vnd.ciedi":{"source":"iana"},"application/vnd.cinderella":{"source":"iana","extensions":["cdy"]},"application/vnd.cirpack.isdn-ext":{"source":"iana"},"application/vnd.citationstyles.style+xml":{"source":"iana","compressible":true,"extensions":["csl"]},"application/vnd.claymore":{"source":"iana","extensions":["cla"]},"application/vnd.cloanto.rp9":{"source":"iana","extensions":["rp9"]},"application/vnd.clonk.c4group":{"source":"iana","extensions":["c4g","c4d","c4f","c4p","c4u"]},"application/vnd.cluetrust.cartomobile-config":{"source":"iana","extensions":["c11amc"]},"application/vnd.cluetrust.cartomobile-config-pkg":{"source":"iana","extensions":["c11amz"]},"application/vnd.coffeescript":{"source":"iana"},"application/vnd.collabio.xodocuments.document":{"source":"iana"},"application/vnd.collabio.xodocuments.document-template":{"source":"iana"},"application/vnd.collabio.xodocuments.presentation":{"source":"iana"},"application/vnd.collabio.xodocuments.presentation-template":{"source":"iana"},"application/vnd.collabio.xodocuments.spreadsheet":{"source":"iana"},"application/vnd.collabio.xodocuments.spreadsheet-template":{"source":"iana"},"application/vnd.collection+json":{"source":"iana","compressible":true},"application/vnd.collection.doc+json":{"source":"iana","compressible":true},"application/vnd.collection.next+json":{"source":"iana","compressible":true},"application/vnd.comicbook+zip":{"source":"iana","compressible":false},"application/vnd.comicbook-rar":{"source":"iana"},"application/vnd.commerce-battelle":{"source":"iana"},"application/vnd.commonspace":{"source":"iana","extensions":["csp"]},"application/vnd.contact.cmsg":{"source":"iana","extensions":["cdbcmsg"]},"application/vnd.coreos.ignition+json":{"source":"iana","compressible":true},"application/vnd.cosmocaller":{"source":"iana","extensions":["cmc"]},"application/vnd.crick.clicker":{"source":"iana","extensions":["clkx"]},"application/vnd.crick.clicker.keyboard":{"source":"iana","extensions":["clkk"]},"application/vnd.crick.clicker.palette":{"source":"iana","extensions":["clkp"]},"application/vnd.crick.clicker.template":{"source":"iana","extensions":["clkt"]},"application/vnd.crick.clicker.wordbank":{"source":"iana","extensions":["clkw"]},"application/vnd.criticaltools.wbs+xml":{"source":"iana","compressible":true,"extensions":["wbs"]},"application/vnd.cryptii.pipe+json":{"source":"iana","compressible":true},"application/vnd.crypto-shade-file":{"source":"iana"},"application/vnd.cryptomator.encrypted":{"source":"iana"},"application/vnd.cryptomator.vault":{"source":"iana"},"application/vnd.ctc-posml":{"source":"iana","extensions":["pml"]},"application/vnd.ctct.ws+xml":{"source":"iana","compressible":true},"application/vnd.cups-pdf":{"source":"iana"},"application/vnd.cups-postscript":{"source":"iana"},"application/vnd.cups-ppd":{"source":"iana","extensions":["ppd"]},"application/vnd.cups-raster":{"source":"iana"},"application/vnd.cups-raw":{"source":"iana"},"application/vnd.curl":{"source":"iana"},"application/vnd.curl.car":{"source":"apache","extensions":["car"]},"application/vnd.curl.pcurl":{"source":"apache","extensions":["pcurl"]},"application/vnd.cyan.dean.root+xml":{"source":"iana","compressible":true},"application/vnd.cybank":{"source":"iana"},"application/vnd.cyclonedx+json":{"source":"iana","compressible":true},"application/vnd.cyclonedx+xml":{"source":"iana","compressible":true},"application/vnd.d2l.coursepackage1p0+zip":{"source":"iana","compressible":false},"application/vnd.d3m-dataset":{"source":"iana"},"application/vnd.d3m-problem":{"source":"iana"},"application/vnd.dart":{"source":"iana","compressible":true,"extensions":["dart"]},"application/vnd.data-vision.rdz":{"source":"iana","extensions":["rdz"]},"application/vnd.datapackage+json":{"source":"iana","compressible":true},"application/vnd.dataresource+json":{"source":"iana","compressible":true},"application/vnd.dbf":{"source":"iana","extensions":["dbf"]},"application/vnd.debian.binary-package":{"source":"iana"},"application/vnd.dece.data":{"source":"iana","extensions":["uvf","uvvf","uvd","uvvd"]},"application/vnd.dece.ttml+xml":{"source":"iana","compressible":true,"extensions":["uvt","uvvt"]},"application/vnd.dece.unspecified":{"source":"iana","extensions":["uvx","uvvx"]},"application/vnd.dece.zip":{"source":"iana","extensions":["uvz","uvvz"]},"application/vnd.denovo.fcselayout-link":{"source":"iana","extensions":["fe_launch"]},"application/vnd.desmume.movie":{"source":"iana"},"application/vnd.dir-bi.plate-dl-nosuffix":{"source":"iana"},"application/vnd.dm.delegation+xml":{"source":"iana","compressible":true},"application/vnd.dna":{"source":"iana","extensions":["dna"]},"application/vnd.document+json":{"source":"iana","compressible":true},"application/vnd.dolby.mlp":{"source":"apache","extensions":["mlp"]},"application/vnd.dolby.mobile.1":{"source":"iana"},"application/vnd.dolby.mobile.2":{"source":"iana"},"application/vnd.doremir.scorecloud-binary-document":{"source":"iana"},"application/vnd.dpgraph":{"source":"iana","extensions":["dpg"]},"application/vnd.dreamfactory":{"source":"iana","extensions":["dfac"]},"application/vnd.drive+json":{"source":"iana","compressible":true},"application/vnd.ds-keypoint":{"source":"apache","extensions":["kpxx"]},"application/vnd.dtg.local":{"source":"iana"},"application/vnd.dtg.local.flash":{"source":"iana"},"application/vnd.dtg.local.html":{"source":"iana"},"application/vnd.dvb.ait":{"source":"iana","extensions":["ait"]},"application/vnd.dvb.dvbisl+xml":{"source":"iana","compressible":true},"application/vnd.dvb.dvbj":{"source":"iana"},"application/vnd.dvb.esgcontainer":{"source":"iana"},"application/vnd.dvb.ipdcdftnotifaccess":{"source":"iana"},"application/vnd.dvb.ipdcesgaccess":{"source":"iana"},"application/vnd.dvb.ipdcesgaccess2":{"source":"iana"},"application/vnd.dvb.ipdcesgpdd":{"source":"iana"},"application/vnd.dvb.ipdcroaming":{"source":"iana"},"application/vnd.dvb.iptv.alfec-base":{"source":"iana"},"application/vnd.dvb.iptv.alfec-enhancement":{"source":"iana"},"application/vnd.dvb.notif-aggregate-root+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-container+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-generic+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-msglist+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-registration-request+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-ia-registration-response+xml":{"source":"iana","compressible":true},"application/vnd.dvb.notif-init+xml":{"source":"iana","compressible":true},"application/vnd.dvb.pfr":{"source":"iana"},"application/vnd.dvb.service":{"source":"iana","extensions":["svc"]},"application/vnd.dxr":{"source":"iana"},"application/vnd.dynageo":{"source":"iana","extensions":["geo"]},"application/vnd.dzr":{"source":"iana"},"application/vnd.easykaraoke.cdgdownload":{"source":"iana"},"application/vnd.ecdis-update":{"source":"iana"},"application/vnd.ecip.rlp":{"source":"iana"},"application/vnd.eclipse.ditto+json":{"source":"iana","compressible":true},"application/vnd.ecowin.chart":{"source":"iana","extensions":["mag"]},"application/vnd.ecowin.filerequest":{"source":"iana"},"application/vnd.ecowin.fileupdate":{"source":"iana"},"application/vnd.ecowin.series":{"source":"iana"},"application/vnd.ecowin.seriesrequest":{"source":"iana"},"application/vnd.ecowin.seriesupdate":{"source":"iana"},"application/vnd.efi.img":{"source":"iana"},"application/vnd.efi.iso":{"source":"iana"},"application/vnd.emclient.accessrequest+xml":{"source":"iana","compressible":true},"application/vnd.enliven":{"source":"iana","extensions":["nml"]},"application/vnd.enphase.envoy":{"source":"iana"},"application/vnd.eprints.data+xml":{"source":"iana","compressible":true},"application/vnd.epson.esf":{"source":"iana","extensions":["esf"]},"application/vnd.epson.msf":{"source":"iana","extensions":["msf"]},"application/vnd.epson.quickanime":{"source":"iana","extensions":["qam"]},"application/vnd.epson.salt":{"source":"iana","extensions":["slt"]},"application/vnd.epson.ssf":{"source":"iana","extensions":["ssf"]},"application/vnd.ericsson.quickcall":{"source":"iana"},"application/vnd.espass-espass+zip":{"source":"iana","compressible":false},"application/vnd.eszigno3+xml":{"source":"iana","compressible":true,"extensions":["es3","et3"]},"application/vnd.etsi.aoc+xml":{"source":"iana","compressible":true},"application/vnd.etsi.asic-e+zip":{"source":"iana","compressible":false},"application/vnd.etsi.asic-s+zip":{"source":"iana","compressible":false},"application/vnd.etsi.cug+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvcommand+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvdiscovery+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvprofile+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-bc+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-cod+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsad-npvr+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvservice+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvsync+xml":{"source":"iana","compressible":true},"application/vnd.etsi.iptvueprofile+xml":{"source":"iana","compressible":true},"application/vnd.etsi.mcid+xml":{"source":"iana","compressible":true},"application/vnd.etsi.mheg5":{"source":"iana"},"application/vnd.etsi.overload-control-policy-dataset+xml":{"source":"iana","compressible":true},"application/vnd.etsi.pstn+xml":{"source":"iana","compressible":true},"application/vnd.etsi.sci+xml":{"source":"iana","compressible":true},"application/vnd.etsi.simservs+xml":{"source":"iana","compressible":true},"application/vnd.etsi.timestamp-token":{"source":"iana"},"application/vnd.etsi.tsl+xml":{"source":"iana","compressible":true},"application/vnd.etsi.tsl.der":{"source":"iana"},"application/vnd.eu.kasparian.car+json":{"source":"iana","compressible":true},"application/vnd.eudora.data":{"source":"iana"},"application/vnd.evolv.ecig.profile":{"source":"iana"},"application/vnd.evolv.ecig.settings":{"source":"iana"},"application/vnd.evolv.ecig.theme":{"source":"iana"},"application/vnd.exstream-empower+zip":{"source":"iana","compressible":false},"application/vnd.exstream-package":{"source":"iana"},"application/vnd.ezpix-album":{"source":"iana","extensions":["ez2"]},"application/vnd.ezpix-package":{"source":"iana","extensions":["ez3"]},"application/vnd.f-secure.mobile":{"source":"iana"},"application/vnd.familysearch.gedcom+zip":{"source":"iana","compressible":false},"application/vnd.fastcopy-disk-image":{"source":"iana"},"application/vnd.fdf":{"source":"iana","extensions":["fdf"]},"application/vnd.fdsn.mseed":{"source":"iana","extensions":["mseed"]},"application/vnd.fdsn.seed":{"source":"iana","extensions":["seed","dataless"]},"application/vnd.ffsns":{"source":"iana"},"application/vnd.ficlab.flb+zip":{"source":"iana","compressible":false},"application/vnd.filmit.zfc":{"source":"iana"},"application/vnd.fints":{"source":"iana"},"application/vnd.firemonkeys.cloudcell":{"source":"iana"},"application/vnd.flographit":{"source":"iana","extensions":["gph"]},"application/vnd.fluxtime.clip":{"source":"iana","extensions":["ftc"]},"application/vnd.font-fontforge-sfd":{"source":"iana"},"application/vnd.framemaker":{"source":"iana","extensions":["fm","frame","maker","book"]},"application/vnd.frogans.fnc":{"source":"iana","extensions":["fnc"]},"application/vnd.frogans.ltf":{"source":"iana","extensions":["ltf"]},"application/vnd.fsc.weblaunch":{"source":"iana","extensions":["fsc"]},"application/vnd.fujifilm.fb.docuworks":{"source":"iana"},"application/vnd.fujifilm.fb.docuworks.binder":{"source":"iana"},"application/vnd.fujifilm.fb.docuworks.container":{"source":"iana"},"application/vnd.fujifilm.fb.jfi+xml":{"source":"iana","compressible":true},"application/vnd.fujitsu.oasys":{"source":"iana","extensions":["oas"]},"application/vnd.fujitsu.oasys2":{"source":"iana","extensions":["oa2"]},"application/vnd.fujitsu.oasys3":{"source":"iana","extensions":["oa3"]},"application/vnd.fujitsu.oasysgp":{"source":"iana","extensions":["fg5"]},"application/vnd.fujitsu.oasysprs":{"source":"iana","extensions":["bh2"]},"application/vnd.fujixerox.art-ex":{"source":"iana"},"application/vnd.fujixerox.art4":{"source":"iana"},"application/vnd.fujixerox.ddd":{"source":"iana","extensions":["ddd"]},"application/vnd.fujixerox.docuworks":{"source":"iana","extensions":["xdw"]},"application/vnd.fujixerox.docuworks.binder":{"source":"iana","extensions":["xbd"]},"application/vnd.fujixerox.docuworks.container":{"source":"iana"},"application/vnd.fujixerox.hbpl":{"source":"iana"},"application/vnd.fut-misnet":{"source":"iana"},"application/vnd.futoin+cbor":{"source":"iana"},"application/vnd.futoin+json":{"source":"iana","compressible":true},"application/vnd.fuzzysheet":{"source":"iana","extensions":["fzs"]},"application/vnd.genomatix.tuxedo":{"source":"iana","extensions":["txd"]},"application/vnd.gentics.grd+json":{"source":"iana","compressible":true},"application/vnd.geo+json":{"source":"iana","compressible":true},"application/vnd.geocube+xml":{"source":"iana","compressible":true},"application/vnd.geogebra.file":{"source":"iana","extensions":["ggb"]},"application/vnd.geogebra.slides":{"source":"iana"},"application/vnd.geogebra.tool":{"source":"iana","extensions":["ggt"]},"application/vnd.geometry-explorer":{"source":"iana","extensions":["gex","gre"]},"application/vnd.geonext":{"source":"iana","extensions":["gxt"]},"application/vnd.geoplan":{"source":"iana","extensions":["g2w"]},"application/vnd.geospace":{"source":"iana","extensions":["g3w"]},"application/vnd.gerber":{"source":"iana"},"application/vnd.globalplatform.card-content-mgt":{"source":"iana"},"application/vnd.globalplatform.card-content-mgt-response":{"source":"iana"},"application/vnd.gmx":{"source":"iana","extensions":["gmx"]},"application/vnd.google-apps.document":{"compressible":false,"extensions":["gdoc"]},"application/vnd.google-apps.presentation":{"compressible":false,"extensions":["gslides"]},"application/vnd.google-apps.spreadsheet":{"compressible":false,"extensions":["gsheet"]},"application/vnd.google-earth.kml+xml":{"source":"iana","compressible":true,"extensions":["kml"]},"application/vnd.google-earth.kmz":{"source":"iana","compressible":false,"extensions":["kmz"]},"application/vnd.gov.sk.e-form+xml":{"source":"iana","compressible":true},"application/vnd.gov.sk.e-form+zip":{"source":"iana","compressible":false},"application/vnd.gov.sk.xmldatacontainer+xml":{"source":"iana","compressible":true},"application/vnd.grafeq":{"source":"iana","extensions":["gqf","gqs"]},"application/vnd.gridmp":{"source":"iana"},"application/vnd.groove-account":{"source":"iana","extensions":["gac"]},"application/vnd.groove-help":{"source":"iana","extensions":["ghf"]},"application/vnd.groove-identity-message":{"source":"iana","extensions":["gim"]},"application/vnd.groove-injector":{"source":"iana","extensions":["grv"]},"application/vnd.groove-tool-message":{"source":"iana","extensions":["gtm"]},"application/vnd.groove-tool-template":{"source":"iana","extensions":["tpl"]},"application/vnd.groove-vcard":{"source":"iana","extensions":["vcg"]},"application/vnd.hal+json":{"source":"iana","compressible":true},"application/vnd.hal+xml":{"source":"iana","compressible":true,"extensions":["hal"]},"application/vnd.handheld-entertainment+xml":{"source":"iana","compressible":true,"extensions":["zmm"]},"application/vnd.hbci":{"source":"iana","extensions":["hbci"]},"application/vnd.hc+json":{"source":"iana","compressible":true},"application/vnd.hcl-bireports":{"source":"iana"},"application/vnd.hdt":{"source":"iana"},"application/vnd.heroku+json":{"source":"iana","compressible":true},"application/vnd.hhe.lesson-player":{"source":"iana","extensions":["les"]},"application/vnd.hl7cda+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.hl7v2+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.hp-hpgl":{"source":"iana","extensions":["hpgl"]},"application/vnd.hp-hpid":{"source":"iana","extensions":["hpid"]},"application/vnd.hp-hps":{"source":"iana","extensions":["hps"]},"application/vnd.hp-jlyt":{"source":"iana","extensions":["jlt"]},"application/vnd.hp-pcl":{"source":"iana","extensions":["pcl"]},"application/vnd.hp-pclxl":{"source":"iana","extensions":["pclxl"]},"application/vnd.httphone":{"source":"iana"},"application/vnd.hydrostatix.sof-data":{"source":"iana","extensions":["sfd-hdstx"]},"application/vnd.hyper+json":{"source":"iana","compressible":true},"application/vnd.hyper-item+json":{"source":"iana","compressible":true},"application/vnd.hyperdrive+json":{"source":"iana","compressible":true},"application/vnd.hzn-3d-crossword":{"source":"iana"},"application/vnd.ibm.afplinedata":{"source":"iana"},"application/vnd.ibm.electronic-media":{"source":"iana"},"application/vnd.ibm.minipay":{"source":"iana","extensions":["mpy"]},"application/vnd.ibm.modcap":{"source":"iana","extensions":["afp","listafp","list3820"]},"application/vnd.ibm.rights-management":{"source":"iana","extensions":["irm"]},"application/vnd.ibm.secure-container":{"source":"iana","extensions":["sc"]},"application/vnd.iccprofile":{"source":"iana","extensions":["icc","icm"]},"application/vnd.ieee.1905":{"source":"iana"},"application/vnd.igloader":{"source":"iana","extensions":["igl"]},"application/vnd.imagemeter.folder+zip":{"source":"iana","compressible":false},"application/vnd.imagemeter.image+zip":{"source":"iana","compressible":false},"application/vnd.immervision-ivp":{"source":"iana","extensions":["ivp"]},"application/vnd.immervision-ivu":{"source":"iana","extensions":["ivu"]},"application/vnd.ims.imsccv1p1":{"source":"iana"},"application/vnd.ims.imsccv1p2":{"source":"iana"},"application/vnd.ims.imsccv1p3":{"source":"iana"},"application/vnd.ims.lis.v2.result+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolconsumerprofile+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolproxy+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolproxy.id+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolsettings+json":{"source":"iana","compressible":true},"application/vnd.ims.lti.v2.toolsettings.simple+json":{"source":"iana","compressible":true},"application/vnd.informedcontrol.rms+xml":{"source":"iana","compressible":true},"application/vnd.informix-visionary":{"source":"iana"},"application/vnd.infotech.project":{"source":"iana"},"application/vnd.infotech.project+xml":{"source":"iana","compressible":true},"application/vnd.innopath.wamp.notification":{"source":"iana"},"application/vnd.insors.igm":{"source":"iana","extensions":["igm"]},"application/vnd.intercon.formnet":{"source":"iana","extensions":["xpw","xpx"]},"application/vnd.intergeo":{"source":"iana","extensions":["i2g"]},"application/vnd.intertrust.digibox":{"source":"iana"},"application/vnd.intertrust.nncp":{"source":"iana"},"application/vnd.intu.qbo":{"source":"iana","extensions":["qbo"]},"application/vnd.intu.qfx":{"source":"iana","extensions":["qfx"]},"application/vnd.iptc.g2.catalogitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.conceptitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.knowledgeitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.newsitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.newsmessage+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.packageitem+xml":{"source":"iana","compressible":true},"application/vnd.iptc.g2.planningitem+xml":{"source":"iana","compressible":true},"application/vnd.ipunplugged.rcprofile":{"source":"iana","extensions":["rcprofile"]},"application/vnd.irepository.package+xml":{"source":"iana","compressible":true,"extensions":["irp"]},"application/vnd.is-xpr":{"source":"iana","extensions":["xpr"]},"application/vnd.isac.fcs":{"source":"iana","extensions":["fcs"]},"application/vnd.iso11783-10+zip":{"source":"iana","compressible":false},"application/vnd.jam":{"source":"iana","extensions":["jam"]},"application/vnd.japannet-directory-service":{"source":"iana"},"application/vnd.japannet-jpnstore-wakeup":{"source":"iana"},"application/vnd.japannet-payment-wakeup":{"source":"iana"},"application/vnd.japannet-registration":{"source":"iana"},"application/vnd.japannet-registration-wakeup":{"source":"iana"},"application/vnd.japannet-setstore-wakeup":{"source":"iana"},"application/vnd.japannet-verification":{"source":"iana"},"application/vnd.japannet-verification-wakeup":{"source":"iana"},"application/vnd.jcp.javame.midlet-rms":{"source":"iana","extensions":["rms"]},"application/vnd.jisp":{"source":"iana","extensions":["jisp"]},"application/vnd.joost.joda-archive":{"source":"iana","extensions":["joda"]},"application/vnd.jsk.isdn-ngn":{"source":"iana"},"application/vnd.kahootz":{"source":"iana","extensions":["ktz","ktr"]},"application/vnd.kde.karbon":{"source":"iana","extensions":["karbon"]},"application/vnd.kde.kchart":{"source":"iana","extensions":["chrt"]},"application/vnd.kde.kformula":{"source":"iana","extensions":["kfo"]},"application/vnd.kde.kivio":{"source":"iana","extensions":["flw"]},"application/vnd.kde.kontour":{"source":"iana","extensions":["kon"]},"application/vnd.kde.kpresenter":{"source":"iana","extensions":["kpr","kpt"]},"application/vnd.kde.kspread":{"source":"iana","extensions":["ksp"]},"application/vnd.kde.kword":{"source":"iana","extensions":["kwd","kwt"]},"application/vnd.kenameaapp":{"source":"iana","extensions":["htke"]},"application/vnd.kidspiration":{"source":"iana","extensions":["kia"]},"application/vnd.kinar":{"source":"iana","extensions":["kne","knp"]},"application/vnd.koan":{"source":"iana","extensions":["skp","skd","skt","skm"]},"application/vnd.kodak-descriptor":{"source":"iana","extensions":["sse"]},"application/vnd.las":{"source":"iana"},"application/vnd.las.las+json":{"source":"iana","compressible":true},"application/vnd.las.las+xml":{"source":"iana","compressible":true,"extensions":["lasxml"]},"application/vnd.laszip":{"source":"iana"},"application/vnd.leap+json":{"source":"iana","compressible":true},"application/vnd.liberty-request+xml":{"source":"iana","compressible":true},"application/vnd.llamagraphics.life-balance.desktop":{"source":"iana","extensions":["lbd"]},"application/vnd.llamagraphics.life-balance.exchange+xml":{"source":"iana","compressible":true,"extensions":["lbe"]},"application/vnd.logipipe.circuit+zip":{"source":"iana","compressible":false},"application/vnd.loom":{"source":"iana"},"application/vnd.lotus-1-2-3":{"source":"iana","extensions":["123"]},"application/vnd.lotus-approach":{"source":"iana","extensions":["apr"]},"application/vnd.lotus-freelance":{"source":"iana","extensions":["pre"]},"application/vnd.lotus-notes":{"source":"iana","extensions":["nsf"]},"application/vnd.lotus-organizer":{"source":"iana","extensions":["org"]},"application/vnd.lotus-screencam":{"source":"iana","extensions":["scm"]},"application/vnd.lotus-wordpro":{"source":"iana","extensions":["lwp"]},"application/vnd.macports.portpkg":{"source":"iana","extensions":["portpkg"]},"application/vnd.mapbox-vector-tile":{"source":"iana","extensions":["mvt"]},"application/vnd.marlin.drm.actiontoken+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.conftoken+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.license+xml":{"source":"iana","compressible":true},"application/vnd.marlin.drm.mdcf":{"source":"iana"},"application/vnd.mason+json":{"source":"iana","compressible":true},"application/vnd.maxar.archive.3tz+zip":{"source":"iana","compressible":false},"application/vnd.maxmind.maxmind-db":{"source":"iana"},"application/vnd.mcd":{"source":"iana","extensions":["mcd"]},"application/vnd.medcalcdata":{"source":"iana","extensions":["mc1"]},"application/vnd.mediastation.cdkey":{"source":"iana","extensions":["cdkey"]},"application/vnd.meridian-slingshot":{"source":"iana"},"application/vnd.mfer":{"source":"iana","extensions":["mwf"]},"application/vnd.mfmp":{"source":"iana","extensions":["mfm"]},"application/vnd.micro+json":{"source":"iana","compressible":true},"application/vnd.micrografx.flo":{"source":"iana","extensions":["flo"]},"application/vnd.micrografx.igx":{"source":"iana","extensions":["igx"]},"application/vnd.microsoft.portable-executable":{"source":"iana"},"application/vnd.microsoft.windows.thumbnail-cache":{"source":"iana"},"application/vnd.miele+json":{"source":"iana","compressible":true},"application/vnd.mif":{"source":"iana","extensions":["mif"]},"application/vnd.minisoft-hp3000-save":{"source":"iana"},"application/vnd.mitsubishi.misty-guard.trustweb":{"source":"iana"},"application/vnd.mobius.daf":{"source":"iana","extensions":["daf"]},"application/vnd.mobius.dis":{"source":"iana","extensions":["dis"]},"application/vnd.mobius.mbk":{"source":"iana","extensions":["mbk"]},"application/vnd.mobius.mqy":{"source":"iana","extensions":["mqy"]},"application/vnd.mobius.msl":{"source":"iana","extensions":["msl"]},"application/vnd.mobius.plc":{"source":"iana","extensions":["plc"]},"application/vnd.mobius.txf":{"source":"iana","extensions":["txf"]},"application/vnd.mophun.application":{"source":"iana","extensions":["mpn"]},"application/vnd.mophun.certificate":{"source":"iana","extensions":["mpc"]},"application/vnd.motorola.flexsuite":{"source":"iana"},"application/vnd.motorola.flexsuite.adsi":{"source":"iana"},"application/vnd.motorola.flexsuite.fis":{"source":"iana"},"application/vnd.motorola.flexsuite.gotap":{"source":"iana"},"application/vnd.motorola.flexsuite.kmr":{"source":"iana"},"application/vnd.motorola.flexsuite.ttc":{"source":"iana"},"application/vnd.motorola.flexsuite.wem":{"source":"iana"},"application/vnd.motorola.iprm":{"source":"iana"},"application/vnd.mozilla.xul+xml":{"source":"iana","compressible":true,"extensions":["xul"]},"application/vnd.ms-3mfdocument":{"source":"iana"},"application/vnd.ms-artgalry":{"source":"iana","extensions":["cil"]},"application/vnd.ms-asf":{"source":"iana"},"application/vnd.ms-cab-compressed":{"source":"iana","extensions":["cab"]},"application/vnd.ms-color.iccprofile":{"source":"apache"},"application/vnd.ms-excel":{"source":"iana","compressible":false,"extensions":["xls","xlm","xla","xlc","xlt","xlw"]},"application/vnd.ms-excel.addin.macroenabled.12":{"source":"iana","extensions":["xlam"]},"application/vnd.ms-excel.sheet.binary.macroenabled.12":{"source":"iana","extensions":["xlsb"]},"application/vnd.ms-excel.sheet.macroenabled.12":{"source":"iana","extensions":["xlsm"]},"application/vnd.ms-excel.template.macroenabled.12":{"source":"iana","extensions":["xltm"]},"application/vnd.ms-fontobject":{"source":"iana","compressible":true,"extensions":["eot"]},"application/vnd.ms-htmlhelp":{"source":"iana","extensions":["chm"]},"application/vnd.ms-ims":{"source":"iana","extensions":["ims"]},"application/vnd.ms-lrm":{"source":"iana","extensions":["lrm"]},"application/vnd.ms-office.activex+xml":{"source":"iana","compressible":true},"application/vnd.ms-officetheme":{"source":"iana","extensions":["thmx"]},"application/vnd.ms-opentype":{"source":"apache","compressible":true},"application/vnd.ms-outlook":{"compressible":false,"extensions":["msg"]},"application/vnd.ms-package.obfuscated-opentype":{"source":"apache"},"application/vnd.ms-pki.seccat":{"source":"apache","extensions":["cat"]},"application/vnd.ms-pki.stl":{"source":"apache","extensions":["stl"]},"application/vnd.ms-playready.initiator+xml":{"source":"iana","compressible":true},"application/vnd.ms-powerpoint":{"source":"iana","compressible":false,"extensions":["ppt","pps","pot"]},"application/vnd.ms-powerpoint.addin.macroenabled.12":{"source":"iana","extensions":["ppam"]},"application/vnd.ms-powerpoint.presentation.macroenabled.12":{"source":"iana","extensions":["pptm"]},"application/vnd.ms-powerpoint.slide.macroenabled.12":{"source":"iana","extensions":["sldm"]},"application/vnd.ms-powerpoint.slideshow.macroenabled.12":{"source":"iana","extensions":["ppsm"]},"application/vnd.ms-powerpoint.template.macroenabled.12":{"source":"iana","extensions":["potm"]},"application/vnd.ms-printdevicecapabilities+xml":{"source":"iana","compressible":true},"application/vnd.ms-printing.printticket+xml":{"source":"apache","compressible":true},"application/vnd.ms-printschematicket+xml":{"source":"iana","compressible":true},"application/vnd.ms-project":{"source":"iana","extensions":["mpp","mpt"]},"application/vnd.ms-tnef":{"source":"iana"},"application/vnd.ms-windows.devicepairing":{"source":"iana"},"application/vnd.ms-windows.nwprinting.oob":{"source":"iana"},"application/vnd.ms-windows.printerpairing":{"source":"iana"},"application/vnd.ms-windows.wsd.oob":{"source":"iana"},"application/vnd.ms-wmdrm.lic-chlg-req":{"source":"iana"},"application/vnd.ms-wmdrm.lic-resp":{"source":"iana"},"application/vnd.ms-wmdrm.meter-chlg-req":{"source":"iana"},"application/vnd.ms-wmdrm.meter-resp":{"source":"iana"},"application/vnd.ms-word.document.macroenabled.12":{"source":"iana","extensions":["docm"]},"application/vnd.ms-word.template.macroenabled.12":{"source":"iana","extensions":["dotm"]},"application/vnd.ms-works":{"source":"iana","extensions":["wps","wks","wcm","wdb"]},"application/vnd.ms-wpl":{"source":"iana","extensions":["wpl"]},"application/vnd.ms-xpsdocument":{"source":"iana","compressible":false,"extensions":["xps"]},"application/vnd.msa-disk-image":{"source":"iana"},"application/vnd.mseq":{"source":"iana","extensions":["mseq"]},"application/vnd.msign":{"source":"iana"},"application/vnd.multiad.creator":{"source":"iana"},"application/vnd.multiad.creator.cif":{"source":"iana"},"application/vnd.music-niff":{"source":"iana"},"application/vnd.musician":{"source":"iana","extensions":["mus"]},"application/vnd.muvee.style":{"source":"iana","extensions":["msty"]},"application/vnd.mynfc":{"source":"iana","extensions":["taglet"]},"application/vnd.nacamar.ybrid+json":{"source":"iana","compressible":true},"application/vnd.ncd.control":{"source":"iana"},"application/vnd.ncd.reference":{"source":"iana"},"application/vnd.nearst.inv+json":{"source":"iana","compressible":true},"application/vnd.nebumind.line":{"source":"iana"},"application/vnd.nervana":{"source":"iana"},"application/vnd.netfpx":{"source":"iana"},"application/vnd.neurolanguage.nlu":{"source":"iana","extensions":["nlu"]},"application/vnd.nimn":{"source":"iana"},"application/vnd.nintendo.nitro.rom":{"source":"iana"},"application/vnd.nintendo.snes.rom":{"source":"iana"},"application/vnd.nitf":{"source":"iana","extensions":["ntf","nitf"]},"application/vnd.noblenet-directory":{"source":"iana","extensions":["nnd"]},"application/vnd.noblenet-sealer":{"source":"iana","extensions":["nns"]},"application/vnd.noblenet-web":{"source":"iana","extensions":["nnw"]},"application/vnd.nokia.catalogs":{"source":"iana"},"application/vnd.nokia.conml+wbxml":{"source":"iana"},"application/vnd.nokia.conml+xml":{"source":"iana","compressible":true},"application/vnd.nokia.iptv.config+xml":{"source":"iana","compressible":true},"application/vnd.nokia.isds-radio-presets":{"source":"iana"},"application/vnd.nokia.landmark+wbxml":{"source":"iana"},"application/vnd.nokia.landmark+xml":{"source":"iana","compressible":true},"application/vnd.nokia.landmarkcollection+xml":{"source":"iana","compressible":true},"application/vnd.nokia.n-gage.ac+xml":{"source":"iana","compressible":true,"extensions":["ac"]},"application/vnd.nokia.n-gage.data":{"source":"iana","extensions":["ngdat"]},"application/vnd.nokia.n-gage.symbian.install":{"source":"iana","extensions":["n-gage"]},"application/vnd.nokia.ncd":{"source":"iana"},"application/vnd.nokia.pcd+wbxml":{"source":"iana"},"application/vnd.nokia.pcd+xml":{"source":"iana","compressible":true},"application/vnd.nokia.radio-preset":{"source":"iana","extensions":["rpst"]},"application/vnd.nokia.radio-presets":{"source":"iana","extensions":["rpss"]},"application/vnd.novadigm.edm":{"source":"iana","extensions":["edm"]},"application/vnd.novadigm.edx":{"source":"iana","extensions":["edx"]},"application/vnd.novadigm.ext":{"source":"iana","extensions":["ext"]},"application/vnd.ntt-local.content-share":{"source":"iana"},"application/vnd.ntt-local.file-transfer":{"source":"iana"},"application/vnd.ntt-local.ogw_remote-access":{"source":"iana"},"application/vnd.ntt-local.sip-ta_remote":{"source":"iana"},"application/vnd.ntt-local.sip-ta_tcp_stream":{"source":"iana"},"application/vnd.oasis.opendocument.chart":{"source":"iana","extensions":["odc"]},"application/vnd.oasis.opendocument.chart-template":{"source":"iana","extensions":["otc"]},"application/vnd.oasis.opendocument.database":{"source":"iana","extensions":["odb"]},"application/vnd.oasis.opendocument.formula":{"source":"iana","extensions":["odf"]},"application/vnd.oasis.opendocument.formula-template":{"source":"iana","extensions":["odft"]},"application/vnd.oasis.opendocument.graphics":{"source":"iana","compressible":false,"extensions":["odg"]},"application/vnd.oasis.opendocument.graphics-template":{"source":"iana","extensions":["otg"]},"application/vnd.oasis.opendocument.image":{"source":"iana","extensions":["odi"]},"application/vnd.oasis.opendocument.image-template":{"source":"iana","extensions":["oti"]},"application/vnd.oasis.opendocument.presentation":{"source":"iana","compressible":false,"extensions":["odp"]},"application/vnd.oasis.opendocument.presentation-template":{"source":"iana","extensions":["otp"]},"application/vnd.oasis.opendocument.spreadsheet":{"source":"iana","compressible":false,"extensions":["ods"]},"application/vnd.oasis.opendocument.spreadsheet-template":{"source":"iana","extensions":["ots"]},"application/vnd.oasis.opendocument.text":{"source":"iana","compressible":false,"extensions":["odt"]},"application/vnd.oasis.opendocument.text-master":{"source":"iana","extensions":["odm"]},"application/vnd.oasis.opendocument.text-template":{"source":"iana","extensions":["ott"]},"application/vnd.oasis.opendocument.text-web":{"source":"iana","extensions":["oth"]},"application/vnd.obn":{"source":"iana"},"application/vnd.ocf+cbor":{"source":"iana"},"application/vnd.oci.image.manifest.v1+json":{"source":"iana","compressible":true},"application/vnd.oftn.l10n+json":{"source":"iana","compressible":true},"application/vnd.oipf.contentaccessdownload+xml":{"source":"iana","compressible":true},"application/vnd.oipf.contentaccessstreaming+xml":{"source":"iana","compressible":true},"application/vnd.oipf.cspg-hexbinary":{"source":"iana"},"application/vnd.oipf.dae.svg+xml":{"source":"iana","compressible":true},"application/vnd.oipf.dae.xhtml+xml":{"source":"iana","compressible":true},"application/vnd.oipf.mippvcontrolmessage+xml":{"source":"iana","compressible":true},"application/vnd.oipf.pae.gem":{"source":"iana"},"application/vnd.oipf.spdiscovery+xml":{"source":"iana","compressible":true},"application/vnd.oipf.spdlist+xml":{"source":"iana","compressible":true},"application/vnd.oipf.ueprofile+xml":{"source":"iana","compressible":true},"application/vnd.oipf.userprofile+xml":{"source":"iana","compressible":true},"application/vnd.olpc-sugar":{"source":"iana","extensions":["xo"]},"application/vnd.oma-scws-config":{"source":"iana"},"application/vnd.oma-scws-http-request":{"source":"iana"},"application/vnd.oma-scws-http-response":{"source":"iana"},"application/vnd.oma.bcast.associated-procedure-parameter+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.drm-trigger+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.imd+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.ltkm":{"source":"iana"},"application/vnd.oma.bcast.notification+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.provisioningtrigger":{"source":"iana"},"application/vnd.oma.bcast.sgboot":{"source":"iana"},"application/vnd.oma.bcast.sgdd+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.sgdu":{"source":"iana"},"application/vnd.oma.bcast.simple-symbol-container":{"source":"iana"},"application/vnd.oma.bcast.smartcard-trigger+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.sprov+xml":{"source":"iana","compressible":true},"application/vnd.oma.bcast.stkm":{"source":"iana"},"application/vnd.oma.cab-address-book+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-feature-handler+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-pcc+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-subs-invite+xml":{"source":"iana","compressible":true},"application/vnd.oma.cab-user-prefs+xml":{"source":"iana","compressible":true},"application/vnd.oma.dcd":{"source":"iana"},"application/vnd.oma.dcdc":{"source":"iana"},"application/vnd.oma.dd2+xml":{"source":"iana","compressible":true,"extensions":["dd2"]},"application/vnd.oma.drm.risd+xml":{"source":"iana","compressible":true},"application/vnd.oma.group-usage-list+xml":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+cbor":{"source":"iana"},"application/vnd.oma.lwm2m+json":{"source":"iana","compressible":true},"application/vnd.oma.lwm2m+tlv":{"source":"iana"},"application/vnd.oma.pal+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.detailed-progress-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.final-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.groups+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.invocation-descriptor+xml":{"source":"iana","compressible":true},"application/vnd.oma.poc.optimized-progress-report+xml":{"source":"iana","compressible":true},"application/vnd.oma.push":{"source":"iana"},"application/vnd.oma.scidm.messages+xml":{"source":"iana","compressible":true},"application/vnd.oma.xcap-directory+xml":{"source":"iana","compressible":true},"application/vnd.omads-email+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omads-file+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omads-folder+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.omaloc-supl-init":{"source":"iana"},"application/vnd.onepager":{"source":"iana"},"application/vnd.onepagertamp":{"source":"iana"},"application/vnd.onepagertamx":{"source":"iana"},"application/vnd.onepagertat":{"source":"iana"},"application/vnd.onepagertatp":{"source":"iana"},"application/vnd.onepagertatx":{"source":"iana"},"application/vnd.openblox.game+xml":{"source":"iana","compressible":true,"extensions":["obgx"]},"application/vnd.openblox.game-binary":{"source":"iana"},"application/vnd.openeye.oeb":{"source":"iana"},"application/vnd.openofficeorg.extension":{"source":"apache","extensions":["oxt"]},"application/vnd.openstreetmap.data+xml":{"source":"iana","compressible":true,"extensions":["osm"]},"application/vnd.opentimestamps.ots":{"source":"iana"},"application/vnd.openxmlformats-officedocument.custom-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.customxmlproperties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawing+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.chart+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.extended-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.presentation":{"source":"iana","compressible":false,"extensions":["pptx"]},"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.presprops+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slide":{"source":"iana","extensions":["sldx"]},"application/vnd.openxmlformats-officedocument.presentationml.slide+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slideshow":{"source":"iana","extensions":["ppsx"]},"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.tags+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.template":{"source":"iana","extensions":["potx"]},"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"source":"iana","compressible":false,"extensions":["xlsx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.template":{"source":"iana","extensions":["xltx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.theme+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.themeoverride+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.vmldrawing":{"source":"iana"},"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{"source":"iana","compressible":false,"extensions":["docx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.template":{"source":"iana","extensions":["dotx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.core-properties+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml":{"source":"iana","compressible":true},"application/vnd.openxmlformats-package.relationships+xml":{"source":"iana","compressible":true},"application/vnd.oracle.resource+json":{"source":"iana","compressible":true},"application/vnd.orange.indata":{"source":"iana"},"application/vnd.osa.netdeploy":{"source":"iana"},"application/vnd.osgeo.mapguide.package":{"source":"iana","extensions":["mgp"]},"application/vnd.osgi.bundle":{"source":"iana"},"application/vnd.osgi.dp":{"source":"iana","extensions":["dp"]},"application/vnd.osgi.subsystem":{"source":"iana","extensions":["esa"]},"application/vnd.otps.ct-kip+xml":{"source":"iana","compressible":true},"application/vnd.oxli.countgraph":{"source":"iana"},"application/vnd.pagerduty+json":{"source":"iana","compressible":true},"application/vnd.palm":{"source":"iana","extensions":["pdb","pqa","oprc"]},"application/vnd.panoply":{"source":"iana"},"application/vnd.paos.xml":{"source":"iana"},"application/vnd.patentdive":{"source":"iana"},"application/vnd.patientecommsdoc":{"source":"iana"},"application/vnd.pawaafile":{"source":"iana","extensions":["paw"]},"application/vnd.pcos":{"source":"iana"},"application/vnd.pg.format":{"source":"iana","extensions":["str"]},"application/vnd.pg.osasli":{"source":"iana","extensions":["ei6"]},"application/vnd.piaccess.application-licence":{"source":"iana"},"application/vnd.picsel":{"source":"iana","extensions":["efif"]},"application/vnd.pmi.widget":{"source":"iana","extensions":["wg"]},"application/vnd.poc.group-advertisement+xml":{"source":"iana","compressible":true},"application/vnd.pocketlearn":{"source":"iana","extensions":["plf"]},"application/vnd.powerbuilder6":{"source":"iana","extensions":["pbd"]},"application/vnd.powerbuilder6-s":{"source":"iana"},"application/vnd.powerbuilder7":{"source":"iana"},"application/vnd.powerbuilder7-s":{"source":"iana"},"application/vnd.powerbuilder75":{"source":"iana"},"application/vnd.powerbuilder75-s":{"source":"iana"},"application/vnd.preminet":{"source":"iana"},"application/vnd.previewsystems.box":{"source":"iana","extensions":["box"]},"application/vnd.proteus.magazine":{"source":"iana","extensions":["mgz"]},"application/vnd.psfs":{"source":"iana"},"application/vnd.publishare-delta-tree":{"source":"iana","extensions":["qps"]},"application/vnd.pvi.ptid1":{"source":"iana","extensions":["ptid"]},"application/vnd.pwg-multiplexed":{"source":"iana"},"application/vnd.pwg-xhtml-print+xml":{"source":"iana","compressible":true},"application/vnd.qualcomm.brew-app-res":{"source":"iana"},"application/vnd.quarantainenet":{"source":"iana"},"application/vnd.quark.quarkxpress":{"source":"iana","extensions":["qxd","qxt","qwd","qwt","qxl","qxb"]},"application/vnd.quobject-quoxdocument":{"source":"iana"},"application/vnd.radisys.moml+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-conf+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-conn+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-dialog+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-audit-stream+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-conf+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-base+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-fax-detect+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-fax-sendrecv+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-group+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-speech+xml":{"source":"iana","compressible":true},"application/vnd.radisys.msml-dialog-transform+xml":{"source":"iana","compressible":true},"application/vnd.rainstor.data":{"source":"iana"},"application/vnd.rapid":{"source":"iana"},"application/vnd.rar":{"source":"iana","extensions":["rar"]},"application/vnd.realvnc.bed":{"source":"iana","extensions":["bed"]},"application/vnd.recordare.musicxml":{"source":"iana","extensions":["mxl"]},"application/vnd.recordare.musicxml+xml":{"source":"iana","compressible":true,"extensions":["musicxml"]},"application/vnd.renlearn.rlprint":{"source":"iana"},"application/vnd.resilient.logic":{"source":"iana"},"application/vnd.restful+json":{"source":"iana","compressible":true},"application/vnd.rig.cryptonote":{"source":"iana","extensions":["cryptonote"]},"application/vnd.rim.cod":{"source":"apache","extensions":["cod"]},"application/vnd.rn-realmedia":{"source":"apache","extensions":["rm"]},"application/vnd.rn-realmedia-vbr":{"source":"apache","extensions":["rmvb"]},"application/vnd.route66.link66+xml":{"source":"iana","compressible":true,"extensions":["link66"]},"application/vnd.rs-274x":{"source":"iana"},"application/vnd.ruckus.download":{"source":"iana"},"application/vnd.s3sms":{"source":"iana"},"application/vnd.sailingtracker.track":{"source":"iana","extensions":["st"]},"application/vnd.sar":{"source":"iana"},"application/vnd.sbm.cid":{"source":"iana"},"application/vnd.sbm.mid2":{"source":"iana"},"application/vnd.scribus":{"source":"iana"},"application/vnd.sealed.3df":{"source":"iana"},"application/vnd.sealed.csf":{"source":"iana"},"application/vnd.sealed.doc":{"source":"iana"},"application/vnd.sealed.eml":{"source":"iana"},"application/vnd.sealed.mht":{"source":"iana"},"application/vnd.sealed.net":{"source":"iana"},"application/vnd.sealed.ppt":{"source":"iana"},"application/vnd.sealed.tiff":{"source":"iana"},"application/vnd.sealed.xls":{"source":"iana"},"application/vnd.sealedmedia.softseal.html":{"source":"iana"},"application/vnd.sealedmedia.softseal.pdf":{"source":"iana"},"application/vnd.seemail":{"source":"iana","extensions":["see"]},"application/vnd.seis+json":{"source":"iana","compressible":true},"application/vnd.sema":{"source":"iana","extensions":["sema"]},"application/vnd.semd":{"source":"iana","extensions":["semd"]},"application/vnd.semf":{"source":"iana","extensions":["semf"]},"application/vnd.shade-save-file":{"source":"iana"},"application/vnd.shana.informed.formdata":{"source":"iana","extensions":["ifm"]},"application/vnd.shana.informed.formtemplate":{"source":"iana","extensions":["itp"]},"application/vnd.shana.informed.interchange":{"source":"iana","extensions":["iif"]},"application/vnd.shana.informed.package":{"source":"iana","extensions":["ipk"]},"application/vnd.shootproof+json":{"source":"iana","compressible":true},"application/vnd.shopkick+json":{"source":"iana","compressible":true},"application/vnd.shp":{"source":"iana"},"application/vnd.shx":{"source":"iana"},"application/vnd.sigrok.session":{"source":"iana"},"application/vnd.simtech-mindmapper":{"source":"iana","extensions":["twd","twds"]},"application/vnd.siren+json":{"source":"iana","compressible":true},"application/vnd.smaf":{"source":"iana","extensions":["mmf"]},"application/vnd.smart.notebook":{"source":"iana"},"application/vnd.smart.teacher":{"source":"iana","extensions":["teacher"]},"application/vnd.snesdev-page-table":{"source":"iana"},"application/vnd.software602.filler.form+xml":{"source":"iana","compressible":true,"extensions":["fo"]},"application/vnd.software602.filler.form-xml-zip":{"source":"iana"},"application/vnd.solent.sdkm+xml":{"source":"iana","compressible":true,"extensions":["sdkm","sdkd"]},"application/vnd.spotfire.dxp":{"source":"iana","extensions":["dxp"]},"application/vnd.spotfire.sfs":{"source":"iana","extensions":["sfs"]},"application/vnd.sqlite3":{"source":"iana"},"application/vnd.sss-cod":{"source":"iana"},"application/vnd.sss-dtf":{"source":"iana"},"application/vnd.sss-ntf":{"source":"iana"},"application/vnd.stardivision.calc":{"source":"apache","extensions":["sdc"]},"application/vnd.stardivision.draw":{"source":"apache","extensions":["sda"]},"application/vnd.stardivision.impress":{"source":"apache","extensions":["sdd"]},"application/vnd.stardivision.math":{"source":"apache","extensions":["smf"]},"application/vnd.stardivision.writer":{"source":"apache","extensions":["sdw","vor"]},"application/vnd.stardivision.writer-global":{"source":"apache","extensions":["sgl"]},"application/vnd.stepmania.package":{"source":"iana","extensions":["smzip"]},"application/vnd.stepmania.stepchart":{"source":"iana","extensions":["sm"]},"application/vnd.street-stream":{"source":"iana"},"application/vnd.sun.wadl+xml":{"source":"iana","compressible":true,"extensions":["wadl"]},"application/vnd.sun.xml.calc":{"source":"apache","extensions":["sxc"]},"application/vnd.sun.xml.calc.template":{"source":"apache","extensions":["stc"]},"application/vnd.sun.xml.draw":{"source":"apache","extensions":["sxd"]},"application/vnd.sun.xml.draw.template":{"source":"apache","extensions":["std"]},"application/vnd.sun.xml.impress":{"source":"apache","extensions":["sxi"]},"application/vnd.sun.xml.impress.template":{"source":"apache","extensions":["sti"]},"application/vnd.sun.xml.math":{"source":"apache","extensions":["sxm"]},"application/vnd.sun.xml.writer":{"source":"apache","extensions":["sxw"]},"application/vnd.sun.xml.writer.global":{"source":"apache","extensions":["sxg"]},"application/vnd.sun.xml.writer.template":{"source":"apache","extensions":["stw"]},"application/vnd.sus-calendar":{"source":"iana","extensions":["sus","susp"]},"application/vnd.svd":{"source":"iana","extensions":["svd"]},"application/vnd.swiftview-ics":{"source":"iana"},"application/vnd.sycle+xml":{"source":"iana","compressible":true},"application/vnd.syft+json":{"source":"iana","compressible":true},"application/vnd.symbian.install":{"source":"apache","extensions":["sis","sisx"]},"application/vnd.syncml+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xsm"]},"application/vnd.syncml.dm+wbxml":{"source":"iana","charset":"UTF-8","extensions":["bdm"]},"application/vnd.syncml.dm+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["xdm"]},"application/vnd.syncml.dm.notification":{"source":"iana"},"application/vnd.syncml.dmddf+wbxml":{"source":"iana"},"application/vnd.syncml.dmddf+xml":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["ddf"]},"application/vnd.syncml.dmtnds+wbxml":{"source":"iana"},"application/vnd.syncml.dmtnds+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/vnd.syncml.ds.notification":{"source":"iana"},"application/vnd.tableschema+json":{"source":"iana","compressible":true},"application/vnd.tao.intent-module-archive":{"source":"iana","extensions":["tao"]},"application/vnd.tcpdump.pcap":{"source":"iana","extensions":["pcap","cap","dmp"]},"application/vnd.think-cell.ppttc+json":{"source":"iana","compressible":true},"application/vnd.tmd.mediaflex.api+xml":{"source":"iana","compressible":true},"application/vnd.tml":{"source":"iana"},"application/vnd.tmobile-livetv":{"source":"iana","extensions":["tmo"]},"application/vnd.tri.onesource":{"source":"iana"},"application/vnd.trid.tpt":{"source":"iana","extensions":["tpt"]},"application/vnd.triscape.mxs":{"source":"iana","extensions":["mxs"]},"application/vnd.trueapp":{"source":"iana","extensions":["tra"]},"application/vnd.truedoc":{"source":"iana"},"application/vnd.ubisoft.webplayer":{"source":"iana"},"application/vnd.ufdl":{"source":"iana","extensions":["ufd","ufdl"]},"application/vnd.uiq.theme":{"source":"iana","extensions":["utz"]},"application/vnd.umajin":{"source":"iana","extensions":["umj"]},"application/vnd.unity":{"source":"iana","extensions":["unityweb"]},"application/vnd.uoml+xml":{"source":"iana","compressible":true,"extensions":["uoml"]},"application/vnd.uplanet.alert":{"source":"iana"},"application/vnd.uplanet.alert-wbxml":{"source":"iana"},"application/vnd.uplanet.bearer-choice":{"source":"iana"},"application/vnd.uplanet.bearer-choice-wbxml":{"source":"iana"},"application/vnd.uplanet.cacheop":{"source":"iana"},"application/vnd.uplanet.cacheop-wbxml":{"source":"iana"},"application/vnd.uplanet.channel":{"source":"iana"},"application/vnd.uplanet.channel-wbxml":{"source":"iana"},"application/vnd.uplanet.list":{"source":"iana"},"application/vnd.uplanet.list-wbxml":{"source":"iana"},"application/vnd.uplanet.listcmd":{"source":"iana"},"application/vnd.uplanet.listcmd-wbxml":{"source":"iana"},"application/vnd.uplanet.signal":{"source":"iana"},"application/vnd.uri-map":{"source":"iana"},"application/vnd.valve.source.material":{"source":"iana"},"application/vnd.vcx":{"source":"iana","extensions":["vcx"]},"application/vnd.vd-study":{"source":"iana"},"application/vnd.vectorworks":{"source":"iana"},"application/vnd.vel+json":{"source":"iana","compressible":true},"application/vnd.verimatrix.vcas":{"source":"iana"},"application/vnd.veritone.aion+json":{"source":"iana","compressible":true},"application/vnd.veryant.thin":{"source":"iana"},"application/vnd.ves.encrypted":{"source":"iana"},"application/vnd.vidsoft.vidconference":{"source":"iana"},"application/vnd.visio":{"source":"iana","extensions":["vsd","vst","vss","vsw"]},"application/vnd.visionary":{"source":"iana","extensions":["vis"]},"application/vnd.vividence.scriptfile":{"source":"iana"},"application/vnd.vsf":{"source":"iana","extensions":["vsf"]},"application/vnd.wap.sic":{"source":"iana"},"application/vnd.wap.slc":{"source":"iana"},"application/vnd.wap.wbxml":{"source":"iana","charset":"UTF-8","extensions":["wbxml"]},"application/vnd.wap.wmlc":{"source":"iana","extensions":["wmlc"]},"application/vnd.wap.wmlscriptc":{"source":"iana","extensions":["wmlsc"]},"application/vnd.webturbo":{"source":"iana","extensions":["wtb"]},"application/vnd.wfa.dpp":{"source":"iana"},"application/vnd.wfa.p2p":{"source":"iana"},"application/vnd.wfa.wsc":{"source":"iana"},"application/vnd.windows.devicepairing":{"source":"iana"},"application/vnd.wmc":{"source":"iana"},"application/vnd.wmf.bootstrap":{"source":"iana"},"application/vnd.wolfram.mathematica":{"source":"iana"},"application/vnd.wolfram.mathematica.package":{"source":"iana"},"application/vnd.wolfram.player":{"source":"iana","extensions":["nbp"]},"application/vnd.wordperfect":{"source":"iana","extensions":["wpd"]},"application/vnd.wqd":{"source":"iana","extensions":["wqd"]},"application/vnd.wrq-hp3000-labelled":{"source":"iana"},"application/vnd.wt.stf":{"source":"iana","extensions":["stf"]},"application/vnd.wv.csp+wbxml":{"source":"iana"},"application/vnd.wv.csp+xml":{"source":"iana","compressible":true},"application/vnd.wv.ssp+xml":{"source":"iana","compressible":true},"application/vnd.xacml+json":{"source":"iana","compressible":true},"application/vnd.xara":{"source":"iana","extensions":["xar"]},"application/vnd.xfdl":{"source":"iana","extensions":["xfdl"]},"application/vnd.xfdl.webform":{"source":"iana"},"application/vnd.xmi+xml":{"source":"iana","compressible":true},"application/vnd.xmpie.cpkg":{"source":"iana"},"application/vnd.xmpie.dpkg":{"source":"iana"},"application/vnd.xmpie.plan":{"source":"iana"},"application/vnd.xmpie.ppkg":{"source":"iana"},"application/vnd.xmpie.xlim":{"source":"iana"},"application/vnd.yamaha.hv-dic":{"source":"iana","extensions":["hvd"]},"application/vnd.yamaha.hv-script":{"source":"iana","extensions":["hvs"]},"application/vnd.yamaha.hv-voice":{"source":"iana","extensions":["hvp"]},"application/vnd.yamaha.openscoreformat":{"source":"iana","extensions":["osf"]},"application/vnd.yamaha.openscoreformat.osfpvg+xml":{"source":"iana","compressible":true,"extensions":["osfpvg"]},"application/vnd.yamaha.remote-setup":{"source":"iana"},"application/vnd.yamaha.smaf-audio":{"source":"iana","extensions":["saf"]},"application/vnd.yamaha.smaf-phrase":{"source":"iana","extensions":["spf"]},"application/vnd.yamaha.through-ngn":{"source":"iana"},"application/vnd.yamaha.tunnel-udpencap":{"source":"iana"},"application/vnd.yaoweme":{"source":"iana"},"application/vnd.yellowriver-custom-menu":{"source":"iana","extensions":["cmp"]},"application/vnd.youtube.yt":{"source":"iana"},"application/vnd.zul":{"source":"iana","extensions":["zir","zirz"]},"application/vnd.zzazz.deck+xml":{"source":"iana","compressible":true,"extensions":["zaz"]},"application/voicexml+xml":{"source":"iana","compressible":true,"extensions":["vxml"]},"application/voucher-cms+json":{"source":"iana","compressible":true},"application/vq-rtcpxr":{"source":"iana"},"application/wasm":{"source":"iana","compressible":true,"extensions":["wasm"]},"application/watcherinfo+xml":{"source":"iana","compressible":true,"extensions":["wif"]},"application/webpush-options+json":{"source":"iana","compressible":true},"application/whoispp-query":{"source":"iana"},"application/whoispp-response":{"source":"iana"},"application/widget":{"source":"iana","extensions":["wgt"]},"application/winhlp":{"source":"apache","extensions":["hlp"]},"application/wita":{"source":"iana"},"application/wordperfect5.1":{"source":"iana"},"application/wsdl+xml":{"source":"iana","compressible":true,"extensions":["wsdl"]},"application/wspolicy+xml":{"source":"iana","compressible":true,"extensions":["wspolicy"]},"application/x-7z-compressed":{"source":"apache","compressible":false,"extensions":["7z"]},"application/x-abiword":{"source":"apache","extensions":["abw"]},"application/x-ace-compressed":{"source":"apache","extensions":["ace"]},"application/x-amf":{"source":"apache"},"application/x-apple-diskimage":{"source":"apache","extensions":["dmg"]},"application/x-arj":{"compressible":false,"extensions":["arj"]},"application/x-authorware-bin":{"source":"apache","extensions":["aab","x32","u32","vox"]},"application/x-authorware-map":{"source":"apache","extensions":["aam"]},"application/x-authorware-seg":{"source":"apache","extensions":["aas"]},"application/x-bcpio":{"source":"apache","extensions":["bcpio"]},"application/x-bdoc":{"compressible":false,"extensions":["bdoc"]},"application/x-bittorrent":{"source":"apache","extensions":["torrent"]},"application/x-blorb":{"source":"apache","extensions":["blb","blorb"]},"application/x-bzip":{"source":"apache","compressible":false,"extensions":["bz"]},"application/x-bzip2":{"source":"apache","compressible":false,"extensions":["bz2","boz"]},"application/x-cbr":{"source":"apache","extensions":["cbr","cba","cbt","cbz","cb7"]},"application/x-cdlink":{"source":"apache","extensions":["vcd"]},"application/x-cfs-compressed":{"source":"apache","extensions":["cfs"]},"application/x-chat":{"source":"apache","extensions":["chat"]},"application/x-chess-pgn":{"source":"apache","extensions":["pgn"]},"application/x-chrome-extension":{"extensions":["crx"]},"application/x-cocoa":{"source":"nginx","extensions":["cco"]},"application/x-compress":{"source":"apache"},"application/x-conference":{"source":"apache","extensions":["nsc"]},"application/x-cpio":{"source":"apache","extensions":["cpio"]},"application/x-csh":{"source":"apache","extensions":["csh"]},"application/x-deb":{"compressible":false},"application/x-debian-package":{"source":"apache","extensions":["deb","udeb"]},"application/x-dgc-compressed":{"source":"apache","extensions":["dgc"]},"application/x-director":{"source":"apache","extensions":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]},"application/x-doom":{"source":"apache","extensions":["wad"]},"application/x-dtbncx+xml":{"source":"apache","compressible":true,"extensions":["ncx"]},"application/x-dtbook+xml":{"source":"apache","compressible":true,"extensions":["dtb"]},"application/x-dtbresource+xml":{"source":"apache","compressible":true,"extensions":["res"]},"application/x-dvi":{"source":"apache","compressible":false,"extensions":["dvi"]},"application/x-envoy":{"source":"apache","extensions":["evy"]},"application/x-eva":{"source":"apache","extensions":["eva"]},"application/x-font-bdf":{"source":"apache","extensions":["bdf"]},"application/x-font-dos":{"source":"apache"},"application/x-font-framemaker":{"source":"apache"},"application/x-font-ghostscript":{"source":"apache","extensions":["gsf"]},"application/x-font-libgrx":{"source":"apache"},"application/x-font-linux-psf":{"source":"apache","extensions":["psf"]},"application/x-font-pcf":{"source":"apache","extensions":["pcf"]},"application/x-font-snf":{"source":"apache","extensions":["snf"]},"application/x-font-speedo":{"source":"apache"},"application/x-font-sunos-news":{"source":"apache"},"application/x-font-type1":{"source":"apache","extensions":["pfa","pfb","pfm","afm"]},"application/x-font-vfont":{"source":"apache"},"application/x-freearc":{"source":"apache","extensions":["arc"]},"application/x-futuresplash":{"source":"apache","extensions":["spl"]},"application/x-gca-compressed":{"source":"apache","extensions":["gca"]},"application/x-glulx":{"source":"apache","extensions":["ulx"]},"application/x-gnumeric":{"source":"apache","extensions":["gnumeric"]},"application/x-gramps-xml":{"source":"apache","extensions":["gramps"]},"application/x-gtar":{"source":"apache","extensions":["gtar"]},"application/x-gzip":{"source":"apache"},"application/x-hdf":{"source":"apache","extensions":["hdf"]},"application/x-httpd-php":{"compressible":true,"extensions":["php"]},"application/x-install-instructions":{"source":"apache","extensions":["install"]},"application/x-iso9660-image":{"source":"apache","extensions":["iso"]},"application/x-iwork-keynote-sffkey":{"extensions":["key"]},"application/x-iwork-numbers-sffnumbers":{"extensions":["numbers"]},"application/x-iwork-pages-sffpages":{"extensions":["pages"]},"application/x-java-archive-diff":{"source":"nginx","extensions":["jardiff"]},"application/x-java-jnlp-file":{"source":"apache","compressible":false,"extensions":["jnlp"]},"application/x-javascript":{"compressible":true},"application/x-keepass2":{"extensions":["kdbx"]},"application/x-latex":{"source":"apache","compressible":false,"extensions":["latex"]},"application/x-lua-bytecode":{"extensions":["luac"]},"application/x-lzh-compressed":{"source":"apache","extensions":["lzh","lha"]},"application/x-makeself":{"source":"nginx","extensions":["run"]},"application/x-mie":{"source":"apache","extensions":["mie"]},"application/x-mobipocket-ebook":{"source":"apache","extensions":["prc","mobi"]},"application/x-mpegurl":{"compressible":false},"application/x-ms-application":{"source":"apache","extensions":["application"]},"application/x-ms-shortcut":{"source":"apache","extensions":["lnk"]},"application/x-ms-wmd":{"source":"apache","extensions":["wmd"]},"application/x-ms-wmz":{"source":"apache","extensions":["wmz"]},"application/x-ms-xbap":{"source":"apache","extensions":["xbap"]},"application/x-msaccess":{"source":"apache","extensions":["mdb"]},"application/x-msbinder":{"source":"apache","extensions":["obd"]},"application/x-mscardfile":{"source":"apache","extensions":["crd"]},"application/x-msclip":{"source":"apache","extensions":["clp"]},"application/x-msdos-program":{"extensions":["exe"]},"application/x-msdownload":{"source":"apache","extensions":["exe","dll","com","bat","msi"]},"application/x-msmediaview":{"source":"apache","extensions":["mvb","m13","m14"]},"application/x-msmetafile":{"source":"apache","extensions":["wmf","wmz","emf","emz"]},"application/x-msmoney":{"source":"apache","extensions":["mny"]},"application/x-mspublisher":{"source":"apache","extensions":["pub"]},"application/x-msschedule":{"source":"apache","extensions":["scd"]},"application/x-msterminal":{"source":"apache","extensions":["trm"]},"application/x-mswrite":{"source":"apache","extensions":["wri"]},"application/x-netcdf":{"source":"apache","extensions":["nc","cdf"]},"application/x-ns-proxy-autoconfig":{"compressible":true,"extensions":["pac"]},"application/x-nzb":{"source":"apache","extensions":["nzb"]},"application/x-perl":{"source":"nginx","extensions":["pl","pm"]},"application/x-pilot":{"source":"nginx","extensions":["prc","pdb"]},"application/x-pkcs12":{"source":"apache","compressible":false,"extensions":["p12","pfx"]},"application/x-pkcs7-certificates":{"source":"apache","extensions":["p7b","spc"]},"application/x-pkcs7-certreqresp":{"source":"apache","extensions":["p7r"]},"application/x-pki-message":{"source":"iana"},"application/x-rar-compressed":{"source":"apache","compressible":false,"extensions":["rar"]},"application/x-redhat-package-manager":{"source":"nginx","extensions":["rpm"]},"application/x-research-info-systems":{"source":"apache","extensions":["ris"]},"application/x-sea":{"source":"nginx","extensions":["sea"]},"application/x-sh":{"source":"apache","compressible":true,"extensions":["sh"]},"application/x-shar":{"source":"apache","extensions":["shar"]},"application/x-shockwave-flash":{"source":"apache","compressible":false,"extensions":["swf"]},"application/x-silverlight-app":{"source":"apache","extensions":["xap"]},"application/x-sql":{"source":"apache","extensions":["sql"]},"application/x-stuffit":{"source":"apache","compressible":false,"extensions":["sit"]},"application/x-stuffitx":{"source":"apache","extensions":["sitx"]},"application/x-subrip":{"source":"apache","extensions":["srt"]},"application/x-sv4cpio":{"source":"apache","extensions":["sv4cpio"]},"application/x-sv4crc":{"source":"apache","extensions":["sv4crc"]},"application/x-t3vm-image":{"source":"apache","extensions":["t3"]},"application/x-tads":{"source":"apache","extensions":["gam"]},"application/x-tar":{"source":"apache","compressible":true,"extensions":["tar"]},"application/x-tcl":{"source":"apache","extensions":["tcl","tk"]},"application/x-tex":{"source":"apache","extensions":["tex"]},"application/x-tex-tfm":{"source":"apache","extensions":["tfm"]},"application/x-texinfo":{"source":"apache","extensions":["texinfo","texi"]},"application/x-tgif":{"source":"apache","extensions":["obj"]},"application/x-ustar":{"source":"apache","extensions":["ustar"]},"application/x-virtualbox-hdd":{"compressible":true,"extensions":["hdd"]},"application/x-virtualbox-ova":{"compressible":true,"extensions":["ova"]},"application/x-virtualbox-ovf":{"compressible":true,"extensions":["ovf"]},"application/x-virtualbox-vbox":{"compressible":true,"extensions":["vbox"]},"application/x-virtualbox-vbox-extpack":{"compressible":false,"extensions":["vbox-extpack"]},"application/x-virtualbox-vdi":{"compressible":true,"extensions":["vdi"]},"application/x-virtualbox-vhd":{"compressible":true,"extensions":["vhd"]},"application/x-virtualbox-vmdk":{"compressible":true,"extensions":["vmdk"]},"application/x-wais-source":{"source":"apache","extensions":["src"]},"application/x-web-app-manifest+json":{"compressible":true,"extensions":["webapp"]},"application/x-www-form-urlencoded":{"source":"iana","compressible":true},"application/x-x509-ca-cert":{"source":"iana","extensions":["der","crt","pem"]},"application/x-x509-ca-ra-cert":{"source":"iana"},"application/x-x509-next-ca-cert":{"source":"iana"},"application/x-xfig":{"source":"apache","extensions":["fig"]},"application/x-xliff+xml":{"source":"apache","compressible":true,"extensions":["xlf"]},"application/x-xpinstall":{"source":"apache","compressible":false,"extensions":["xpi"]},"application/x-xz":{"source":"apache","extensions":["xz"]},"application/x-zmachine":{"source":"apache","extensions":["z1","z2","z3","z4","z5","z6","z7","z8"]},"application/x400-bp":{"source":"iana"},"application/xacml+xml":{"source":"iana","compressible":true},"application/xaml+xml":{"source":"apache","compressible":true,"extensions":["xaml"]},"application/xcap-att+xml":{"source":"iana","compressible":true,"extensions":["xav"]},"application/xcap-caps+xml":{"source":"iana","compressible":true,"extensions":["xca"]},"application/xcap-diff+xml":{"source":"iana","compressible":true,"extensions":["xdf"]},"application/xcap-el+xml":{"source":"iana","compressible":true,"extensions":["xel"]},"application/xcap-error+xml":{"source":"iana","compressible":true},"application/xcap-ns+xml":{"source":"iana","compressible":true,"extensions":["xns"]},"application/xcon-conference-info+xml":{"source":"iana","compressible":true},"application/xcon-conference-info-diff+xml":{"source":"iana","compressible":true},"application/xenc+xml":{"source":"iana","compressible":true,"extensions":["xenc"]},"application/xhtml+xml":{"source":"iana","compressible":true,"extensions":["xhtml","xht"]},"application/xhtml-voice+xml":{"source":"apache","compressible":true},"application/xliff+xml":{"source":"iana","compressible":true,"extensions":["xlf"]},"application/xml":{"source":"iana","compressible":true,"extensions":["xml","xsl","xsd","rng"]},"application/xml-dtd":{"source":"iana","compressible":true,"extensions":["dtd"]},"application/xml-external-parsed-entity":{"source":"iana"},"application/xml-patch+xml":{"source":"iana","compressible":true},"application/xmpp+xml":{"source":"iana","compressible":true},"application/xop+xml":{"source":"iana","compressible":true,"extensions":["xop"]},"application/xproc+xml":{"source":"apache","compressible":true,"extensions":["xpl"]},"application/xslt+xml":{"source":"iana","compressible":true,"extensions":["xsl","xslt"]},"application/xspf+xml":{"source":"apache","compressible":true,"extensions":["xspf"]},"application/xv+xml":{"source":"iana","compressible":true,"extensions":["mxml","xhvml","xvml","xvm"]},"application/yang":{"source":"iana","extensions":["yang"]},"application/yang-data+json":{"source":"iana","compressible":true},"application/yang-data+xml":{"source":"iana","compressible":true},"application/yang-patch+json":{"source":"iana","compressible":true},"application/yang-patch+xml":{"source":"iana","compressible":true},"application/yin+xml":{"source":"iana","compressible":true,"extensions":["yin"]},"application/zip":{"source":"iana","compressible":false,"extensions":["zip"]},"application/zlib":{"source":"iana"},"application/zstd":{"source":"iana"},"audio/1d-interleaved-parityfec":{"source":"iana"},"audio/32kadpcm":{"source":"iana"},"audio/3gpp":{"source":"iana","compressible":false,"extensions":["3gpp"]},"audio/3gpp2":{"source":"iana"},"audio/aac":{"source":"iana"},"audio/ac3":{"source":"iana"},"audio/adpcm":{"source":"apache","extensions":["adp"]},"audio/amr":{"source":"iana","extensions":["amr"]},"audio/amr-wb":{"source":"iana"},"audio/amr-wb+":{"source":"iana"},"audio/aptx":{"source":"iana"},"audio/asc":{"source":"iana"},"audio/atrac-advanced-lossless":{"source":"iana"},"audio/atrac-x":{"source":"iana"},"audio/atrac3":{"source":"iana"},"audio/basic":{"source":"iana","compressible":false,"extensions":["au","snd"]},"audio/bv16":{"source":"iana"},"audio/bv32":{"source":"iana"},"audio/clearmode":{"source":"iana"},"audio/cn":{"source":"iana"},"audio/dat12":{"source":"iana"},"audio/dls":{"source":"iana"},"audio/dsr-es201108":{"source":"iana"},"audio/dsr-es202050":{"source":"iana"},"audio/dsr-es202211":{"source":"iana"},"audio/dsr-es202212":{"source":"iana"},"audio/dv":{"source":"iana"},"audio/dvi4":{"source":"iana"},"audio/eac3":{"source":"iana"},"audio/encaprtp":{"source":"iana"},"audio/evrc":{"source":"iana"},"audio/evrc-qcp":{"source":"iana"},"audio/evrc0":{"source":"iana"},"audio/evrc1":{"source":"iana"},"audio/evrcb":{"source":"iana"},"audio/evrcb0":{"source":"iana"},"audio/evrcb1":{"source":"iana"},"audio/evrcnw":{"source":"iana"},"audio/evrcnw0":{"source":"iana"},"audio/evrcnw1":{"source":"iana"},"audio/evrcwb":{"source":"iana"},"audio/evrcwb0":{"source":"iana"},"audio/evrcwb1":{"source":"iana"},"audio/evs":{"source":"iana"},"audio/flexfec":{"source":"iana"},"audio/fwdred":{"source":"iana"},"audio/g711-0":{"source":"iana"},"audio/g719":{"source":"iana"},"audio/g722":{"source":"iana"},"audio/g7221":{"source":"iana"},"audio/g723":{"source":"iana"},"audio/g726-16":{"source":"iana"},"audio/g726-24":{"source":"iana"},"audio/g726-32":{"source":"iana"},"audio/g726-40":{"source":"iana"},"audio/g728":{"source":"iana"},"audio/g729":{"source":"iana"},"audio/g7291":{"source":"iana"},"audio/g729d":{"source":"iana"},"audio/g729e":{"source":"iana"},"audio/gsm":{"source":"iana"},"audio/gsm-efr":{"source":"iana"},"audio/gsm-hr-08":{"source":"iana"},"audio/ilbc":{"source":"iana"},"audio/ip-mr_v2.5":{"source":"iana"},"audio/isac":{"source":"apache"},"audio/l16":{"source":"iana"},"audio/l20":{"source":"iana"},"audio/l24":{"source":"iana","compressible":false},"audio/l8":{"source":"iana"},"audio/lpc":{"source":"iana"},"audio/melp":{"source":"iana"},"audio/melp1200":{"source":"iana"},"audio/melp2400":{"source":"iana"},"audio/melp600":{"source":"iana"},"audio/mhas":{"source":"iana"},"audio/midi":{"source":"apache","extensions":["mid","midi","kar","rmi"]},"audio/mobile-xmf":{"source":"iana","extensions":["mxmf"]},"audio/mp3":{"compressible":false,"extensions":["mp3"]},"audio/mp4":{"source":"iana","compressible":false,"extensions":["m4a","mp4a"]},"audio/mp4a-latm":{"source":"iana"},"audio/mpa":{"source":"iana"},"audio/mpa-robust":{"source":"iana"},"audio/mpeg":{"source":"iana","compressible":false,"extensions":["mpga","mp2","mp2a","mp3","m2a","m3a"]},"audio/mpeg4-generic":{"source":"iana"},"audio/musepack":{"source":"apache"},"audio/ogg":{"source":"iana","compressible":false,"extensions":["oga","ogg","spx","opus"]},"audio/opus":{"source":"iana"},"audio/parityfec":{"source":"iana"},"audio/pcma":{"source":"iana"},"audio/pcma-wb":{"source":"iana"},"audio/pcmu":{"source":"iana"},"audio/pcmu-wb":{"source":"iana"},"audio/prs.sid":{"source":"iana"},"audio/qcelp":{"source":"iana"},"audio/raptorfec":{"source":"iana"},"audio/red":{"source":"iana"},"audio/rtp-enc-aescm128":{"source":"iana"},"audio/rtp-midi":{"source":"iana"},"audio/rtploopback":{"source":"iana"},"audio/rtx":{"source":"iana"},"audio/s3m":{"source":"apache","extensions":["s3m"]},"audio/scip":{"source":"iana"},"audio/silk":{"source":"apache","extensions":["sil"]},"audio/smv":{"source":"iana"},"audio/smv-qcp":{"source":"iana"},"audio/smv0":{"source":"iana"},"audio/sofa":{"source":"iana"},"audio/sp-midi":{"source":"iana"},"audio/speex":{"source":"iana"},"audio/t140c":{"source":"iana"},"audio/t38":{"source":"iana"},"audio/telephone-event":{"source":"iana"},"audio/tetra_acelp":{"source":"iana"},"audio/tetra_acelp_bb":{"source":"iana"},"audio/tone":{"source":"iana"},"audio/tsvcis":{"source":"iana"},"audio/uemclip":{"source":"iana"},"audio/ulpfec":{"source":"iana"},"audio/usac":{"source":"iana"},"audio/vdvi":{"source":"iana"},"audio/vmr-wb":{"source":"iana"},"audio/vnd.3gpp.iufp":{"source":"iana"},"audio/vnd.4sb":{"source":"iana"},"audio/vnd.audiokoz":{"source":"iana"},"audio/vnd.celp":{"source":"iana"},"audio/vnd.cisco.nse":{"source":"iana"},"audio/vnd.cmles.radio-events":{"source":"iana"},"audio/vnd.cns.anp1":{"source":"iana"},"audio/vnd.cns.inf1":{"source":"iana"},"audio/vnd.dece.audio":{"source":"iana","extensions":["uva","uvva"]},"audio/vnd.digital-winds":{"source":"iana","extensions":["eol"]},"audio/vnd.dlna.adts":{"source":"iana"},"audio/vnd.dolby.heaac.1":{"source":"iana"},"audio/vnd.dolby.heaac.2":{"source":"iana"},"audio/vnd.dolby.mlp":{"source":"iana"},"audio/vnd.dolby.mps":{"source":"iana"},"audio/vnd.dolby.pl2":{"source":"iana"},"audio/vnd.dolby.pl2x":{"source":"iana"},"audio/vnd.dolby.pl2z":{"source":"iana"},"audio/vnd.dolby.pulse.1":{"source":"iana"},"audio/vnd.dra":{"source":"iana","extensions":["dra"]},"audio/vnd.dts":{"source":"iana","extensions":["dts"]},"audio/vnd.dts.hd":{"source":"iana","extensions":["dtshd"]},"audio/vnd.dts.uhd":{"source":"iana"},"audio/vnd.dvb.file":{"source":"iana"},"audio/vnd.everad.plj":{"source":"iana"},"audio/vnd.hns.audio":{"source":"iana"},"audio/vnd.lucent.voice":{"source":"iana","extensions":["lvp"]},"audio/vnd.ms-playready.media.pya":{"source":"iana","extensions":["pya"]},"audio/vnd.nokia.mobile-xmf":{"source":"iana"},"audio/vnd.nortel.vbk":{"source":"iana"},"audio/vnd.nuera.ecelp4800":{"source":"iana","extensions":["ecelp4800"]},"audio/vnd.nuera.ecelp7470":{"source":"iana","extensions":["ecelp7470"]},"audio/vnd.nuera.ecelp9600":{"source":"iana","extensions":["ecelp9600"]},"audio/vnd.octel.sbc":{"source":"iana"},"audio/vnd.presonus.multitrack":{"source":"iana"},"audio/vnd.qcelp":{"source":"iana"},"audio/vnd.rhetorex.32kadpcm":{"source":"iana"},"audio/vnd.rip":{"source":"iana","extensions":["rip"]},"audio/vnd.rn-realaudio":{"compressible":false},"audio/vnd.sealedmedia.softseal.mpeg":{"source":"iana"},"audio/vnd.vmx.cvsd":{"source":"iana"},"audio/vnd.wave":{"compressible":false},"audio/vorbis":{"source":"iana","compressible":false},"audio/vorbis-config":{"source":"iana"},"audio/wav":{"compressible":false,"extensions":["wav"]},"audio/wave":{"compressible":false,"extensions":["wav"]},"audio/webm":{"source":"apache","compressible":false,"extensions":["weba"]},"audio/x-aac":{"source":"apache","compressible":false,"extensions":["aac"]},"audio/x-aiff":{"source":"apache","extensions":["aif","aiff","aifc"]},"audio/x-caf":{"source":"apache","compressible":false,"extensions":["caf"]},"audio/x-flac":{"source":"apache","extensions":["flac"]},"audio/x-m4a":{"source":"nginx","extensions":["m4a"]},"audio/x-matroska":{"source":"apache","extensions":["mka"]},"audio/x-mpegurl":{"source":"apache","extensions":["m3u"]},"audio/x-ms-wax":{"source":"apache","extensions":["wax"]},"audio/x-ms-wma":{"source":"apache","extensions":["wma"]},"audio/x-pn-realaudio":{"source":"apache","extensions":["ram","ra"]},"audio/x-pn-realaudio-plugin":{"source":"apache","extensions":["rmp"]},"audio/x-realaudio":{"source":"nginx","extensions":["ra"]},"audio/x-tta":{"source":"apache"},"audio/x-wav":{"source":"apache","extensions":["wav"]},"audio/xm":{"source":"apache","extensions":["xm"]},"chemical/x-cdx":{"source":"apache","extensions":["cdx"]},"chemical/x-cif":{"source":"apache","extensions":["cif"]},"chemical/x-cmdf":{"source":"apache","extensions":["cmdf"]},"chemical/x-cml":{"source":"apache","extensions":["cml"]},"chemical/x-csml":{"source":"apache","extensions":["csml"]},"chemical/x-pdb":{"source":"apache"},"chemical/x-xyz":{"source":"apache","extensions":["xyz"]},"font/collection":{"source":"iana","extensions":["ttc"]},"font/otf":{"source":"iana","compressible":true,"extensions":["otf"]},"font/sfnt":{"source":"iana"},"font/ttf":{"source":"iana","compressible":true,"extensions":["ttf"]},"font/woff":{"source":"iana","extensions":["woff"]},"font/woff2":{"source":"iana","extensions":["woff2"]},"image/aces":{"source":"iana","extensions":["exr"]},"image/apng":{"compressible":false,"extensions":["apng"]},"image/avci":{"source":"iana","extensions":["avci"]},"image/avcs":{"source":"iana","extensions":["avcs"]},"image/avif":{"source":"iana","compressible":false,"extensions":["avif"]},"image/bmp":{"source":"iana","compressible":true,"extensions":["bmp"]},"image/cgm":{"source":"iana","extensions":["cgm"]},"image/dicom-rle":{"source":"iana","extensions":["drle"]},"image/emf":{"source":"iana","extensions":["emf"]},"image/fits":{"source":"iana","extensions":["fits"]},"image/g3fax":{"source":"iana","extensions":["g3"]},"image/gif":{"source":"iana","compressible":false,"extensions":["gif"]},"image/heic":{"source":"iana","extensions":["heic"]},"image/heic-sequence":{"source":"iana","extensions":["heics"]},"image/heif":{"source":"iana","extensions":["heif"]},"image/heif-sequence":{"source":"iana","extensions":["heifs"]},"image/hej2k":{"source":"iana","extensions":["hej2"]},"image/hsj2":{"source":"iana","extensions":["hsj2"]},"image/ief":{"source":"iana","extensions":["ief"]},"image/jls":{"source":"iana","extensions":["jls"]},"image/jp2":{"source":"iana","compressible":false,"extensions":["jp2","jpg2"]},"image/jpeg":{"source":"iana","compressible":false,"extensions":["jpeg","jpg","jpe"]},"image/jph":{"source":"iana","extensions":["jph"]},"image/jphc":{"source":"iana","extensions":["jhc"]},"image/jpm":{"source":"iana","compressible":false,"extensions":["jpm"]},"image/jpx":{"source":"iana","compressible":false,"extensions":["jpx","jpf"]},"image/jxr":{"source":"iana","extensions":["jxr"]},"image/jxra":{"source":"iana","extensions":["jxra"]},"image/jxrs":{"source":"iana","extensions":["jxrs"]},"image/jxs":{"source":"iana","extensions":["jxs"]},"image/jxsc":{"source":"iana","extensions":["jxsc"]},"image/jxsi":{"source":"iana","extensions":["jxsi"]},"image/jxss":{"source":"iana","extensions":["jxss"]},"image/ktx":{"source":"iana","extensions":["ktx"]},"image/ktx2":{"source":"iana","extensions":["ktx2"]},"image/naplps":{"source":"iana"},"image/pjpeg":{"compressible":false},"image/png":{"source":"iana","compressible":false,"extensions":["png"]},"image/prs.btif":{"source":"iana","extensions":["btif"]},"image/prs.pti":{"source":"iana","extensions":["pti"]},"image/pwg-raster":{"source":"iana"},"image/sgi":{"source":"apache","extensions":["sgi"]},"image/svg+xml":{"source":"iana","compressible":true,"extensions":["svg","svgz"]},"image/t38":{"source":"iana","extensions":["t38"]},"image/tiff":{"source":"iana","compressible":false,"extensions":["tif","tiff"]},"image/tiff-fx":{"source":"iana","extensions":["tfx"]},"image/vnd.adobe.photoshop":{"source":"iana","compressible":true,"extensions":["psd"]},"image/vnd.airzip.accelerator.azv":{"source":"iana","extensions":["azv"]},"image/vnd.cns.inf2":{"source":"iana"},"image/vnd.dece.graphic":{"source":"iana","extensions":["uvi","uvvi","uvg","uvvg"]},"image/vnd.djvu":{"source":"iana","extensions":["djvu","djv"]},"image/vnd.dvb.subtitle":{"source":"iana","extensions":["sub"]},"image/vnd.dwg":{"source":"iana","extensions":["dwg"]},"image/vnd.dxf":{"source":"iana","extensions":["dxf"]},"image/vnd.fastbidsheet":{"source":"iana","extensions":["fbs"]},"image/vnd.fpx":{"source":"iana","extensions":["fpx"]},"image/vnd.fst":{"source":"iana","extensions":["fst"]},"image/vnd.fujixerox.edmics-mmr":{"source":"iana","extensions":["mmr"]},"image/vnd.fujixerox.edmics-rlc":{"source":"iana","extensions":["rlc"]},"image/vnd.globalgraphics.pgb":{"source":"iana"},"image/vnd.microsoft.icon":{"source":"iana","compressible":true,"extensions":["ico"]},"image/vnd.mix":{"source":"iana"},"image/vnd.mozilla.apng":{"source":"iana"},"image/vnd.ms-dds":{"compressible":true,"extensions":["dds"]},"image/vnd.ms-modi":{"source":"iana","extensions":["mdi"]},"image/vnd.ms-photo":{"source":"apache","extensions":["wdp"]},"image/vnd.net-fpx":{"source":"iana","extensions":["npx"]},"image/vnd.pco.b16":{"source":"iana","extensions":["b16"]},"image/vnd.radiance":{"source":"iana"},"image/vnd.sealed.png":{"source":"iana"},"image/vnd.sealedmedia.softseal.gif":{"source":"iana"},"image/vnd.sealedmedia.softseal.jpg":{"source":"iana"},"image/vnd.svf":{"source":"iana"},"image/vnd.tencent.tap":{"source":"iana","extensions":["tap"]},"image/vnd.valve.source.texture":{"source":"iana","extensions":["vtf"]},"image/vnd.wap.wbmp":{"source":"iana","extensions":["wbmp"]},"image/vnd.xiff":{"source":"iana","extensions":["xif"]},"image/vnd.zbrush.pcx":{"source":"iana","extensions":["pcx"]},"image/webp":{"source":"apache","extensions":["webp"]},"image/wmf":{"source":"iana","extensions":["wmf"]},"image/x-3ds":{"source":"apache","extensions":["3ds"]},"image/x-cmu-raster":{"source":"apache","extensions":["ras"]},"image/x-cmx":{"source":"apache","extensions":["cmx"]},"image/x-freehand":{"source":"apache","extensions":["fh","fhc","fh4","fh5","fh7"]},"image/x-icon":{"source":"apache","compressible":true,"extensions":["ico"]},"image/x-jng":{"source":"nginx","extensions":["jng"]},"image/x-mrsid-image":{"source":"apache","extensions":["sid"]},"image/x-ms-bmp":{"source":"nginx","compressible":true,"extensions":["bmp"]},"image/x-pcx":{"source":"apache","extensions":["pcx"]},"image/x-pict":{"source":"apache","extensions":["pic","pct"]},"image/x-portable-anymap":{"source":"apache","extensions":["pnm"]},"image/x-portable-bitmap":{"source":"apache","extensions":["pbm"]},"image/x-portable-graymap":{"source":"apache","extensions":["pgm"]},"image/x-portable-pixmap":{"source":"apache","extensions":["ppm"]},"image/x-rgb":{"source":"apache","extensions":["rgb"]},"image/x-tga":{"source":"apache","extensions":["tga"]},"image/x-xbitmap":{"source":"apache","extensions":["xbm"]},"image/x-xcf":{"compressible":false},"image/x-xpixmap":{"source":"apache","extensions":["xpm"]},"image/x-xwindowdump":{"source":"apache","extensions":["xwd"]},"message/cpim":{"source":"iana"},"message/delivery-status":{"source":"iana"},"message/disposition-notification":{"source":"iana","extensions":["disposition-notification"]},"message/external-body":{"source":"iana"},"message/feedback-report":{"source":"iana"},"message/global":{"source":"iana","extensions":["u8msg"]},"message/global-delivery-status":{"source":"iana","extensions":["u8dsn"]},"message/global-disposition-notification":{"source":"iana","extensions":["u8mdn"]},"message/global-headers":{"source":"iana","extensions":["u8hdr"]},"message/http":{"source":"iana","compressible":false},"message/imdn+xml":{"source":"iana","compressible":true},"message/news":{"source":"iana"},"message/partial":{"source":"iana","compressible":false},"message/rfc822":{"source":"iana","compressible":true,"extensions":["eml","mime"]},"message/s-http":{"source":"iana"},"message/sip":{"source":"iana"},"message/sipfrag":{"source":"iana"},"message/tracking-status":{"source":"iana"},"message/vnd.si.simp":{"source":"iana"},"message/vnd.wfa.wsc":{"source":"iana","extensions":["wsc"]},"model/3mf":{"source":"iana","extensions":["3mf"]},"model/e57":{"source":"iana"},"model/gltf+json":{"source":"iana","compressible":true,"extensions":["gltf"]},"model/gltf-binary":{"source":"iana","compressible":true,"extensions":["glb"]},"model/iges":{"source":"iana","compressible":false,"extensions":["igs","iges"]},"model/mesh":{"source":"iana","compressible":false,"extensions":["msh","mesh","silo"]},"model/mtl":{"source":"iana","extensions":["mtl"]},"model/obj":{"source":"iana","extensions":["obj"]},"model/step":{"source":"iana"},"model/step+xml":{"source":"iana","compressible":true,"extensions":["stpx"]},"model/step+zip":{"source":"iana","compressible":false,"extensions":["stpz"]},"model/step-xml+zip":{"source":"iana","compressible":false,"extensions":["stpxz"]},"model/stl":{"source":"iana","extensions":["stl"]},"model/vnd.collada+xml":{"source":"iana","compressible":true,"extensions":["dae"]},"model/vnd.dwf":{"source":"iana","extensions":["dwf"]},"model/vnd.flatland.3dml":{"source":"iana"},"model/vnd.gdl":{"source":"iana","extensions":["gdl"]},"model/vnd.gs-gdl":{"source":"apache"},"model/vnd.gs.gdl":{"source":"iana"},"model/vnd.gtw":{"source":"iana","extensions":["gtw"]},"model/vnd.moml+xml":{"source":"iana","compressible":true},"model/vnd.mts":{"source":"iana","extensions":["mts"]},"model/vnd.opengex":{"source":"iana","extensions":["ogex"]},"model/vnd.parasolid.transmit.binary":{"source":"iana","extensions":["x_b"]},"model/vnd.parasolid.transmit.text":{"source":"iana","extensions":["x_t"]},"model/vnd.pytha.pyox":{"source":"iana"},"model/vnd.rosette.annotated-data-model":{"source":"iana"},"model/vnd.sap.vds":{"source":"iana","extensions":["vds"]},"model/vnd.usdz+zip":{"source":"iana","compressible":false,"extensions":["usdz"]},"model/vnd.valve.source.compiled-map":{"source":"iana","extensions":["bsp"]},"model/vnd.vtu":{"source":"iana","extensions":["vtu"]},"model/vrml":{"source":"iana","compressible":false,"extensions":["wrl","vrml"]},"model/x3d+binary":{"source":"apache","compressible":false,"extensions":["x3db","x3dbz"]},"model/x3d+fastinfoset":{"source":"iana","extensions":["x3db"]},"model/x3d+vrml":{"source":"apache","compressible":false,"extensions":["x3dv","x3dvz"]},"model/x3d+xml":{"source":"iana","compressible":true,"extensions":["x3d","x3dz"]},"model/x3d-vrml":{"source":"iana","extensions":["x3dv"]},"multipart/alternative":{"source":"iana","compressible":false},"multipart/appledouble":{"source":"iana"},"multipart/byteranges":{"source":"iana"},"multipart/digest":{"source":"iana"},"multipart/encrypted":{"source":"iana","compressible":false},"multipart/form-data":{"source":"iana","compressible":false},"multipart/header-set":{"source":"iana"},"multipart/mixed":{"source":"iana"},"multipart/multilingual":{"source":"iana"},"multipart/parallel":{"source":"iana"},"multipart/related":{"source":"iana","compressible":false},"multipart/report":{"source":"iana"},"multipart/signed":{"source":"iana","compressible":false},"multipart/vnd.bint.med-plus":{"source":"iana"},"multipart/voice-message":{"source":"iana"},"multipart/x-mixed-replace":{"source":"iana"},"text/1d-interleaved-parityfec":{"source":"iana"},"text/cache-manifest":{"source":"iana","compressible":true,"extensions":["appcache","manifest"]},"text/calendar":{"source":"iana","extensions":["ics","ifb"]},"text/calender":{"compressible":true},"text/cmd":{"compressible":true},"text/coffeescript":{"extensions":["coffee","litcoffee"]},"text/cql":{"source":"iana"},"text/cql-expression":{"source":"iana"},"text/cql-identifier":{"source":"iana"},"text/css":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["css"]},"text/csv":{"source":"iana","compressible":true,"extensions":["csv"]},"text/csv-schema":{"source":"iana"},"text/directory":{"source":"iana"},"text/dns":{"source":"iana"},"text/ecmascript":{"source":"iana"},"text/encaprtp":{"source":"iana"},"text/enriched":{"source":"iana"},"text/fhirpath":{"source":"iana"},"text/flexfec":{"source":"iana"},"text/fwdred":{"source":"iana"},"text/gff3":{"source":"iana"},"text/grammar-ref-list":{"source":"iana"},"text/html":{"source":"iana","compressible":true,"extensions":["html","htm","shtml"]},"text/jade":{"extensions":["jade"]},"text/javascript":{"source":"iana","compressible":true},"text/jcr-cnd":{"source":"iana"},"text/jsx":{"compressible":true,"extensions":["jsx"]},"text/less":{"compressible":true,"extensions":["less"]},"text/markdown":{"source":"iana","compressible":true,"extensions":["markdown","md"]},"text/mathml":{"source":"nginx","extensions":["mml"]},"text/mdx":{"compressible":true,"extensions":["mdx"]},"text/mizar":{"source":"iana"},"text/n3":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["n3"]},"text/parameters":{"source":"iana","charset":"UTF-8"},"text/parityfec":{"source":"iana"},"text/plain":{"source":"iana","compressible":true,"extensions":["txt","text","conf","def","list","log","in","ini"]},"text/provenance-notation":{"source":"iana","charset":"UTF-8"},"text/prs.fallenstein.rst":{"source":"iana"},"text/prs.lines.tag":{"source":"iana","extensions":["dsc"]},"text/prs.prop.logic":{"source":"iana"},"text/raptorfec":{"source":"iana"},"text/red":{"source":"iana"},"text/rfc822-headers":{"source":"iana"},"text/richtext":{"source":"iana","compressible":true,"extensions":["rtx"]},"text/rtf":{"source":"iana","compressible":true,"extensions":["rtf"]},"text/rtp-enc-aescm128":{"source":"iana"},"text/rtploopback":{"source":"iana"},"text/rtx":{"source":"iana"},"text/sgml":{"source":"iana","extensions":["sgml","sgm"]},"text/shaclc":{"source":"iana"},"text/shex":{"source":"iana","extensions":["shex"]},"text/slim":{"extensions":["slim","slm"]},"text/spdx":{"source":"iana","extensions":["spdx"]},"text/strings":{"source":"iana"},"text/stylus":{"extensions":["stylus","styl"]},"text/t140":{"source":"iana"},"text/tab-separated-values":{"source":"iana","compressible":true,"extensions":["tsv"]},"text/troff":{"source":"iana","extensions":["t","tr","roff","man","me","ms"]},"text/turtle":{"source":"iana","charset":"UTF-8","extensions":["ttl"]},"text/ulpfec":{"source":"iana"},"text/uri-list":{"source":"iana","compressible":true,"extensions":["uri","uris","urls"]},"text/vcard":{"source":"iana","compressible":true,"extensions":["vcard"]},"text/vnd.a":{"source":"iana"},"text/vnd.abc":{"source":"iana"},"text/vnd.ascii-art":{"source":"iana"},"text/vnd.curl":{"source":"iana","extensions":["curl"]},"text/vnd.curl.dcurl":{"source":"apache","extensions":["dcurl"]},"text/vnd.curl.mcurl":{"source":"apache","extensions":["mcurl"]},"text/vnd.curl.scurl":{"source":"apache","extensions":["scurl"]},"text/vnd.debian.copyright":{"source":"iana","charset":"UTF-8"},"text/vnd.dmclientscript":{"source":"iana"},"text/vnd.dvb.subtitle":{"source":"iana","extensions":["sub"]},"text/vnd.esmertec.theme-descriptor":{"source":"iana","charset":"UTF-8"},"text/vnd.familysearch.gedcom":{"source":"iana","extensions":["ged"]},"text/vnd.ficlab.flt":{"source":"iana"},"text/vnd.fly":{"source":"iana","extensions":["fly"]},"text/vnd.fmi.flexstor":{"source":"iana","extensions":["flx"]},"text/vnd.gml":{"source":"iana"},"text/vnd.graphviz":{"source":"iana","extensions":["gv"]},"text/vnd.hans":{"source":"iana"},"text/vnd.hgl":{"source":"iana"},"text/vnd.in3d.3dml":{"source":"iana","extensions":["3dml"]},"text/vnd.in3d.spot":{"source":"iana","extensions":["spot"]},"text/vnd.iptc.newsml":{"source":"iana"},"text/vnd.iptc.nitf":{"source":"iana"},"text/vnd.latex-z":{"source":"iana"},"text/vnd.motorola.reflex":{"source":"iana"},"text/vnd.ms-mediapackage":{"source":"iana"},"text/vnd.net2phone.commcenter.command":{"source":"iana"},"text/vnd.radisys.msml-basic-layout":{"source":"iana"},"text/vnd.senx.warpscript":{"source":"iana"},"text/vnd.si.uricatalogue":{"source":"iana"},"text/vnd.sosi":{"source":"iana"},"text/vnd.sun.j2me.app-descriptor":{"source":"iana","charset":"UTF-8","extensions":["jad"]},"text/vnd.trolltech.linguist":{"source":"iana","charset":"UTF-8"},"text/vnd.wap.si":{"source":"iana"},"text/vnd.wap.sl":{"source":"iana"},"text/vnd.wap.wml":{"source":"iana","extensions":["wml"]},"text/vnd.wap.wmlscript":{"source":"iana","extensions":["wmls"]},"text/vtt":{"source":"iana","charset":"UTF-8","compressible":true,"extensions":["vtt"]},"text/x-asm":{"source":"apache","extensions":["s","asm"]},"text/x-c":{"source":"apache","extensions":["c","cc","cxx","cpp","h","hh","dic"]},"text/x-component":{"source":"nginx","extensions":["htc"]},"text/x-fortran":{"source":"apache","extensions":["f","for","f77","f90"]},"text/x-gwt-rpc":{"compressible":true},"text/x-handlebars-template":{"extensions":["hbs"]},"text/x-java-source":{"source":"apache","extensions":["java"]},"text/x-jquery-tmpl":{"compressible":true},"text/x-lua":{"extensions":["lua"]},"text/x-markdown":{"compressible":true,"extensions":["mkd"]},"text/x-nfo":{"source":"apache","extensions":["nfo"]},"text/x-opml":{"source":"apache","extensions":["opml"]},"text/x-org":{"compressible":true,"extensions":["org"]},"text/x-pascal":{"source":"apache","extensions":["p","pas"]},"text/x-processing":{"compressible":true,"extensions":["pde"]},"text/x-sass":{"extensions":["sass"]},"text/x-scss":{"extensions":["scss"]},"text/x-setext":{"source":"apache","extensions":["etx"]},"text/x-sfv":{"source":"apache","extensions":["sfv"]},"text/x-suse-ymp":{"compressible":true,"extensions":["ymp"]},"text/x-uuencode":{"source":"apache","extensions":["uu"]},"text/x-vcalendar":{"source":"apache","extensions":["vcs"]},"text/x-vcard":{"source":"apache","extensions":["vcf"]},"text/xml":{"source":"iana","compressible":true,"extensions":["xml"]},"text/xml-external-parsed-entity":{"source":"iana"},"text/yaml":{"compressible":true,"extensions":["yaml","yml"]},"video/1d-interleaved-parityfec":{"source":"iana"},"video/3gpp":{"source":"iana","extensions":["3gp","3gpp"]},"video/3gpp-tt":{"source":"iana"},"video/3gpp2":{"source":"iana","extensions":["3g2"]},"video/av1":{"source":"iana"},"video/bmpeg":{"source":"iana"},"video/bt656":{"source":"iana"},"video/celb":{"source":"iana"},"video/dv":{"source":"iana"},"video/encaprtp":{"source":"iana"},"video/ffv1":{"source":"iana"},"video/flexfec":{"source":"iana"},"video/h261":{"source":"iana","extensions":["h261"]},"video/h263":{"source":"iana","extensions":["h263"]},"video/h263-1998":{"source":"iana"},"video/h263-2000":{"source":"iana"},"video/h264":{"source":"iana","extensions":["h264"]},"video/h264-rcdo":{"source":"iana"},"video/h264-svc":{"source":"iana"},"video/h265":{"source":"iana"},"video/iso.segment":{"source":"iana","extensions":["m4s"]},"video/jpeg":{"source":"iana","extensions":["jpgv"]},"video/jpeg2000":{"source":"iana"},"video/jpm":{"source":"apache","extensions":["jpm","jpgm"]},"video/jxsv":{"source":"iana"},"video/mj2":{"source":"iana","extensions":["mj2","mjp2"]},"video/mp1s":{"source":"iana"},"video/mp2p":{"source":"iana"},"video/mp2t":{"source":"iana","extensions":["ts"]},"video/mp4":{"source":"iana","compressible":false,"extensions":["mp4","mp4v","mpg4"]},"video/mp4v-es":{"source":"iana"},"video/mpeg":{"source":"iana","compressible":false,"extensions":["mpeg","mpg","mpe","m1v","m2v"]},"video/mpeg4-generic":{"source":"iana"},"video/mpv":{"source":"iana"},"video/nv":{"source":"iana"},"video/ogg":{"source":"iana","compressible":false,"extensions":["ogv"]},"video/parityfec":{"source":"iana"},"video/pointer":{"source":"iana"},"video/quicktime":{"source":"iana","compressible":false,"extensions":["qt","mov"]},"video/raptorfec":{"source":"iana"},"video/raw":{"source":"iana"},"video/rtp-enc-aescm128":{"source":"iana"},"video/rtploopback":{"source":"iana"},"video/rtx":{"source":"iana"},"video/scip":{"source":"iana"},"video/smpte291":{"source":"iana"},"video/smpte292m":{"source":"iana"},"video/ulpfec":{"source":"iana"},"video/vc1":{"source":"iana"},"video/vc2":{"source":"iana"},"video/vnd.cctv":{"source":"iana"},"video/vnd.dece.hd":{"source":"iana","extensions":["uvh","uvvh"]},"video/vnd.dece.mobile":{"source":"iana","extensions":["uvm","uvvm"]},"video/vnd.dece.mp4":{"source":"iana"},"video/vnd.dece.pd":{"source":"iana","extensions":["uvp","uvvp"]},"video/vnd.dece.sd":{"source":"iana","extensions":["uvs","uvvs"]},"video/vnd.dece.video":{"source":"iana","extensions":["uvv","uvvv"]},"video/vnd.directv.mpeg":{"source":"iana"},"video/vnd.directv.mpeg-tts":{"source":"iana"},"video/vnd.dlna.mpeg-tts":{"source":"iana"},"video/vnd.dvb.file":{"source":"iana","extensions":["dvb"]},"video/vnd.fvt":{"source":"iana","extensions":["fvt"]},"video/vnd.hns.video":{"source":"iana"},"video/vnd.iptvforum.1dparityfec-1010":{"source":"iana"},"video/vnd.iptvforum.1dparityfec-2005":{"source":"iana"},"video/vnd.iptvforum.2dparityfec-1010":{"source":"iana"},"video/vnd.iptvforum.2dparityfec-2005":{"source":"iana"},"video/vnd.iptvforum.ttsavc":{"source":"iana"},"video/vnd.iptvforum.ttsmpeg2":{"source":"iana"},"video/vnd.motorola.video":{"source":"iana"},"video/vnd.motorola.videop":{"source":"iana"},"video/vnd.mpegurl":{"source":"iana","extensions":["mxu","m4u"]},"video/vnd.ms-playready.media.pyv":{"source":"iana","extensions":["pyv"]},"video/vnd.nokia.interleaved-multimedia":{"source":"iana"},"video/vnd.nokia.mp4vr":{"source":"iana"},"video/vnd.nokia.videovoip":{"source":"iana"},"video/vnd.objectvideo":{"source":"iana"},"video/vnd.radgamettools.bink":{"source":"iana"},"video/vnd.radgamettools.smacker":{"source":"iana"},"video/vnd.sealed.mpeg1":{"source":"iana"},"video/vnd.sealed.mpeg4":{"source":"iana"},"video/vnd.sealed.swf":{"source":"iana"},"video/vnd.sealedmedia.softseal.mov":{"source":"iana"},"video/vnd.uvvu.mp4":{"source":"iana","extensions":["uvu","uvvu"]},"video/vnd.vivo":{"source":"iana","extensions":["viv"]},"video/vnd.youtube.yt":{"source":"iana"},"video/vp8":{"source":"iana"},"video/vp9":{"source":"iana"},"video/webm":{"source":"apache","compressible":false,"extensions":["webm"]},"video/x-f4v":{"source":"apache","extensions":["f4v"]},"video/x-fli":{"source":"apache","extensions":["fli"]},"video/x-flv":{"source":"apache","compressible":false,"extensions":["flv"]},"video/x-m4v":{"source":"apache","extensions":["m4v"]},"video/x-matroska":{"source":"apache","compressible":false,"extensions":["mkv","mk3d","mks"]},"video/x-mng":{"source":"apache","extensions":["mng"]},"video/x-ms-asf":{"source":"apache","extensions":["asf","asx"]},"video/x-ms-vob":{"source":"apache","extensions":["vob"]},"video/x-ms-wm":{"source":"apache","extensions":["wm"]},"video/x-ms-wmv":{"source":"apache","compressible":false,"extensions":["wmv"]},"video/x-ms-wmx":{"source":"apache","extensions":["wmx"]},"video/x-ms-wvx":{"source":"apache","extensions":["wvx"]},"video/x-msvideo":{"source":"apache","extensions":["avi"]},"video/x-sgi-movie":{"source":"apache","extensions":["movie"]},"video/x-smv":{"source":"apache","extensions":["smv"]},"x-conference/x-cooltalk":{"source":"apache","extensions":["ice"]},"x-shader/x-fragment":{"compressible":true},"x-shader/x-vertex":{"compressible":true}}')}},t={};function n(a){var i=t[a];if(void 0!==i)return i.exports;var o=t[a]={id:a,loaded:!1,exports:{}};return e[a].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}n.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);var a=n(7530);return a=a.default})())); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLEtBQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLEtBQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLEtBQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxzNEJDYkE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsS0FBQTdMLHM0QkNKQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsR0FDQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsR0FDQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsR0FDQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsR0FDQTRqQixFQUFBL1gsRUFBQSxLQUFBN0wsdWxCQ0pBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxzbEJDQUE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLHVsQkNBQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsdWxCQ0FBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxtcUJDQUE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsTUFBQTdMLHVsQkNEQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsdWxCQ0FBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCx1bEJDQUE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLHVsQkNBQTRqQixFQUFBL1gsRUFBQSxNQUFBN0wsdTRCQ0FBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxrcUJDSkE0akIsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0E0akIsRUFBQS9YLEVBQUEsS0FBQTdMLHNsQkNEQTRqQixFQUFBL1gsRUFBQSxLQUFBN0wsMmdCQ0FBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLEtBQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCxHQUNBNGpCLEVBQUEvWCxFQUFBLE1BQUE3TCx1OEJDYkEsSUFBQTZqQixFQUFBalksRUFBQUMsRUFBQSxPQUlBN0wsRUFBQUEsTUFBQXdoQixFQUFBM1YsRUFBQSxPQUNBK1gsRUFBQS9YLEVBQUEsTUFBQTdMLEdBQ0FBLEVBQUFBLFdBQUF3aEIsRUFBQTNWLEVBQUEsTUFFQSxJQUFBaVksRUFBQSxXQUlFLFNBQUFBLEVBQVk5ZixHQUNWNUQsS0FBSzZVLFNBQVdqUixDQUNsQixDQUtGLE9BVkVwRCxPQUFBbWpCLGVBQVdELEVBQUEsVUFBTyxLQUFsQixXQUF1QyxPQUFPMWpCLElBQU0sa0NBT3BEMGpCLEVBQUFwZixVQUFBOEMsT0FBQSxTQUFPdkQsR0FDTCxPQUFPLElBQUk0ZixFQUFBN1csUUFBYy9JLEVBQVM3RCxLQUFLNlUsU0FDekMsRUFDRjZPLENBQUEsQ0FYQSxxQ0NSQSxpQkFDRSxTQUFTaGtCLEdBR1YsSUFBSWtrQixFQUE0Q2hrQixFQVE1Q2lrQixHQUwwQ2hrQixHQUM3Q0EsRUFBT0QsUUFJMEIsaUJBQVZra0IsUUFBc0JBLFFBQzFDRCxFQUFXQyxTQUFXRCxHQUFjQSxFQUFXRSxPQU1uRCxJQUFJQyxFQUF3QixTQUFTdlYsR0FDcEN6TyxLQUFLeU8sUUFBVUEsQ0FDaEIsR0FDQXVWLEVBQXNCMWYsVUFBWSxJQUFJTSxPQUNOc0MsS0FBTyx3QkFFdkMsSUFBSW5GLEVBQVEsU0FBUzBNLEdBR3BCLE1BQU0sSUFBSXVWLEVBQXNCdlYsRUFDakMsRUFFSXdWLEVBQVEsbUVBRVJDLEVBQXlCLGVBc0d6Qi9DLEVBQVMsQ0FDWixPQTNEWSxTQUFTZ0QsR0FDckJBLEVBQVFDLE9BQU9ELEdBQ1gsYUFBYTNGLEtBQUsyRixJQUdyQnBpQixFQUNDLDZFQWNGLElBVkEsSUFHSVcsRUFDQUMsRUFDQTBoQixFQUNBQyxFQU5BQyxFQUFVSixFQUFNdGlCLE9BQVMsRUFDekJHLEVBQVMsR0FDVHdpQixHQUFZLEVBTVozaUIsRUFBU3NpQixFQUFNdGlCLE9BQVMwaUIsSUFFbkJDLEVBQVczaUIsR0FFbkJhLEVBQUl5aEIsRUFBTU0sV0FBV0QsSUFBYSxHQUNsQzdoQixFQUFJd2hCLEVBQU1NLGFBQWFELElBQWEsRUFDcENILEVBQUlGLEVBQU1NLGFBQWFELEdBSXZCeGlCLEdBQ0NpaUIsRUFBTVMsUUFKUEosRUFBUzVoQixFQUFJQyxFQUFJMGhCLElBSU8sR0FBSyxJQUM1QkosRUFBTVMsT0FBT0osR0FBVSxHQUFLLElBQzVCTCxFQUFNUyxPQUFPSixHQUFVLEVBQUksSUFDM0JMLEVBQU1TLE9BQWdCLEdBQVRKLEdBdUJmLE9BbkJlLEdBQVhDLEdBQ0g3aEIsRUFBSXloQixFQUFNTSxXQUFXRCxJQUFhLEVBQ2xDN2hCLEVBQUl3aEIsRUFBTU0sYUFBYUQsR0FFdkJ4aUIsR0FDQ2lpQixFQUFNUyxRQUZQSixFQUFTNWhCLEVBQUlDLElBRVcsSUFDdkJzaEIsRUFBTVMsT0FBUUosR0FBVSxFQUFLLElBQzdCTCxFQUFNUyxPQUFRSixHQUFVLEVBQUssSUFDN0IsS0FFb0IsR0FBWEMsSUFDVkQsRUFBU0gsRUFBTU0sV0FBV0QsR0FDMUJ4aUIsR0FDQ2lpQixFQUFNUyxPQUFPSixHQUFVLEdBQ3ZCTCxFQUFNUyxPQUFRSixHQUFVLEVBQUssSUFDN0IsTUFJS3RpQixDQUNSLEVBSUMsT0FsR1ksU0FBU21pQixHQUdyQixJQUFJdGlCLEdBRkpzaUIsRUFBUUMsT0FBT0QsR0FDYmxkLFFBQVFpZCxFQUF3QixLQUNmcmlCLE9BQ2ZBLEVBQVMsR0FBSyxJQUVqQkEsR0FEQXNpQixFQUFRQSxFQUFNbGQsUUFBUSxPQUFRLEtBQ2ZwRixTQUdmQSxFQUFTLEdBQUssR0FFZCxpQkFBaUIyYyxLQUFLMkYsS0FFdEJwaUIsRUFDQyx5RUFRRixJQUxBLElBQ0k0aUIsRUFDQUwsRUFGQU0sRUFBYSxFQUdiNWlCLEVBQVMsR0FDVHdpQixHQUFZLElBQ1BBLEVBQVczaUIsR0FDbkJ5aUIsRUFBU0wsRUFBTVksUUFBUVYsRUFBTU8sT0FBT0YsSUFDcENHLEVBQWFDLEVBQWEsRUFBaUIsR0FBYkQsRUFBa0JMLEVBQVNBLEVBRXJETSxJQUFlLElBRWxCNWlCLEdBQVVvaUIsT0FBT1UsYUFDaEIsSUFBT0gsS0FBZ0IsRUFBSUMsRUFBYSxLQUkzQyxPQUFPNWlCLENBQ1IsRUFpRUMsUUFBVyxjQVlWLEtBRkQsYUFDQyxPQUFPbWYsQ0FDUCwrQkFhSCxDQWxLQyxtQkNERCxJQUFJamUsRUFBTyxFQUFRLE1BQ2ZNLEVBQVMsZUFDVHVoQixFQUFnQixFQUFRLE1BRzVCLFNBQVM5aEIsSUFDUGpELEtBQUtnbEIsVUFBVyxFQUNoQmhsQixLQUFLdUYsVUFBVyxFQUNoQnZGLEtBQUtpbEIsU0FBVyxFQUNoQmpsQixLQUFLa2xCLFlBQWMsUUFDbkJsbEIsS0FBS21sQixjQUFlLEVBRXBCbmxCLEtBQUtvbEIsV0FBWSxFQUNqQnBsQixLQUFLd0gsU0FBVyxHQUNoQnhILEtBQUtxbEIsZUFBaUIsS0FDdEJybEIsS0FBS3NsQixhQUFjLEVBQ25CdGxCLEtBQUt1bEIsY0FBZSxDQUN0QixDQWJBMWxCLEVBQU9ELFFBQVVxRCxFQWNqQkMsRUFBS2lCLFNBQVNsQixFQUFnQk8sR0FFOUJQLEVBQWVzSyxPQUFTLFNBQVMxSixHQUMvQixJQUFJMmhCLEVBQWlCLElBQUl4bEIsS0FHekIsSUFBSyxJQUFJOEQsS0FEVEQsRUFBVUEsR0FBVyxDQUFDLEVBRXBCMmhCLEVBQWUxaEIsR0FBVUQsRUFBUUMsR0FHbkMsT0FBTzBoQixDQUNULEVBRUF2aUIsRUFBZXdpQixhQUFlLFNBQVNDLEdBQ3JDLE1BQTBCLG1CQUFYQSxHQUNTLGlCQUFYQSxHQUNXLGtCQUFYQSxHQUNXLGlCQUFYQSxJQUNOdGdCLE9BQU9DLFNBQVNxZ0IsRUFDekIsRUFFQXppQixFQUFlcUIsVUFBVUMsT0FBUyxTQUFTbWhCLEdBR3pDLEdBRm1CemlCLEVBQWV3aUIsYUFBYUMsR0FFN0IsQ0FDaEIsS0FBTUEsYUFBa0JYLEdBQWdCLENBQ3RDLElBQUlZLEVBQVlaLEVBQWN4WCxPQUFPbVksRUFBUSxDQUMzQ1IsWUFBYXJmLElBQ2IrZixZQUFhNWxCLEtBQUttbEIsZUFFcEJPLEVBQU94ZixHQUFHLE9BQVFsRyxLQUFLNmxCLGVBQWVsbEIsS0FBS1gsT0FDM0MwbEIsRUFBU0MsQ0FDWCxDQUVBM2xCLEtBQUs4bEIsY0FBY0osR0FFZjFsQixLQUFLbWxCLGNBQ1BPLEVBQU90ZixPQUVYLENBR0EsT0FEQXBHLEtBQUt3SCxTQUFTL0IsS0FBS2lnQixHQUNaMWxCLElBQ1QsRUFFQWlELEVBQWVxQixVQUFVdUYsS0FBTyxTQUFTa2MsRUFBTWxpQixHQUc3QyxPQUZBTCxFQUFPYyxVQUFVdUYsS0FBSzNGLEtBQUtsRSxLQUFNK2xCLEVBQU1saUIsR0FDdkM3RCxLQUFLcUcsU0FDRTBmLENBQ1QsRUFFQTlpQixFQUFlcUIsVUFBVTBoQixTQUFXLFdBR2xDLEdBRkFobUIsS0FBS3FsQixlQUFpQixLQUVsQnJsQixLQUFLc2xCLFlBQ1B0bEIsS0FBS3VsQixjQUFlLE1BRHRCLENBS0F2bEIsS0FBS3NsQixhQUFjLEVBQ25CLElBQ0UsR0FDRXRsQixLQUFLdWxCLGNBQWUsRUFDcEJ2bEIsS0FBS2ltQixxQkFDRWptQixLQUFLdWxCLGFBR2hCLENBRkUsUUFDQXZsQixLQUFLc2xCLGFBQWMsQ0FDckIsQ0FWQSxDQVdGLEVBRUFyaUIsRUFBZXFCLFVBQVUyaEIsYUFBZSxXQUN0QyxJQUFJUCxFQUFTMWxCLEtBQUt3SCxTQUFTMGUsYUFHTixJQUFWUixFQUtXLG1CQUFYQSxFQUtLQSxFQUNOLFNBQVNBLEdBQ0V6aUIsRUFBZXdpQixhQUFhQyxLQUU3Q0EsRUFBT3hmLEdBQUcsT0FBUWxHLEtBQUs2bEIsZUFBZWxsQixLQUFLWCxPQUMzQ0EsS0FBSzhsQixjQUFjSixJQUdyQjFsQixLQUFLbW1CLFVBQVVULEVBQ2pCLEVBQUUva0IsS0FBS1gsT0FiTEEsS0FBS21tQixVQUFVVCxHQUxmMWxCLEtBQUs0RixLQW1CVCxFQUVBM0MsRUFBZXFCLFVBQVU2aEIsVUFBWSxTQUFTVCxHQUk1QyxHQUhBMWxCLEtBQUtxbEIsZUFBaUJLLEVBRUh6aUIsRUFBZXdpQixhQUFhQyxHQUk3QyxPQUZBQSxFQUFPeGYsR0FBRyxNQUFPbEcsS0FBS2dtQixTQUFTcmxCLEtBQUtYLFlBQ3BDMGxCLEVBQU83YixLQUFLN0osS0FBTSxDQUFDNEYsS0FBSyxJQUkxQixJQUFJbkIsRUFBUWloQixFQUNaMWxCLEtBQUtvbUIsTUFBTTNoQixHQUNYekUsS0FBS2dtQixVQUNQLEVBRUEvaUIsRUFBZXFCLFVBQVV3aEIsY0FBZ0IsU0FBU0osR0FDaEQsSUFBSXBXLEVBQU90UCxLQUNYMGxCLEVBQU94ZixHQUFHLFNBQVMsU0FBU25GLEdBQzFCdU8sRUFBSytXLFdBQVd0bEIsRUFDbEIsR0FDRixFQUVBa0MsRUFBZXFCLFVBQVU4aEIsTUFBUSxTQUFTL2IsR0FDeENySyxLQUFLaUssS0FBSyxPQUFRSSxFQUNwQixFQUVBcEgsRUFBZXFCLFVBQVU4QixNQUFRLFdBQzFCcEcsS0FBS21sQixlQUlQbmxCLEtBQUttbEIsY0FBZ0JubEIsS0FBS3FsQixnQkFBdUQsbUJBQTlCcmxCLEtBQUtxbEIsZUFBb0IsT0FBaUJybEIsS0FBS3FsQixlQUFlamYsUUFDcEhwRyxLQUFLaUssS0FBSyxTQUNaLEVBRUFoSCxFQUFlcUIsVUFBVStCLE9BQVMsV0FDM0JyRyxLQUFLb2xCLFlBQ1JwbEIsS0FBS29sQixXQUFZLEVBQ2pCcGxCLEtBQUtnbEIsVUFBVyxFQUNoQmhsQixLQUFLZ21CLFlBR0pobUIsS0FBS21sQixjQUFnQm5sQixLQUFLcWxCLGdCQUF3RCxtQkFBL0JybEIsS0FBS3FsQixlQUFxQixRQUFpQnJsQixLQUFLcWxCLGVBQWVoZixTQUNySHJHLEtBQUtpSyxLQUFLLFNBQ1osRUFFQWhILEVBQWVxQixVQUFVc0IsSUFBTSxXQUM3QjVGLEtBQUtzbUIsU0FDTHRtQixLQUFLaUssS0FBSyxNQUNaLEVBRUFoSCxFQUFlcUIsVUFBVXlKLFFBQVUsV0FDakMvTixLQUFLc21CLFNBQ0x0bUIsS0FBS2lLLEtBQUssUUFDWixFQUVBaEgsRUFBZXFCLFVBQVVnaUIsT0FBUyxXQUNoQ3RtQixLQUFLZ2xCLFVBQVcsRUFDaEJobEIsS0FBS3dILFNBQVcsR0FDaEJ4SCxLQUFLcWxCLGVBQWlCLElBQ3hCLEVBRUFwaUIsRUFBZXFCLFVBQVV1aEIsZUFBaUIsV0FFeEMsR0FEQTdsQixLQUFLdW1CLG9CQUNEdm1CLEtBQUtpbEIsVUFBWWpsQixLQUFLa2xCLGFBQTFCLENBSUEsSUFBSXpXLEVBQ0YsZ0NBQWtDek8sS0FBS2tsQixZQUFjLG1CQUN2RGxsQixLQUFLcW1CLFdBQVcsSUFBSXpoQixNQUFNNkosR0FKMUIsQ0FLRixFQUVBeEwsRUFBZXFCLFVBQVVpaUIsZ0JBQWtCLFdBQ3pDdm1CLEtBQUtpbEIsU0FBVyxFQUVoQixJQUFJM1YsRUFBT3RQLEtBQ1hBLEtBQUt3SCxTQUFTOUcsU0FBUSxTQUFTZ2xCLEdBQ3hCQSxFQUFPVCxXQUlaM1YsRUFBSzJWLFVBQVlTLEVBQU9ULFNBQzFCLElBRUlqbEIsS0FBS3FsQixnQkFBa0JybEIsS0FBS3FsQixlQUFlSixXQUM3Q2psQixLQUFLaWxCLFVBQVlqbEIsS0FBS3FsQixlQUFlSixTQUV6QyxFQUVBaGlCLEVBQWVxQixVQUFVK2hCLFdBQWEsU0FBU3RsQixHQUM3Q2YsS0FBS3NtQixTQUNMdG1CLEtBQUtpSyxLQUFLLFFBQVNsSixFQUNyQixrQkN6TUFuQixFQUFRNG1CLFdBMklSLFNBQW9CQyxHQVFuQixHQVBBQSxFQUFLLElBQU16bUIsS0FBSzBtQixVQUFZLEtBQU8sSUFDbEMxbUIsS0FBSzJtQixXQUNKM21CLEtBQUswbUIsVUFBWSxNQUFRLEtBQzFCRCxFQUFLLElBQ0p6bUIsS0FBSzBtQixVQUFZLE1BQVEsS0FDMUIsSUFBTTdtQixFQUFPRCxRQUFRZ25CLFNBQVM1bUIsS0FBSzZtQixPQUUvQjdtQixLQUFLMG1CLFVBQ1QsT0FHRCxNQUFNckMsRUFBSSxVQUFZcmtCLEtBQUs4bUIsTUFDM0JMLEVBQUtNLE9BQU8sRUFBRyxFQUFHMUMsRUFBRyxrQkFLckIsSUFBSTNpQixFQUFRLEVBQ1JzbEIsRUFBUSxFQUNaUCxFQUFLLEdBQUd4ZixRQUFRLGVBQWVnZ0IsSUFDaEIsT0FBVkEsSUFHSnZsQixJQUNjLE9BQVZ1bEIsSUFHSEQsRUFBUXRsQixHQUNULElBR0Qra0IsRUFBS00sT0FBT0MsRUFBTyxFQUFHM0MsRUFDdkIsRUEzS0F6a0IsRUFBUXNuQixLQTZMUixTQUFjQyxHQUNiLElBQ0tBLEVBQ0h2bkIsRUFBUXduQixRQUFRQyxRQUFRLFFBQVNGLEdBRWpDdm5CLEVBQVF3bkIsUUFBUUUsV0FBVyxRQUs3QixDQUhFLE1BQU92bEIsR0FHVCxDQUNELEVBdk1BbkMsRUFBUTJuQixLQStNUixXQUNDLElBQUlDLEVBQ0osSUFDQ0EsRUFBSTVuQixFQUFRd25CLFFBQVFLLFFBQVEsUUFJN0IsQ0FIRSxNQUFPMWxCLEdBR1QsRUFHS3lsQixHQUF3QixvQkFBWnBtQixTQUEyQixRQUFTQSxVQUNwRG9tQixFQUFJcG1CLFFBQVFzbUIsSUFBSUMsT0FHakIsT0FBT0gsQ0FDUixFQTdOQTVuQixFQUFROG1CLFVBeUdSLFdBSUMsR0FBc0Isb0JBQVgzQyxRQUEwQkEsT0FBTzNpQixVQUFvQyxhQUF4QjJpQixPQUFPM2lCLFFBQVEySixNQUF1QmdaLE9BQU8zaUIsUUFBUXdtQixRQUM1RyxPQUFPLEVBSVIsR0FBeUIsb0JBQWRDLFdBQTZCQSxVQUFVQyxXQUFhRCxVQUFVQyxVQUFVamdCLGNBQWNvZixNQUFNLHlCQUN0RyxPQUFPLEVBS1IsTUFBNEIsb0JBQWJjLFVBQTRCQSxTQUFTQyxpQkFBbUJELFNBQVNDLGdCQUFnQkMsT0FBU0YsU0FBU0MsZ0JBQWdCQyxNQUFNQyxrQkFFcEgsb0JBQVhuRSxRQUEwQkEsT0FBT3hMLFVBQVl3TCxPQUFPeEwsUUFBUTRQLFNBQVlwRSxPQUFPeEwsUUFBUTZQLFdBQWFyRSxPQUFPeEwsUUFBUThQLFFBR3JHLG9CQUFkUixXQUE2QkEsVUFBVUMsV0FBYUQsVUFBVUMsVUFBVWpnQixjQUFjb2YsTUFBTSxtQkFBcUJxQixTQUFTQyxPQUFPQyxHQUFJLEtBQU8sSUFFOUgsb0JBQWRYLFdBQTZCQSxVQUFVQyxXQUFhRCxVQUFVQyxVQUFVamdCLGNBQWNvZixNQUFNLHFCQUN0RyxFQS9IQXJuQixFQUFRd25CLFFBeU9SLFdBQ0MsSUFHQyxPQUFPcUIsWUFJUixDQUhFLE1BQU8xbUIsR0FHVCxDQUNELENBbFBrQjJtQixHQUNsQjlvQixFQUFRbU8sUUFBVSxNQUNqQixJQUFJNGEsR0FBUyxFQUViLE1BQU8sS0FDREEsSUFDSkEsR0FBUyxFQUNUcFEsUUFBUUcsS0FBSyx5SUFDZCxDQUVELEVBVGlCLEdBZWxCOVksRUFBUWdwQixPQUFTLENBQ2hCLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFVBQ0EsVUFDQSxVQUNBLFdBc0ZEaHBCLEVBQVFpcEIsSUFBTXRRLFFBQVF1USxPQUFTdlEsUUFBUXNRLEtBQU8sTUFBUyxHQWtFdkRocEIsRUFBT0QsUUFBVSxFQUFRLEtBQVIsQ0FBb0JBLEdBRXJDLE1BQU0sV0FBQ21wQixHQUFjbHBCLEVBQU9ELFFBTTVCbXBCLEVBQVdDLEVBQUksU0FBVUMsR0FDeEIsSUFDQyxPQUFPMVMsS0FBS0MsVUFBVXlTLEVBR3ZCLENBRkUsTUFBT2xuQixHQUNSLE1BQU8sK0JBQWlDQSxFQUFNME0sT0FDL0MsQ0FDRCxrQkNLQTVPLEVBQU9ELFFBM1FQLFNBQWU4bkIsR0FxRGQsU0FBU3dCLEVBQVl2QyxHQUNwQixJQUFJd0MsRUFFQUMsRUFDQUMsRUFGQUMsRUFBaUIsS0FJckIsU0FBU1IsS0FBU3JDLEdBRWpCLElBQUtxQyxFQUFNUyxRQUNWLE9BR0QsTUFBTWphLEVBQU93WixFQUdQVSxFQUFPQyxPQUFPLElBQUloWixNQUNsQmlaLEVBQUtGLEdBQVFMLEdBQVlLLEdBQy9CbGEsRUFBS3VYLEtBQU82QyxFQUNacGEsRUFBS3FhLEtBQU9SLEVBQ1o3WixFQUFLa2EsS0FBT0EsRUFDWkwsRUFBV0ssRUFFWC9DLEVBQUssR0FBS3lDLEVBQVlVLE9BQU9uRCxFQUFLLElBRVgsaUJBQVpBLEVBQUssSUFFZkEsRUFBS29ELFFBQVEsTUFJZCxJQUFJbm9CLEVBQVEsRUFDWitrQixFQUFLLEdBQUtBLEVBQUssR0FBR3hmLFFBQVEsaUJBQWlCLENBQUNnZ0IsRUFBTzZDLEtBRWxELEdBQWMsT0FBVjdDLEVBQ0gsTUFBTyxJQUVSdmxCLElBQ0EsTUFBTXFvQixFQUFZYixFQUFZSCxXQUFXZSxHQUN6QyxHQUF5QixtQkFBZEMsRUFBMEIsQ0FDcEMsTUFBTUMsRUFBTXZELEVBQUsva0IsR0FDakJ1bEIsRUFBUThDLEVBQVU3bEIsS0FBS29MLEVBQU0wYSxHQUc3QnZELEVBQUtNLE9BQU9ybEIsRUFBTyxHQUNuQkEsR0FDRCxDQUNBLE9BQU91bEIsQ0FBSyxJQUliaUMsRUFBWTFDLFdBQVd0aUIsS0FBS29MLEVBQU1tWCxJQUVwQm5YLEVBQUt1WixLQUFPSyxFQUFZTCxLQUNoQ29CLE1BQU0zYSxFQUFNbVgsRUFDbkIsQ0FnQ0EsT0E5QkFxQyxFQUFNbkMsVUFBWUEsRUFDbEJtQyxFQUFNcEMsVUFBWXdDLEVBQVl4QyxZQUM5Qm9DLEVBQU1oQyxNQUFRb0MsRUFBWWdCLFlBQVl2RCxHQUN0Q21DLEVBQU1xQixPQUFTQSxFQUNmckIsRUFBTS9hLFFBQVVtYixFQUFZbmIsUUFFNUJ2TixPQUFPbWpCLGVBQWVtRixFQUFPLFVBQVcsQ0FDdkNzQixZQUFZLEVBQ1pDLGNBQWMsRUFDZGpkLElBQUssSUFDbUIsT0FBbkJrYyxFQUNJQSxHQUVKRixJQUFvQkYsRUFBWS9CLGFBQ25DaUMsRUFBa0JGLEVBQVkvQixXQUM5QmtDLEVBQWVILEVBQVlLLFFBQVE1QyxJQUc3QjBDLEdBRVJ4RyxJQUFLb0csSUFDSkssRUFBaUJMLENBQUMsSUFLWSxtQkFBckJDLEVBQVlvQixNQUN0QnBCLEVBQVlvQixLQUFLeEIsR0FHWEEsQ0FDUixDQUVBLFNBQVNxQixFQUFPeEQsRUFBVzRELEdBQzFCLE1BQU1DLEVBQVd0QixFQUFZbHBCLEtBQUsybUIsZ0JBQWtDLElBQWQ0RCxFQUE0QixJQUFNQSxHQUFhNUQsR0FFckcsT0FEQTZELEVBQVMzQixJQUFNN29CLEtBQUs2b0IsSUFDYjJCLENBQ1IsQ0F3RkEsU0FBU0MsRUFBWUMsR0FDcEIsT0FBT0EsRUFBTzloQixXQUNaSixVQUFVLEVBQUdraUIsRUFBTzloQixXQUFXL0csT0FBUyxHQUN4Q29GLFFBQVEsVUFBVyxJQUN0QixDQTBCQSxPQXZRQWlpQixFQUFZSixNQUFRSSxFQUNwQkEsRUFBWXRjLFFBQVVzYyxFQUN0QkEsRUFBWVUsT0FvUFosU0FBZ0JJLEdBQ2YsR0FBSUEsYUFBZXBsQixNQUNsQixPQUFPb2xCLEVBQUlwTCxPQUFTb0wsRUFBSXZiLFFBRXpCLE9BQU91YixDQUNSLEVBeFBBZCxFQUFZMVAsUUF3TFosV0FDQyxNQUFNMk4sRUFBYSxJQUNmK0IsRUFBWXlCLE1BQU1oZSxJQUFJOGQsTUFDdEJ2QixFQUFZMEIsTUFBTWplLElBQUk4ZCxHQUFhOWQsS0FBSWdhLEdBQWEsSUFBTUEsS0FDNUQ5ZixLQUFLLEtBRVAsT0FEQXFpQixFQUFZM1AsT0FBTyxJQUNaNE4sQ0FDUixFQTlMQStCLEVBQVkzUCxPQXNKWixTQUFnQjROLEdBT2YsSUFBSTllLEVBTko2Z0IsRUFBWWhDLEtBQUtDLEdBQ2pCK0IsRUFBWS9CLFdBQWFBLEVBRXpCK0IsRUFBWXlCLE1BQVEsR0FDcEJ6QixFQUFZMEIsTUFBUSxHQUdwQixNQUFNbEssR0FBK0IsaUJBQWZ5RyxFQUEwQkEsRUFBYSxJQUFJekcsTUFBTSxVQUNqRXBZLEVBQU1vWSxFQUFNN2UsT0FFbEIsSUFBS3dHLEVBQUksRUFBR0EsRUFBSUMsRUFBS0QsSUFDZnFZLEVBQU1yWSxLQU9XLE9BRnRCOGUsRUFBYXpHLEVBQU1yWSxHQUFHcEIsUUFBUSxNQUFPLFFBRXRCLEdBQ2RpaUIsRUFBWTBCLE1BQU1ubEIsS0FBSyxJQUFJOGlCLE9BQU8sSUFBTXBCLEVBQVcwRCxNQUFNLEdBQUssTUFFOUQzQixFQUFZeUIsTUFBTWxsQixLQUFLLElBQUk4aUIsT0FBTyxJQUFNcEIsRUFBYSxNQUd4RCxFQTlLQStCLEVBQVlLLFFBc01aLFNBQWlCcmlCLEdBQ2hCLEdBQThCLE1BQTFCQSxFQUFLQSxFQUFLckYsT0FBUyxHQUN0QixPQUFPLEVBR1IsSUFBSXdHLEVBQ0FDLEVBRUosSUFBS0QsRUFBSSxFQUFHQyxFQUFNNGdCLEVBQVkwQixNQUFNL29CLE9BQVF3RyxFQUFJQyxFQUFLRCxJQUNwRCxHQUFJNmdCLEVBQVkwQixNQUFNdmlCLEdBQUdtVyxLQUFLdFgsR0FDN0IsT0FBTyxFQUlULElBQUttQixFQUFJLEVBQUdDLEVBQU00Z0IsRUFBWXlCLE1BQU05b0IsT0FBUXdHLEVBQUlDLEVBQUtELElBQ3BELEdBQUk2Z0IsRUFBWXlCLE1BQU10aUIsR0FBR21XLEtBQUt0WCxHQUM3QixPQUFPLEVBSVQsT0FBTyxDQUNSLEVBMU5BZ2lCLEVBQVl0QyxTQUFXLEVBQVEsTUFDL0JzQyxFQUFZbmIsUUEwUFosV0FDQ3dLLFFBQVFHLEtBQUssd0lBQ2QsRUExUEFsWSxPQUFPQyxLQUFLaW5CLEdBQUtobkIsU0FBUUwsSUFDeEI2b0IsRUFBWTdvQixHQUFPcW5CLEVBQUlybkIsRUFBSSxJQU81QjZvQixFQUFZeUIsTUFBUSxHQUNwQnpCLEVBQVkwQixNQUFRLEdBT3BCMUIsRUFBWUgsV0FBYSxDQUFDLEVBa0IxQkcsRUFBWWdCLFlBVlosU0FBcUJ2RCxHQUNwQixJQUFJbUUsRUFBTyxFQUVYLElBQUssSUFBSXppQixFQUFJLEVBQUdBLEVBQUlzZSxFQUFVOWtCLE9BQVF3RyxJQUNyQ3lpQixHQUFTQSxHQUFRLEdBQUtBLEVBQVFuRSxFQUFVbEMsV0FBV3BjLEdBQ25EeWlCLEdBQVEsRUFHVCxPQUFPNUIsRUFBWU4sT0FBT25nQixLQUFLc2lCLElBQUlELEdBQVE1QixFQUFZTixPQUFPL21CLE9BQy9ELEVBMk5BcW5CLEVBQVkzUCxPQUFPMlAsRUFBWTNCLFFBRXhCMkIsQ0FDUixrQkMxUXVCLG9CQUFaOW5CLFNBQTRDLGFBQWpCQSxRQUFRMkosT0FBMkMsSUFBcEIzSixRQUFRNHBCLFNBQW9CNXBCLFFBQVF3bUIsT0FDeEcvbkIsRUFBT0QsUUFBVSxFQUFqQixNQUVBQyxFQUFPRCxRQUFVLEVBQWpCLGtCQ0pELE1BQU1xckIsRUFBTSxFQUFRLE1BQ2QvbkIsRUFBTyxFQUFRLE1BTXJCdEQsRUFBUTBxQixLQTJOUixTQUFjeEIsR0FDYkEsRUFBTW9DLFlBQWMsQ0FBQyxFQUVyQixNQUFNenFCLEVBQU9ELE9BQU9DLEtBQUtiLEVBQVFzckIsYUFDakMsSUFBSyxJQUFJN2lCLEVBQUksRUFBR0EsRUFBSTVILEVBQUtvQixPQUFRd0csSUFDaEN5Z0IsRUFBTW9DLFlBQVl6cUIsRUFBSzRILElBQU16SSxFQUFRc3JCLFlBQVl6cUIsRUFBSzRILEdBRXhELEVBak9BekksRUFBUWlwQixJQW9MUixZQUFnQnBDLEdBQ2YsT0FBT3JsQixRQUFRK3BCLE9BQU8vRSxNQUFNbGpCLEVBQUs0bUIsVUFBVXJELEdBQVEsS0FDcEQsRUFyTEE3bUIsRUFBUTRtQixXQXlKUixTQUFvQkMsR0FDbkIsTUFBT0UsVUFBV3pmLEVBQUksVUFBRXdmLEdBQWExbUIsS0FFckMsR0FBSTBtQixFQUFXLENBQ2QsTUFBTXJDLEVBQUlya0IsS0FBSzhtQixNQUNUc0UsRUFBWSxPQUFjL0csRUFBSSxFQUFJQSxFQUFJLE9BQVNBLEdBQy9DZ0gsRUFBUyxLQUFLRCxPQUFlbGtCLFNBRW5DdWYsRUFBSyxHQUFLNEUsRUFBUzVFLEVBQUssR0FBRy9GLE1BQU0sTUFBTTdaLEtBQUssS0FBT3drQixHQUNuRDVFLEVBQUtoaEIsS0FBSzJsQixFQUFZLEtBQU92ckIsRUFBT0QsUUFBUWduQixTQUFTNW1CLEtBQUs2bUIsTUFBUSxPQUNuRSxNQUNDSixFQUFLLEdBSVAsV0FDQyxHQUFJN21CLEVBQVFzckIsWUFBWUksU0FDdkIsTUFBTyxHQUVSLE9BQU8sSUFBSTdhLE1BQU84YSxjQUFnQixHQUNuQyxDQVRZQyxHQUFZdGtCLEVBQU8sSUFBTXVmLEVBQUssRUFFMUMsRUFyS0E3bUIsRUFBUXNuQixLQTRMUixTQUFjQyxHQUNUQSxFQUNIL2xCLFFBQVFzbUIsSUFBSUMsTUFBUVIsU0FJYi9sQixRQUFRc21CLElBQUlDLEtBRXJCLEVBbk1BL25CLEVBQVEybkIsS0E0TVIsV0FDQyxPQUFPbm1CLFFBQVFzbUIsSUFBSUMsS0FDcEIsRUE3TUEvbkIsRUFBUThtQixVQTBJUixXQUNDLE1BQU8sV0FBWTltQixFQUFRc3JCLFlBQzFCTyxRQUFRN3JCLEVBQVFzckIsWUFBWXRDLFFBQzVCcUMsRUFBSVMsT0FBT3RxQixRQUFRK3BCLE9BQU9qTCxHQUM1QixFQTdJQXRnQixFQUFRbU8sUUFBVTdLLEVBQUt5b0IsV0FDdEIsUUFDQSx5SUFPRC9yQixFQUFRZ3BCLE9BQVMsQ0FBQyxFQUFHLEVBQUcsRUFBRyxFQUFHLEVBQUcsR0FFakMsSUFHQyxNQUFNZ0QsRUFBZ0IsRUFBUSxNQUUxQkEsSUFBa0JBLEVBQWNULFFBQVVTLEdBQWVDLE9BQVMsSUFDckVqc0IsRUFBUWdwQixPQUFTLENBQ2hCLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxHQUNBLEdBQ0EsR0FDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLElBQ0EsSUFDQSxJQUNBLEtBS0gsQ0FGRSxNQUFPN21CLEdBRVQsQ0FRQW5DLEVBQVFzckIsWUFBYzFxQixPQUFPQyxLQUFLVyxRQUFRc21CLEtBQUt6SSxRQUFPNWUsR0FDOUMsV0FBV21lLEtBQUtuZSxLQUNyQjhLLFFBQU8sQ0FBQzZVLEVBQUszZixLQUVmLE1BQU11RyxFQUFPdkcsRUFDWG1JLFVBQVUsR0FDVlgsY0FDQVosUUFBUSxhQUFhLENBQUM2a0IsRUFBR0MsSUFDbEJBLEVBQUVDLGdCQUlYLElBQUloQyxFQUFNNW9CLFFBQVFzbUIsSUFBSXJuQixHQVl0QixPQVZDMnBCLElBREcsMkJBQTJCeEwsS0FBS3dMLEtBRXpCLDZCQUE2QnhMLEtBQUt3TCxLQUUxQixTQUFSQSxFQUNKLEtBRUFQLE9BQU9PLElBR2RoSyxFQUFJcFosR0FBUW9qQixFQUNMaEssQ0FBRyxHQUNSLENBQUMsR0EyRkpuZ0IsRUFBT0QsUUFBVSxFQUFRLEtBQVIsQ0FBb0JBLEdBRXJDLE1BQU0sV0FBQ21wQixHQUFjbHBCLEVBQU9ELFFBTTVCbXBCLEVBQVdrRCxFQUFJLFNBQVVoRCxHQUV4QixPQURBanBCLEtBQUtrckIsWUFBWXRDLE9BQVM1b0IsS0FBSzBtQixVQUN4QnhqQixFQUFLZ3BCLFFBQVFqRCxFQUFHanBCLEtBQUtrckIsYUFDMUJ4SyxNQUFNLE1BQ04vVCxLQUFJd2YsR0FBT0EsRUFBSUMsU0FDZnZsQixLQUFLLElBQ1IsRUFNQWtpQixFQUFXc0QsRUFBSSxTQUFVcEQsR0FFeEIsT0FEQWpwQixLQUFLa3JCLFlBQVl0QyxPQUFTNW9CLEtBQUswbUIsVUFDeEJ4akIsRUFBS2dwQixRQUFRakQsRUFBR2pwQixLQUFLa3JCLFlBQzdCLGtCQ3RRQSxJQUFJMW5CLEVBQVMsZUFDVE4sRUFBTyxFQUFRLE1BR25CLFNBQVM2aEIsSUFDUC9rQixLQUFLc3NCLE9BQVMsS0FDZHRzQixLQUFLaWxCLFNBQVcsRUFDaEJqbEIsS0FBS2tsQixZQUFjLFFBQ25CbGxCLEtBQUs0bEIsYUFBYyxFQUVuQjVsQixLQUFLdXNCLHNCQUF1QixFQUM1QnZzQixLQUFLb2xCLFdBQVksRUFDakJwbEIsS0FBS3dzQixnQkFBa0IsRUFDekIsQ0FWQTNzQixFQUFPRCxRQUFVbWxCLEVBV2pCN2hCLEVBQUtpQixTQUFTNGdCLEVBQWV2aEIsR0FFN0J1aEIsRUFBY3hYLE9BQVMsU0FBUytlLEVBQVF6b0IsR0FDdEMsSUFBSTRvQixFQUFnQixJQUFJenNCLEtBR3hCLElBQUssSUFBSThELEtBRFRELEVBQVVBLEdBQVcsQ0FBQyxFQUVwQjRvQixFQUFjM29CLEdBQVVELEVBQVFDLEdBR2xDMm9CLEVBQWNILE9BQVNBLEVBRXZCLElBQUlJLEVBQVdKLEVBQU9yaUIsS0FXdEIsT0FWQXFpQixFQUFPcmlCLEtBQU8sV0FFWixPQURBd2lCLEVBQWNFLFlBQVlDLFdBQ25CRixFQUFTekMsTUFBTXFDLEVBQVFNLFVBQ2hDLEVBRUFOLEVBQU9wbUIsR0FBRyxTQUFTLFdBQVksSUFDM0J1bUIsRUFBYzdHLGFBQ2hCMEcsRUFBT2xtQixRQUdGcW1CLENBQ1QsRUFFQWpzQixPQUFPbWpCLGVBQWVvQixFQUFjemdCLFVBQVcsV0FBWSxDQUN6RCtsQixjQUFjLEVBQ2RELFlBQVksRUFDWmhkLElBQUssV0FDSCxPQUFPcE4sS0FBS3NzQixPQUFPL21CLFFBQ3JCLElBR0Z3ZixFQUFjemdCLFVBQVV1b0IsWUFBYyxXQUNwQyxPQUFPN3NCLEtBQUtzc0IsT0FBT08sWUFBWTVDLE1BQU1qcUIsS0FBS3NzQixPQUFRTSxVQUNwRCxFQUVBN0gsRUFBY3pnQixVQUFVK0IsT0FBUyxXQUMxQnJHLEtBQUtvbEIsV0FDUnBsQixLQUFLOHNCLFVBR1A5c0IsS0FBS3NzQixPQUFPam1CLFFBQ2QsRUFFQTBlLEVBQWN6Z0IsVUFBVThCLE1BQVEsV0FDOUJwRyxLQUFLc3NCLE9BQU9sbUIsT0FDZCxFQUVBMmUsRUFBY3pnQixVQUFVd29CLFFBQVUsV0FDaEM5c0IsS0FBS29sQixXQUFZLEVBRWpCcGxCLEtBQUt3c0IsZ0JBQWdCOXJCLFFBQVEsU0FBUytsQixHQUNwQ3ptQixLQUFLaUssS0FBS2dnQixNQUFNanFCLEtBQU15bUIsRUFDeEIsRUFBRTlsQixLQUFLWCxPQUNQQSxLQUFLd3NCLGdCQUFrQixFQUN6QixFQUVBekgsRUFBY3pnQixVQUFVdUYsS0FBTyxXQUM3QixJQUFJMmQsRUFBSWhrQixFQUFPYyxVQUFVdUYsS0FBS29nQixNQUFNanFCLEtBQU00c0IsV0FFMUMsT0FEQTVzQixLQUFLcUcsU0FDRW1oQixDQUNULEVBRUF6QyxFQUFjemdCLFVBQVVxb0IsWUFBYyxTQUFTbEcsR0FDekN6bUIsS0FBS29sQixVQUNQcGxCLEtBQUtpSyxLQUFLZ2dCLE1BQU1qcUIsS0FBTXltQixJQUlSLFNBQVpBLEVBQUssS0FDUHptQixLQUFLaWxCLFVBQVl3QixFQUFLLEdBQUc1a0IsT0FDekI3QixLQUFLK3NCLCtCQUdQL3NCLEtBQUt3c0IsZ0JBQWdCL21CLEtBQUtnaEIsR0FDNUIsRUFFQTFCLEVBQWN6Z0IsVUFBVXlvQiw0QkFBOEIsV0FDcEQsS0FBSS9zQixLQUFLdXNCLHNCQUlMdnNCLEtBQUtpbEIsVUFBWWpsQixLQUFLa2xCLGFBQTFCLENBSUFsbEIsS0FBS3VzQixzQkFBdUIsRUFDNUIsSUFBSTlkLEVBQ0YsZ0NBQWtDek8sS0FBS2tsQixZQUFjLG1CQUN2RGxsQixLQUFLaUssS0FBSyxRQUFTLElBQUlyRixNQUFNNkosR0FMN0IsQ0FNRixrQkMxR0EsSUFBSXFhLEVBRUpqcEIsRUFBT0QsUUFBVSxXQUNmLElBQUtrcEIsRUFBTyxDQUNWLElBRUVBLEVBQVEsRUFBUSxLQUFSLENBQWlCLG1CQUVMLENBQXRCLE1BQU8vbUIsR0FBZSxDQUNELG1CQUFWK21CLElBQ1RBLEVBQVEsV0FBb0IsRUFFaEMsQ0FDQUEsRUFBTW1CLE1BQU0sS0FBTTJDLFVBQ3BCLGlCQ2RBLElBQUk3WCxFQUFNLEVBQVEsTUFDZHlMLEVBQU16TCxFQUFJeUwsSUFDVnBkLEVBQU8sRUFBUSxNQUNmQyxFQUFRLEVBQVEsTUFDaEIycEIsRUFBVyxpQkFDWEMsRUFBUyxFQUFRLE1BQ2pCbkUsRUFBUSxFQUFRLE1BR2hCb0UsR0FBZSxFQUNuQixJQUNFRCxFQUFPLElBQUl6TSxFQUliLENBRkEsTUFBT3plLEdBQ0xtckIsRUFBOEIsb0JBQWZuckIsRUFBTWdZLElBQ3ZCLENBR0EsSUFBSW9ULEVBQXFCLENBQ3ZCLE9BQ0EsT0FDQSxXQUNBLE9BQ0EsT0FDQSxXQUNBLE9BQ0EsV0FDQSxRQUNBLFNBQ0EsUUFJRTlYLEVBQVMsQ0FBQyxRQUFTLFVBQVcsVUFBVyxRQUFTLFNBQVUsV0FDNUQrWCxFQUFnQjVzQixPQUFPK00sT0FBTyxNQUNsQzhILEVBQU8zVSxTQUFRLFNBQVUyc0IsR0FDdkJELEVBQWNDLEdBQVMsU0FBVUMsRUFBTUMsRUFBTUMsR0FDM0N4dEIsS0FBS3l0QixjQUFjeGpCLEtBQUtvakIsRUFBT0MsRUFBTUMsRUFBTUMsRUFDN0MsQ0FDRixJQUdBLElBQUlFLEVBQWtCQyxFQUNwQixrQkFDQSxjQUNBQyxXQUVFQyxFQUFtQkYsRUFDckIsNkJBQ0EsNkJBRUVHLEVBQXdCSCxFQUMxQiw0QkFDQSx1Q0FDQUUsR0FFRUUsRUFBNkJKLEVBQy9CLGtDQUNBLGdEQUVFSyxFQUFxQkwsRUFDdkIsNkJBQ0EsbUJBSUU1ZixFQUFVaWYsRUFBUzFvQixVQUFVeUosU0FBV2tnQixFQUc1QyxTQUFTQyxFQUFvQnJxQixFQUFTc3FCLEdBRXBDbkIsRUFBUzlvQixLQUFLbEUsTUFDZEEsS0FBS291QixpQkFBaUJ2cUIsR0FDdEI3RCxLQUFLcXVCLFNBQVd4cUIsRUFDaEI3RCxLQUFLc3VCLFFBQVMsRUFDZHR1QixLQUFLdXVCLFNBQVUsRUFDZnZ1QixLQUFLd3VCLGVBQWlCLEVBQ3RCeHVCLEtBQUt5dUIsV0FBYSxHQUNsQnp1QixLQUFLMHVCLG1CQUFxQixFQUMxQjF1QixLQUFLMnVCLG9CQUFzQixHQUd2QlIsR0FDRm51QixLQUFLa0csR0FBRyxXQUFZaW9CLEdBSXRCLElBQUk3ZSxFQUFPdFAsS0FDWEEsS0FBSzR1QixrQkFBb0IsU0FBVXpvQixHQUNqQyxJQUNFbUosRUFBS3VmLGlCQUFpQjFvQixFQUt4QixDQUhBLE1BQU8yb0IsR0FDTHhmLEVBQUtyRixLQUFLLFFBQVM2a0IsYUFBaUJqQixFQUNsQ2lCLEVBQVEsSUFBSWpCLEVBQWlCLENBQUVpQixNQUFPQSxJQUMxQyxDQUNGLEVBR0E5dUIsS0FBSyt1QixpQkFDUCxDQWtZQSxTQUFTQyxFQUFLQyxHQUVaLElBQUlydkIsRUFBVSxDQUNac3ZCLGFBQWMsR0FDZHZOLGNBQWUsVUFJYndOLEVBQWtCLENBQUMsRUFxRHZCLE9BcERBM3VCLE9BQU9DLEtBQUt3dUIsR0FBV3Z1QixTQUFRLFNBQVUwdUIsR0FDdkMsSUFBSXpsQixFQUFXeWxCLEVBQVMsSUFDcEJDLEVBQWlCRixFQUFnQnhsQixHQUFZc2xCLEVBQVVHLEdBQ3ZERSxFQUFrQjF2QixFQUFRd3ZCLEdBQVU1dUIsT0FBTytNLE9BQU84aEIsR0E0Q3REN3VCLE9BQU8rdUIsaUJBQWlCRCxFQUFpQixDQUN2Q2xtQixRQUFTLENBQUUzRSxNQTFDYixTQUFpQjBmLEVBQU90Z0IsRUFBU2hELEdBb0tyQyxJQUFlNEQsRUF0SVQsT0FzSVNBLEVBbEtDMGYsRUFtS1AzRCxHQUFPL2IsYUFBaUIrYixFQWxLekIyRCxFQUFRcUwsRUFBZ0JyTCxHQUVqQnNMLEVBQVN0TCxHQUNoQkEsRUFBUXFMLEVBQWdCbHNCLEVBQVM2Z0IsS0FHakN0akIsRUFBV2dELEVBQ1hBLEVBQVU2ckIsRUFBWXZMLEdBQ3RCQSxFQUFRLENBQUV4YSxTQUFVQSxJQUVsQmdtQixFQUFXOXJCLEtBQ2JoRCxFQUFXZ0QsRUFDWEEsRUFBVSxPQUlaQSxFQUFVckQsT0FBTzhLLE9BQU8sQ0FDdEI0akIsYUFBY3R2QixFQUFRc3ZCLGFBQ3RCdk4sY0FBZS9oQixFQUFRK2hCLGVBQ3RCd0MsRUFBT3RnQixJQUNGc3JCLGdCQUFrQkEsRUFDckJNLEVBQVM1ckIsRUFBUTRGLE9BQVVnbUIsRUFBUzVyQixFQUFRNkYsWUFDL0M3RixFQUFRNkYsU0FBVyxPQUdyQnVqQixFQUFPMkMsTUFBTS9yQixFQUFROEYsU0FBVUEsRUFBVSxxQkFDekNtZixFQUFNLFVBQVdqbEIsR0FDVixJQUFJcXFCLEVBQW9CcnFCLEVBQVNoRCxFQUMxQyxFQVc2QndwQixjQUFjLEVBQU1ELFlBQVksRUFBTXBGLFVBQVUsR0FDM0U1WCxJQUFLLENBQUUzSSxNQVRULFNBQWEwZixFQUFPdGdCLEVBQVNoRCxHQUMzQixJQUFJZ3ZCLEVBQWlCUCxFQUFnQmxtQixRQUFRK2EsRUFBT3RnQixFQUFTaEQsR0FFN0QsT0FEQWd2QixFQUFlanFCLE1BQ1JpcUIsQ0FDVCxFQUtxQnhGLGNBQWMsRUFBTUQsWUFBWSxFQUFNcEYsVUFBVSxJQUV2RSxJQUNPcGxCLENBQ1QsQ0FFQSxTQUFTcXVCLElBQXFCLENBRTlCLFNBQVMzcUIsRUFBUzZnQixHQUNoQixJQUFJMkwsRUFFSixHQUFJNUMsRUFDRjRDLEVBQVMsSUFBSXRQLEVBQUkyRCxRQUtqQixJQUFLc0wsR0FETEssRUFBU0osRUFBWTNhLEVBQUlnYixNQUFNNUwsS0FDVnhhLFVBQ25CLE1BQU0sSUFBSStqQixFQUFnQixDQUFFdkosVUFHaEMsT0FBTzJMLENBQ1QsQ0FPQSxTQUFTSixFQUFZdkwsR0FDbkIsR0FBSSxNQUFNM0YsS0FBSzJGLEVBQU16YSxZQUFjLG9CQUFvQjhVLEtBQUsyRixFQUFNemEsVUFDaEUsTUFBTSxJQUFJZ2tCLEVBQWdCLENBQUV2SixNQUFPQSxFQUFNNkwsTUFBUTdMLElBRW5ELEdBQUksTUFBTTNGLEtBQUsyRixFQUFNMWEsUUFBVSwyQkFBMkIrVSxLQUFLMkYsRUFBTTFhLE1BQ25FLE1BQU0sSUFBSWlrQixFQUFnQixDQUFFdkosTUFBT0EsRUFBTTZMLE1BQVE3TCxJQUVuRCxPQUFPQSxDQUNULENBRUEsU0FBU3FMLEVBQWdCUyxFQUFXQyxHQUNsQyxJQUFJQyxFQUFTRCxHQUFVLENBQUMsRUFDeEIsSUFBSyxJQUFJN3ZCLEtBQU84c0IsRUFDZGdELEVBQU85dkIsR0FBTzR2QixFQUFVNXZCLEdBYzFCLE9BVkk4dkIsRUFBT3ptQixTQUFTMG1CLFdBQVcsT0FDN0JELEVBQU96bUIsU0FBV3ltQixFQUFPem1CLFNBQVNtaEIsTUFBTSxHQUFJLElBRzFCLEtBQWhCc0YsRUFBTzVtQixPQUNUNG1CLEVBQU81bUIsS0FBT2tnQixPQUFPMEcsRUFBTzVtQixPQUc5QjRtQixFQUFPaHRCLEtBQU9ndEIsRUFBT0UsT0FBU0YsRUFBTzNtQixTQUFXMm1CLEVBQU9FLE9BQVNGLEVBQU8zbUIsU0FFaEUybUIsQ0FDVCxDQUVBLFNBQVNHLEVBQXNCQyxFQUFPdHFCLEdBQ3BDLElBQUl1cUIsRUFDSixJQUFLLElBQUkzckIsS0FBVW9CLEVBQ2JzcUIsRUFBTS9SLEtBQUszWixLQUNiMnJCLEVBQVl2cUIsRUFBUXBCLFVBQ2JvQixFQUFRcEIsSUFHbkIsT0FBTyxNQUFDMnJCLE9BQ043cUIsRUFBWXllLE9BQU9vTSxHQUFXcEUsTUFDbEMsQ0FFQSxTQUFTdUIsRUFBZ0I1VCxFQUFNdEwsRUFBU2dpQixHQUV0QyxTQUFTQyxFQUFZQyxHQUNuQi9yQixNQUFNZ3NCLGtCQUFrQjV3QixLQUFNQSxLQUFLNndCLGFBQ25DcndCLE9BQU84SyxPQUFPdEwsS0FBTTJ3QixHQUFjLENBQUMsR0FDbkMzd0IsS0FBSytaLEtBQU9BLEVBQ1ovWixLQUFLeU8sUUFBVXpPLEtBQUs4dUIsTUFBUXJnQixFQUFVLEtBQU96TyxLQUFLOHVCLE1BQU1yZ0IsUUFBVUEsQ0FDcEUsQ0FjQSxPQVhBaWlCLEVBQVlwc0IsVUFBWSxJQUFLbXNCLEdBQWE3ckIsT0FDMUNwRSxPQUFPK3VCLGlCQUFpQm1CLEVBQVlwc0IsVUFBVyxDQUM3Q3VzQixZQUFhLENBQ1hwc0IsTUFBT2lzQixFQUNQdEcsWUFBWSxHQUVkbGpCLEtBQU0sQ0FDSnpDLE1BQU8sVUFBWXNWLEVBQU8sSUFDMUJxUSxZQUFZLEtBR1RzRyxDQUNULENBRUEsU0FBU0ksRUFBZTFuQixFQUFTckgsR0FDL0IsSUFBSyxJQUFJc3JCLEtBQVNoWSxFQUNoQmpNLEVBQVFZLGVBQWVxakIsRUFBT0QsRUFBY0MsSUFFOUNqa0IsRUFBUWxELEdBQUcsUUFBUytuQixHQUNwQjdrQixFQUFRMkUsUUFBUWhNLEVBQ2xCLENBUUEsU0FBUzB0QixFQUFTaHJCLEdBQ2hCLE1BQXdCLGlCQUFWQSxHQUFzQkEsYUFBaUIyZixNQUN2RCxDQUVBLFNBQVN1TCxFQUFXbHJCLEdBQ2xCLE1BQXdCLG1CQUFWQSxDQUNoQixDQTlpQkF5cEIsRUFBb0I1cEIsVUFBWTlELE9BQU8rTSxPQUFPeWYsRUFBUzFvQixXQUV2RDRwQixFQUFvQjVwQixVQUFVL0MsTUFBUSxXQUNwQ3V2QixFQUFlOXdCLEtBQUsrd0IsaUJBQ3BCL3dCLEtBQUsrd0IsZ0JBQWdCeHZCLFFBQ3JCdkIsS0FBS2lLLEtBQUssUUFDWixFQUVBaWtCLEVBQW9CNXBCLFVBQVV5SixRQUFVLFNBQVVoTSxHQUdoRCxPQUZBK3VCLEVBQWU5d0IsS0FBSyt3QixnQkFBaUJodkIsR0FDckNnTSxFQUFRN0osS0FBS2xFLEtBQU0rQixHQUNaL0IsSUFDVCxFQUdBa3VCLEVBQW9CNXBCLFVBQVU4aEIsTUFBUSxTQUFVL2IsRUFBTTJtQixFQUFVbndCLEdBRTlELEdBQUliLEtBQUt1dUIsUUFDUCxNQUFNLElBQUlQLEVBSVosSUFBS3lCLEVBQVNwbEIsS0EyaEJVLGlCQURSNUYsRUExaEJpQjRGLE1BMmhCSSxXQUFZNUYsSUExaEIvQyxNQUFNLElBQUltcEIsVUFBVSxpREF5aEJ4QixJQUFrQm5wQixFQXZoQlprckIsRUFBV3FCLEtBQ2Jud0IsRUFBV213QixFQUNYQSxFQUFXLE1BS08sSUFBaEIzbUIsRUFBS3hJLE9BT0w3QixLQUFLMHVCLG1CQUFxQnJrQixFQUFLeEksUUFBVTdCLEtBQUtxdUIsU0FBUzFNLGVBQ3pEM2hCLEtBQUswdUIsb0JBQXNCcmtCLEVBQUt4SSxPQUNoQzdCLEtBQUsydUIsb0JBQW9CbHBCLEtBQUssQ0FBRTRFLEtBQU1BLEVBQU0ybUIsU0FBVUEsSUFDdERoeEIsS0FBSyt3QixnQkFBZ0IzSyxNQUFNL2IsRUFBTTJtQixFQUFVbndCLEtBSTNDYixLQUFLaUssS0FBSyxRQUFTLElBQUk4akIsR0FDdkIvdEIsS0FBS3VCLFNBZERWLEdBQ0ZBLEdBZU4sRUFHQXF0QixFQUFvQjVwQixVQUFVc0IsSUFBTSxTQUFVeUUsRUFBTTJtQixFQUFVbndCLEdBWTVELEdBVkk4dUIsRUFBV3RsQixJQUNieEosRUFBV3dKLEVBQ1hBLEVBQU8ybUIsRUFBVyxNQUVYckIsRUFBV3FCLEtBQ2xCbndCLEVBQVdtd0IsRUFDWEEsRUFBVyxNQUlSM21CLEVBSUEsQ0FDSCxJQUFJaUYsRUFBT3RQLEtBQ1BpeEIsRUFBaUJqeEIsS0FBSyt3QixnQkFDMUIvd0IsS0FBS29tQixNQUFNL2IsRUFBTTJtQixHQUFVLFdBQ3pCMWhCLEVBQUtnZixRQUFTLEVBQ2QyQyxFQUFlcnJCLElBQUksS0FBTSxLQUFNL0UsRUFDakMsSUFDQWIsS0FBS3V1QixTQUFVLENBQ2pCLE1BWEV2dUIsS0FBS3N1QixPQUFTdHVCLEtBQUt1dUIsU0FBVSxFQUM3QnZ1QixLQUFLK3dCLGdCQUFnQm5yQixJQUFJLEtBQU0sS0FBTS9FLEVBV3pDLEVBR0FxdEIsRUFBb0I1cEIsVUFBVXNGLFVBQVksU0FBVTFDLEVBQU16QyxHQUN4RHpFLEtBQUtxdUIsU0FBU3BvQixRQUFRaUIsR0FBUXpDLEVBQzlCekUsS0FBSyt3QixnQkFBZ0JubkIsVUFBVTFDLEVBQU16QyxFQUN2QyxFQUdBeXBCLEVBQW9CNXBCLFVBQVU0c0IsYUFBZSxTQUFVaHFCLFVBQzlDbEgsS0FBS3F1QixTQUFTcG9CLFFBQVFpQixHQUM3QmxILEtBQUsrd0IsZ0JBQWdCRyxhQUFhaHFCLEVBQ3BDLEVBR0FnbkIsRUFBb0I1cEIsVUFBVWpELFdBQWEsU0FBVTh2QixFQUFPdHdCLEdBQzFELElBQUl5TyxFQUFPdFAsS0FHWCxTQUFTb3hCLEVBQWlCQyxHQUN4QkEsRUFBT2h3QixXQUFXOHZCLEdBQ2xCRSxFQUFPcm5CLGVBQWUsVUFBV3FuQixFQUFPdGpCLFNBQ3hDc2pCLEVBQU9DLFlBQVksVUFBV0QsRUFBT3RqQixRQUN2QyxDQUdBLFNBQVN3akIsRUFBV0YsR0FDZC9oQixFQUFLa2lCLFVBQ1BDLGFBQWFuaUIsRUFBS2tpQixVQUVwQmxpQixFQUFLa2lCLFNBQVdud0IsWUFBVyxXQUN6QmlPLEVBQUtyRixLQUFLLFdBQ1Z5bkIsR0FDRixHQUFHUCxHQUNIQyxFQUFpQkMsRUFDbkIsQ0FHQSxTQUFTSyxJQUVIcGlCLEVBQUtraUIsV0FDUEMsYUFBYW5pQixFQUFLa2lCLFVBQ2xCbGlCLEVBQUtraUIsU0FBVyxNQUlsQmxpQixFQUFLdEYsZUFBZSxRQUFTMG5CLEdBQzdCcGlCLEVBQUt0RixlQUFlLFFBQVMwbkIsR0FDN0JwaUIsRUFBS3RGLGVBQWUsV0FBWTBuQixHQUNoQ3BpQixFQUFLdEYsZUFBZSxRQUFTMG5CLEdBQ3pCN3dCLEdBQ0Z5TyxFQUFLdEYsZUFBZSxVQUFXbkosR0FFNUJ5TyxFQUFLK2hCLFFBQ1IvaEIsRUFBS3loQixnQkFBZ0IvbUIsZUFBZSxTQUFVdW5CLEVBRWxELENBc0JBLE9BbkJJMXdCLEdBQ0ZiLEtBQUtrRyxHQUFHLFVBQVdyRixHQUlqQmIsS0FBS3F4QixPQUNQRSxFQUFXdnhCLEtBQUtxeEIsUUFHaEJyeEIsS0FBSyt3QixnQkFBZ0JZLEtBQUssU0FBVUosR0FJdEN2eEIsS0FBS2tHLEdBQUcsU0FBVWtyQixHQUNsQnB4QixLQUFLa0csR0FBRyxRQUFTd3JCLEdBQ2pCMXhCLEtBQUtrRyxHQUFHLFFBQVN3ckIsR0FDakIxeEIsS0FBS2tHLEdBQUcsV0FBWXdyQixHQUNwQjF4QixLQUFLa0csR0FBRyxRQUFTd3JCLEdBRVYxeEIsSUFDVCxFQUdBLENBQ0UsZUFBZ0IsWUFDaEIsYUFBYyxzQkFDZFUsU0FBUSxTQUFVNEksR0FDbEI0a0IsRUFBb0I1cEIsVUFBVWdGLEdBQVUsU0FBVTVHLEVBQUdDLEdBQ25ELE9BQU8zQyxLQUFLK3dCLGdCQUFnQnpuQixHQUFRNUcsRUFBR0MsRUFDekMsQ0FDRixJQUdBLENBQUMsVUFBVyxhQUFjLFVBQVVqQyxTQUFRLFNBQVVreEIsR0FDcERweEIsT0FBT21qQixlQUFldUssRUFBb0I1cEIsVUFBV3N0QixFQUFVLENBQzdEeGtCLElBQUssV0FBYyxPQUFPcE4sS0FBSyt3QixnQkFBZ0JhLEVBQVcsR0FFOUQsSUFFQTFELEVBQW9CNXBCLFVBQVU4cEIsaUJBQW1CLFNBQVV2cUIsR0FrQnpELEdBaEJLQSxFQUFRb0MsVUFDWHBDLEVBQVFvQyxRQUFVLENBQUMsR0FNakJwQyxFQUFRNEYsT0FFTDVGLEVBQVE2RixXQUNYN0YsRUFBUTZGLFNBQVc3RixFQUFRNEYsYUFFdEI1RixFQUFRNEYsT0FJWjVGLEVBQVEyRixVQUFZM0YsRUFBUVYsS0FBTSxDQUNyQyxJQUFJMHVCLEVBQVlodUIsRUFBUVYsS0FBSzBoQixRQUFRLEtBQ2pDZ04sRUFBWSxFQUNkaHVCLEVBQVEyRixTQUFXM0YsRUFBUVYsTUFHM0JVLEVBQVEyRixTQUFXM0YsRUFBUVYsS0FBS3FGLFVBQVUsRUFBR3FwQixHQUM3Q2h1QixFQUFRd3NCLE9BQVN4c0IsRUFBUVYsS0FBS3FGLFVBQVVxcEIsR0FFNUMsQ0FDRixFQUlBM0QsRUFBb0I1cEIsVUFBVXlxQixnQkFBa0IsV0FFOUMsSUFBSXBsQixFQUFXM0osS0FBS3F1QixTQUFTMWtCLFNBQ3pCMGxCLEVBQWlCcnZCLEtBQUtxdUIsU0FBU2MsZ0JBQWdCeGxCLEdBQ25ELElBQUswbEIsRUFDSCxNQUFNLElBQUl6QixVQUFVLHdCQUEwQmprQixHQUtoRCxHQUFJM0osS0FBS3F1QixTQUFTeUQsT0FBUSxDQUN4QixJQUFJMUMsRUFBU3psQixFQUFTa2hCLE1BQU0sR0FBSSxHQUNoQzdxQixLQUFLcXVCLFNBQVMwRCxNQUFRL3hCLEtBQUtxdUIsU0FBU3lELE9BQU8xQyxFQUM3QyxDQUdBLElBQUlobUIsRUFBVXBKLEtBQUsrd0IsZ0JBQ2IxQixFQUFlam1CLFFBQVFwSixLQUFLcXVCLFNBQVVydUIsS0FBSzR1QixtQkFFakQsSUFBSyxJQUFJdkIsS0FEVGprQixFQUFRcWtCLGNBQWdCenRCLEtBQ05xVixHQUNoQmpNLEVBQVFsRCxHQUFHbW5CLEVBQU9ELEVBQWNDLElBYWxDLEdBUkFydEIsS0FBS2d5QixZQUFjLE1BQU14VCxLQUFLeGUsS0FBS3F1QixTQUFTbHJCLE1BQzFDNFIsRUFBSStVLE9BQU85cEIsS0FBS3F1QixVQUdoQnJ1QixLQUFLcXVCLFNBQVNsckIsS0FJWm5ELEtBQUtpeUIsWUFBYSxDQUVwQixJQUFJNXBCLEVBQUksRUFDSmlILEVBQU90UCxLQUNQa3lCLEVBQVVseUIsS0FBSzJ1QixxQkFDbEIsU0FBU3dELEVBQVVwd0IsR0FHbEIsR0FBSXFILElBQVlrRyxFQUFLeWhCLGdCQUduQixHQUFJaHZCLEVBQ0Z1TixFQUFLckYsS0FBSyxRQUFTbEksUUFHaEIsR0FBSXNHLEVBQUk2cEIsRUFBUXJ3QixPQUFRLENBQzNCLElBQUl5aUIsRUFBUzROLEVBQVE3cEIsS0FFaEJlLEVBQVFncEIsVUFDWGhwQixFQUFRZ2QsTUFBTTlCLEVBQU9qYSxLQUFNaWEsRUFBTzBNLFNBQVVtQixFQUVoRCxNQUVTN2lCLEVBQUtnZixRQUNabGxCLEVBQVF4RCxLQUdkLENBdEJBLEVBdUJGLENBQ0YsRUFHQXNvQixFQUFvQjVwQixVQUFVdXFCLGlCQUFtQixTQUFVMW9CLEdBRXpELElBQUlrc0IsRUFBYWxzQixFQUFTa3NCLFdBQ3RCcnlCLEtBQUtxdUIsU0FBU2lFLGdCQUNoQnR5QixLQUFLeXVCLFdBQVdocEIsS0FBSyxDQUNuQnNQLElBQUsvVSxLQUFLZ3lCLFlBQ1YvckIsUUFBU0UsRUFBU0YsUUFDbEJvc0IsV0FBWUEsSUFZaEIsSUF3Qkl2USxFQXhCQXlRLEVBQVdwc0IsRUFBU0YsUUFBUXNzQixTQUNoQyxJQUFLQSxJQUE4QyxJQUFsQ3Z5QixLQUFLcXVCLFNBQVNtRSxpQkFDM0JILEVBQWEsS0FBT0EsR0FBYyxJQU9wQyxPQU5BbHNCLEVBQVNzc0IsWUFBY3p5QixLQUFLZ3lCLFlBQzVCN3JCLEVBQVN1c0IsVUFBWTF5QixLQUFLeXVCLFdBQzFCenVCLEtBQUtpSyxLQUFLLFdBQVk5RCxRQUd0Qm5HLEtBQUsydUIsb0JBQXNCLElBVzdCLEdBTkFtQyxFQUFlOXdCLEtBQUsrd0IsaUJBRXBCNXFCLEVBQVM0SCxZQUlIL04sS0FBS3d1QixlQUFpQnh1QixLQUFLcXVCLFNBQVNhLGFBQ3hDLE1BQU0sSUFBSXBCLEVBS1osSUFBSTZFLEVBQWlCM3lCLEtBQUtxdUIsU0FBU3NFLGVBQy9CQSxJQUNGN1EsRUFBaUJ0aEIsT0FBTzhLLE9BQU8sQ0FFN0JzbkIsS0FBTXpzQixFQUFTMHNCLElBQUlDLFVBQVUsU0FDNUI5eUIsS0FBS3F1QixTQUFTcG9CLFVBT25CLElBQUlxRCxFQUFTdEosS0FBS3F1QixTQUFTL2tCLFNBQ1AsTUFBZitvQixHQUFxQyxNQUFmQSxJQUFnRCxTQUF6QnJ5QixLQUFLcXVCLFNBQVMva0IsUUFLNUMsTUFBZitvQixJQUF3QixpQkFBaUI3VCxLQUFLeGUsS0FBS3F1QixTQUFTL2tCLFdBQy9EdEosS0FBS3F1QixTQUFTL2tCLE9BQVMsTUFFdkJ0SixLQUFLMnVCLG9CQUFzQixHQUMzQjJCLEVBQXNCLGFBQWN0d0IsS0FBS3F1QixTQUFTcG9CLFVBSXBELElBNkhrQjhzQixFQUFVQyxFQTdIeEJDLEVBQW9CM0MsRUFBc0IsVUFBV3R3QixLQUFLcXVCLFNBQVNwb0IsU0FHbkVpdEIsRUFBa0I1dkIsRUFBU3RELEtBQUtneUIsYUFDaENtQixFQUFjRixHQUFxQkMsRUFBZ0J6cEIsS0FDbkQycEIsRUFBYSxRQUFRNVUsS0FBSytULEdBQVl2eUIsS0FBS2d5QixZQUM3Q2pkLEVBQUkrVSxPQUFPdHBCLE9BQU84SyxPQUFPNG5CLEVBQWlCLENBQUV6cEIsS0FBTTBwQixLQUdoREUsR0FvSGNOLEVBcEhXUixFQW9IRFMsRUFwSFdJLEVBc0hoQ2xHLEVBQWUsSUFBSTFNLEVBQUl1UyxFQUFVQyxHQUFRMXZCLEVBQVN5UixFQUFJdWUsUUFBUU4sRUFBTUQsS0F2RzNFLEdBZEFqSyxFQUFNLGlCQUFrQnVLLEVBQVlyRCxNQUNwQ2h3QixLQUFLaXlCLGFBQWMsRUFDbkJ6QyxFQUFnQjZELEVBQWFyekIsS0FBS3F1QixXQUk5QmdGLEVBQVkxcEIsV0FBYXVwQixFQUFnQnZwQixVQUNqQixXQUF6QjBwQixFQUFZMXBCLFVBQ1owcEIsRUFBWTVwQixPQUFTMHBCLElBMEwxQixTQUFxQkksRUFBV3ptQixHQUM5Qm1nQixFQUFPd0MsRUFBUzhELElBQWM5RCxFQUFTM2lCLElBQ3ZDLElBQUkwbUIsRUFBTUQsRUFBVTF4QixPQUFTaUwsRUFBT2pMLE9BQVMsRUFDN0MsT0FBTzJ4QixFQUFNLEdBQXdCLE1BQW5CRCxFQUFVQyxJQUFnQkQsRUFBVUUsU0FBUzNtQixFQUNqRSxDQTdMTTRtQixDQUFZTCxFQUFZNXBCLEtBQU0wcEIsS0FDaEM3QyxFQUFzQiw4QkFBK0J0d0IsS0FBS3F1QixTQUFTcG9CLFNBSWpFMHBCLEVBQVdnRCxHQUFpQixDQUM5QixJQUFJZ0IsRUFBa0IsQ0FDcEIxdEIsUUFBU0UsRUFBU0YsUUFDbEJvc0IsV0FBWUEsR0FFVnVCLEVBQWlCLENBQ25CN2UsSUFBS3FlLEVBQ0w5cEIsT0FBUUEsRUFDUnJELFFBQVM2YixHQUVYNlEsRUFBZTN5QixLQUFLcXVCLFNBQVVzRixFQUFpQkMsR0FDL0M1ekIsS0FBS291QixpQkFBaUJwdUIsS0FBS3F1QixTQUM3QixDQUdBcnVCLEtBQUsrdUIsaUJBQ1AsRUEyTEFsdkIsRUFBT0QsUUFBVW92QixFQUFLLENBQUU1ckIsS0FBTUEsRUFBTUMsTUFBT0EsSUFDM0N4RCxFQUFPRCxRQUFRb3ZCLEtBQU9BLHlCQzlwQnRCbnZCLEVBQU9ELFFBQVUsQ0FBQ2kwQixFQUFNQyxLQUN2QkEsRUFBT0EsR0FBUTF5QixRQUFRMHlCLEtBQ3ZCLE1BQU16SSxFQUFTd0ksRUFBS3pELFdBQVcsS0FBTyxHQUFzQixJQUFoQnlELEVBQUtoeUIsT0FBZSxJQUFNLEtBQ2hFa3lCLEVBQU1ELEVBQUtqUCxRQUFRd0csRUFBU3dJLEdBQzVCRyxFQUFnQkYsRUFBS2pQLFFBQVEsTUFDbkMsT0FBZ0IsSUFBVGtQLEtBQWtDLElBQW5CQyxHQUE4QkQsRUFBTUMsRUFBYyxrQkNLekVuMEIsRUFBT0QsUUFBVSxFQUFqQixrQ0NHQSxJQTJJdUJxMEIsRUFBWUMsRUFFN0JDLEVBN0lGQyxFQUFLLEVBQVEsTUFDYkMsRUFBVSxnQkFPVkMsRUFBc0IsMEJBQ3RCQyxFQUFtQixXQXlCdkIsU0FBU0MsRUFBU3pwQixHQUNoQixJQUFLQSxHQUF3QixpQkFBVEEsRUFDbEIsT0FBTyxFQUlULElBQUlrYyxFQUFRcU4sRUFBb0JHLEtBQUsxcEIsR0FDakN0SCxFQUFPd2pCLEdBQVNtTixFQUFHbk4sRUFBTSxHQUFHcGYsZUFFaEMsT0FBSXBFLEdBQVFBLEVBQUsrd0IsUUFDUi93QixFQUFLK3dCLFdBSVZ2TixJQUFTc04sRUFBaUIvVixLQUFLeUksRUFBTSxNQUNoQyxPQUlYLENBckNBcm5CLEVBQVE0MEIsUUFBVUEsRUFDbEI1MEIsRUFBUTgwQixTQUFXLENBQUVwdEIsT0FBUWt0QixHQUM3QjUwQixFQUFRNEcsWUE0Q1IsU0FBc0IybEIsR0FFcEIsSUFBS0EsR0FBc0IsaUJBQVJBLEVBQ2pCLE9BQU8sRUFHVCxJQUFJMW9CLEdBQTZCLElBQXRCMG9CLEVBQUl0SCxRQUFRLEtBQ25CamxCLEVBQVEwSCxPQUFPNmtCLEdBQ2ZBLEVBRUosSUFBSzFvQixFQUNILE9BQU8sRUFJVCxJQUFpQyxJQUE3QkEsRUFBS29oQixRQUFRLFdBQW1CLENBQ2xDLElBQUkyUCxFQUFVNTBCLEVBQVE0MEIsUUFBUS93QixHQUMxQit3QixJQUFTL3dCLEdBQVEsYUFBZSt3QixFQUFRM3NCLGNBQzlDLENBRUEsT0FBT3BFLENBQ1QsRUFoRUE3RCxFQUFRKzBCLFVBeUVSLFNBQW9CNXBCLEdBQ2xCLElBQUtBLEdBQXdCLGlCQUFUQSxFQUNsQixPQUFPLEVBSVQsSUFBSWtjLEVBQVFxTixFQUFvQkcsS0FBSzFwQixHQUdqQzZwQixFQUFPM04sR0FBU3JuQixFQUFRcTBCLFdBQVdoTixFQUFNLEdBQUdwZixlQUVoRCxJQUFLK3NCLElBQVNBLEVBQUsveUIsT0FDakIsT0FBTyxFQUdULE9BQU8reUIsRUFBSyxFQUNkLEVBeEZBaDFCLEVBQVFxMEIsV0FBYXp6QixPQUFPK00sT0FBTyxNQUNuQzNOLEVBQVEwSCxPQWdHUixTQUFpQm5FLEdBQ2YsSUFBS0EsR0FBd0IsaUJBQVRBLEVBQ2xCLE9BQU8sRUFJVCxJQUFJd3hCLEVBQVlOLEVBQVEsS0FBT2x4QixHQUM1QjBFLGNBQ0FndEIsT0FBTyxHQUVWLElBQUtGLEVBQ0gsT0FBTyxFQUdULE9BQU8vMEIsRUFBUXMwQixNQUFNUyxLQUFjLENBQ3JDLEVBOUdBLzBCLEVBQVFzMEIsTUFBUTF6QixPQUFPK00sT0FBTyxNQXFIUDBtQixFQWxIVnIwQixFQUFRcTBCLFdBa0hjQyxFQWxIRnQwQixFQUFRczBCLE1Bb0huQ0MsRUFBYSxDQUFDLFFBQVMsY0FBVXh1QixFQUFXLFFBRWhEbkYsT0FBT0MsS0FBSzJ6QixHQUFJMXpCLFNBQVEsU0FBMEJxSyxHQUNoRCxJQUFJdEgsRUFBTzJ3QixFQUFHcnBCLEdBQ1Y2cEIsRUFBT254QixFQUFLd3dCLFdBRWhCLEdBQUtXLEdBQVNBLEVBQUsveUIsT0FBbkIsQ0FLQW95QixFQUFXbHBCLEdBQVE2cEIsRUFHbkIsSUFBSyxJQUFJdnNCLEVBQUksRUFBR0EsRUFBSXVzQixFQUFLL3lCLE9BQVF3RyxJQUFLLENBQ3BDLElBQUlzc0IsRUFBWUMsRUFBS3ZzQixHQUVyQixHQUFJNnJCLEVBQU1TLEdBQVksQ0FDcEIsSUFBSXBzQixFQUFPNHJCLEVBQVd0UCxRQUFRdVAsRUFBR0YsRUFBTVMsSUFBWXJJLFFBQy9Dd0ksRUFBS1gsRUFBV3RQLFFBQVFwaEIsRUFBSzZvQixRQUVqQyxHQUF5Qiw2QkFBckI0SCxFQUFNUyxLQUNQcHNCLEVBQU91c0IsR0FBT3ZzQixJQUFTdXNCLEdBQXlDLGlCQUFuQ1osRUFBTVMsR0FBV0UsT0FBTyxFQUFHLEtBRXpELFFBRUosQ0FHQVgsRUFBTVMsR0FBYTVwQixDQUNyQixDQXRCQSxDQXVCRixjQ3RMRixJQUFJZ3FCLEVBQUksSUFDSkMsRUFBUSxHQUFKRCxFQUNKRSxFQUFRLEdBQUpELEVBQ0pyaUIsRUFBUSxHQUFKc2lCLEVBQ0pDLEVBQVEsRUFBSnZpQixFQUNKd2lCLEVBQVEsT0FBSnhpQixFQXFKUixTQUFTeWlCLEVBQU8xTCxFQUFJMkwsRUFBT0MsRUFBR3B1QixHQUM1QixJQUFJcXVCLEVBQVdGLEdBQWEsSUFBSkMsRUFDeEIsT0FBTzdzQixLQUFLK3NCLE1BQU05TCxFQUFLNEwsR0FBSyxJQUFNcHVCLEdBQVFxdUIsRUFBVyxJQUFNLEdBQzdELENBeElBMTFCLEVBQU9ELFFBQVUsU0FBU29xQixFQUFLbm1CLEdBQzdCQSxFQUFVQSxHQUFXLENBQUMsRUFDdEIsSUFBSWtILFNBQWNpZixFQUNsQixHQUFhLFdBQVRqZixHQUFxQmlmLEVBQUlub0IsT0FBUyxFQUNwQyxPQWtCSixTQUFlc3FCLEdBRWIsSUFEQUEsRUFBTS9ILE9BQU8rSCxJQUNMdHFCLE9BQVMsSUFDZixPQUVGLElBQUlvbEIsRUFBUSxtSUFBbUl3TixLQUM3SXRJLEdBRUYsSUFBS2xGLEVBQ0gsT0FFRixJQUFJcU8sRUFBSUcsV0FBV3hPLEVBQU0sSUFFekIsUUFEWUEsRUFBTSxJQUFNLE1BQU1wZixlQUU1QixJQUFLLFFBQ0wsSUFBSyxPQUNMLElBQUssTUFDTCxJQUFLLEtBQ0wsSUFBSyxJQUNILE9BQU95dEIsRUFBSUgsRUFDYixJQUFLLFFBQ0wsSUFBSyxPQUNMLElBQUssSUFDSCxPQUFPRyxFQUFJSixFQUNiLElBQUssT0FDTCxJQUFLLE1BQ0wsSUFBSyxJQUNILE9BQU9JLEVBQUkzaUIsRUFDYixJQUFLLFFBQ0wsSUFBSyxPQUNMLElBQUssTUFDTCxJQUFLLEtBQ0wsSUFBSyxJQUNILE9BQU8yaUIsRUFBSUwsRUFDYixJQUFLLFVBQ0wsSUFBSyxTQUNMLElBQUssT0FDTCxJQUFLLE1BQ0wsSUFBSyxJQUNILE9BQU9LLEVBQUlOLEVBQ2IsSUFBSyxVQUNMLElBQUssU0FDTCxJQUFLLE9BQ0wsSUFBSyxNQUNMLElBQUssSUFDSCxPQUFPTSxFQUFJUCxFQUNiLElBQUssZUFDTCxJQUFLLGNBQ0wsSUFBSyxRQUNMLElBQUssT0FDTCxJQUFLLEtBQ0gsT0FBT08sRUFDVCxRQUNFLE9BRU4sQ0F6RVd2RixDQUFNL0YsR0FDUixHQUFhLFdBQVRqZixHQUFxQjJxQixTQUFTMUwsR0FDdkMsT0FBT25tQixFQUFROHhCLEtBMEduQixTQUFpQmpNLEdBQ2YsSUFBSTJMLEVBQVE1c0IsS0FBS3NpQixJQUFJckIsR0FDckIsR0FBSTJMLEdBQVMxaUIsRUFDWCxPQUFPeWlCLEVBQU8xTCxFQUFJMkwsRUFBTzFpQixFQUFHLE9BRTlCLEdBQUkwaUIsR0FBU0osRUFDWCxPQUFPRyxFQUFPMUwsRUFBSTJMLEVBQU9KLEVBQUcsUUFFOUIsR0FBSUksR0FBU0wsRUFDWCxPQUFPSSxFQUFPMUwsRUFBSTJMLEVBQU9MLEVBQUcsVUFFOUIsR0FBSUssR0FBU04sRUFDWCxPQUFPSyxFQUFPMUwsRUFBSTJMLEVBQU9OLEVBQUcsVUFFOUIsT0FBT3JMLEVBQUssS0FDZCxDQXpIMEJrTSxDQUFRNUwsR0FpRmxDLFNBQWtCTixHQUNoQixJQUFJMkwsRUFBUTVzQixLQUFLc2lCLElBQUlyQixHQUNyQixHQUFJMkwsR0FBUzFpQixFQUNYLE9BQU9sSyxLQUFLK3NCLE1BQU05TCxFQUFLL1csR0FBSyxJQUU5QixHQUFJMGlCLEdBQVNKLEVBQ1gsT0FBT3hzQixLQUFLK3NCLE1BQU05TCxFQUFLdUwsR0FBSyxJQUU5QixHQUFJSSxHQUFTTCxFQUNYLE9BQU92c0IsS0FBSytzQixNQUFNOUwsRUFBS3NMLEdBQUssSUFFOUIsR0FBSUssR0FBU04sRUFDWCxPQUFPdHNCLEtBQUsrc0IsTUFBTTlMLEVBQUtxTCxHQUFLLElBRTlCLE9BQU9yTCxFQUFLLElBQ2QsQ0FoR3lDbU0sQ0FBUzdMLEdBRWhELE1BQU0sSUFBSXBsQixNQUNSLHdEQUNFMlIsS0FBS0MsVUFBVXdULEdBRXJCLCtCQ25DQSxJQUFJMW1CLEVBQVcsY0FFWHd5QixFQUFnQixDQUNsQkMsSUFBSyxHQUNMQyxPQUFRLEdBQ1I1eUIsS0FBTSxHQUNOQyxNQUFPLElBQ1A0eUIsR0FBSSxHQUNKQyxJQUFLLEtBR0hDLEVBQWlCL1IsT0FBTzlmLFVBQVVtdkIsVUFBWSxTQUFTc0IsR0FDekQsT0FBT0EsRUFBRWx6QixRQUFVN0IsS0FBSzZCLFNBQ3VCLElBQTdDN0IsS0FBSzZrQixRQUFRa1EsRUFBRy8wQixLQUFLNkIsT0FBU2t6QixFQUFFbHpCLE9BQ3BDLEVBdUZBLFNBQVN1MEIsRUFBTy8xQixHQUNkLE9BQU9lLFFBQVFzbUIsSUFBSXJuQixFQUFJd0gsZ0JBQWtCekcsUUFBUXNtQixJQUFJcm5CLEVBQUkyckIsZ0JBQWtCLEVBQzdFLENBRUFwc0IsRUFBUXkyQixlQXBGUixTQUF3QnRoQixHQUN0QixJQUFJdWhCLEVBQTJCLGlCQUFSdmhCLEVBQW1CelIsRUFBU3lSLEdBQU9BLEdBQU8sQ0FBQyxFQUM5RHdoQixFQUFRRCxFQUFVM3NCLFNBQ2xCRCxFQUFXNHNCLEVBQVU3c0IsS0FDckJGLEVBQU8rc0IsRUFBVS9zQixLQUNyQixHQUF3QixpQkFBYkcsSUFBMEJBLEdBQTZCLGlCQUFWNnNCLEVBQ3RELE1BQU8sR0FRVCxHQUxBQSxFQUFRQSxFQUFNN1YsTUFBTSxJQUFLLEdBQUcsSUE2QjlCLFNBQXFCaFgsRUFBVUgsR0FDN0IsSUFBSWl0QixHQUNESixFQUFPLHdCQUEwQkEsRUFBTyxhQUFhdnVCLGNBQ3hELElBQUsydUIsRUFDSCxPQUFPLEVBRVQsR0FBaUIsTUFBYkEsRUFDRixPQUFPLEVBR1QsT0FBT0EsRUFBUzlWLE1BQU0sU0FBUytWLE9BQU0sU0FBUzdVLEdBQzVDLElBQUtBLEVBQ0gsT0FBTyxFQUVULElBQUk4VSxFQUFjOVUsRUFBTXFGLE1BQU0sZ0JBQzFCMFAsRUFBc0JELEVBQWNBLEVBQVksR0FBSzlVLEVBQ3JEZ1YsRUFBa0JGLEVBQWNwTyxTQUFTb08sRUFBWSxJQUFNLEVBQy9ELFNBQUlFLEdBQW1CQSxJQUFvQnJ0QixLQUl0QyxRQUFRaVYsS0FBS21ZLElBS29CLE1BQWxDQSxFQUFvQmpTLE9BQU8sS0FFN0JpUyxFQUFzQkEsRUFBb0I5TCxNQUFNLEtBRzFDc0wsRUFBZWp5QixLQUFLd0YsRUFBVWl0QixJQVI3Qmp0QixJQUFhaXRCLEVBU3hCLEdBQ0YsQ0F6RE9FLENBRkxudEIsRUFBV0EsRUFBU3pDLFFBQVEsUUFBUyxJQUNyQ3NDLEVBQU8rZSxTQUFTL2UsSUFBU3VzQixFQUFjUyxJQUFVLEdBRS9DLE1BQU8sR0FHVCxJQUFJM1UsRUFDRndVLEVBQU8sY0FBZ0JHLEVBQVEsV0FDL0JILEVBQU9HLEVBQVEsV0FDZkgsRUFBTyxxQkFDUEEsRUFBTyxhQUtULE9BSkl4VSxJQUFtQyxJQUExQkEsRUFBTWlELFFBQVEsU0FFekJqRCxFQUFRMlUsRUFBUSxNQUFRM1UsR0FFbkJBLENBQ1QsK0JDbERBLE1BQU1rVixFQUFLLEVBQVEsTUFDYkMsRUFBVSxFQUFRLE1BRWxCclAsRUFBTXRtQixRQUFRc21CLElBRXBCLElBQUlzUCxFQW1ISixTQUFTQyxFQUFnQnZSLEdBQ3hCLE1BQU1tRyxFQXhGUCxTQUF1Qm5HLEdBQ3RCLElBQW1CLElBQWZzUixFQUNILE9BQU8sRUFHUixHQUFJRCxFQUFRLGNBQ1hBLEVBQVEsZUFDUkEsRUFBUSxtQkFDUixPQUFPLEVBR1IsR0FBSUEsRUFBUSxhQUNYLE9BQU8sRUFHUixHQUFJclIsSUFBV0EsRUFBT3dSLFFBQXdCLElBQWZGLEVBQzlCLE9BQU8sRUFHUixNQUFNRyxFQUFNSCxFQUFhLEVBQUksRUFFN0IsR0FBeUIsVUFBckI1MUIsUUFBUWcyQixTQUFzQixDQU9qQyxNQUFNQyxFQUFZUCxFQUFHaEssVUFBVXBNLE1BQU0sS0FDckMsT0FDQytJLE9BQU9yb0IsUUFBUTZRLFNBQVNxbEIsS0FBSzVXLE1BQU0sS0FBSyxLQUFPLEdBQy9DK0ksT0FBTzROLEVBQVUsS0FBTyxJQUN4QjVOLE9BQU80TixFQUFVLEtBQU8sTUFFakI1TixPQUFPNE4sRUFBVSxLQUFPLE1BQVEsRUFBSSxFQUdyQyxDQUNSLENBRUEsR0FBSSxPQUFRM1AsRUFDWCxNQUFJLENBQUMsU0FBVSxXQUFZLFdBQVksYUFBYXRNLE1BQUttYyxHQUFRQSxLQUFRN1AsS0FBd0IsYUFBaEJBLEVBQUk4UCxRQUM3RSxFQUdETCxFQUdSLEdBQUkscUJBQXNCelAsRUFDekIsTUFBTyxnQ0FBZ0NsSixLQUFLa0osRUFBSStQLGtCQUFvQixFQUFJLEVBR3pFLEdBQXNCLGNBQWxCL1AsRUFBSWdRLFVBQ1AsT0FBTyxFQUdSLEdBQUksaUJBQWtCaFEsRUFBSyxDQUMxQixNQUFNMVYsRUFBVXNXLFVBQVVaLEVBQUlpUSxzQkFBd0IsSUFBSWpYLE1BQU0sS0FBSyxHQUFJLElBRXpFLE9BQVFnSCxFQUFJa1EsY0FDWCxJQUFLLFlBQ0osT0FBTzVsQixHQUFXLEVBQUksRUFBSSxFQUMzQixJQUFLLGlCQUNKLE9BQU8sRUFHVixDQUVBLE1BQUksaUJBQWlCd00sS0FBS2tKLEVBQUltUSxNQUN0QixFQUdKLDhEQUE4RHJaLEtBQUtrSixFQUFJbVEsT0FJdkUsY0FBZW5RLEVBSFgsR0FPSkEsRUFBSW1RLEtBQ0FWLEVBSVQsQ0FHZXZMLENBQWNsRyxHQUM1QixPQXRHRCxTQUF3Qm1HLEdBQ3ZCLE9BQWMsSUFBVkEsR0FJRyxDQUNOQSxRQUNBaU0sVUFBVSxFQUNWQyxPQUFRbE0sR0FBUyxFQUNqQm1NLE9BQVFuTSxHQUFTLEVBRW5CLENBMkZRb00sQ0FBZXBNLEVBQ3ZCLENBckhJa0wsRUFBUSxhQUNYQSxFQUFRLGNBQ1JBLEVBQVEsZUFDUkMsR0FBYSxHQUNIRCxFQUFRLFVBQ2xCQSxFQUFRLFdBQ1JBLEVBQVEsZUFDUkEsRUFBUSxtQkFDUkMsR0FBYSxHQUVWLGdCQUFpQnRQLElBQ3BCc1AsRUFBd0MsSUFBM0J0UCxFQUFJd1EsWUFBWXIyQixRQUFrRCxJQUFsQ3ltQixTQUFTWixFQUFJd1EsWUFBYSxLQTRHeEVyNEIsRUFBT0QsUUFBVSxDQUNoQmdzQixjQUFlcUwsRUFDZmtCLE9BQVFsQixFQUFnQjcxQixRQUFRKzJCLFFBQ2hDaE4sT0FBUThMLEVBQWdCNzFCLFFBQVErcEIsK0JDaklqQyxZQUlvQixXQUVsQixTQUFTbmtCLEVBQVdveEIsR0FDbEIsSUFBSUMsRUFBYyxHQUNsQixHQUF3QixJQUFwQkQsRUFBU3YyQixPQUFnQixNQUFPLEdBRXBDLEdBQTJCLGlCQUFoQnUyQixFQUFTLEdBQ2xCLE1BQU0sSUFBSXhLLFVBQVUsa0NBQW9Dd0ssRUFBUyxJQUluRSxHQUFJQSxFQUFTLEdBQUduUixNQUFNLGlCQUFtQm1SLEVBQVN2MkIsT0FBUyxFQUFHLENBQzVELElBQUl5MkIsRUFBUUYsRUFBU2xTLFFBQ3JCa1MsRUFBUyxHQUFLRSxFQUFRRixFQUFTLEVBQ2pDLENBR0lBLEVBQVMsR0FBR25SLE1BQU0sZ0JBQ3BCbVIsRUFBUyxHQUFLQSxFQUFTLEdBQUdueEIsUUFBUSxnQkFBaUIsVUFFbkRteEIsRUFBUyxHQUFLQSxFQUFTLEdBQUdueEIsUUFBUSxnQkFBaUIsU0FHckQsSUFBSyxJQUFJb0IsRUFBSSxFQUFHQSxFQUFJK3ZCLEVBQVN2MkIsT0FBUXdHLElBQUssQ0FDeEMsSUFBSWt3QixFQUFZSCxFQUFTL3ZCLEdBRXpCLEdBQXlCLGlCQUFka3dCLEVBQ1QsTUFBTSxJQUFJM0ssVUFBVSxrQ0FBb0MySyxHQUd4QyxLQUFkQSxJQUVBbHdCLEVBQUksSUFFTmt3QixFQUFZQSxFQUFVdHhCLFFBQVEsU0FBVSxLQUl4Q3N4QixFQUZFbHdCLEVBQUkrdkIsRUFBU3YyQixPQUFTLEVBRVowMkIsRUFBVXR4QixRQUFRLFNBQVUsSUFHNUJzeEIsRUFBVXR4QixRQUFRLFNBQVUsS0FHMUNveEIsRUFBWTV5QixLQUFLOHlCLEdBRW5CLENBRUEsSUFBSXBNLEVBQU1rTSxFQUFZeHhCLEtBQUssS0FPdkIyeEIsR0FISnJNLEVBQU1BLEVBQUlsbEIsUUFBUSxrQkFBbUIsT0FHckJ5WixNQUFNLEtBR3RCLE9BRkF5TCxFQUFNcU0sRUFBTXRTLFNBQVdzUyxFQUFNMzJCLE9BQVMsRUFBSSxJQUFLLElBQU0yMkIsRUFBTTN4QixLQUFLLElBR2xFLENBRUEsT0FBTyxXQVNMLE9BQU9HLEVBTnFCLGlCQUFqQjRsQixVQUFVLEdBQ1hBLFVBQVUsR0FFVixHQUFHL0IsTUFBTTNtQixLQUFLMG9CLFdBSTFCLENBRUYsRUE1RXVDL3NCLEVBQU9ELFFBQVNDLEVBQU9ELFFBQVU2NEIsU0FDQSwwQkFBakIsS0FBaUIseURDRnhFNTRCLEVBQU9ELFFBQVU2TCxRQUFRLGlDQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLGlDQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLDZCQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLCtCQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLGdDQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLDZCQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLCtCQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLGlDQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLDhCQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLDhCQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLCtCQ0F6QjVMLEVBQU9ELFFBQVU2TCxRQUFRLHFDQ0d6QixNQUFNaXRCLEVBQWEsRUFBUSxNQUNyQjNqQixFQUFNLEVBQVEsTUFDZDRqQixFQUFlLEVBQVEsTUFDdkJ2MUIsRUFBTyxFQUFRLE1BQ2ZDLEVBQVEsRUFBUSxNQUNoQkgsRUFBTyxFQUFRLE1BQ2ZzdkIsRUFBa0IsRUFBUSxLQUMxQm9HLEVBQU8sRUFBUSxNQUNmbFQsRUFBUyxFQUFRLE1BQ2pCbVQsRUFBZSxFQUFRLE1BRTdCLFNBQVNDLEVBQXVCQyxHQUFLLE9BQU9BLEdBQWtCLGlCQUFOQSxHQUFrQixZQUFhQSxFQUFJQSxFQUFJLENBQUUsUUFBV0EsRUFBSyxDQUVqSCxNQUFNQyxFQUFpQ0YsRUFBc0JKLEdBQ3ZETyxFQUE0QkgsRUFBc0IvakIsR0FDbERta0IsRUFBNkJKLEVBQXNCMTFCLEdBQ25EKzFCLEVBQThCTCxFQUFzQnoxQixHQUNwRCsxQixFQUE2Qk4sRUFBc0I1MUIsR0FDbkRtMkIsRUFBd0NQLEVBQXNCdEcsR0FDOUQ4RyxFQUE2QlIsRUFBc0JGLEdBQ25EVyxFQUErQlQsRUFBc0JwVCxHQUNyRDhULEVBQXFDVixFQUFzQkQsR0FFakUsU0FBU2w0QixFQUFLTSxFQUFJdzRCLEdBQ2hCLE9BQU8sV0FDTCxPQUFPeDRCLEVBQUdncEIsTUFBTXdQLEVBQVM3TSxVQUMzQixDQUNGLENBSUEsTUFBTSxTQUFDaGtCLEdBQVlwSSxPQUFPOEQsV0FDcEIsZUFBQ28xQixHQUFrQmw1QixPQUVuQm01QixHQUFVQyxFQUdicDVCLE9BQU8rTSxPQUFPLE1BSFFzc0IsSUFDckIsTUFBTTFOLEVBQU12akIsRUFBUzFFLEtBQUsyMUIsR0FDMUIsT0FBT0QsRUFBTXpOLEtBQVN5TixFQUFNek4sR0FBT0EsRUFBSXRCLE1BQU0sR0FBSSxHQUFHaGpCLGNBQWMsR0FGdkQsSUFBQyt4QixFQUtoQixNQUFNRSxFQUFjL3VCLElBQ2xCQSxFQUFPQSxFQUFLbEQsY0FDSmd5QixHQUFVRixFQUFPRSxLQUFXOXVCLEdBR2hDZ3ZCLEVBQWFodkIsR0FBUTh1QixVQUFnQkEsSUFBVTl1QixHQVMvQyxRQUFDMUksR0FBV0QsTUFTWjQzQixFQUFjRCxFQUFXLGFBcUIvQixNQUFNRSxFQUFnQkgsRUFBVyxlQTJCakMsTUFBTXJLLEVBQVdzSyxFQUFXLFVBUXRCcEssRUFBYW9LLEVBQVcsWUFTeEJHLEVBQVdILEVBQVcsVUFTdEJJLEVBQVlOLEdBQW9CLE9BQVZBLEdBQW1DLGlCQUFWQSxFQWlCL0NPLEVBQWlCcFEsSUFDckIsR0FBb0IsV0FBaEIyUCxFQUFPM1AsR0FDVCxPQUFPLEVBR1QsTUFBTTFsQixFQUFZbzFCLEVBQWUxUCxHQUNqQyxRQUFzQixPQUFkMWxCLEdBQXNCQSxJQUFjOUQsT0FBTzhELFdBQWtELE9BQXJDOUQsT0FBT2s1QixlQUFlcDFCLElBQTBCKzFCLE9BQU9DLGVBQWV0USxHQUFVcVEsT0FBTzU0QixZQUFZdW9CLEVBQUksRUFVbkt1USxFQUFTVCxFQUFXLFFBU3BCVSxFQUFTVixFQUFXLFFBU3BCVyxFQUFTWCxFQUFXLFFBU3BCWSxFQUFhWixFQUFXLFlBc0N4QmEsRUFBb0JiLEVBQVcsbUJBMkJyQyxTQUFTcDVCLEVBQVFzZixFQUFLL2UsR0FBSSxXQUFDMjVCLEdBQWEsR0FBUyxDQUFDLEdBRWhELEdBQUk1YSxRQUNGLE9BR0YsSUFBSTNYLEVBQ0F3eUIsRUFRSixHQUxtQixpQkFBUjdhLElBRVRBLEVBQU0sQ0FBQ0EsSUFHTDNkLEVBQVEyZCxHQUVWLElBQUszWCxFQUFJLEVBQUd3eUIsRUFBSTdhLEVBQUluZSxPQUFRd0csRUFBSXd5QixFQUFHeHlCLElBQ2pDcEgsRUFBR2lELEtBQUssS0FBTThiLEVBQUkzWCxHQUFJQSxFQUFHMlgsT0FFdEIsQ0FFTCxNQUFNdmYsRUFBT202QixFQUFhcDZCLE9BQU93aEIsb0JBQW9CaEMsR0FBT3hmLE9BQU9DLEtBQUt1ZixHQUNsRTFYLEVBQU03SCxFQUFLb0IsT0FDakIsSUFBSXhCLEVBRUosSUFBS2dJLEVBQUksRUFBR0EsRUFBSUMsRUFBS0QsSUFDbkJoSSxFQUFNSSxFQUFLNEgsR0FDWHBILEVBQUdpRCxLQUFLLEtBQU04YixFQUFJM2YsR0FBTUEsRUFBSzJmLEVBRWpDLENBQ0YsQ0FFQSxTQUFTOGEsRUFBUTlhLEVBQUszZixHQUNwQkEsRUFBTUEsRUFBSXdILGNBQ1YsTUFBTXBILEVBQU9ELE9BQU9DLEtBQUt1ZixHQUN6QixJQUNJK2EsRUFEQTF5QixFQUFJNUgsRUFBS29CLE9BRWIsS0FBT3dHLEtBQU0sR0FFWCxHQURBMHlCLEVBQU90NkIsRUFBSzRILEdBQ1JoSSxJQUFRMDZCLEVBQUtsekIsY0FDZixPQUFPa3pCLEVBR1gsT0FBTyxJQUNULENBRUEsTUFBTUMsRUFFc0Isb0JBQWZDLFdBQW1DQSxXQUN2QixvQkFBVDNyQixLQUF1QkEsS0FBMEIsb0JBQVh5VSxPQUF5QkEsT0FBU0QsT0FHbEZvWCxFQUFvQkMsSUFBYW5CLEVBQVltQixJQUFZQSxJQUFZSCxFQW9EM0UsTUE4SE1JLEdBQWdCQyxFQUtHLG9CQUFmQyxZQUE4QjVCLEVBQWU0QixZQUg5Q3pCLEdBQ0V3QixHQUFjeEIsYUFBaUJ3QixHQUhyQixJQUFDQSxFQWV0QixNQWlDTUUsRUFBYXpCLEVBQVcsbUJBV3hCdDBCLEVBQWlCLEdBQUdBLG9CQUFvQixDQUFDd2EsRUFBS3BaLElBQVNwQixFQUFldEIsS0FBSzhiLEVBQUtwWixHQUEvRCxDQUFzRXBHLE9BQU84RCxXQVM5RmszQixFQUFXMUIsRUFBVyxVQUV0QjJCLEVBQW9CLENBQUN6YixFQUFLMGIsS0FDOUIsTUFBTUMsRUFBY243QixPQUFPbzdCLDBCQUEwQjViLEdBQy9DNmIsRUFBcUIsQ0FBQyxFQUU1Qm43QixFQUFRaTdCLEdBQWEsQ0FBQ0csRUFBWTUwQixLQUNoQyxJQUFJNjBCLEdBQzJDLEtBQTFDQSxFQUFNTCxFQUFRSSxFQUFZNTBCLEVBQU04WSxNQUNuQzZiLEVBQW1CMzBCLEdBQVE2MEIsR0FBT0QsRUFDcEMsSUFHRnQ3QixPQUFPK3VCLGlCQUFpQnZQLEVBQUs2YixFQUFtQixFQXVENUNHLEVBQVEsNkJBRVJDLEdBQVEsYUFFUkMsR0FBVyxDQUNmRCxTQUNBRCxRQUNBRyxZQUFhSCxFQUFRQSxFQUFNaFEsY0FBZ0JpUSxJQXdCN0MsTUErQk1HLEdBQVl0QyxFQUFXLGlCQUt2QnVDLEdBQVEsQ0FDWmg2QixVQUNBNDNCLGdCQUNBNTBCLFNBbm5CRixTQUFrQjJrQixHQUNoQixPQUFlLE9BQVJBLElBQWlCZ1EsRUFBWWhRLElBQTRCLE9BQXBCQSxFQUFJNkcsY0FBeUJtSixFQUFZaFEsRUFBSTZHLGNBQ3BGbEIsRUFBVzNGLEVBQUk2RyxZQUFZeHJCLFdBQWEya0IsRUFBSTZHLFlBQVl4ckIsU0FBUzJrQixFQUN4RSxFQWluQkVzUyxXQXJla0J6QyxJQUNsQixJQUFJMEMsRUFDSixPQUFPMUMsSUFDZ0IsbUJBQWJqMkIsVUFBMkJpMkIsYUFBaUJqMkIsVUFDbEQrckIsRUFBV2tLLEVBQU10MUIsVUFDWSxjQUExQmc0QixFQUFPNUMsRUFBT0UsS0FFTCxXQUFUMEMsR0FBcUI1TSxFQUFXa0ssRUFBTWp4QixXQUFrQyxzQkFBckJpeEIsRUFBTWp4QixZQUdoRSxFQTRkQTR6QixrQkEvbEJGLFNBQTJCeFMsR0FDekIsSUFBSWhwQixFQU1KLE9BSkVBLEVBRDBCLG9CQUFoQnk3QixhQUFpQ0EsWUFBa0IsT0FDcERBLFlBQVlDLE9BQU8xUyxHQUVuQixHQUFVQSxFQUFVLFFBQU1pUSxFQUFjalEsRUFBSTFGLFFBRWhEdGpCLENBQ1QsRUF3bEJFeXVCLFdBQ0F5SyxXQUNBeUMsVUEvaUJnQjlDLElBQW1CLElBQVZBLElBQTRCLElBQVZBLEVBZ2pCM0NNLFdBQ0FDLGdCQUNBSixjQUNBTyxTQUNBQyxTQUNBQyxTQUNBZSxXQUNBN0wsYUFDQWpRLFNBM2ZnQnNLLEdBQVFtUSxFQUFTblEsSUFBUTJGLEVBQVczRixFQUFJbmdCLE1BNGZ4RDh3QixvQkFDQVMsZUFDQVYsYUFDQWg2QixVQUNBazhCLE1BL1hGLFNBQVNBLElBQ1AsTUFBTSxTQUFDQyxHQUFZM0IsRUFBaUJsN0IsT0FBU0EsTUFBUSxDQUFDLEVBQ2hEZ0IsRUFBUyxDQUFDLEVBQ1Y4N0IsRUFBYyxDQUFDOVMsRUFBSzNwQixLQUN4QixNQUFNMDhCLEVBQVlGLEdBQVkvQixFQUFROTVCLEVBQVFYLElBQVFBLEVBQ2xEKzVCLEVBQWNwNUIsRUFBTys3QixLQUFlM0MsRUFBY3BRLEdBQ3BEaHBCLEVBQU8rN0IsR0FBYUgsRUFBTTU3QixFQUFPKzdCLEdBQVkvUyxHQUNwQ29RLEVBQWNwUSxHQUN2QmhwQixFQUFPKzdCLEdBQWFILEVBQU0sQ0FBQyxFQUFHNVMsR0FDckIzbkIsRUFBUTJuQixHQUNqQmhwQixFQUFPKzdCLEdBQWEvUyxFQUFJYSxRQUV4QjdwQixFQUFPKzdCLEdBQWEvUyxDQUN0QixFQUdGLElBQUssSUFBSTNoQixFQUFJLEVBQUd3eUIsRUFBSWpPLFVBQVUvcUIsT0FBUXdHLEVBQUl3eUIsRUFBR3h5QixJQUMzQ3VrQixVQUFVdmtCLElBQU0zSCxFQUFRa3NCLFVBQVV2a0IsR0FBSXkwQixHQUV4QyxPQUFPOTdCLENBQ1QsRUE0V0VtcEIsT0FoV2EsQ0FBQ3puQixFQUFHQyxFQUFHODJCLEdBQVVtQixjQUFhLENBQUMsS0FDNUNsNkIsRUFBUWlDLEdBQUcsQ0FBQ3FuQixFQUFLM3BCLEtBQ1hvNUIsR0FBVzlKLEVBQVczRixHQUN4QnRuQixFQUFFckMsR0FBT00sRUFBS3FwQixFQUFLeVAsR0FFbkIvMkIsRUFBRXJDLEdBQU8ycEIsQ0FDWCxHQUNDLENBQUM0USxlQUNHbDRCLEdBeVZQMHBCLEtBNWRZRCxHQUFRQSxFQUFJQyxLQUN4QkQsRUFBSUMsT0FBU0QsRUFBSWxsQixRQUFRLHFDQUFzQyxJQTRkL0QrMUIsU0FoVmdCQyxJQUNjLFFBQTFCQSxFQUFReFksV0FBVyxLQUNyQndZLEVBQVVBLEVBQVFwUyxNQUFNLElBRW5Cb1MsR0E2VVA5NEIsU0FqVWUsQ0FBQzBzQixFQUFhcU0sRUFBa0JDLEVBQU94QixLQUN0RDlLLEVBQVl2c0IsVUFBWTlELE9BQU8rTSxPQUFPMnZCLEVBQWlCNTRCLFVBQVdxM0IsR0FDbEU5SyxFQUFZdnNCLFVBQVV1c0IsWUFBY0EsRUFDcENyd0IsT0FBT21qQixlQUFla04sRUFBYSxRQUFTLENBQzFDcHNCLE1BQU95NEIsRUFBaUI1NEIsWUFFMUI2NEIsR0FBUzM4QixPQUFPOEssT0FBT3VsQixFQUFZdnNCLFVBQVc2NEIsRUFBTSxFQTRUcERDLGFBaFRtQixDQUFDQyxFQUFXQyxFQUFTcmUsRUFBUXNlLEtBQ2hELElBQUlKLEVBQ0E5MEIsRUFDQXpCLEVBQ0osTUFBTTQyQixFQUFTLENBQUMsRUFJaEIsR0FGQUYsRUFBVUEsR0FBVyxDQUFDLEVBRUwsTUFBYkQsRUFBbUIsT0FBT0MsRUFFOUIsRUFBRyxDQUdELElBRkFILEVBQVEzOEIsT0FBT3doQixvQkFBb0JxYixHQUNuQ2gxQixFQUFJODBCLEVBQU10N0IsT0FDSHdHLEtBQU0sR0FDWHpCLEVBQU91MkIsRUFBTTkwQixHQUNQazFCLElBQWNBLEVBQVczMkIsRUFBTXkyQixFQUFXQyxJQUFjRSxFQUFPNTJCLEtBQ25FMDJCLEVBQVExMkIsR0FBUXkyQixFQUFVejJCLEdBQzFCNDJCLEVBQU81MkIsSUFBUSxHQUduQnkyQixHQUF1QixJQUFYcGUsR0FBb0J5YSxFQUFlMkQsRUFDakQsT0FBU0EsS0FBZXBlLEdBQVVBLEVBQU9vZSxFQUFXQyxLQUFhRCxJQUFjNzhCLE9BQU84RCxXQUV0RixPQUFPZzVCLENBQU8sRUEwUmQzRCxTQUNBRyxhQUNBckcsU0FoUmUsQ0FBQ3RILEVBQUtzUixFQUFjalosS0FDbkMySCxFQUFNL0gsT0FBTytILFNBQ0l4bUIsSUFBYjZlLEdBQTBCQSxFQUFXMkgsRUFBSXRxQixVQUMzQzJpQixFQUFXMkgsRUFBSXRxQixRQUVqQjJpQixHQUFZaVosRUFBYTU3QixPQUN6QixNQUFNNjdCLEVBQVl2UixFQUFJdEgsUUFBUTRZLEVBQWNqWixHQUM1QyxPQUFzQixJQUFma1osR0FBb0JBLElBQWNsWixDQUFRLEVBMFFqRG1aLFFBL1BlOUQsSUFDZixJQUFLQSxFQUFPLE9BQU8sS0FDbkIsR0FBSXgzQixFQUFRdzNCLEdBQVEsT0FBT0EsRUFDM0IsSUFBSXh4QixFQUFJd3hCLEVBQU1oNEIsT0FDZCxJQUFLcTRCLEVBQVM3eEIsR0FBSSxPQUFPLEtBQ3pCLE1BQU11MUIsRUFBTSxJQUFJeDdCLE1BQU1pRyxHQUN0QixLQUFPQSxLQUFNLEdBQ1h1MUIsRUFBSXYxQixHQUFLd3hCLEVBQU14eEIsR0FFakIsT0FBT3UxQixDQUFHLEVBdVBWQyxhQTVObUIsQ0FBQzdkLEVBQUsvZSxLQUN6QixNQUVNUSxHQUZZdWUsR0FBT0EsRUFBSXFhLE9BQU81NEIsV0FFVHlDLEtBQUs4YixHQUVoQyxJQUFJaGYsRUFFSixNQUFRQSxFQUFTUyxFQUFTOEYsVUFBWXZHLEVBQU84OEIsTUFBTSxDQUNqRCxNQUFNQyxFQUFPLzhCLEVBQU95RCxNQUNwQnhELEVBQUdpRCxLQUFLOGIsRUFBSytkLEVBQUssR0FBSUEsRUFBSyxHQUM3QixHQW1OQUMsU0F4TWUsQ0FBQ0MsRUFBUTlSLEtBQ3hCLElBQUkrUixFQUNKLE1BQU1OLEVBQU0sR0FFWixLQUF3QyxRQUFoQ00sRUFBVUQsRUFBT3hKLEtBQUt0SSxLQUM1QnlSLEVBQUluNEIsS0FBS3k0QixHQUdYLE9BQU9OLENBQUcsRUFpTVZyQyxhQUNBLzFCLGlCQUNBMjRCLFdBQVkzNEIsRUFDWmkyQixvQkFDQTJDLGNBeEpxQnBlLElBQ3JCeWIsRUFBa0J6YixHQUFLLENBQUM4YixFQUFZNTBCLEtBRWxDLEdBQUl5b0IsRUFBVzNQLEtBQTZELElBQXJELENBQUMsWUFBYSxTQUFVLFVBQVU2RSxRQUFRM2QsR0FDL0QsT0FBTyxFQUdULE1BQU16QyxFQUFRdWIsRUFBSTlZLEdBRWJ5b0IsRUFBV2xyQixLQUVoQnEzQixFQUFXMVIsWUFBYSxFQUVwQixhQUFjMFIsRUFDaEJBLEVBQVc5VyxVQUFXLEVBSW5COFcsRUFBV2paLE1BQ2RpWixFQUFXalosSUFBTSxLQUNmLE1BQU1qZSxNQUFNLHFDQUF3Q3NDLEVBQU8sSUFBSyxHQUVwRSxHQUNBLEVBa0lGbTNCLFlBL0hrQixDQUFDQyxFQUFlL1QsS0FDbEMsTUFBTXZLLEVBQU0sQ0FBQyxFQUVQbGdCLEVBQVU4OUIsSUFDZEEsRUFBSWw5QixTQUFRK0QsSUFDVnViLEVBQUl2YixJQUFTLENBQUksR0FDakIsRUFLSixPQUZBcEMsRUFBUWk4QixHQUFpQngrQixFQUFPdytCLEdBQWlCeCtCLEVBQU9za0IsT0FBT2thLEdBQWU1ZCxNQUFNNkosSUFFN0V2SyxDQUFHLEVBcUhWdWUsWUFqTWtCcFMsR0FDWEEsRUFBSXRrQixjQUFjWixRQUFRLHlCQUMvQixTQUFrQit0QixFQUFHd0osRUFBSUMsR0FDdkIsT0FBT0QsRUFBR3hTLGNBQWdCeVMsQ0FDNUIsSUE4TEZ4USxLQW5IVyxPQW9IWHlRLGVBbEhxQixDQUFDajZCLEVBQU9rNkIsS0FDN0JsNkIsR0FBU0EsRUFDRmdsQixPQUFPaU0sU0FBU2p4QixHQUFTQSxFQUFRazZCLEdBaUh4QzdELFVBQ0FoWCxPQUFRa1gsRUFDUkUsbUJBQ0FnQixZQUNBMEMsZUF4R3FCLENBQUNwOEIsRUFBTyxHQUFJcThCLEVBQVczQyxHQUFTQyxlQUNyRCxJQUFJaFEsRUFBTSxHQUNWLE1BQU0sT0FBQ3RxQixHQUFVZzlCLEVBQ2pCLEtBQU9yOEIsS0FDTDJwQixHQUFPMFMsRUFBU3AyQixLQUFLRSxTQUFXOUcsRUFBTyxHQUd6QyxPQUFPc3FCLENBQUcsRUFrR1YyUyxvQkF4RkYsU0FBNkJqRixHQUMzQixTQUFVQSxHQUFTbEssRUFBV2tLLEVBQU10MUIsU0FBeUMsYUFBOUJzMUIsRUFBTVEsT0FBT0MsY0FBK0JULEVBQU1RLE9BQU81NEIsVUFDMUcsRUF1RkVzOUIsYUFyRm9CL2UsSUFDcEIsTUFBTXBCLEVBQVEsSUFBSXhjLE1BQU0sSUFFbEI0OEIsRUFBUSxDQUFDMVMsRUFBUWprQixLQUVyQixHQUFJOHhCLEVBQVM3TixHQUFTLENBQ3BCLEdBQUkxTixFQUFNaUcsUUFBUXlILElBQVcsRUFDM0IsT0FHRixLQUFLLFdBQVlBLEdBQVMsQ0FDeEIxTixFQUFNdlcsR0FBS2lrQixFQUNYLE1BQU00RCxFQUFTN3RCLEVBQVFpcUIsR0FBVSxHQUFLLENBQUMsRUFTdkMsT0FQQTVyQixFQUFRNHJCLEdBQVEsQ0FBQzduQixFQUFPcEUsS0FDdEIsTUFBTTQrQixFQUFlRCxFQUFNdjZCLEVBQU80RCxFQUFJLElBQ3JDMnhCLEVBQVlpRixLQUFrQi9PLEVBQU83dkIsR0FBTzQrQixFQUFhLElBRzVEcmdCLEVBQU12VyxRQUFLMUMsRUFFSnVxQixDQUNULENBQ0YsQ0FFQSxPQUFPNUQsQ0FBTSxFQUdmLE9BQU8wUyxFQUFNaGYsRUFBSyxFQUFFLEVBMERwQm9jLGFBQ0E4QyxXQXREa0JyRixHQUNsQkEsSUFBVU0sRUFBU04sSUFBVWxLLEVBQVdrSyxLQUFXbEssRUFBV2tLLEVBQU14c0IsT0FBU3NpQixFQUFXa0ssRUFBTXNGLFFBbUVoRyxTQUFTQyxHQUFXM3dCLEVBQVNzTCxFQUFNakYsRUFBUTFMLEVBQVNqRCxHQUNsRHZCLE1BQU1WLEtBQUtsRSxNQUVQNEUsTUFBTWdzQixrQkFDUmhzQixNQUFNZ3NCLGtCQUFrQjV3QixLQUFNQSxLQUFLNndCLGFBRW5DN3dCLEtBQUs0ZSxPQUFRLElBQUtoYSxPQUFTZ2EsTUFHN0I1ZSxLQUFLeU8sUUFBVUEsRUFDZnpPLEtBQUtrSCxLQUFPLGFBQ1o2UyxJQUFTL1osS0FBSytaLEtBQU9BLEdBQ3JCakYsSUFBVzlVLEtBQUs4VSxPQUFTQSxHQUN6QjFMLElBQVlwSixLQUFLb0osUUFBVUEsR0FDM0JqRCxJQUFhbkcsS0FBS21HLFNBQVdBLEVBQy9CLENBRUFrMkIsR0FBTWw0QixTQUFTaTdCLEdBQVl4NkIsTUFBTyxDQUNoQ3k2QixPQUFRLFdBQ04sTUFBTyxDQUVMNXdCLFFBQVN6TyxLQUFLeU8sUUFDZHZILEtBQU1sSCxLQUFLa0gsS0FFWHNKLFlBQWF4USxLQUFLd1EsWUFDbEI4dUIsT0FBUXQvQixLQUFLcy9CLE9BRWJDLFNBQVV2L0IsS0FBS3UvQixTQUNmQyxXQUFZeC9CLEtBQUt3L0IsV0FDakJDLGFBQWN6L0IsS0FBS3kvQixhQUNuQjdnQixNQUFPNWUsS0FBSzRlLE1BRVo5SixPQUFRdW5CLEdBQU0wQyxhQUFhLytCLEtBQUs4VSxRQUNoQ2lGLEtBQU0vWixLQUFLK1osS0FDWHhMLE9BQVF2TyxLQUFLbUcsVUFBWW5HLEtBQUttRyxTQUFTb0ksT0FBU3ZPLEtBQUttRyxTQUFTb0ksT0FBUyxLQUUzRSxJQUdGLE1BQU1teEIsR0FBY04sR0FBVzk2QixVQUN6QnEzQixHQUFjLENBQUMsRUFtRHJCLFNBQVNnRSxHQUFZOUYsR0FDbkIsT0FBT3dDLEdBQU1qQyxjQUFjUCxJQUFVd0MsR0FBTWg2QixRQUFRdzNCLEVBQ3JELENBU0EsU0FBUytGLEdBQWV2L0IsR0FDdEIsT0FBT2c4QixHQUFNNUksU0FBU3B6QixFQUFLLE1BQVFBLEVBQUl3cUIsTUFBTSxHQUFJLEdBQUt4cUIsQ0FDeEQsQ0FXQSxTQUFTdy9CLEdBQVUxOEIsRUFBTTlDLEVBQUt5L0IsR0FDNUIsT0FBSzM4QixFQUNFQSxFQUFLd0QsT0FBT3RHLEdBQUtzTSxLQUFJLFNBQWNvekIsRUFBTzEzQixHQUcvQyxPQURBMDNCLEVBQVFILEdBQWVHLElBQ2ZELEdBQVF6M0IsRUFBSSxJQUFNMDNCLEVBQVEsSUFBTUEsQ0FDMUMsSUFBR2w1QixLQUFLaTVCLEVBQU8sSUFBTSxJQUxIei9CLENBTXBCLENBaEZBLENBQ0UsdUJBQ0EsaUJBQ0EsZUFDQSxZQUNBLGNBQ0EsNEJBQ0EsaUJBQ0EsbUJBQ0Esa0JBQ0EsZUFDQSxrQkFDQSxtQkFFQUssU0FBUXFaLElBQ1I0aEIsR0FBWTVoQixHQUFRLENBQUN0VixNQUFPc1YsRUFBSyxJQUduQ3ZaLE9BQU8rdUIsaUJBQWlCNlAsR0FBWXpELElBQ3BDbjdCLE9BQU9takIsZUFBZStiLEdBQWEsZUFBZ0IsQ0FBQ2o3QixPQUFPLElBRzNEMjZCLEdBQVc3MkIsS0FBTyxDQUFDeEcsRUFBT2dZLEVBQU1qRixFQUFRMUwsRUFBU2pELEVBQVU2NUIsS0FDekQsTUFBTUMsRUFBYXovQixPQUFPK00sT0FBT215QixJQWdCakMsT0FkQXJELEdBQU1lLGFBQWFyN0IsRUFBT2srQixHQUFZLFNBQWdCamdCLEdBQ3BELE9BQU9BLElBQVFwYixNQUFNTixTQUN2QixJQUFHc0MsR0FDZSxpQkFBVEEsSUFHVHc0QixHQUFXbDdCLEtBQUsrN0IsRUFBWWwrQixFQUFNME0sUUFBU3NMLEVBQU1qRixFQUFRMUwsRUFBU2pELEdBRWxFODVCLEVBQVduUixNQUFRL3NCLEVBRW5CaytCLEVBQVcvNEIsS0FBT25GLEVBQU1tRixLQUV4Qjg0QixHQUFleC9CLE9BQU84SyxPQUFPMjBCLEVBQVlELEdBRWxDQyxDQUFVLEVBc0RuQixNQUFNQyxHQUFhN0QsR0FBTWUsYUFBYWYsR0FBTyxDQUFDLEVBQUcsTUFBTSxTQUFnQnoxQixHQUNyRSxNQUFPLFdBQVc0WCxLQUFLNVgsRUFDekIsSUF5QkEsU0FBU3U1QixHQUFXbmdCLEVBQUtuTCxFQUFVaFIsR0FDakMsSUFBS3c0QixHQUFNbEMsU0FBU25hLEdBQ2xCLE1BQU0sSUFBSTROLFVBQVUsNEJBSXRCL1ksRUFBV0EsR0FBWSxJQUFLbWtCLEVBQTJCLFNBQUtwMUIsVUFZNUQsTUFBTXc4QixHQVROdjhCLEVBQVV3NEIsR0FBTWUsYUFBYXY1QixFQUFTLENBQ3BDdThCLFlBQVksRUFDWk4sTUFBTSxFQUNOTyxTQUFTLElBQ1IsR0FBTyxTQUFpQnY4QixFQUFRd29CLEdBRWpDLE9BQVErUCxHQUFNckMsWUFBWTFOLEVBQU94b0IsR0FDbkMsS0FFMkJzOEIsV0FFckJFLEVBQVV6OEIsRUFBUXk4QixTQUFXQyxFQUM3QlQsRUFBT2o4QixFQUFRaThCLEtBQ2ZPLEVBQVV4OEIsRUFBUXc4QixRQUVsQkcsR0FEUTM4QixFQUFROGIsTUFBd0Isb0JBQVRBLE1BQXdCQSxPQUNwQzBjLEdBQU15QyxvQkFBb0JqcUIsR0FFbkQsSUFBS3duQixHQUFNMU0sV0FBVzJRLEdBQ3BCLE1BQU0sSUFBSTFTLFVBQVUsOEJBR3RCLFNBQVM2UyxFQUFhaDhCLEdBQ3BCLEdBQWMsT0FBVkEsRUFBZ0IsTUFBTyxHQUUzQixHQUFJNDNCLEdBQU05QixPQUFPOTFCLEdBQ2YsT0FBT0EsRUFBTThtQixjQUdmLElBQUtpVixHQUFXbkUsR0FBTTVCLE9BQU9oMkIsR0FDM0IsTUFBTSxJQUFJMjZCLEdBQVcsZ0RBR3ZCLE9BQUkvQyxHQUFNcEMsY0FBY3gxQixJQUFVNDNCLEdBQU1qQixhQUFhMzJCLEdBQzVDKzdCLEdBQTJCLG1CQUFUN2dCLEtBQXNCLElBQUlBLEtBQUssQ0FBQ2xiLElBQVVXLE9BQU9tRCxLQUFLOUQsR0FHMUVBLENBQ1QsQ0FZQSxTQUFTODdCLEVBQWU5N0IsRUFBT3BFLEVBQUs4QyxHQUNsQyxJQUFJeTZCLEVBQU1uNUIsRUFFVixHQUFJQSxJQUFVdEIsR0FBeUIsaUJBQVZzQixFQUMzQixHQUFJNDNCLEdBQU01SSxTQUFTcHpCLEVBQUssTUFFdEJBLEVBQU0rL0IsRUFBYS8vQixFQUFNQSxFQUFJd3FCLE1BQU0sR0FBSSxHQUV2Q3BtQixFQUFROFIsS0FBS0MsVUFBVS9SLFFBQ2xCLEdBQ0o0M0IsR0FBTWg2QixRQUFRb0MsSUFuR3ZCLFNBQXFCbTVCLEdBQ25CLE9BQU92QixHQUFNaDZCLFFBQVF1N0IsS0FBU0EsRUFBSXhpQixLQUFLdWtCLEdBQ3pDLENBaUdpQ2UsQ0FBWWo4QixLQUNuQzQzQixHQUFNM0IsV0FBV2oyQixJQUFVNDNCLEdBQU01SSxTQUFTcHpCLEVBQUssU0FBV3U5QixFQUFNdkIsR0FBTXNCLFFBQVFsNUIsSUFZaEYsT0FUQXBFLEVBQU11L0IsR0FBZXYvQixHQUVyQnU5QixFQUFJbDlCLFNBQVEsU0FBY2lnQyxFQUFJai9CLElBQzFCMjZCLEdBQU1yQyxZQUFZMkcsSUFBYyxPQUFQQSxHQUFnQjlyQixFQUFTdFEsUUFFdEMsSUFBWjg3QixFQUFtQlIsR0FBVSxDQUFDeC9CLEdBQU1xQixFQUFPbytCLEdBQXFCLE9BQVpPLEVBQW1CaGdDLEVBQU1BLEVBQU0sS0FDbkZvZ0MsRUFBYUUsR0FFakIsS0FDTyxFQUlYLFFBQUloQixHQUFZbDdCLEtBSWhCb1EsRUFBU3RRLE9BQU9zN0IsR0FBVTE4QixFQUFNOUMsRUFBS3kvQixHQUFPVyxFQUFhaDhCLEtBRWxELEVBQ1QsQ0FFQSxNQUFNbWEsRUFBUSxHQUVSZ2lCLEVBQWlCcGdDLE9BQU84SyxPQUFPNDBCLEdBQVksQ0FDL0NLLGlCQUNBRSxlQUNBZCxpQkF5QkYsSUFBS3RELEdBQU1sQyxTQUFTbmEsR0FDbEIsTUFBTSxJQUFJNE4sVUFBVSwwQkFLdEIsT0E1QkEsU0FBU2lULEVBQU1wOEIsRUFBT3RCLEdBQ3BCLElBQUlrNUIsR0FBTXJDLFlBQVl2MUIsR0FBdEIsQ0FFQSxJQUE4QixJQUExQm1hLEVBQU1pRyxRQUFRcGdCLEdBQ2hCLE1BQU1HLE1BQU0sa0NBQW9DekIsRUFBSzBELEtBQUssTUFHNUQrWCxFQUFNblosS0FBS2hCLEdBRVg0M0IsR0FBTTM3QixRQUFRK0QsR0FBTyxTQUFjazhCLEVBQUl0Z0MsSUFLdEIsT0FKRWc4QixHQUFNckMsWUFBWTJHLElBQWMsT0FBUEEsSUFBZ0JMLEVBQVFwOEIsS0FDaEUyUSxFQUFVOHJCLEVBQUl0RSxHQUFNNU0sU0FBU3B2QixHQUFPQSxFQUFJK3JCLE9BQVMvckIsRUFBSzhDLEVBQU15OUIsS0FJNURDLEVBQU1GLEVBQUl4OUIsRUFBT0EsRUFBS3dELE9BQU90RyxHQUFPLENBQUNBLEdBRXpDLElBRUF1ZSxFQUFNK0IsS0FsQjhCLENBbUJ0QyxDQU1Ba2dCLENBQU03Z0IsR0FFQ25MLENBQ1QsQ0FVQSxTQUFTaXNCLEdBQVMzVSxHQUNoQixNQUFNNFUsRUFBVSxDQUNkLElBQUssTUFDTCxJQUFLLE1BQ0wsSUFBSyxNQUNMLElBQUssTUFDTCxJQUFLLE1BQ0wsTUFBTyxJQUNQLE1BQU8sTUFFVCxPQUFPdGxCLG1CQUFtQjBRLEdBQUtsbEIsUUFBUSxvQkFBb0IsU0FBa0JnZ0IsR0FDM0UsT0FBTzhaLEVBQVE5WixFQUNqQixHQUNGLENBVUEsU0FBUytaLEdBQXFCNzNCLEVBQVF0RixHQUNwQzdELEtBQUtpaEMsT0FBUyxHQUVkOTNCLEdBQVVnM0IsR0FBV2gzQixFQUFRbkosS0FBTTZELEVBQ3JDLENBRUEsTUFBTVMsR0FBWTA4QixHQUFxQjE4QixVQXdCdkMsU0FBU3FlLEdBQU9xSCxHQUNkLE9BQU92TyxtQkFBbUJ1TyxHQUN4Qi9pQixRQUFRLFFBQVMsS0FDakJBLFFBQVEsT0FBUSxLQUNoQkEsUUFBUSxRQUFTLEtBQ2pCQSxRQUFRLE9BQVEsS0FDaEJBLFFBQVEsUUFBUyxLQUNqQkEsUUFBUSxRQUFTLElBQ3JCLENBV0EsU0FBU2k2QixHQUFTbnNCLEVBQUs1TCxFQUFRdEYsR0FFN0IsSUFBS3NGLEVBQ0gsT0FBTzRMLEVBR1QsTUFBTW9zQixFQUFVdDlCLEdBQVdBLEVBQVE4ZSxRQUFVQSxHQUV2Q3llLEVBQWN2OUIsR0FBV0EsRUFBUXc5QixVQUV2QyxJQUFJQyxFQVVKLEdBUEVBLEVBREVGLEVBQ2lCQSxFQUFZajRCLEVBQVF0RixHQUVwQnc0QixHQUFNMUIsa0JBQWtCeHhCLEdBQ3pDQSxFQUFPUCxXQUNQLElBQUlvNEIsR0FBcUI3M0IsRUFBUXRGLEdBQVMrRSxTQUFTdTRCLEdBR25ERyxFQUFrQixDQUNwQixNQUFNQyxFQUFnQnhzQixFQUFJOFAsUUFBUSxNQUVYLElBQW5CMGMsSUFDRnhzQixFQUFNQSxFQUFJOFYsTUFBTSxFQUFHMFcsSUFFckJ4c0IsS0FBOEIsSUFBdEJBLEVBQUk4UCxRQUFRLEtBQWMsSUFBTSxLQUFPeWMsQ0FDakQsQ0FFQSxPQUFPdnNCLENBQ1QsQ0F2RUF6USxHQUFVQyxPQUFTLFNBQWdCMkMsRUFBTXpDLEdBQ3ZDekUsS0FBS2loQyxPQUFPeDdCLEtBQUssQ0FBQ3lCLEVBQU16QyxHQUMxQixFQUVBSCxHQUFVc0UsU0FBVyxTQUFrQjQ0QixHQUNyQyxNQUFNTCxFQUFVSyxFQUFVLFNBQVMvOEIsR0FDakMsT0FBTys4QixFQUFRdDlCLEtBQUtsRSxLQUFNeUUsRUFBT3E4QixHQUNuQyxFQUFJQSxHQUVKLE9BQU85Z0MsS0FBS2loQyxPQUFPdDBCLEtBQUksU0FBY294QixHQUNuQyxPQUFPb0QsRUFBUXBELEVBQUssSUFBTSxJQUFNb0QsRUFBUXBELEVBQUssR0FDL0MsR0FBRyxJQUFJbDNCLEtBQUssSUFDZCxFQStIQSxNQUFNNDZCLEdBbEVOLE1BQU1DLG1CQUNKN1EsY0FDRTd3QixLQUFLMmhDLFNBQVcsRUFDbEIsQ0FVQUMsSUFBSUMsRUFBV0MsRUFBVWorQixHQU92QixPQU5BN0QsS0FBSzJoQyxTQUFTbDhCLEtBQUssQ0FDakJvOEIsWUFDQUMsV0FDQUMsY0FBYWwrQixHQUFVQSxFQUFRaytCLFlBQy9CQyxRQUFTbitCLEVBQVVBLEVBQVFtK0IsUUFBVSxPQUVoQ2hpQyxLQUFLMmhDLFNBQVM5L0IsT0FBUyxDQUNoQyxDQVNBb2dDLE1BQU1sd0IsR0FDQS9SLEtBQUsyaEMsU0FBUzV2QixLQUNoQi9SLEtBQUsyaEMsU0FBUzV2QixHQUFNLEtBRXhCLENBT0Ftd0IsUUFDTWxpQyxLQUFLMmhDLFdBQ1AzaEMsS0FBSzJoQyxTQUFXLEdBRXBCLENBWUFqaEMsUUFBUU8sR0FDTm83QixHQUFNMzdCLFFBQVFWLEtBQUsyaEMsVUFBVSxTQUF3QjFNLEdBQ3pDLE9BQU5BLEdBQ0ZoMEIsRUFBR2cwQixFQUVQLEdBQ0YsR0FLSWtOLEdBQXVCLENBQzNCQyxtQkFBbUIsRUFDbkJDLG1CQUFtQixFQUNuQkMscUJBQXFCLEdBS2pCbEwsR0FBVyxDQUNmbUwsUUFBUSxFQUNSQyxRQUFTLENBQ1B2Z0IsZ0JBTG9CZ1gsRUFBc0IsUUFBRWhYLGdCQU01Q3JlLFNBQVVvMUIsRUFBMkIsUUFDckNyWixLQUFzQixvQkFBVEEsTUFBd0JBLE1BQVEsTUFFL0NzUCxVQUFXLENBQUUsT0FBUSxRQUFTLE9BQVEsU0E0RHhDLFNBQVN3VCxHQUFlNXRCLEdBQ3RCLFNBQVM2dEIsRUFBVXYvQixFQUFNc0IsRUFBT3lyQixFQUFReHVCLEdBQ3RDLElBQUl3RixFQUFPL0QsRUFBS3pCLEtBQ2hCLE1BQU1paEMsRUFBZWxaLE9BQU9pTSxVQUFVeHVCLEdBQ2hDMDdCLEVBQVNsaEMsR0FBU3lCLEVBQUt0QixPQUc3QixHQUZBcUYsR0FBUUEsR0FBUW0xQixHQUFNaDZCLFFBQVE2dEIsR0FBVUEsRUFBT3J1QixPQUFTcUYsRUFFcEQwN0IsRUFPRixPQU5JdkcsR0FBTThCLFdBQVdqTyxFQUFRaHBCLEdBQzNCZ3BCLEVBQU9ocEIsR0FBUSxDQUFDZ3BCLEVBQU9ocEIsR0FBT3pDLEdBRTlCeXJCLEVBQU9ocEIsR0FBUXpDLEdBR1RrK0IsRUFHTHpTLEVBQU9ocEIsSUFBVW0xQixHQUFNbEMsU0FBU2pLLEVBQU9ocEIsTUFDMUNncEIsRUFBT2hwQixHQUFRLElBU2pCLE9BTmV3N0IsRUFBVXYvQixFQUFNc0IsRUFBT3lyQixFQUFPaHBCLEdBQU94RixJQUV0QzI2QixHQUFNaDZCLFFBQVE2dEIsRUFBT2hwQixNQUNqQ2dwQixFQUFPaHBCLEdBNUNiLFNBQXVCMDJCLEdBQ3JCLE1BQU01ZCxFQUFNLENBQUMsRUFDUHZmLEVBQU9ELE9BQU9DLEtBQUttOUIsR0FDekIsSUFBSXYxQixFQUNKLE1BQU1DLEVBQU03SCxFQUFLb0IsT0FDakIsSUFBSXhCLEVBQ0osSUFBS2dJLEVBQUksRUFBR0EsRUFBSUMsRUFBS0QsSUFDbkJoSSxFQUFNSSxFQUFLNEgsR0FDWDJYLEVBQUkzZixHQUFPdTlCLEVBQUl2OUIsR0FFakIsT0FBTzJmLENBQ1QsQ0FpQ3FCNmlCLENBQWMzUyxFQUFPaHBCLE1BRzlCeTdCLENBQ1YsQ0FFQSxHQUFJdEcsR0FBTUMsV0FBV3puQixJQUFhd25CLEdBQU0xTSxXQUFXOWEsRUFBU2dFLFNBQVUsQ0FDcEUsTUFBTW1ILEVBQU0sQ0FBQyxFQU1iLE9BSkFxYyxHQUFNd0IsYUFBYWhwQixHQUFVLENBQUMzTixFQUFNekMsS0FDbENpK0IsRUF2RU4sU0FBdUJ4N0IsR0FLckIsT0FBT20xQixHQUFNMkIsU0FBUyxnQkFBaUI5MkIsR0FBTXlGLEtBQUlzYSxHQUMzQixPQUFiQSxFQUFNLEdBQWMsR0FBS0EsRUFBTSxJQUFNQSxFQUFNLElBRXRELENBK0RnQjZiLENBQWM1N0IsR0FBT3pDLEVBQU91YixFQUFLLEVBQUUsSUFHeENBLENBQ1QsQ0FFQSxPQUFPLElBQ1QsQ0EyQkEsTUFBTTNXLEdBQVcsQ0FFZjA1QixhQUFjWixHQUVkYSxRQUFTLENBQUMsTUFBTyxRQUVqQkMsaUJBQWtCLENBQUMsU0FBMEI1NEIsRUFBTXBFLEdBQ2pELE1BQU1PLEVBQWNQLEVBQVFpOUIsa0JBQW9CLEdBQzFDQyxFQUFxQjM4QixFQUFZcWUsUUFBUSxxQkFBdUIsRUFDaEV1ZSxFQUFrQi9HLEdBQU1sQyxTQUFTOXZCLEdBRW5DKzRCLEdBQW1CL0csR0FBTWQsV0FBV2x4QixLQUN0Q0EsRUFBTyxJQUFJekcsU0FBU3lHLElBS3RCLEdBRm1CZ3lCLEdBQU1DLFdBQVdqeUIsR0FHbEMsT0FBSzg0QixHQUdFQSxFQUFxQjVzQixLQUFLQyxVQUFVaXNCLEdBQWVwNEIsSUFGakRBLEVBS1gsR0FBSWd5QixHQUFNcEMsY0FBYzV2QixJQUN0Qmd5QixHQUFNaDNCLFNBQVNnRixJQUNmZ3lCLEdBQU0zYyxTQUFTclYsSUFDZmd5QixHQUFNN0IsT0FBT253QixJQUNiZ3lCLEdBQU01QixPQUFPcHdCLEdBRWIsT0FBT0EsRUFFVCxHQUFJZ3lCLEdBQU1HLGtCQUFrQm55QixHQUMxQixPQUFPQSxFQUFLaWEsT0FFZCxHQUFJK1gsR0FBTTFCLGtCQUFrQnR3QixHQUUxQixPQURBcEUsRUFBUW85QixlQUFlLG1EQUFtRCxHQUNuRWg1QixFQUFLekIsV0FHZCxJQUFJOHhCLEVBRUosR0FBSTBJLEVBQWlCLENBQ25CLEdBQUk1OEIsRUFBWXFlLFFBQVEsc0NBQXdDLEVBQzlELE9BektSLFNBQTBCeGEsRUFBTXhHLEdBQzlCLE9BQU9zOEIsR0FBVzkxQixFQUFNLElBQUkrc0IsR0FBU29MLFFBQVF2Z0IsZ0JBQW1CemhCLE9BQU84SyxPQUFPLENBQzVFZzFCLFFBQVMsU0FBUzc3QixFQUFPcEUsRUFBSzhDLEVBQU1tZ0MsR0FDbEMsT0FBSWpILEdBQU1oM0IsU0FBU1osSUFDakJ6RSxLQUFLdUUsT0FBT2xFLEVBQUtvRSxFQUFNbUUsU0FBUyxZQUN6QixHQUdGMDZCLEVBQVEvQyxlQUFldFcsTUFBTWpxQixLQUFNNHNCLFVBQzVDLEdBQ0Mvb0IsR0FDTCxDQThKZTAvQixDQUFpQmw1QixFQUFNckssS0FBS3dqQyxnQkFBZ0I1NkIsV0FHckQsSUFBSzh4QixFQUFhMkIsR0FBTTNCLFdBQVdyd0IsS0FBVTdELEVBQVlxZSxRQUFRLHdCQUEwQixFQUFHLENBQzVGLE1BQU00ZSxFQUFZempDLEtBQUswbkIsS0FBTzFuQixLQUFLMG5CLElBQUk5akIsU0FFdkMsT0FBT3U4QixHQUNMekYsRUFBYSxDQUFDLFVBQVdyd0IsR0FBUUEsRUFDakNvNUIsR0FBYSxJQUFJQSxFQUNqQnpqQyxLQUFLd2pDLGVBRVQsQ0FDRixDQUVBLE9BQUlKLEdBQW1CRCxHQUNyQmw5QixFQUFRbzlCLGVBQWUsb0JBQW9CLEdBMUVqRCxTQUF5QkssRUFBVUMsRUFBUW5DLEdBQ3pDLEdBQUluRixHQUFNNU0sU0FBU2lVLEdBQ2pCLElBRUUsT0FEQ0MsR0FBVXB0QixLQUFLd1osT0FBTzJULEdBQ2hCckgsR0FBTWpRLEtBQUtzWCxFQUtwQixDQUpFLE1BQU8zSyxHQUNQLEdBQWUsZ0JBQVhBLEVBQUU3eEIsS0FDSixNQUFNNnhCLENBRVYsQ0FHRixPQUFReUksR0FBV2pyQixLQUFLQyxXQUFXa3RCLEVBQ3JDLENBOERhRSxDQUFnQnY1QixJQUdsQkEsQ0FDVCxHQUVBdzVCLGtCQUFtQixDQUFDLFNBQTJCeDVCLEdBQzdDLE1BQU0wNEIsRUFBZS9pQyxLQUFLK2lDLGNBQWdCMTVCLEdBQVMwNUIsYUFDN0NWLEVBQW9CVSxHQUFnQkEsRUFBYVYsa0JBQ2pEeUIsRUFBc0MsU0FBdEI5akMsS0FBSytqQyxhQUUzQixHQUFJMTVCLEdBQVFneUIsR0FBTTVNLFNBQVNwbEIsS0FBV2c0QixJQUFzQnJpQyxLQUFLK2pDLGNBQWlCRCxHQUFnQixDQUNoRyxNQUNNRSxJQURvQmpCLEdBQWdCQSxFQUFhWCxvQkFDUDBCLEVBRWhELElBQ0UsT0FBT3Z0QixLQUFLd1osTUFBTTFsQixFQVFwQixDQVBFLE1BQU8wdUIsR0FDUCxHQUFJaUwsRUFBbUIsQ0FDckIsR0FBZSxnQkFBWGpMLEVBQUU3eEIsS0FDSixNQUFNazRCLEdBQVc3MkIsS0FBS3d3QixFQUFHcUcsR0FBVzZFLGlCQUFrQmprQyxLQUFNLEtBQU1BLEtBQUttRyxVQUV6RSxNQUFNNHlCLENBQ1IsQ0FDRixDQUNGLENBRUEsT0FBTzF1QixDQUNULEdBTUFtWCxRQUFTLEVBRVQwaUIsZUFBZ0IsYUFDaEJDLGVBQWdCLGVBRWhCQyxrQkFBbUIsRUFDbkJ6aUIsZUFBZ0IsRUFFaEIrRixJQUFLLENBQ0g5akIsU0FBVXd6QixHQUFTb0wsUUFBUTUrQixTQUMzQitiLEtBQU15WCxHQUFTb0wsUUFBUTdpQixNQUd6QjBrQixlQUFnQixTQUF3QjkxQixHQUN0QyxPQUFPQSxHQUFVLEtBQU9BLEVBQVMsR0FDbkMsRUFFQXRJLFFBQVMsQ0FDUHErQixPQUFRLENBQ04sT0FBVSxvQ0FDVixvQkFBZ0IzK0IsS0FLdEIwMkIsR0FBTTM3QixRQUFRLENBQUMsU0FBVSxNQUFPLE9BQVEsT0FBUSxNQUFPLFVBQVc0SSxJQUNoRUQsR0FBU3BELFFBQVFxRCxHQUFVLENBQUMsQ0FBQyxJQUcvQixNQUFNaTdCLEdBQWFsN0IsR0FJYm03QixHQUFvQm5JLEdBQU1nQyxZQUFZLENBQzFDLE1BQU8sZ0JBQWlCLGlCQUFrQixlQUFnQixPQUMxRCxVQUFXLE9BQVEsT0FBUSxvQkFBcUIsc0JBQ2hELGdCQUFpQixXQUFZLGVBQWdCLHNCQUM3QyxVQUFXLGNBQWUsZUE4Q3RCb0csR0FBYXBLLE9BQU8sYUFFMUIsU0FBU3FLLEdBQWdCNy9CLEdBQ3ZCLE9BQU9BLEdBQVV1ZixPQUFPdmYsR0FBUXVuQixPQUFPdmtCLGFBQ3pDLENBRUEsU0FBUzg4QixHQUFlbGdDLEdBQ3RCLE9BQWMsSUFBVkEsR0FBNEIsTUFBVEEsRUFDZEEsRUFHRjQzQixHQUFNaDZCLFFBQVFvQyxHQUFTQSxFQUFNa0ksSUFBSWc0QixJQUFrQnZnQixPQUFPM2YsRUFDbkUsQ0FnQkEsU0FBU21nQyxHQUFpQnpKLEVBQVMxMkIsRUFBT0ksRUFBUW9hLEVBQVE0bEIsR0FDeEQsT0FBSXhJLEdBQU0xTSxXQUFXMVEsR0FDWkEsRUFBTy9hLEtBQUtsRSxLQUFNeUUsRUFBT0ksSUFHOUJnZ0MsSUFDRnBnQyxFQUFRSSxHQUdMdzNCLEdBQU01TSxTQUFTaHJCLEdBRWhCNDNCLEdBQU01TSxTQUFTeFEsSUFDaUIsSUFBM0J4YSxFQUFNb2dCLFFBQVE1RixHQUduQm9kLEdBQU1iLFNBQVN2YyxHQUNWQSxFQUFPVCxLQUFLL1osUUFEckIsT0FOQSxFQVNGLENBc0JBLE1BQU1nZSxhQUNKb08sWUFBWTVxQixHQUNWQSxHQUFXakcsS0FBSzZpQixJQUFJNWMsRUFDdEIsQ0FFQTRjLElBQUloZSxFQUFRaWdDLEVBQWdCQyxHQUMxQixNQUFNejFCLEVBQU90UCxLQUViLFNBQVM0SixFQUFVbzdCLEVBQVFDLEVBQVNDLEdBQ2xDLE1BQU1DLEVBQVVULEdBQWdCTyxHQUVoQyxJQUFLRSxFQUNILE1BQU0sSUFBSXZnQyxNQUFNLDBDQUdsQixNQUFNdkUsRUFBTWc4QixHQUFNdkIsUUFBUXhyQixFQUFNNjFCLEtBRTVCOWtDLFFBQXFCc0YsSUFBZDJKLEVBQUtqUCxLQUFtQyxJQUFiNmtDLFFBQW1Ddi9CLElBQWJ1L0IsSUFBd0MsSUFBZDUxQixFQUFLalAsTUFDekZpUCxFQUFLalAsR0FBTzRrQyxHQUFXTixHQUFlSyxHQUUxQyxDQUVBLE1BQU1JLEVBQWEsQ0FBQ24vQixFQUFTaS9CLElBQzNCN0ksR0FBTTM3QixRQUFRdUYsR0FBUyxDQUFDKytCLEVBQVFDLElBQVlyN0IsRUFBVW83QixFQUFRQyxFQUFTQyxLQVV6RSxPQVJJN0ksR0FBTWpDLGNBQWN2MUIsSUFBV0EsYUFBa0I3RSxLQUFLNndCLFlBQ3hEdVUsRUFBV3ZnQyxFQUFRaWdDLEdBQ1h6SSxHQUFNNU0sU0FBUzVxQixLQUFZQSxFQUFTQSxFQUFPdW5CLFVBckV0QixpQ0FBaUM1TixLQXFFbUIzWixFQXJFVnVuQixRQXNFdkVnWixFQTdIZUMsS0FDbkIsTUFBTXZWLEVBQVMsQ0FBQyxFQUNoQixJQUFJenZCLEVBQ0EycEIsRUFDQTNoQixFQXNCSixPQXBCQWc5QixHQUFjQSxFQUFXM2tCLE1BQU0sTUFBTWhnQixTQUFRLFNBQWdCNGtDLEdBQzNEajlCLEVBQUlpOUIsRUFBS3pnQixRQUFRLEtBQ2pCeGtCLEVBQU1pbEMsRUFBSzk4QixVQUFVLEVBQUdILEdBQUcrakIsT0FBT3ZrQixjQUNsQ21pQixFQUFNc2IsRUFBSzk4QixVQUFVSCxFQUFJLEdBQUcrakIsUUFFdkIvckIsR0FBUXl2QixFQUFPenZCLElBQVFta0MsR0FBa0Jua0MsS0FJbEMsZUFBUkEsRUFDRXl2QixFQUFPenZCLEdBQ1R5dkIsRUFBT3p2QixHQUFLb0YsS0FBS3VrQixHQUVqQjhGLEVBQU96dkIsR0FBTyxDQUFDMnBCLEdBR2pCOEYsRUFBT3p2QixHQUFPeXZCLEVBQU96dkIsR0FBT3l2QixFQUFPenZCLEdBQU8sS0FBTzJwQixFQUFNQSxFQUUzRCxJQUVPOEYsQ0FBTSxFQW1HRXlWLENBQWExZ0MsR0FBU2lnQyxHQUV2QixNQUFWamdDLEdBQWtCK0UsRUFBVWs3QixFQUFnQmpnQyxFQUFRa2dDLEdBRy9DL2tDLElBQ1QsQ0FFQW9OLElBQUl2SSxFQUFROCtCLEdBR1YsR0FGQTkrQixFQUFTNi9CLEdBQWdCNy9CLEdBRWIsQ0FDVixNQUFNeEUsRUFBTWc4QixHQUFNdkIsUUFBUTk2QixLQUFNNkUsR0FFaEMsR0FBSXhFLEVBQUssQ0FDUCxNQUFNb0UsRUFBUXpFLEtBQUtLLEdBRW5CLElBQUtzakMsRUFDSCxPQUFPbC9CLEVBR1QsSUFBZSxJQUFYay9CLEVBQ0YsT0F4R1YsU0FBcUJ4WCxHQUNuQixNQUFNcVosRUFBU2hsQyxPQUFPK00sT0FBTyxNQUN2Qms0QixFQUFXLG1DQUNqQixJQUFJeGUsRUFFSixLQUFRQSxFQUFRd2UsRUFBU2hSLEtBQUt0SSxJQUM1QnFaLEVBQU92ZSxFQUFNLElBQU1BLEVBQU0sR0FHM0IsT0FBT3VlLENBQ1QsQ0E4RmlCRSxDQUFZamhDLEdBR3JCLEdBQUk0M0IsR0FBTTFNLFdBQVdnVSxHQUNuQixPQUFPQSxFQUFPei9CLEtBQUtsRSxLQUFNeUUsRUFBT3BFLEdBR2xDLEdBQUlnOEIsR0FBTWIsU0FBU21JLEdBQ2pCLE9BQU9BLEVBQU9sUCxLQUFLaHdCLEdBR3JCLE1BQU0sSUFBSW1wQixVQUFVLHlDQUN0QixDQUNGLENBQ0YsQ0FFQTdWLElBQUlsVCxFQUFROGdDLEdBR1YsR0FGQTlnQyxFQUFTNi9CLEdBQWdCNy9CLEdBRWIsQ0FDVixNQUFNeEUsRUFBTWc4QixHQUFNdkIsUUFBUTk2QixLQUFNNkUsR0FFaEMsU0FBVXhFLFFBQXFCc0YsSUFBZDNGLEtBQUtLLElBQXdCc2xDLElBQVdmLEdBQWlCNWtDLEVBQU1BLEtBQUtLLEdBQU1BLEVBQUtzbEMsR0FDbEcsQ0FFQSxPQUFPLENBQ1QsQ0FFQTMzQixPQUFPbkosRUFBUThnQyxHQUNiLE1BQU1yMkIsRUFBT3RQLEtBQ2IsSUFBSTRsQyxHQUFVLEVBRWQsU0FBU0MsRUFBYVosR0FHcEIsR0FGQUEsRUFBVVAsR0FBZ0JPLEdBRWIsQ0FDWCxNQUFNNWtDLEVBQU1nOEIsR0FBTXZCLFFBQVF4ckIsRUFBTTIxQixJQUU1QjVrQyxHQUFTc2xDLElBQVdmLEdBQWlCdDFCLEVBQU1BLEVBQUtqUCxHQUFNQSxFQUFLc2xDLFlBQ3REcjJCLEVBQUtqUCxHQUVadWxDLEdBQVUsRUFFZCxDQUNGLENBUUEsT0FOSXZKLEdBQU1oNkIsUUFBUXdDLEdBQ2hCQSxFQUFPbkUsUUFBUW1sQyxHQUVmQSxFQUFhaGhDLEdBR1IrZ0MsQ0FDVCxDQUVBMUQsTUFBTXlELEdBQ0osTUFBTWxsQyxFQUFPRCxPQUFPQyxLQUFLVCxNQUN6QixJQUFJcUksRUFBSTVILEVBQUtvQixPQUNUK2pDLEdBQVUsRUFFZCxLQUFPdjlCLEtBQUssQ0FDVixNQUFNaEksRUFBTUksRUFBSzRILEdBQ2JzOUIsSUFBV2YsR0FBaUI1a0MsRUFBTUEsS0FBS0ssR0FBTUEsRUFBS3NsQyxHQUFTLFlBQ3REM2xDLEtBQUtLLEdBQ1p1bEMsR0FBVSxFQUVkLENBRUEsT0FBT0EsQ0FDVCxDQUVBNStCLFVBQVU4aUIsR0FDUixNQUFNeGEsRUFBT3RQLEtBQ1BpRyxFQUFVLENBQUMsRUFzQmpCLE9BcEJBbzJCLEdBQU0zN0IsUUFBUVYsTUFBTSxDQUFDeUUsRUFBT0ksS0FDMUIsTUFBTXhFLEVBQU1nOEIsR0FBTXZCLFFBQVE3MEIsRUFBU3BCLEdBRW5DLEdBQUl4RSxFQUdGLE9BRkFpUCxFQUFLalAsR0FBT3NrQyxHQUFlbGdDLGVBQ3BCNkssRUFBS3pLLEdBSWQsTUFBTWloQyxFQUFhaGMsRUExSnpCLFNBQXNCamxCLEdBQ3BCLE9BQU9BLEVBQU91bkIsT0FDWHZrQixjQUFjWixRQUFRLG1CQUFtQixDQUFDaXVCLEVBQUc2USxFQUFNNVosSUFDM0M0WixFQUFLL1osY0FBZ0JHLEdBRWxDLENBcUprQzZaLENBQWFuaEMsR0FBVXVmLE9BQU92ZixHQUFRdW5CLE9BRTlEMFosSUFBZWpoQyxVQUNWeUssRUFBS3pLLEdBR2R5SyxFQUFLdzJCLEdBQWNuQixHQUFlbGdDLEdBRWxDd0IsRUFBUTYvQixJQUFjLENBQUksSUFHckI5bEMsSUFDVCxDQUVBMkcsVUFBVXMvQixHQUNSLE9BQU9qbUMsS0FBSzZ3QixZQUFZbHFCLE9BQU8zRyxRQUFTaW1DLEVBQzFDLENBRUE1RyxPQUFPNkcsR0FDTCxNQUFNbG1CLEVBQU14ZixPQUFPK00sT0FBTyxNQU0xQixPQUpBOHVCLEdBQU0zN0IsUUFBUVYsTUFBTSxDQUFDeUUsRUFBT0ksS0FDakIsTUFBVEosSUFBMkIsSUFBVkEsSUFBb0J1YixFQUFJbmIsR0FBVXFoQyxHQUFhN0osR0FBTWg2QixRQUFRb0MsR0FBU0EsRUFBTW9DLEtBQUssTUFBUXBDLEVBQU0sSUFHM0d1YixDQUNULENBRUEsQ0FBQ3FhLE9BQU81NEIsWUFDTixPQUFPakIsT0FBT3FZLFFBQVE3WSxLQUFLcS9CLFVBQVVoRixPQUFPNTRCLFdBQzlDLENBRUFtSCxXQUNFLE9BQU9wSSxPQUFPcVksUUFBUTdZLEtBQUtxL0IsVUFBVTF5QixLQUFJLEVBQUU5SCxFQUFRSixLQUFXSSxFQUFTLEtBQU9KLElBQU9vQyxLQUFLLEtBQzVGLENBRVl5ekIsSUFBUEQsT0FBT0MsZUFDVixNQUFPLGNBQ1QsQ0FFQTZMLFlBQVl0TSxHQUNWLE9BQU9BLGFBQWlCNzVCLEtBQU82NUIsRUFBUSxJQUFJNzVCLEtBQUs2NUIsRUFDbEQsQ0FFQXNNLGNBQWM3TixLQUFVMk4sR0FDdEIsTUFBTUcsRUFBVyxJQUFJcG1DLEtBQUtzNEIsR0FJMUIsT0FGQTJOLEVBQVF2bEMsU0FBU3d2QixHQUFXa1csRUFBU3ZqQixJQUFJcU4sS0FFbENrVyxDQUNULENBRUFELGdCQUFnQnRoQyxHQUNkLE1BSU13aEMsR0FKWXJtQyxLQUFLeWtDLElBQWV6a0MsS0FBS3lrQyxJQUFjLENBQ3ZENEIsVUFBVyxDQUFDLElBR2NBLFVBQ3RCL2hDLEVBQVl0RSxLQUFLc0UsVUFFdkIsU0FBU2dpQyxFQUFlckIsR0FDdEIsTUFBTUUsRUFBVVQsR0FBZ0JPLEdBRTNCb0IsRUFBVWxCLE1BbE5yQixTQUF3Qm5sQixFQUFLbmIsR0FDM0IsTUFBTTBoQyxFQUFlbEssR0FBTWtDLFlBQVksSUFBTTE1QixHQUU3QyxDQUFDLE1BQU8sTUFBTyxPQUFPbkUsU0FBUThsQyxJQUM1QmhtQyxPQUFPbWpCLGVBQWUzRCxFQUFLd21CLEVBQWFELEVBQWMsQ0FDcEQ5aEMsTUFBTyxTQUFTNm9CLEVBQU1DLEVBQU1DLEdBQzFCLE9BQU94dEIsS0FBS3dtQyxHQUFZdGlDLEtBQUtsRSxLQUFNNkUsRUFBUXlvQixFQUFNQyxFQUFNQyxFQUN6RCxFQUNBbkQsY0FBYyxHQUNkLEdBRU4sQ0F3TVFvYyxDQUFlbmlDLEVBQVcyZ0MsR0FDMUJvQixFQUFVbEIsSUFBVyxFQUV6QixDQUlBLE9BRkE5SSxHQUFNaDZCLFFBQVF3QyxHQUFVQSxFQUFPbkUsUUFBUTRsQyxHQUFrQkEsRUFBZXpoQyxHQUVqRTdFLElBQ1QsRUFHRnlpQixhQUFhaWtCLFNBQVMsQ0FBQyxlQUFnQixpQkFBa0IsU0FBVSxrQkFBbUIsYUFBYyxrQkFHcEdySyxHQUFNWixrQkFBa0JoWixhQUFhbmUsV0FBVyxFQUFFRyxTQUFRcEUsS0FDeEQsSUFBSXNtQyxFQUFTdG1DLEVBQUksR0FBRzJyQixjQUFnQjNyQixFQUFJd3FCLE1BQU0sR0FDOUMsTUFBTyxDQUNMemQsSUFBSyxJQUFNM0ksRUFDWG9lLElBQUkrakIsR0FDRjVtQyxLQUFLMm1DLEdBQVVDLENBQ2pCLEVBQ0YsSUFHRnZLLEdBQU0rQixjQUFjM2IsY0FFcEIsTUFBTW9rQixHQUFpQnBrQixhQVV2QixTQUFTcWtCLEdBQWNDLEVBQUs1Z0MsR0FDMUIsTUFBTTJPLEVBQVM5VSxNQUFRdWtDLEdBQ2pCcEosRUFBVWgxQixHQUFZMk8sRUFDdEI3TyxFQUFVNGdDLEdBQWV0K0IsS0FBSzR5QixFQUFRbDFCLFNBQzVDLElBQUlvRSxFQUFPOHdCLEVBQVE5d0IsS0FRbkIsT0FOQWd5QixHQUFNMzdCLFFBQVFxbUMsR0FBSyxTQUFtQjlsQyxHQUNwQ29KLEVBQU9wSixFQUFHaUQsS0FBSzRRLEVBQVF6SyxFQUFNcEUsRUFBUWUsWUFBYWIsRUFBV0EsRUFBU29JLFlBQVM1SSxFQUNqRixJQUVBTSxFQUFRZSxZQUVEcUQsQ0FDVCxDQUVBLFNBQVMyOEIsR0FBU3ZpQyxHQUNoQixTQUFVQSxJQUFTQSxFQUFNd2lDLFdBQzNCLENBV0EsU0FBU0MsR0FBY3o0QixFQUFTcUcsRUFBUTFMLEdBRXRDZzJCLEdBQVdsN0IsS0FBS2xFLEtBQWlCLE1BQVh5TyxFQUFrQixXQUFhQSxFQUFTMndCLEdBQVcrSCxhQUFjcnlCLEVBQVExTCxHQUMvRnBKLEtBQUtrSCxLQUFPLGVBQ2QsQ0FlQSxTQUFTa2dDLEdBQU85VCxFQUFTK1QsRUFBUWxoQyxHQUMvQixNQUFNaytCLEVBQWlCbCtCLEVBQVMyTyxPQUFPdXZCLGVBQ2xDbCtCLEVBQVNvSSxRQUFXODFCLElBQWtCQSxFQUFlbCtCLEVBQVNvSSxRQUdqRTg0QixFQUFPLElBQUlqSSxHQUNULG1DQUFxQ2o1QixFQUFTb0ksT0FDOUMsQ0FBQzZ3QixHQUFXa0ksZ0JBQWlCbEksR0FBVzZFLGtCQUFrQng3QixLQUFLQyxNQUFNdkMsRUFBU29JLE9BQVMsS0FBTyxHQUM5RnBJLEVBQVMyTyxPQUNUM08sRUFBU2lELFFBQ1RqRCxJQVBGbXRCLEVBQVFudEIsRUFVWixDQXdDQSxTQUFTb2hDLEdBQWNDLEVBQVNDLEdBQzlCLE9BQUlELElBaENOLFNBQXVCenlCLEdBSXJCLE1BQU8sOEJBQThCeUosS0FBS3pKLEVBQzVDLENBMkJrQjJ5QixDQUFjRCxHQWpCaEMsU0FBcUJELEVBQVNHLEdBQzVCLE9BQU9BLEVBQ0hILEVBQVF2Z0MsUUFBUSxPQUFRLElBQU0sSUFBTTBnQyxFQUFZMWdDLFFBQVEsT0FBUSxJQUNoRXVnQyxDQUNOLENBY1dJLENBQVlKLEVBQVNDLEdBRXZCQSxDQUNULENBdkVBcEwsR0FBTWw0QixTQUFTK2lDLEdBQWU5SCxHQUFZLENBQ3hDNkgsWUFBWSxJQXdFZCxNQUFNWSxHQUFVLFFBRWhCLFNBQVNDLEdBQWMveUIsR0FDckIsTUFBTWtTLEVBQVEsNEJBQTRCd04sS0FBSzFmLEdBQy9DLE9BQU9rUyxHQUFTQSxFQUFNLElBQU0sRUFDOUIsQ0FFQSxNQUFNOGdCLEdBQW1CLGdEQW9GekIsU0FBU0MsR0FBWUMsRUFBYzlRLEdBQ2pDOFEsRUFBZUEsR0FBZ0IsR0FDL0IsTUFBTUMsRUFBUSxJQUFJOWxDLE1BQU02bEMsR0FDbEJFLEVBQWEsSUFBSS9sQyxNQUFNNmxDLEdBQzdCLElBRUlHLEVBRkFDLEVBQU8sRUFDUEMsRUFBTyxFQUtYLE9BRkFuUixPQUFjeHhCLElBQVJ3eEIsRUFBb0JBLEVBQU0sSUFFekIsU0FBY29SLEdBQ25CLE1BQU1DLEVBQU0vM0IsS0FBSyszQixNQUVYQyxFQUFZTixFQUFXRyxHQUV4QkYsSUFDSEEsRUFBZ0JJLEdBR2xCTixFQUFNRyxHQUFRRSxFQUNkSixFQUFXRSxHQUFRRyxFQUVuQixJQUFJbmdDLEVBQUlpZ0MsRUFDSkksRUFBYSxFQUVqQixLQUFPcmdDLElBQU1nZ0MsR0FDWEssR0FBY1IsRUFBTTcvQixLQUNwQkEsR0FBUTQvQixFQVNWLEdBTkFJLEdBQVFBLEVBQU8sR0FBS0osRUFFaEJJLElBQVNDLElBQ1hBLEdBQVFBLEVBQU8sR0FBS0wsR0FHbEJPLEVBQU1KLEVBQWdCalIsRUFDeEIsT0FHRixNQUFNd1IsRUFBU0YsR0FBYUQsRUFBTUMsRUFFbEMsT0FBT0UsRUFBU2xnQyxLQUFLK3NCLE1BQW1CLElBQWJrVCxFQUFvQkMsUUFBVWhqQyxDQUMzRCxDQUNGLENBRUEsTUFBTWlqQyxHQUFhdk8sT0FBTyxhQUUxQixNQUFNd08sNkJBQTZCdFAsRUFBeUIsUUFBRXVQLFVBQzVEalksWUFBWWh0QixHQVlWa2xDLE1BQU0sQ0FDSkMsdUJBWkZubEMsRUFBVXc0QixHQUFNZSxhQUFhdjVCLEVBQVMsQ0FDcENvbEMsUUFBUyxFQUNUQyxVQUFXLE1BQ1hDLGFBQWMsSUFDZEMsV0FBWSxJQUNaQyxVQUFXLEVBQ1hwQixhQUFjLElBQ2IsTUFBTSxDQUFDcmhDLEVBQU0wbEIsS0FDTitQLEdBQU1yQyxZQUFZMU4sRUFBTzFsQixPQUlGc2lDLFlBR2pDLE1BQU01NUIsRUFBT3RQLEtBRVBzcEMsRUFBWXRwQyxLQUFLNG9DLElBQWMsQ0FDbkMvbUMsT0FBUWdDLEVBQVFoQyxPQUNoQnVuQyxXQUFZdmxDLEVBQVF1bEMsV0FDcEJDLFVBQVd4bEMsRUFBUXdsQyxVQUNuQkgsVUFBV3JsQyxFQUFRcWxDLFVBQ25CRCxRQUFTcGxDLEVBQVFvbEMsUUFDakJFLGFBQWN0bEMsRUFBUXNsQyxhQUN0QkksVUFBVyxFQUNYQyxZQUFZLEVBQ1pDLG9CQUFxQixFQUNyQkMsR0FBSWo1QixLQUFLKzNCLE1BQ1ROLE1BQU8sRUFDUHlCLGVBQWdCLE1BR1pDLEVBQWU1QixHQUFZc0IsRUFBVUQsVUFBWXhsQyxFQUFRb2tDLGFBQWNxQixFQUFVRixZQUV2RnBwQyxLQUFLa0csR0FBRyxlQUFlbW5CLElBQ1AsYUFBVkEsSUFDR2ljLEVBQVVFLGFBQ2JGLEVBQVVFLFlBQWEsR0FFM0IsSUFHRixJQUFJSyxFQUFnQixFQUVwQlAsRUFBVVEsZUE1SGQsU0FBa0I3b0MsRUFBSThvQyxHQUNwQixJQUFJQyxFQUFZLEVBQ2hCLE1BQU1DLEVBQVksSUFBT0YsRUFDekIsSUFBSUcsRUFBUSxLQUNaLE9BQU8sU0FBbUJDLEVBQU8xakIsR0FDL0IsTUFBTStoQixFQUFNLzNCLEtBQUsrM0IsTUFDakIsR0FBSTJCLEdBQVMzQixFQUFNd0IsRUFBWUMsRUFNN0IsT0FMSUMsSUFDRnpZLGFBQWF5WSxHQUNiQSxFQUFRLE1BRVZGLEVBQVl4QixFQUNMdm5DLEVBQUdncEIsTUFBTSxLQUFNeEQsR0FFbkJ5akIsSUFDSEEsRUFBUTdvQyxZQUFXLEtBQ2pCNm9DLEVBQVEsS0FDUkYsRUFBWXY1QixLQUFLKzNCLE1BQ1Z2bkMsRUFBR2dwQixNQUFNLEtBQU14RCxLQUNyQndqQixHQUFhekIsRUFBTXdCLElBRTFCLENBQ0YsQ0FzRytCSSxFQUFTLFdBQ2xDLE1BQU1DLEVBQWFmLEVBQVV6bkMsT0FDdkJ5b0MsRUFBbUJoQixFQUFVQyxVQUM3QmdCLEVBQWdCRCxFQUFtQlQsRUFDekMsSUFBS1UsR0FBaUJqN0IsRUFBS2s3QixVQUFXLE9BRXRDLE1BQU1DLEVBQU9iLEVBQWFXLEdBRTFCVixFQUFnQlMsRUFFaEJscEMsUUFBUUYsVUFBUyxLQUNmb08sRUFBS3JGLEtBQUssV0FBWSxDQUNwQixPQUFVcWdDLEVBQ1YsTUFBU0QsRUFDVCxTQUFZQSxFQUFjQyxFQUFtQkQsT0FBYzFrQyxFQUMzRCxNQUFTNGtDLEVBQ1QsS0FBUUUsUUFBYzlrQyxFQUN0QixVQUFhOGtDLEdBQVFKLEdBQWNDLEdBQW9CRCxHQUNwREEsRUFBYUMsR0FBb0JHLE9BQU85a0MsR0FDM0MsR0FFTixHQUFHMmpDLEVBQVVELFdBRWIsTUFBTXFCLEVBQVcsS0FDZnBCLEVBQVVRLGdCQUFlLEVBQUssRUFHaEM5cEMsS0FBSzJ4QixLQUFLLE1BQU8rWSxHQUNqQjFxQyxLQUFLMnhCLEtBQUssUUFBUytZLEVBQ3JCLENBRUFDLE1BQU1ub0MsR0FDSixNQUFNOG1DLEVBQVl0cEMsS0FBSzRvQyxJQU12QixPQUpJVSxFQUFVSyxnQkFDWkwsRUFBVUssaUJBR0xaLE1BQU00QixNQUFNbm9DLEVBQ3JCLENBRUFvb0MsV0FBV0MsRUFBTzdaLEVBQVVud0IsR0FDMUIsTUFBTXlPLEVBQU90UCxLQUNQc3BDLEVBQVl0cEMsS0FBSzRvQyxJQUNqQkssRUFBVUssRUFBVUwsUUFFcEJELEVBQXdCaHBDLEtBQUtncEMsc0JBRTdCSSxFQUFhRSxFQUFVRixXQUd2QjBCLEVBQWtCN0IsR0FEUixJQUFPRyxHQUVqQkQsR0FBMEMsSUFBM0JHLEVBQVVILGFBQXlCMWdDLEtBQUtzaUMsSUFBSXpCLEVBQVVILGFBQStCLElBQWpCMkIsR0FBeUIsRUFxQmxILE1BQU1FLEVBQWlCLENBQUNDLEVBQVFDLEtBQzlCLE1BQU1oQyxFQUFZOWpDLE9BQU9FLFdBQVcybEMsR0FDcEMsSUFFSUUsRUFGQUMsRUFBaUIsS0FDakJDLEVBQWVyQyxFQUVmTCxFQUFTLEVBRWIsR0FBSU0sRUFBUyxDQUNYLE1BQU1ULEVBQU0vM0IsS0FBSyszQixRQUVaYyxFQUFVSSxLQUFPZixFQUFVSCxFQUFNYyxFQUFVSSxLQUFRTixLQUN0REUsRUFBVUksR0FBS2xCLEVBQ2YyQyxFQUFZTCxFQUFpQnhCLEVBQVVwQixNQUN2Q29CLEVBQVVwQixNQUFRaUQsRUFBWSxHQUFLQSxFQUFZLEVBQy9DeEMsRUFBUyxHQUdYd0MsRUFBWUwsRUFBaUJ4QixFQUFVcEIsS0FDekMsQ0FFQSxHQUFJZSxFQUFTLENBQ1gsR0FBSWtDLEdBQWEsRUFFZixPQUFPOXBDLFlBQVcsS0FDaEI2cEMsRUFBVSxLQUFNRCxFQUFPLEdBQ3RCN0IsRUFBYVQsR0FHZHdDLEVBQVlFLElBQ2RBLEVBQWVGLEVBRW5CLENBRUlFLEdBQWdCbkMsRUFBWW1DLEdBQWlCbkMsRUFBWW1DLEVBQWdCbEMsSUFDM0VpQyxFQUFpQkgsRUFBT0ssU0FBU0QsR0FDakNKLEVBQVNBLEVBQU9LLFNBQVMsRUFBR0QsSUF0RGhDLFNBQW1CSixFQUFRQyxHQUN6QixNQUFNaEQsRUFBUTlpQyxPQUFPRSxXQUFXMmxDLEdBQ2hDM0IsRUFBVUMsV0FBYXJCLEVBQ3ZCb0IsRUFBVXBCLE9BQVNBLEVBRWZvQixFQUFVRSxZQUNaRixFQUFVUSxpQkFHUng2QixFQUFLN0osS0FBS3dsQyxHQUNaN3BDLFFBQVFGLFNBQVNncUMsR0FFakI1QixFQUFVSyxlQUFpQixLQUN6QkwsRUFBVUssZUFBaUIsS0FDM0J2b0MsUUFBUUYsU0FBU2dxQyxFQUFVLENBR2pDLENBd0NFSyxDQUFVTixFQUFRRyxFQUFpQixLQUNqQ2hxQyxRQUFRRixTQUFTZ3FDLEVBQVcsS0FBTUUsRUFBZSxFQUMvQ0YsRUFBVSxFQUdoQkYsRUFBZUgsR0FBTyxTQUFTVyxFQUFtQnpxQyxFQUFLa3FDLEdBQ3JELEdBQUlscUMsRUFDRixPQUFPRixFQUFTRSxHQUdka3FDLEVBQ0ZELEVBQWVDLEVBQVFPLEdBRXZCM3FDLEVBQVMsS0FFYixHQUNGLENBRUE0cUMsVUFBVTVwQyxHQUVSLE9BREE3QixLQUFLNG9DLElBQVkvbUMsUUFBVUEsRUFDcEI3QixJQUNULEVBR0YsTUFBTTByQyxHQUF5QjdDLHNCQUV6QixjQUFDOEMsSUFBaUJ0UixPQWNsQnVSLEdBWld0cUMsZ0JBQWlCdXFDLEdBQzVCQSxFQUFLbm1CLGFBQ0FtbUIsRUFBS25tQixTQUNIbW1CLEVBQUtDLHdCQUNGRCxFQUFLQyxjQUNSRCxFQUFLRixVQUNQRSxFQUFLRixZQUVORSxDQUVWLEVBSU1FLEdBQW9CMVAsR0FBTUgsU0FBU0MsWUFBYyxLQUVqRDZQLEdBQWMsSUFBSTlvQyxFQUFLK29DLFlBRXZCQyxHQUFPLE9BQ1BDLEdBQWFILEdBQVlycEIsT0FBT3VwQixJQUd0QyxNQUFNRSxhQUNKdmIsWUFBWTNwQixFQUFNekMsR0FDaEIsTUFBTSxXQUFDNG5DLEdBQWNyc0MsS0FBSzZ3QixZQUNwQnliLEVBQWdCalEsR0FBTTVNLFNBQVNockIsR0FFckMsSUFBSXdCLEVBQVUseUNBQXlDb21DLEVBQVdubEMsT0FDL0RvbEMsR0FBaUI3bkMsRUFBTXlDLEtBQU8sZUFBZW1sQyxFQUFXNW5DLEVBQU15QyxTQUFXLFNBR3hFb2xDLEVBQ0Y3bkMsRUFBUXVuQyxHQUFZcnBCLE9BQU95QixPQUFPM2YsR0FBT3dDLFFBQVEsZUFBZ0JpbEMsS0FFakVqbUMsR0FBVyxpQkFBaUJ4QixFQUFNc0csTUFBUSxpQ0FHNUMvSyxLQUFLaUcsUUFBVStsQyxHQUFZcnBCLE9BQU8xYyxFQUFVaW1DLElBRTVDbHNDLEtBQUt1c0MsY0FBZ0JELEVBQWdCN25DLEVBQU1hLFdBQWFiLEVBQU1qQyxLQUU5RHhDLEtBQUt3QyxLQUFPeEMsS0FBS2lHLFFBQVFYLFdBQWF0RixLQUFLdXNDLGNBckJ0QixFQXVCckJ2c0MsS0FBS2tILEtBQU9BLEVBQ1psSCxLQUFLeUUsTUFBUUEsQ0FDZixDQUVBbkQscUJBQ1F0QixLQUFLaUcsUUFFWCxNQUFNLE1BQUN4QixHQUFTekUsS0FFYnE4QixHQUFNakIsYUFBYTMyQixTQUNkQSxRQUVDbW5DLEdBQVdubkMsU0FHZDBuQyxFQUNSLENBRUFoRyxrQkFBa0JqL0IsR0FDZCxPQUFPa2QsT0FBT2xkLEdBQU1ELFFBQVEsWUFBYWdnQixJQUFXLENBQ2xELEtBQU8sTUFDUCxLQUFPLE1BQ1AsSUFBTSxPQUNOQSxLQUNOLEVBR0YsTUFpRE11bEIsR0FqRG1CLENBQUNDLEVBQU1DLEVBQWdCN29DLEtBQzlDLE1BQU0sSUFDSjBNLEVBQU0scUJBQW9CLEtBQzFCL04sRUFBTyxHQUFFLFNBQ1R1RixFQUFXd0ksRUFBTSxJQUFNOHJCLEdBQU11QyxlQUFlcDhCLEVBQU11cEMsS0FDaERsb0MsR0FBVyxDQUFDLEVBRWhCLElBQUl3NEIsR0FBTUMsV0FBV21RLEdBQ25CLE1BQU03ZSxVQUFVLDhCQUdsQixHQUFJN2xCLEVBQVNsRyxPQUFTLEdBQUtrRyxFQUFTbEcsT0FBUyxHQUMzQyxNQUFNK0MsTUFBTSwwQ0FHZCxNQUFNK25DLEVBQWdCWCxHQUFZcnBCLE9BQU8sS0FBTzVhLEVBQVdta0MsSUFDckRVLEVBQWNaLEdBQVlycEIsT0FBTyxLQUFPNWEsRUFBVyxLQUFPbWtDLEdBQU9BLElBQ3ZFLElBQUlLLEVBQWdCSyxFQUFZdG5DLFdBRWhDLE1BQU1rekIsRUFBUXAyQixNQUFNbUcsS0FBS2trQyxFQUFLNXpCLFdBQVdsTSxLQUFJLEVBQUV6RixFQUFNekMsTUFDbkQsTUFBTW9vQyxFQUFPLElBQUlULGFBQWFsbEMsRUFBTXpDLEdBRXBDLE9BREE4bkMsR0FBaUJNLEVBQUtycUMsS0FDZnFxQyxDQUFJLElBR2JOLEdBQWlCSSxFQUFjcm5DLFdBQWFrekIsRUFBTTMyQixPQUVsRDBxQyxFQUFnQmxRLEdBQU1xQyxlQUFlNk4sR0FFckMsTUFBTU8sRUFBa0IsQ0FDdEIsZUFBZ0IsaUNBQWlDL2tDLEtBU25ELE9BTkkwaEIsT0FBT2lNLFNBQVM2VyxLQUNsQk8sRUFBZ0Isa0JBQW9CUCxHQUd0Q0csR0FBa0JBLEVBQWVJLEdBRTFCcG5CLEVBQU9xbkIsU0FBU3hrQyxLQUFLLGtCQUMxQixJQUFJLE1BQU1za0MsS0FBUXJVLFFBQ1ZtVSxRQUNDRSxFQUFLbHFCLGVBR1JpcUIsQ0FDUCxDQVAyQixHQU92QixFQUtQLE1BQU1JLGtDQUFrQ3pULEVBQXlCLFFBQUV1UCxVQUNqRW1FLFlBQVlwQyxFQUFPN1osRUFBVW53QixHQUMzQmIsS0FBS3lGLEtBQUtvbEMsR0FDVmhxQyxHQUNGLENBRUErcEMsV0FBV0MsRUFBTzdaLEVBQVVud0IsR0FDMUIsR0FBcUIsSUFBakJncUMsRUFBTWhwQyxTQUNSN0IsS0FBSzRxQyxXQUFhNXFDLEtBQUtpdEMsWUFHTixNQUFicEMsRUFBTSxJQUFZLENBQ3BCLE1BQU1obUMsRUFBU08sT0FBT2dELE1BQU0sR0FDNUJ2RCxFQUFPLEdBQUssSUFDWkEsRUFBTyxHQUFLLElBQ1o3RSxLQUFLeUYsS0FBS1osRUFBUW1zQixFQUNwQixDQUdGaHhCLEtBQUtpdEMsWUFBWXBDLEVBQU83WixFQUFVbndCLEVBQ3BDLEVBR0YsTUFBTXFzQyxHQUE4QkYsMEJBZTlCRyxHQWJjLENBQUNsc0MsRUFBSXk2QixJQUNoQlcsR0FBTUQsVUFBVW43QixHQUFNLFlBQWF3bEIsR0FDeEMsTUFBTXpkLEVBQUt5ZCxFQUFLOUYsTUFDaEIxZixFQUFHZ3BCLE1BQU1qcUIsS0FBTXltQixHQUFNcFosTUFBTTVJLElBQ3pCLElBQ0VpM0IsRUFBVTF5QixFQUFHLFFBQVMweUIsRUFBUWozQixJQUFVdUUsRUFBRyxLQUFNdkUsRUFHbkQsQ0FGRSxNQUFPMUQsR0FDUGlJLEVBQUdqSSxFQUNMLElBQ0NpSSxFQUNMLEVBQUkvSCxFQUtBbXNDLEdBQWMsQ0FDbEJDLE1BQU8vVCxFQUF1QixRQUFFZ1UsVUFBVUMsYUFDMUNDLFlBQWFsVSxFQUF1QixRQUFFZ1UsVUFBVUMsY0FHNUNFLEdBQWdCLENBQ3BCSixNQUFPL1QsRUFBdUIsUUFBRWdVLFVBQVVJLHVCQUMxQ0YsWUFBYWxVLEVBQXVCLFFBQUVnVSxVQUFVSSx3QkFHNUNDLEdBQW9CdFIsR0FBTTFNLFdBQVcySixFQUF1QixRQUFFc1UseUJBRTdEeHFDLEtBQU15cUMsR0FBWXhxQyxNQUFPeXFDLElBQWV6VSxFQUFrQyxRQUUzRTBVLEdBQVUsVUFFVkMsR0FBcUI1VyxHQUFTbkksVUFBVXRpQixLQUFJaEQsR0FDekNBLEVBQVcsTUFXcEIsU0FBU3NrQyxHQUF1QnBxQyxHQUMxQkEsRUFBUXFxQyxnQkFBZ0J0c0IsT0FDMUIvZCxFQUFRcXFDLGdCQUFnQnRzQixNQUFNL2QsR0FFNUJBLEVBQVFxcUMsZ0JBQWdCcDVCLFFBQzFCalIsRUFBUXFxQyxnQkFBZ0JwNUIsT0FBT2pSLEVBRW5DLENBV0EsU0FBU3NxQyxHQUFTdHFDLEVBQVN1cUMsRUFBYTdiLEdBQ3RDLElBQUkzUSxFQUFRd3NCLEVBQ1osSUFBS3hzQixJQUFtQixJQUFWQSxFQUFpQixDQUM3QixNQUFNeXNCLEVBQVcxVixFQUFhdEMsZUFBZTlELEdBQ3pDOGIsSUFDRnpzQixFQUFRLElBQUlwQixJQUFJNnRCLEdBRXBCLENBQ0EsR0FBSXpzQixFQUFPLENBTVQsR0FKSUEsRUFBTTVNLFdBQ1I0TSxFQUFNMHNCLE1BQVExc0IsRUFBTTVNLFVBQVksSUFBTSxLQUFPNE0sRUFBTTJzQixVQUFZLEtBRzdEM3NCLEVBQU0wc0IsS0FBTSxFQUVWMXNCLEVBQU0wc0IsS0FBS3Q1QixVQUFZNE0sRUFBTTBzQixLQUFLQyxZQUNwQzNzQixFQUFNMHNCLE1BQVExc0IsRUFBTTBzQixLQUFLdDVCLFVBQVksSUFBTSxLQUFPNE0sRUFBTTBzQixLQUFLQyxVQUFZLEtBRTNFLE1BQU1wdEIsRUFBUy9iLE9BQ1ptRCxLQUFLcVosRUFBTTBzQixLQUFNLFFBQ2pCMWxDLFNBQVMsVUFDWi9FLEVBQVFvQyxRQUFRLHVCQUF5QixTQUFXa2IsQ0FDdEQsQ0FFQXRkLEVBQVFvQyxRQUFRd0QsS0FBTzVGLEVBQVE2RixVQUFZN0YsRUFBUTBGLEtBQU8sSUFBTTFGLEVBQVEwRixLQUFPLElBQy9FLE1BQU1pbEMsRUFBWTVzQixFQUFNbFksVUFBWWtZLEVBQU1uWSxLQUMxQzVGLEVBQVE2RixTQUFXOGtDLEVBRW5CM3FDLEVBQVE0RixLQUFPK2tDLEVBQ2YzcUMsRUFBUTBGLEtBQU9xWSxFQUFNclksS0FDckIxRixFQUFRVixLQUFPb3ZCLEVBQ1gzUSxFQUFNalksV0FDUjlGLEVBQVE4RixTQUFXaVksRUFBTWpZLFNBQVN3VixTQUFTLEtBQU95QyxFQUFNalksU0FBVyxHQUFHaVksRUFBTWpZLFlBRWhGLENBRUE5RixFQUFRcXFDLGdCQUFnQnRzQixNQUFRLFNBQXdCNnNCLEdBR3RETixHQUFTTSxFQUFpQkwsRUFBYUssRUFBZ0J6ZSxLQUN6RCxDQUNGLENBRUEsTUFBTTBlLEdBQTRDLG9CQUFadHRDLFNBQXFELFlBQTFCaTdCLEdBQU0xQyxPQUFPdjRCLFNBdUN4RXV0QyxHQUFvQixDQUFDNzBCLEVBQVM4MEIsSUFWZCxHQUFFOTBCLFVBQVM4MEIsYUFDL0IsSUFBS3ZTLEdBQU01TSxTQUFTM1YsR0FDbEIsTUFBTThULFVBQVUsNEJBRWxCLE1BQU8sQ0FDTDlULFVBQ0E4MEIsT0FBUUEsSUFBVzkwQixFQUFRK0ssUUFBUSxLQUFPLEVBQUksRUFBSSxHQUNsRCxFQUcyQ2dxQixDQUFjeFMsR0FBTWxDLFNBQVNyZ0IsR0FBV0EsRUFBVSxDQUFDQSxVQUFTODBCLFdBR3JHRSxHQUFjSixJQUEwQixTQUFxQjU1QixHQUNqRSxPQXZDaUJpNkIsRUF1Q0F6dEMsZUFBbUNneUIsRUFBUytULEVBQVEySCxHQUNuRSxJQUFJLEtBQUMza0MsRUFBSSxPQUFFL0MsRUFBTSxPQUFFc25DLEdBQVU5NUIsRUFDN0IsTUFBTSxhQUFDaXZCLEVBQVksaUJBQUVrTCxHQUFvQm42QixFQUNuQ3hMLEVBQVN3TCxFQUFPeEwsT0FBTzBpQixjQUM3QixJQUFJa2pCLEVBRUFyYyxFQURBaVAsR0FBVyxFQUdmLEdBQUl4NkIsRUFBUSxDQUNWLE1BQU02bkMsRUFBVWhDLEdBQWM3bEMsR0FBUzdDLEdBQVU0M0IsR0FBTWg2QixRQUFRb0MsR0FBU0EsRUFBUSxDQUFDQSxLQUVqRjZDLEVBQVMsQ0FBQ29DLEVBQVUwbEMsRUFBS3BtQyxLQUN2Qm1tQyxFQUFRemxDLEVBQVUwbEMsR0FBSyxDQUFDcnVDLEVBQUtzdUMsRUFBTS9oQixLQUNqQyxNQUFNZ2lCLEVBQVlqVCxHQUFNaDZCLFFBQVFndEMsR0FBUUEsRUFBSzFpQyxLQUFJNGlDLEdBQVFaLEdBQWtCWSxLQUFTLENBQUNaLEdBQWtCVSxFQUFNL2hCLElBRTdHOGhCLEVBQUlJLElBQU14bUMsRUFBR2pJLEVBQUt1dUMsR0FBYXRtQyxFQUFHakksRUFBS3V1QyxFQUFVLEdBQUd4MUIsUUFBU3cxQixFQUFVLEdBQUdWLE9BQU8sR0FDakYsQ0FFTixDQUdBLE1BQU1hLEVBQVUsSUFBSWpXLEVBQStCLFFBRTdDa1csRUFBYSxLQUNiNTZCLEVBQU82NkIsYUFDVDc2QixFQUFPNjZCLFlBQVl0MEIsWUFBWTlaLEdBRzdCdVQsRUFBTzg2QixRQUNUOTZCLEVBQU84NkIsT0FBT0Msb0JBQW9CLFFBQVN0dUMsR0FHN0NrdUMsRUFBUUssb0JBQW9CLEVBVzlCLFNBQVN2dUMsRUFBTXdhLEdBQ2IwekIsRUFBUXhsQyxLQUFLLFNBQVU4UixHQUFVQSxFQUFPaFIsS0FBTyxJQUFJbThCLEdBQWMsS0FBTXB5QixFQUFRK2QsR0FBTzlXLEVBQ3hGLENBVkFpekIsR0FBTyxDQUFDdnFDLEVBQU9zckMsS0FDYmIsR0FBUyxFQUNMYSxJQUNGak8sR0FBVyxFQUNYNE4sSUFDRixJQU9GRCxFQUFROWQsS0FBSyxRQUFTMFYsSUFFbEJ2eUIsRUFBTzY2QixhQUFlNzZCLEVBQU84NkIsVUFDL0I5NkIsRUFBTzY2QixhQUFlNzZCLEVBQU82NkIsWUFBWUssVUFBVXp1QyxHQUMvQ3VULEVBQU84NkIsU0FDVDk2QixFQUFPODZCLE9BQU9LLFFBQVUxdUMsSUFBVXVULEVBQU84NkIsT0FBT00saUJBQWlCLFFBQVMzdUMsS0FLOUUsTUFBTTR1QyxFQUFXNUksR0FBY3p5QixFQUFPMHlCLFFBQVMxeUIsRUFBT0MsS0FDaEQrYSxFQUFTLElBQUl0UCxJQUFJMnZCLEVBQVUsb0JBQzNCeG1DLEVBQVdtbUIsRUFBT25tQixVQUFZcWtDLEdBQW1CLEdBRXZELEdBQWlCLFVBQWJya0MsRUFBc0IsQ0FDeEIsSUFBSXltQyxFQUVKLEdBQWUsUUFBWDltQyxFQUNGLE9BQU84OUIsR0FBTzlULEVBQVMrVCxFQUFRLENBQzdCOTRCLE9BQVEsSUFDUkMsV0FBWSxxQkFDWnZJLFFBQVMsQ0FBQyxFQUNWNk8sV0FJSixJQUNFczdCLEVBanFCUixTQUFxQkMsRUFBS0MsRUFBUXpzQyxHQUNoQyxNQUFNMHNDLEVBQVExc0MsR0FBV0EsRUFBUThiLE1BQVF5WCxHQUFTb0wsUUFBUTdpQixLQUNwRGhXLEVBQVdtK0IsR0FBY3VJLEdBTS9CLFFBSmUxcUMsSUFBWDJxQyxHQUF3QkMsSUFDMUJELEdBQVMsR0FHTSxTQUFiM21DLEVBQXFCLENBQ3ZCMG1DLEVBQU0xbUMsRUFBUzlILE9BQVN3dUMsRUFBSXhsQixNQUFNbGhCLEVBQVM5SCxPQUFTLEdBQUt3dUMsRUFFekQsTUFBTXBwQixFQUFROGdCLEdBQWlCdFQsS0FBSzRiLEdBRXBDLElBQUtwcEIsRUFDSCxNQUFNLElBQUltWSxHQUFXLGNBQWVBLEdBQVdvUixpQkFHakQsTUFBTS9zQyxFQUFPd2pCLEVBQU0sR0FDYndwQixFQUFXeHBCLEVBQU0sR0FDakJ6YSxFQUFPeWEsRUFBTSxHQUNiM0MsRUFBU2xmLE9BQU9tRCxLQUFLbW9DLG1CQUFtQmxrQyxHQUFPaWtDLEVBQVcsU0FBVyxRQUUzRSxHQUFJSCxFQUFRLENBQ1YsSUFBS0MsRUFDSCxNQUFNLElBQUluUixHQUFXLHdCQUF5QkEsR0FBV3VSLGlCQUczRCxPQUFPLElBQUlKLEVBQU0sQ0FBQ2pzQixHQUFTLENBQUN2WixLQUFNdEgsR0FDcEMsQ0FFQSxPQUFPNmdCLENBQ1QsQ0FFQSxNQUFNLElBQUk4YSxHQUFXLHdCQUEwQnoxQixFQUFVeTFCLEdBQVd1UixnQkFDdEUsQ0ErbkJ3QkMsQ0FBWTk3QixFQUFPQyxJQUFzQixTQUFqQmd2QixFQUF5QixDQUMvRHBrQixLQUFNN0ssRUFBTzRTLEtBQU81UyxFQUFPNFMsSUFBSS9ILE1BSW5DLENBRkUsTUFBTzVlLEdBQ1AsTUFBTXErQixHQUFXNzJCLEtBQUt4SCxFQUFLcStCLEdBQVdrSSxnQkFBaUJ4eUIsRUFDekQsQ0FZQSxNQVZxQixTQUFqQml2QixHQUNGcU0sRUFBZ0JBLEVBQWN4bkMsU0FBU3FtQyxHQUVsQ0EsR0FBeUMsU0FBckJBLElBQ3ZCbUIsRUFBZ0IvVCxHQUFNVyxTQUFTb1QsS0FFUCxXQUFqQnJNLElBQ1RxTSxFQUFnQjdXLEVBQXlCLFFBQUV3VCxTQUFTeGtDLEtBQUs2bkMsSUFHcERoSixHQUFPOVQsRUFBUytULEVBQVEsQ0FDN0JoOUIsS0FBTStsQyxFQUNON2hDLE9BQVEsSUFDUkMsV0FBWSxLQUNadkksUUFBUyxJQUFJNGdDLEdBQ2IveEIsVUFFSixDQUVBLElBQThDLElBQTFDazVCLEdBQW1CbnBCLFFBQVFsYixHQUM3QixPQUFPMDlCLEVBQU8sSUFBSWpJLEdBQ2hCLHdCQUEwQnoxQixFQUMxQnkxQixHQUFXa0ksZ0JBQ1h4eUIsSUFJSixNQUFNN08sRUFBVTRnQyxHQUFldCtCLEtBQUt1TSxFQUFPN08sU0FBU2UsWUFNcERmLEVBQVE0YyxJQUFJLGFBQWMsZUFBb0IsR0FFOUMsTUFBTWd1QixFQUFxQi83QixFQUFPKzdCLG1CQUM1QkMsRUFBbUJoOEIsRUFBT2c4QixpQkFDMUI3SCxFQUFVbjBCLEVBQU9tMEIsUUFDdkIsSUFBSThILEVBQ0FDLEVBR0osR0FBSTNVLEdBQU15QyxvQkFBb0J6MEIsR0FBTyxDQUNuQyxNQUFNNG1DLEVBQWVockMsRUFBUWk5QixlQUFlLCtCQUU1Qzc0QixFQUFPbWlDLEdBQW1CbmlDLEdBQU96QyxJQUMvQjNCLEVBQVE0YyxJQUFJamIsRUFBWSxHQUN2QixDQUNEMkksSUFBSyx1QkFDTHhJLFNBQVVrcEMsR0FBZ0JBLEVBQWEsU0FBTXRyQyxHQUdqRCxNQUFPLEdBQUkwMkIsR0FBTUMsV0FBV2p5QixJQUFTZ3lCLEdBQU0xTSxXQUFXdGxCLEVBQUszQyxhQUd6RCxHQUZBekIsRUFBUTRjLElBQUl4WSxFQUFLM0MsZUFFWnpCLEVBQVFpckMsbUJBQ1gsSUFDRSxNQUFNL3JDLFFBQW9CaTBCLEVBQXVCLFFBQUUrWCxVQUFVOW1DLEVBQUt0QixXQUFXN0UsS0FBS21HLEdBQ2xGb2YsT0FBT2lNLFNBQVN2d0IsSUFBZ0JBLEdBQWUsR0FBS2MsRUFBUW1yQyxpQkFBaUJqc0MsRUFHL0UsQ0FERSxNQUFPNHpCLEdBQ1QsT0FFRyxHQUFJc0QsR0FBTTVCLE9BQU9wd0IsR0FDdEJBLEVBQUs3SCxNQUFReUQsRUFBUW85QixlQUFlaDVCLEVBQUtVLE1BQVEsNEJBQ2pEOUUsRUFBUW1yQyxpQkFBaUIvbUMsRUFBSzdILE1BQVEsR0FDdEM2SCxFQUFPa3ZCLEVBQXlCLFFBQUV3VCxTQUFTeGtDLEtBQUtxakMsR0FBV3ZoQyxTQUN0RCxHQUFJQSxJQUFTZ3lCLEdBQU0zYyxTQUFTclYsR0FBTyxDQUN4QyxHQUFJakYsT0FBT0MsU0FBU2dGLFNBQWMsR0FBSWd5QixHQUFNcEMsY0FBYzV2QixHQUN4REEsRUFBT2pGLE9BQU9tRCxLQUFLLElBQUkreUIsV0FBV2p4QixRQUM3QixLQUFJZ3lCLEdBQU01TSxTQUFTcGxCLEdBR3hCLE9BQU9nOUIsRUFBTyxJQUFJakksR0FDaEIsb0ZBQ0FBLEdBQVdrSSxnQkFDWHh5QixJQUxGekssRUFBT2pGLE9BQU9tRCxLQUFLOEIsRUFBTSxRQU8zQixDQUtBLEdBRkFwRSxFQUFRbXJDLGlCQUFpQi9tQyxFQUFLeEksUUFBUSxHQUVsQ2lULEVBQU82TSxlQUFpQixHQUFLdFgsRUFBS3hJLE9BQVNpVCxFQUFPNk0sY0FDcEQsT0FBTzBsQixFQUFPLElBQUlqSSxHQUNoQiwrQ0FDQUEsR0FBV2tJLGdCQUNYeHlCLEdBR04sQ0FFQSxNQUFNeTNCLEVBQWdCbFEsR0FBTXFDLGVBQWV6NEIsRUFBUW9yQyxvQkEyQm5ELElBQUkvQyxFQWVBbnJDLEVBeENBazVCLEdBQU1oNkIsUUFBUTRtQyxJQUNoQjhILEVBQWdCOUgsRUFBUSxHQUN4QitILEVBQWtCL0gsRUFBUSxJQUUxQjhILEVBQWdCQyxFQUFrQi9ILEVBR2hDNStCLElBQVN5bUMsR0FBb0JDLEtBQzFCMVUsR0FBTTNjLFNBQVNyVixLQUNsQkEsRUFBT2t2QixFQUF5QixRQUFFd1QsU0FBU3hrQyxLQUFLOEIsRUFBTSxDQUFDaW5DLFlBQVksS0FHckVqbkMsRUFBT2t2QixFQUF5QixRQUFFZ1ksU0FBUyxDQUFDbG5DLEVBQU0sSUFBSXFoQyxHQUF1QixDQUMzRTdwQyxPQUFRMHFDLEVBQ1J0RCxRQUFTNU0sR0FBTXFDLGVBQWVxUyxNQUMzQjFVLEdBQU1wTyxNQUVYNmlCLEdBQW9Cem1DLEVBQUtuRSxHQUFHLFlBQVlzckMsSUFDdENWLEVBQWlCdHdDLE9BQU84SyxPQUFPa21DLEVBQVUsQ0FDdkNDLFFBQVEsSUFDUCxLQU1IMzhCLEVBQU93NUIsT0FHVEEsR0FGaUJ4NUIsRUFBT3c1QixLQUFLdDVCLFVBQVksSUFFdkIsS0FEREYsRUFBT3c1QixLQUFLQyxVQUFZLE1BSXRDRCxHQUFReGUsRUFBTzlhLFdBR2xCczVCLEVBRm9CeGUsRUFBTzlhLFNBRU4sSUFERDhhLEVBQU95ZSxVQUk3QkQsR0FBUXJvQyxFQUFRK0gsT0FBTyxpQkFJdkIsSUFDRTdLLEVBQU8rOUIsR0FDTHBSLEVBQU90bUIsU0FBV3NtQixFQUFPTyxPQUN6QnZiLEVBQU8zTCxPQUNQMkwsRUFBTzQ4QixrQkFDUHpxQyxRQUFRLE1BQU8sR0FPbkIsQ0FORSxNQUFPbEcsR0FDUCxNQUFNNHdDLEVBQVksSUFBSS9zQyxNQUFNN0QsRUFBSTBOLFNBSWhDLE9BSEFrakMsRUFBVTc4QixPQUFTQSxFQUNuQjY4QixFQUFVNThCLElBQU1ELEVBQU9DLElBQ3ZCNDhCLEVBQVVDLFFBQVMsRUFDWnZLLEVBQU9zSyxFQUNoQixDQUVBMXJDLEVBQVE0YyxJQUNOLGtCQUNBLDJCQUE2QjhxQixHQUFvQixPQUFTLEtBQUssR0FHakUsTUFBTTlwQyxFQUFVLENBQ2RWLE9BQ0FtRyxPQUFRQSxFQUNSckQsUUFBU0EsRUFBUW81QixTQUNqQnZOLE9BQVEsQ0FBRTF1QixLQUFNMFIsRUFBTys4QixVQUFXeHVDLE1BQU95UixFQUFPZzlCLFlBQ2hEeEQsT0FDQTNrQyxXQUNBaWxDLFNBQ0FqYyxlQUFnQnNiLEdBQ2hCQyxnQkFBaUIsQ0FBQyxHQWNwQixJQUFJNkQsR0FWSDFWLEdBQU1yQyxZQUFZMXlCLEtBQVl6RCxFQUFReUQsT0FBU0EsR0FFNUN3TixFQUFPazlCLFdBQ1RudUMsRUFBUW11QyxXQUFhbDlCLEVBQU9rOUIsWUFFNUJudUMsRUFBUTZGLFNBQVdvbUIsRUFBT3BtQixTQUMxQjdGLEVBQVEwRixLQUFPdW1CLEVBQU92bUIsS0FDdEI0a0MsR0FBU3RxQyxFQUFTaVIsRUFBTzhNLE1BQU9qWSxFQUFXLEtBQU9tbUIsRUFBT3BtQixVQUFZb21CLEVBQU92bUIsS0FBTyxJQUFNdW1CLEVBQU92bUIsS0FBTyxJQUFNMUYsRUFBUVYsT0FJdkgsTUFBTTh1QyxFQUFpQmxFLEdBQVF2dkIsS0FBSzNhLEVBQVE4RixVQWlNNUMsR0FoTUE5RixFQUFRa3VCLE1BQVFrZ0IsRUFBaUJuOUIsRUFBT2c5QixXQUFhaDlCLEVBQU8rOEIsVUFDeEQvOEIsRUFBT2k5QixVQUNUQSxFQUFZajlCLEVBQU9pOUIsVUFDYyxJQUF4Qmo5QixFQUFPb2EsYUFDaEI2aUIsRUFBWUUsRUFBaUI5WSxFQUF3QixRQUFJRCxFQUF1QixTQUU1RXBrQixFQUFPb2EsZUFDVHJyQixFQUFRcXJCLGFBQWVwYSxFQUFPb2EsY0FFNUJwYSxFQUFPNmQsaUJBQ1Q5dUIsRUFBUXFxQyxnQkFBZ0JwNUIsT0FBU0EsRUFBTzZkLGdCQUUxQ29mLEVBQVlFLEVBQWlCbkUsR0FBY0QsSUFHekMvNEIsRUFBTzZNLGVBQWlCLEVBQzFCOWQsRUFBUThkLGNBQWdCN00sRUFBTzZNLGNBRy9COWQsRUFBUThkLGNBQWdCOWIsSUFHdEJpUCxFQUFPbzlCLHFCQUNUcnVDLEVBQVFxdUMsbUJBQXFCcDlCLEVBQU9vOUIsb0JBSXRDcmYsRUFBTWtmLEVBQVUzb0MsUUFBUXZGLEdBQVMsU0FBd0J5SixHQUN2RCxHQUFJdWxCLEVBQUkyWCxVQUFXLE9BRW5CLE1BQU0ySCxFQUFVLENBQUM3a0MsR0FFWDhrQyxHQUFrQjlrQyxFQUFJckgsUUFBUSxrQkFFcEMsR0FBSTRxQyxFQUFvQixDQUN0QixNQUFNd0IsRUFBa0IsSUFBSTNHLEdBQXVCLENBQ2pEN3BDLE9BQVF3NkIsR0FBTXFDLGVBQWUwVCxHQUM3Qm5KLFFBQVM1TSxHQUFNcUMsZUFBZXNTLEtBR2hDSCxHQUFzQndCLEVBQWdCbnNDLEdBQUcsWUFBWXNyQyxJQUNuRFgsRUFBbUJyd0MsT0FBTzhLLE9BQU9rbUMsRUFBVSxDQUN6Q2MsVUFBVSxJQUNULElBR0xILEVBQVExc0MsS0FBSzRzQyxFQUNmLENBR0EsSUFBSUUsRUFBaUJqbEMsRUFHckIsTUFBTWtsQyxFQUFjbGxDLEVBQUl1bEIsS0FBT0EsRUFHL0IsSUFBMEIsSUFBdEIvZCxFQUFPMjlCLFlBQXdCbmxDLEVBQUlySCxRQUFRLG9CQU83QyxPQUplLFNBQVhxRCxHQUF3QyxNQUFuQmdFLEVBQUkra0IsbUJBQ3BCL2tCLEVBQUlySCxRQUFRLHFCQUdacUgsRUFBSXJILFFBQVEscUJBQXVCLElBQUk0QixlQUVoRCxJQUFLLE9BQ0wsSUFBSyxTQUNMLElBQUssV0FDTCxJQUFLLGFBRUhzcUMsRUFBUTFzQyxLQUFLNnpCLEVBQXVCLFFBQUVvWixZQUFZdEYsWUFHM0M5L0IsRUFBSXJILFFBQVEsb0JBQ25CLE1BQ0YsSUFBSyxVQUNIa3NDLEVBQVExc0MsS0FBSyxJQUFJeW5DLElBR2pCaUYsRUFBUTFzQyxLQUFLNnpCLEVBQXVCLFFBQUVvWixZQUFZdEYsWUFHM0M5L0IsRUFBSXJILFFBQVEsb0JBQ25CLE1BQ0YsSUFBSyxLQUNDMG5DLEtBQ0Z3RSxFQUFRMXNDLEtBQUs2ekIsRUFBdUIsUUFBRXNVLHVCQUF1QkgsWUFDdERuZ0MsRUFBSXJILFFBQVEscUJBS3pCc3NDLEVBQWlCSixFQUFRdHdDLE9BQVMsRUFBSTAzQixFQUF5QixRQUFFZ1ksU0FBU1ksRUFBUzlWLEdBQU1wTyxNQUFRa2tCLEVBQVEsR0FFekcsTUFBTVEsRUFBZXBaLEVBQXlCLFFBQUVuSCxTQUFTbWdCLEdBQWdCLEtBQ3ZFSSxJQUNBakQsR0FBWSxJQUdSdnBDLEVBQVcsQ0FDZm9JLE9BQVFqQixFQUFJK2tCLFdBQ1o3akIsV0FBWWxCLEVBQUlzbEMsY0FDaEIzc0MsUUFBUyxJQUFJNGdDLEdBQWV2NUIsRUFBSXJILFNBQ2hDNk8sU0FDQTFMLFFBQVNvcEMsR0FHWCxHQUFxQixXQUFqQnpPLEVBQ0Y1OUIsRUFBU2tFLEtBQU9rb0MsRUFDaEJuTCxHQUFPOVQsRUFBUytULEVBQVFsaEMsT0FDbkIsQ0FDTCxNQUFNMHNDLEVBQWlCLEdBQ3ZCLElBQUlDLEVBQXFCLEVBRXpCUCxFQUFlcnNDLEdBQUcsUUFBUSxTQUEwQjJrQyxHQUNsRGdJLEVBQWVwdEMsS0FBS29sQyxHQUNwQmlJLEdBQXNCakksRUFBTWhwQyxPQUd4QmlULEVBQU9zdkIsa0JBQW9CLEdBQUswTyxFQUFxQmgrQixFQUFPc3ZCLG1CQUU5RHRDLEdBQVcsRUFDWHlRLEVBQWV4a0MsVUFDZnM1QixFQUFPLElBQUlqSSxHQUFXLDRCQUE4QnRxQixFQUFPc3ZCLGlCQUFtQixZQUM1RWhGLEdBQVc2RSxpQkFBa0JudkIsRUFBUTA5QixJQUUzQyxJQUVBRCxFQUFlcnNDLEdBQUcsV0FBVyxXQUMzQixHQUFJNDdCLEVBQ0YsT0FHRixNQUFNL2dDLEVBQU0sSUFBSXErQixHQUNkLDRCQUE4QnRxQixFQUFPc3ZCLGlCQUFtQixZQUN4RGhGLEdBQVc2RSxpQkFDWG52QixFQUNBMDlCLEdBRUZELEVBQWV4a0MsUUFBUWhOLEdBQ3ZCc21DLEVBQU90bUMsRUFDVCxJQUVBd3hDLEVBQWVyc0MsR0FBRyxTQUFTLFNBQTJCbkYsR0FDaEQ4eEIsRUFBSTJYLFdBQ1JuRCxFQUFPakksR0FBVzcyQixLQUFLeEgsRUFBSyxLQUFNK1QsRUFBUTA5QixHQUM1QyxJQUVBRCxFQUFlcnNDLEdBQUcsT0FBTyxXQUN2QixJQUNFLElBQUk2c0MsRUFBeUMsSUFBMUJGLEVBQWVoeEMsT0FBZWd4QyxFQUFlLEdBQUt6dEMsT0FBT3VCLE9BQU9rc0MsR0FDOUQsZ0JBQWpCOU8sSUFDRmdQLEVBQWVBLEVBQWFucUMsU0FBU3FtQyxHQUNoQ0EsR0FBeUMsU0FBckJBLElBQ3ZCOEQsRUFBZTFXLEdBQU1XLFNBQVMrVixLQUdsQzVzQyxFQUFTa0UsS0FBTzBvQyxDQUdsQixDQUZFLE1BQU9oeUMsR0FDUCxPQUFPc21DLEVBQU9qSSxHQUFXNzJCLEtBQUt4SCxFQUFLLEtBQU0rVCxFQUFRM08sRUFBU2lELFFBQVNqRCxHQUNyRSxDQUNBaWhDLEdBQU85VCxFQUFTK1QsRUFBUWxoQyxFQUMxQixHQUNGLENBRUFzcEMsRUFBUTlkLEtBQUssU0FBUzV3QixJQUNmd3hDLEVBQWUvSCxZQUNsQitILEVBQWV0b0MsS0FBSyxRQUFTbEosR0FDN0J3eEMsRUFBZXhrQyxVQUNqQixHQUVKLElBRUEwaEMsRUFBUTlkLEtBQUssU0FBUzV3QixJQUNwQnNtQyxFQUFPdG1DLEdBQ1A4eEIsRUFBSTlrQixRQUFRaE4sRUFBSSxJQUlsQjh4QixFQUFJM3NCLEdBQUcsU0FBUyxTQUE0Qm5GLEdBRzFDc21DLEVBQU9qSSxHQUFXNzJCLEtBQUt4SCxFQUFLLEtBQU0rVCxFQUFRK2QsR0FDNUMsSUFHQUEsRUFBSTNzQixHQUFHLFVBQVUsU0FBNkJtckIsR0FFNUNBLEVBQU8yaEIsY0FBYSxFQUFNLElBQzVCLElBR0lsK0IsRUFBTzBNLFFBQVMsQ0FFbEIsTUFBTUEsRUFBVThHLFNBQVN4VCxFQUFPME0sUUFBUyxJQUV6QyxHQUFJaUksT0FBT3dwQixNQUFNenhCLEdBUWYsWUFQQTZsQixFQUFPLElBQUlqSSxHQUNULGdEQUNBQSxHQUFXOFQscUJBQ1hwK0IsRUFDQStkLElBV0pBLEVBQUl4eEIsV0FBV21nQixHQUFTLFdBQ3RCLEdBQUkwdEIsRUFBUSxPQUNaLElBQUlpRSxFQUFzQnIrQixFQUFPME0sUUFBVSxjQUFnQjFNLEVBQU8wTSxRQUFVLGNBQWdCLG1CQUM1RixNQUFNdWhCLEVBQWVqdUIsRUFBT2l1QixjQUFnQlosR0FDeENydEIsRUFBT3ErQixzQkFDVEEsRUFBc0JyK0IsRUFBT3ErQixxQkFFL0I5TCxFQUFPLElBQUlqSSxHQUNUK1QsRUFDQXBRLEVBQWFULG9CQUFzQmxELEdBQVdnVSxVQUFZaFUsR0FBV2lVLGFBQ3JFditCLEVBQ0ErZCxJQUVGdHhCLEdBQ0YsR0FDRixDQUlBLEdBQUk4NkIsR0FBTTNjLFNBQVNyVixHQUFPLENBQ3hCLElBQUlpcEMsR0FBUSxFQUNSQyxHQUFVLEVBRWRscEMsRUFBS25FLEdBQUcsT0FBTyxLQUNib3RDLEdBQVEsQ0FBSSxJQUdkanBDLEVBQUtzbkIsS0FBSyxTQUFTNXdCLElBQ2pCd3lDLEdBQVUsRUFDVjFnQixFQUFJOWtCLFFBQVFoTixFQUFJLElBR2xCc0osRUFBS25FLEdBQUcsU0FBUyxLQUNWb3RDLEdBQVVDLEdBQ2JoeUMsRUFBTSxJQUFJMmxDLEdBQWMsa0NBQW1DcHlCLEVBQVErZCxHQUNyRSxJQUdGeG9CLEVBQUtSLEtBQUtncEIsRUFDWixNQUNFQSxFQUFJanRCLElBQUl5RSxFQUVaLEVBemlCTyxJQUFJbXBDLFNBQVEsQ0FBQ2xnQixFQUFTK1QsS0FDM0IsSUFBSTJILEVBQ0FFLEVBRUosTUFBTXBSLEVBQU8sQ0FBQ3I1QixFQUFPc3JDLEtBQ2ZiLElBQ0pBLEdBQVMsRUFDVEYsR0FBVUEsRUFBT3ZxQyxFQUFPc3JDLEdBQVcsRUFRL0IwRCxFQUFXMTNCLElBQ2YraEIsRUFBSy9oQixHQUFRLEdBQ2JzckIsRUFBT3RyQixFQUFPLEVBR2hCZ3pCLEdBVmtCdHFDLElBQ2hCcTVCLEVBQUtyNUIsR0FDTDZ1QixFQUFRN3VCLEVBQU0sR0FRUWd2QyxHQUFVQyxHQUFtQjFFLEVBQVMwRSxJQUFnQnZVLE1BQU1zVSxFQUFRLElBckI5RSxJQUFDMUUsQ0EyaUJuQixFQUVNNEUsR0FBVXZjLEdBQVN3YyxxQkFJZCxDQUNMeHRCLE1BQU8sU0FBZWxmLEVBQU16QyxFQUFPb3ZDLEVBQVMxd0MsRUFBTTJKLEVBQVFnbkMsR0FDeEQsTUFBTUMsRUFBUyxHQUNmQSxFQUFPdHVDLEtBQUt5QixFQUFPLElBQU11VSxtQkFBbUJoWCxJQUV4QzQzQixHQUFNbkMsU0FBUzJaLElBQ2pCRSxFQUFPdHVDLEtBQUssV0FBYSxJQUFJZ0wsS0FBS29qQyxHQUFTRyxlQUd6QzNYLEdBQU01TSxTQUFTdHNCLElBQ2pCNHdDLEVBQU90dUMsS0FBSyxRQUFVdEMsR0FHcEJrNUIsR0FBTTVNLFNBQVMzaUIsSUFDakJpbkMsRUFBT3R1QyxLQUFLLFVBQVlxSCxJQUdYLElBQVhnbkMsR0FDRkMsRUFBT3R1QyxLQUFLLFVBR2RzaUIsU0FBU2dzQixPQUFTQSxFQUFPbHRDLEtBQUssS0FDaEMsRUFFQW90QyxLQUFNLFNBQWMvc0MsR0FDbEIsTUFBTStmLEVBQVFjLFNBQVNnc0IsT0FBTzlzQixNQUFNLElBQUlzQixPQUFPLGFBQWVyaEIsRUFBTyxjQUNyRSxPQUFRK2YsRUFBUXlwQixtQkFBbUJ6cEIsRUFBTSxJQUFNLElBQ2pELEVBRUFpdEIsT0FBUSxTQUFnQmh0QyxHQUN0QmxILEtBQUtvbUIsTUFBTWxmLEVBQU0sR0FBSXVKLEtBQUsrM0IsTUFBUSxNQUNwQyxHQU1LLENBQ0xwaUIsTUFBTyxXQUFrQixFQUN6QjZ0QixLQUFNLFdBQWtCLE9BQU8sSUFBTSxFQUNyQ0MsT0FBUSxXQUFtQixHQUkzQkMsR0FBa0IvYyxHQUFTd2MscUJBSS9CLFdBQ0UsTUFBTVEsRUFBTyxrQkFBa0I1MUIsS0FBS3FKLFVBQVVDLFdBQ3hDdXNCLEVBQWlCdHNCLFNBQVN1c0IsY0FBYyxLQUM5QyxJQUFJQyxFQVFKLFNBQVNDLEVBQVd6L0IsR0FDbEIsSUFBSWliLEVBQU9qYixFQVdYLE9BVElxL0IsSUFFRkMsRUFBZUksYUFBYSxPQUFRemtCLEdBQ3BDQSxFQUFPcWtCLEVBQWVya0IsTUFHeEJxa0IsRUFBZUksYUFBYSxPQUFRemtCLEdBRzdCLENBQ0xBLEtBQU1xa0IsRUFBZXJrQixLQUNyQnJtQixTQUFVMHFDLEVBQWUxcUMsU0FBVzBxQyxFQUFlMXFDLFNBQVMxQyxRQUFRLEtBQU0sSUFBTSxHQUNoRndDLEtBQU00cUMsRUFBZTVxQyxLQUNyQjRtQixPQUFRZ2tCLEVBQWVoa0IsT0FBU2drQixFQUFlaGtCLE9BQU9wcEIsUUFBUSxNQUFPLElBQU0sR0FDM0U2akIsS0FBTXVwQixFQUFldnBCLEtBQU91cEIsRUFBZXZwQixLQUFLN2pCLFFBQVEsS0FBTSxJQUFNLEdBQ3BFeUMsU0FBVTJxQyxFQUFlM3FDLFNBQ3pCSCxLQUFNOHFDLEVBQWU5cUMsS0FDckJDLFNBQWlELE1BQXRDNnFDLEVBQWU3cUMsU0FBU2tiLE9BQU8sR0FDeEMydkIsRUFBZTdxQyxTQUNmLElBQU02cUMsRUFBZTdxQyxTQUUzQixDQVVBLE9BUkErcUMsRUFBWUMsRUFBV3p3QixPQUFPd08sU0FBU3ZDLE1BUWhDLFNBQXlCMGtCLEdBQzlCLE1BQU01a0IsRUFBVXVNLEdBQU01TSxTQUFTaWxCLEdBQWVGLEVBQVdFLEdBQWNBLEVBQ3ZFLE9BQVE1a0IsRUFBT25tQixXQUFhNHFDLEVBQVU1cUMsVUFDbENtbUIsRUFBT3JtQixPQUFTOHFDLEVBQVU5cUMsSUFDaEMsQ0FDRCxDQWxERCxHQXNEUyxXQUNMLE9BQU8sQ0FDVCxFQUdKLFNBQVNrckMsR0FBcUJDLEVBQVVDLEdBQ3RDLElBQUloTCxFQUFnQixFQUNwQixNQUFNRCxFQUFlNUIsR0FBWSxHQUFJLEtBRXJDLE9BQU9qUCxJQUNMLE1BQU0rYixFQUFTL2IsRUFBRStiLE9BQ1hyM0IsRUFBUXNiLEVBQUVnYyxpQkFBbUJoYyxFQUFFdGIsV0FBUTlYLEVBQ3ZDNGtDLEVBQWdCdUssRUFBU2pMLEVBQ3pCWSxFQUFPYixFQUFhVyxHQUcxQlYsRUFBZ0JpTCxFQUVoQixNQUFNenFDLEVBQU8sQ0FDWHlxQyxTQUNBcjNCLFFBQ0ErekIsU0FBVS96QixFQUFTcTNCLEVBQVNyM0IsT0FBUzlYLEVBQ3JDdWlDLE1BQU9xQyxFQUNQRSxLQUFNQSxRQUFjOWtDLEVBQ3BCcXZDLFVBQVd2SyxHQUFRaHRCLEdBVkxxM0IsR0FBVXIzQixHQVVlQSxFQUFRcTNCLEdBQVVySyxPQUFPOWtDLEVBQ2hFMG5CLE1BQU8wTCxHQUdUMXVCLEVBQUt3cUMsRUFBbUIsV0FBYSxXQUFZLEVBRWpERCxFQUFTdnFDLEVBQUssQ0FFbEIsQ0FFQSxNQXNOTTRxQyxHQUFnQixDQUNwQjd4QyxLQUFNMHJDLEdBQ05vRyxJQXhOc0Qsb0JBQW5CQyxnQkFFTyxTQUFVcmdDLEdBQ3BELE9BQU8sSUFBSTArQixTQUFRLFNBQTRCbGdCLEVBQVMrVCxHQUN0RCxJQUFJK04sRUFBY3RnQyxFQUFPekssS0FDekIsTUFBTXlYLEVBQWlCK2tCLEdBQWV0K0IsS0FBS3VNLEVBQU83TyxTQUFTZSxZQUNyRCs4QixFQUFlanZCLEVBQU9pdkIsYUFDNUIsSUFBSXNSLEVBV0E3dUMsRUFWSixTQUFTczNCLElBQ0hocEIsRUFBTzY2QixhQUNUNzZCLEVBQU82NkIsWUFBWXQwQixZQUFZZzZCLEdBRzdCdmdDLEVBQU84NkIsUUFDVDk2QixFQUFPODZCLE9BQU9DLG9CQUFvQixRQUFTd0YsRUFFL0MsQ0FJSWhaLEdBQU1DLFdBQVc4WSxLQUNmaGUsR0FBU3djLHNCQUF3QnhjLEdBQVNrZSw4QkFDNUN4ekIsRUFBZXVoQixnQkFBZSxHQUNyQnZoQixFQUFlb2hCLGVBQWUsNEJBRS9CN0csR0FBTTVNLFNBQVNqcEIsRUFBY3NiLEVBQWVvaEIsbUJBRXBEcGhCLEVBQWV1aEIsZUFBZTc4QixFQUFZUyxRQUFRLCtCQUFnQyxPQUhsRjZhLEVBQWV1aEIsZUFBZSx3QkFPbEMsSUFBSWo2QixFQUFVLElBQUkrckMsZUFHbEIsR0FBSXJnQyxFQUFPdzVCLEtBQU0sQ0FDZixNQUFNdDVCLEVBQVdGLEVBQU93NUIsS0FBS3Q1QixVQUFZLEdBQ25DdTVCLEVBQVd6NUIsRUFBT3c1QixLQUFLQyxTQUFXZ0gsU0FBUzk1QixtQkFBbUIzRyxFQUFPdzVCLEtBQUtDLFdBQWEsR0FDN0Z6c0IsRUFBZWUsSUFBSSxnQkFBaUIsU0FBVzJ5QixLQUFLeGdDLEVBQVcsSUFBTXU1QixHQUN2RSxDQUVBLE1BQU00QixFQUFXNUksR0FBY3p5QixFQUFPMHlCLFFBQVMxeUIsRUFBT0MsS0FPdEQsU0FBUzBnQyxJQUNQLElBQUtyc0MsRUFDSCxPQUdGLE1BQU1zc0MsRUFBa0I3TyxHQUFldCtCLEtBQ3JDLDBCQUEyQmEsR0FBV0EsRUFBUXVzQyx5QkFhaER2TyxJQUFPLFNBQWtCM2lDLEdBQ3ZCNnVCLEVBQVE3dUIsR0FDUnE1QixHQUNGLElBQUcsU0FBaUIvOEIsR0FDbEJzbUMsRUFBT3RtQyxHQUNQKzhCLEdBQ0YsR0FmaUIsQ0FDZnp6QixLQUhvQjA1QixHQUFpQyxTQUFqQkEsR0FBNEMsU0FBakJBLEVBQ3hDMzZCLEVBQVFqRCxTQUEvQmlELEVBQVF3c0MsYUFHUnJuQyxPQUFRbkYsRUFBUW1GLE9BQ2hCQyxXQUFZcEYsRUFBUW9GLFdBQ3BCdkksUUFBU3l2QyxFQUNUNWdDLFNBQ0ExTCxZQVlGQSxFQUFVLElBQ1osQ0FtRUEsR0FyR0FBLEVBQVF5c0MsS0FBSy9nQyxFQUFPeEwsT0FBTzBpQixjQUFla1YsR0FBU2lQLEVBQVVyN0IsRUFBTzNMLE9BQVEyTCxFQUFPNDhCLG1CQUFtQixHQUd0R3RvQyxFQUFRb1ksUUFBVTFNLEVBQU8wTSxRQWlDckIsY0FBZXBZLEVBRWpCQSxFQUFRcXNDLFVBQVlBLEVBR3BCcnNDLEVBQVEwc0MsbUJBQXFCLFdBQ3RCMXNDLEdBQWtDLElBQXZCQSxFQUFRMnNDLGFBUUQsSUFBbkIzc0MsRUFBUW1GLFFBQWtCbkYsRUFBUTRzQyxhQUF3RCxJQUF6QzVzQyxFQUFRNHNDLFlBQVlueEIsUUFBUSxXQUtqRnhqQixXQUFXbzBDLEVBQ2IsRUFJRnJzQyxFQUFRNnNDLFFBQVUsV0FDWDdzQyxJQUlMaStCLEVBQU8sSUFBSWpJLEdBQVcsa0JBQW1CQSxHQUFXaVUsYUFBY3YrQixFQUFRMUwsSUFHMUVBLEVBQVUsS0FDWixFQUdBQSxFQUFROHNDLFFBQVUsV0FHaEI3TyxFQUFPLElBQUlqSSxHQUFXLGdCQUFpQkEsR0FBVytXLFlBQWFyaEMsRUFBUTFMLElBR3ZFQSxFQUFVLElBQ1osRUFHQUEsRUFBUWd0QyxVQUFZLFdBQ2xCLElBQUlqRCxFQUFzQnIrQixFQUFPME0sUUFBVSxjQUFnQjFNLEVBQU8wTSxRQUFVLGNBQWdCLG1CQUM1RixNQUFNdWhCLEVBQWVqdUIsRUFBT2l1QixjQUFnQlosR0FDeENydEIsRUFBT3ErQixzQkFDVEEsRUFBc0JyK0IsRUFBT3ErQixxQkFFL0I5TCxFQUFPLElBQUlqSSxHQUNUK1QsRUFDQXBRLEVBQWFULG9CQUFzQmxELEdBQVdnVSxVQUFZaFUsR0FBV2lVLGFBQ3JFditCLEVBQ0ExTCxJQUdGQSxFQUFVLElBQ1osRUFLSWd1QixHQUFTd2MscUJBQXNCLENBR2pDLE1BQU15QyxFQUFZbEMsR0FBZ0JoRSxJQUFhcjdCLEVBQU9vdkIsZ0JBQWtCeVAsR0FBUU0sS0FBS24vQixFQUFPb3ZCLGdCQUV4Rm1TLEdBQ0Z2MEIsRUFBZWUsSUFBSS9OLEVBQU9xdkIsZUFBZ0JrUyxFQUU5QyxNQUdnQjF3QyxJQUFoQnl2QyxHQUE2QnR6QixFQUFldWhCLGVBQWUsTUFHdkQscUJBQXNCajZCLEdBQ3hCaXpCLEdBQU0zN0IsUUFBUW9oQixFQUFldWQsVUFBVSxTQUEwQnJWLEVBQUszcEIsR0FDcEUrSSxFQUFRa3RDLGlCQUFpQmoyQyxFQUFLMnBCLEVBQ2hDLElBSUdxUyxHQUFNckMsWUFBWWxsQixFQUFPeWhDLG1CQUM1Qm50QyxFQUFRbXRDLGtCQUFvQnpoQyxFQUFPeWhDLGlCQUlqQ3hTLEdBQWlDLFNBQWpCQSxJQUNsQjM2QixFQUFRMjZCLGFBQWVqdkIsRUFBT2l2QixjQUlTLG1CQUE5Qmp2QixFQUFPKzdCLG9CQUNoQnpuQyxFQUFROG1DLGlCQUFpQixXQUFZeUUsR0FBcUI3L0IsRUFBTys3QixvQkFBb0IsSUFJaEQsbUJBQTVCLzdCLEVBQU9nOEIsa0JBQW1DMW5DLEVBQVFxb0MsUUFDM0Ryb0MsRUFBUXFvQyxPQUFPdkIsaUJBQWlCLFdBQVl5RSxHQUFxQjcvQixFQUFPZzhCLG9CQUd0RWg4QixFQUFPNjZCLGFBQWU3NkIsRUFBTzg2QixVQUcvQnlGLEVBQWFtQixJQUNOcHRDLElBR0xpK0IsR0FBUW1QLEdBQVVBLEVBQU96ckMsS0FBTyxJQUFJbThCLEdBQWMsS0FBTXB5QixFQUFRMUwsR0FBV290QyxHQUMzRXB0QyxFQUFRN0gsUUFDUjZILEVBQVUsS0FBSSxFQUdoQjBMLEVBQU82NkIsYUFBZTc2QixFQUFPNjZCLFlBQVlLLFVBQVVxRixHQUMvQ3ZnQyxFQUFPODZCLFNBQ1Q5NkIsRUFBTzg2QixPQUFPSyxRQUFVb0YsSUFBZXZnQyxFQUFPODZCLE9BQU9NLGlCQUFpQixRQUFTbUYsS0FJbkYsTUFBTTFyQyxFQUFXbStCLEdBQWNxSSxHQUUzQnhtQyxJQUFzRCxJQUExQ3l0QixHQUFTbkksVUFBVXBLLFFBQVFsYixHQUN6QzA5QixFQUFPLElBQUlqSSxHQUFXLHdCQUEwQnoxQixFQUFXLElBQUt5MUIsR0FBV2tJLGdCQUFpQnh5QixJQU05RjFMLEVBQVFxdEMsS0FBS3JCLEdBQWUsS0FDOUIsR0FDRixHQU9BL1ksR0FBTTM3QixRQUFRdTBDLElBQWUsQ0FBQ2gwQyxFQUFJd0QsS0FDaEMsR0FBSXhELEVBQUksQ0FDTixJQUNFVCxPQUFPbWpCLGVBQWUxaUIsRUFBSSxPQUFRLENBQUN3RCxTQUdyQyxDQUZFLE1BQU9zMEIsR0FFVCxDQUNBdjRCLE9BQU9takIsZUFBZTFpQixFQUFJLGNBQWUsQ0FBQ3dELFNBQzVDLEtBR0YsTUFBTWl5QyxHQUFnQjM2QixHQUFXLEtBQUtBLElBRWhDNDZCLEdBQW9CM1QsR0FBWTNHLEdBQU0xTSxXQUFXcVQsSUFBd0IsT0FBWkEsSUFBZ0MsSUFBWkEsRUFFakY0VCxHQUNTQSxJQUNYQSxFQUFXdmEsR0FBTWg2QixRQUFRdTBDLEdBQVlBLEVBQVcsQ0FBQ0EsR0FFakQsTUFBTSxPQUFDLzBDLEdBQVUrMEMsRUFDakIsSUFBSUMsRUFDQTdULEVBRUosTUFBTThULEVBQWtCLENBQUMsRUFFekIsSUFBSyxJQUFJenVDLEVBQUksRUFBR0EsRUFBSXhHLEVBQVF3RyxJQUFLLENBRS9CLElBQUkwSixFQUlKLEdBTEE4a0MsRUFBZ0JELEVBQVN2dUMsR0FHekIyNkIsRUFBVTZULEdBRUxGLEdBQWlCRSxLQUNwQjdULEVBQVVpUyxJQUFlbGpDLEVBQUtxUyxPQUFPeXlCLElBQWdCaHZDLG9CQUVyQ2xDLElBQVpxOUIsR0FDRixNQUFNLElBQUk1RCxHQUFXLG9CQUFvQnJ0QixNQUk3QyxHQUFJaXhCLEVBQ0YsTUFHRjhULEVBQWdCL2tDLEdBQU0sSUFBTTFKLEdBQUsyNkIsQ0FDbkMsQ0FFQSxJQUFLQSxFQUFTLENBRVosTUFBTStULEVBQVV2MkMsT0FBT3FZLFFBQVFpK0IsR0FDNUJucUMsS0FBSSxFQUFFb0YsRUFBSXhSLEtBQVcsV0FBV3dSLE9BQ3BCLElBQVZ4UixFQUFrQixzQ0FBd0MsbUNBTy9ELE1BQU0sSUFBSTYrQixHQUNSLHlEQUxNdjlCLEVBQ0xrMUMsRUFBUWwxQyxPQUFTLEVBQUksWUFBY2sxQyxFQUFRcHFDLElBQUkrcEMsSUFBYzd2QyxLQUFLLE1BQVEsSUFBTTZ2QyxHQUFhSyxFQUFRLElBQ3RHLDJCQUlBLGtCQUVKLENBRUEsT0FBTy9ULENBQU8sRUFZbEIsU0FBU2dVLEdBQTZCbGlDLEdBS3BDLEdBSklBLEVBQU82NkIsYUFDVDc2QixFQUFPNjZCLFlBQVlzSCxtQkFHakJuaUMsRUFBTzg2QixRQUFVOTZCLEVBQU84NkIsT0FBT0ssUUFDakMsTUFBTSxJQUFJL0ksR0FBYyxLQUFNcHlCLEVBRWxDLENBU0EsU0FBU29pQyxHQUFnQnBpQyxHQUN2QmtpQyxHQUE2QmxpQyxHQUU3QkEsRUFBTzdPLFFBQVU0Z0MsR0FBZXQrQixLQUFLdU0sRUFBTzdPLFNBRzVDNk8sRUFBT3pLLEtBQU95OEIsR0FBYzVpQyxLQUMxQjRRLEVBQ0FBLEVBQU9tdUIsbUJBR2dELElBQXJELENBQUMsT0FBUSxNQUFPLFNBQVNwZSxRQUFRL1AsRUFBT3hMLFNBQzFDd0wsRUFBTzdPLFFBQVFvOUIsZUFBZSxxQ0FBcUMsR0FLckUsT0FGZ0J1VCxHQUFvQjloQyxFQUFPa3VCLFNBQVd1QixHQUFXdkIsUUFFMURBLENBQVFsdUIsR0FBUXpILE1BQUssU0FBNkJsSCxHQVl2RCxPQVhBNndDLEdBQTZCbGlDLEdBRzdCM08sRUFBU2tFLEtBQU95OEIsR0FBYzVpQyxLQUM1QjRRLEVBQ0FBLEVBQU8rdUIsa0JBQ1AxOUIsR0FHRkEsRUFBU0YsUUFBVTRnQyxHQUFldCtCLEtBQUtwQyxFQUFTRixTQUV6Q0UsQ0FDVCxJQUFHLFNBQTRCNFYsR0FlN0IsT0FkS2lyQixHQUFTanJCLEtBQ1ppN0IsR0FBNkJsaUMsR0FHekJpSCxHQUFVQSxFQUFPNVYsV0FDbkI0VixFQUFPNVYsU0FBU2tFLEtBQU95OEIsR0FBYzVpQyxLQUNuQzRRLEVBQ0FBLEVBQU8rdUIsa0JBQ1A5bkIsRUFBTzVWLFVBRVQ0VixFQUFPNVYsU0FBU0YsUUFBVTRnQyxHQUFldCtCLEtBQUt3VCxFQUFPNVYsU0FBU0YsV0FJM0R1dEMsUUFBUW5NLE9BQU90ckIsRUFDeEIsR0FDRixDQUVBLE1BQU1vN0IsR0FBbUJ0ZCxHQUFVQSxhQUFpQmdOLEdBQWlCaE4sRUFBTXdGLFNBQVd4RixFQVd0RixTQUFTdWQsR0FBWUMsRUFBU0MsR0FFNUJBLEVBQVVBLEdBQVcsQ0FBQyxFQUN0QixNQUFNeGlDLEVBQVMsQ0FBQyxFQUVoQixTQUFTeWlDLEVBQWVybkIsRUFBUTVELEVBQVF1USxHQUN0QyxPQUFJUixHQUFNakMsY0FBY2xLLElBQVdtTSxHQUFNakMsY0FBYzlOLEdBQzlDK1AsR0FBTU8sTUFBTTE0QixLQUFLLENBQUMyNEIsWUFBVzNNLEVBQVE1RCxHQUNuQytQLEdBQU1qQyxjQUFjOU4sR0FDdEIrUCxHQUFNTyxNQUFNLENBQUMsRUFBR3RRLEdBQ2QrUCxHQUFNaDZCLFFBQVFpcUIsR0FDaEJBLEVBQU96QixRQUVUeUIsQ0FDVCxDQUdBLFNBQVNrckIsRUFBb0I5MEMsRUFBR0MsRUFBR2s2QixHQUNqQyxPQUFLUixHQUFNckMsWUFBWXIzQixHQUVYMDVCLEdBQU1yQyxZQUFZdDNCLFFBQXZCLEVBQ0U2MEMsT0FBZTV4QyxFQUFXakQsRUFBR202QixHQUY3QjBhLEVBQWU3MEMsRUFBR0MsRUFBR2s2QixFQUloQyxDQUdBLFNBQVM0YSxFQUFpQi8wQyxFQUFHQyxHQUMzQixJQUFLMDVCLEdBQU1yQyxZQUFZcjNCLEdBQ3JCLE9BQU80MEMsT0FBZTV4QyxFQUFXaEQsRUFFckMsQ0FHQSxTQUFTKzBDLEVBQWlCaDFDLEVBQUdDLEdBQzNCLE9BQUswNUIsR0FBTXJDLFlBQVlyM0IsR0FFWDA1QixHQUFNckMsWUFBWXQzQixRQUF2QixFQUNFNjBDLE9BQWU1eEMsRUFBV2pELEdBRjFCNjBDLE9BQWU1eEMsRUFBV2hELEVBSXJDLENBR0EsU0FBU2cxQyxFQUFnQmoxQyxFQUFHQyxFQUFHaUUsR0FDN0IsT0FBSUEsS0FBUTB3QyxFQUNIQyxFQUFlNzBDLEVBQUdDLEdBQ2hCaUUsS0FBUXl3QyxFQUNWRSxPQUFlNXhDLEVBQVdqRCxRQUQ1QixDQUdULENBRUEsTUFBTWsxQyxFQUFXLENBQ2Y3aUMsSUFBSzBpQyxFQUNMbnVDLE9BQVFtdUMsRUFDUnB0QyxLQUFNb3RDLEVBQ05qUSxRQUFTa1EsRUFDVHpVLGlCQUFrQnlVLEVBQ2xCN1Qsa0JBQW1CNlQsRUFDbkJoRyxpQkFBa0JnRyxFQUNsQmwyQixRQUFTazJCLEVBQ1RHLGVBQWdCSCxFQUNoQm5CLGdCQUFpQm1CLEVBQ2pCMVUsUUFBUzBVLEVBQ1QzVCxhQUFjMlQsRUFDZHhULGVBQWdCd1QsRUFDaEJ2VCxlQUFnQnVULEVBQ2hCNUcsaUJBQWtCNEcsRUFDbEI3RyxtQkFBb0I2RyxFQUNwQmpGLFdBQVlpRixFQUNadFQsaUJBQWtCc1QsRUFDbEIvMUIsY0FBZSsxQixFQUNmL2tCLGVBQWdCK2tCLEVBQ2hCM0YsVUFBVzJGLEVBQ1g3RixVQUFXNkYsRUFDWDVGLFdBQVk0RixFQUNaL0gsWUFBYStILEVBQ2IxRixXQUFZMEYsRUFDWnpJLGlCQUFrQnlJLEVBQ2xCclQsZUFBZ0JzVCxFQUNoQjF4QyxRQUFTLENBQUN2RCxFQUFHQyxJQUFNNjBDLEVBQW9CTCxHQUFnQnowQyxHQUFJeTBDLEdBQWdCeDBDLElBQUksSUFTakYsT0FOQTA1QixHQUFNMzdCLFFBQVFGLE9BQU9DLEtBQUtELE9BQU84SyxPQUFPLENBQUMsRUFBRytyQyxFQUFTQyxLQUFXLFNBQTRCMXdDLEdBQzFGLE1BQU1nMkIsRUFBUWdiLEVBQVNoeEMsSUFBUzR3QyxFQUMxQk0sRUFBY2xiLEVBQU15YSxFQUFRendDLEdBQU8wd0MsRUFBUTF3QyxHQUFPQSxHQUN2RHkxQixHQUFNckMsWUFBWThkLElBQWdCbGIsSUFBVSthLElBQXFCN2lDLEVBQU9sTyxHQUFRa3hDLEVBQ25GLElBRU9oakMsQ0FDVCxDQUVBLE1BQU1pakMsR0FBZSxDQUFDLEVBR3RCLENBQUMsU0FBVSxVQUFXLFNBQVUsV0FBWSxTQUFVLFVBQVVyM0MsU0FBUSxDQUFDcUssRUFBTTFDLEtBQzdFMHZDLEdBQWFodEMsR0FBUSxTQUFtQjh1QixHQUN0QyxjQUFjQSxJQUFVOXVCLEdBQVEsS0FBTzFDLEVBQUksRUFBSSxLQUFPLEtBQU8wQyxDQUMvRCxDQUFDLElBR0gsTUFBTWl0QyxHQUFxQixDQUFDLEVBVzVCRCxHQUFhaFYsYUFBZSxTQUFzQmtWLEVBQVdqbUMsRUFBU3ZELEdBQ3BFLFNBQVN5cEMsRUFBYzlJLEVBQUsrSSxHQUMxQixNQUFPLHVDQUFvRC9JLEVBQU0sSUFBTytJLEdBQVExcEMsRUFBVSxLQUFPQSxFQUFVLEdBQzdHLENBR0EsTUFBTyxDQUFDaEssRUFBTzJxQyxFQUFLZ0osS0FDbEIsSUFBa0IsSUFBZEgsRUFDRixNQUFNLElBQUk3WSxHQUNSOFksRUFBYzlJLEVBQUsscUJBQXVCcDlCLEVBQVUsT0FBU0EsRUFBVSxLQUN2RW90QixHQUFXaVosZ0JBZWYsT0FYSXJtQyxJQUFZZ21DLEdBQW1CNUksS0FDakM0SSxHQUFtQjVJLElBQU8sRUFFMUI3MkIsUUFBUUcsS0FDTncvQixFQUNFOUksRUFDQSwrQkFBaUNwOUIsRUFBVSw4Q0FLMUNpbUMsR0FBWUEsRUFBVXh6QyxFQUFPMnFDLEVBQUtnSixFQUFZLENBRXpELEVBbUNBLE1BQU1ILEdBQVksQ0FDaEJLLGNBeEJGLFNBQXVCejBDLEVBQVMwMEMsRUFBUUMsR0FDdEMsR0FBdUIsaUJBQVozMEMsRUFDVCxNQUFNLElBQUl1N0IsR0FBVyw0QkFBNkJBLEdBQVc4VCxzQkFFL0QsTUFBTXp5QyxFQUFPRCxPQUFPQyxLQUFLb0QsR0FDekIsSUFBSXdFLEVBQUk1SCxFQUFLb0IsT0FDYixLQUFPd0csS0FBTSxHQUFHLENBQ2QsTUFBTSttQyxFQUFNM3VDLEVBQUs0SCxHQUNYNHZDLEVBQVlNLEVBQU9uSixHQUN6QixHQUFJNkksRUFBSixDQUNFLE1BQU14ekMsRUFBUVosRUFBUXVyQyxHQUNoQnB1QyxPQUFtQjJFLElBQVZsQixHQUF1Qnd6QyxFQUFVeHpDLEVBQU8ycUMsRUFBS3ZyQyxHQUM1RCxJQUFlLElBQVg3QyxFQUNGLE1BQU0sSUFBSW8rQixHQUFXLFVBQVlnUSxFQUFNLFlBQWNwdUMsRUFBUW8rQixHQUFXOFQscUJBRzVFLE1BQ0EsSUFBcUIsSUFBakJzRixFQUNGLE1BQU0sSUFBSXBaLEdBQVcsa0JBQW9CZ1EsRUFBS2hRLEdBQVdxWixlQUU3RCxDQUNGLEVBSUVDLFdBQVlYLElBR1JXLEdBQWFULEdBQVVTLFdBUzdCLE1BQU1DLE1BQ0o5bkIsWUFBWStuQixHQUNWNTRDLEtBQUtxSixTQUFXdXZDLEVBQ2hCNTRDLEtBQUs2NEMsYUFBZSxDQUNsQnp2QyxRQUFTLElBQUlxNEIsR0FDYnQ3QixTQUFVLElBQUlzN0IsR0FFbEIsQ0FVQXI0QixRQUFRMHZDLEVBQWFoa0MsR0FHUSxpQkFBaEJna0MsR0FDVGhrQyxFQUFTQSxHQUFVLENBQUMsR0FDYkMsSUFBTStqQyxFQUViaGtDLEVBQVNna0MsR0FBZSxDQUFDLEVBRzNCaGtDLEVBQVNzaUMsR0FBWXAzQyxLQUFLcUosU0FBVXlMLEdBRXBDLE1BQU0sYUFBQ2l1QixFQUFZLGlCQUFFMk8sRUFBZ0IsUUFBRXpyQyxHQUFXNk8sT0FFN0JuUCxJQUFqQm85QixHQUNGa1YsR0FBVUssY0FBY3ZWLEVBQWMsQ0FDcENYLGtCQUFtQnNXLEdBQVczVixhQUFhMlYsR0FBV0ssU0FDdEQxVyxrQkFBbUJxVyxHQUFXM1YsYUFBYTJWLEdBQVdLLFNBQ3REelcsb0JBQXFCb1csR0FBVzNWLGFBQWEyVixHQUFXSyxXQUN2RCxHQUdtQixNQUFwQnJILElBQ0VyVixHQUFNMU0sV0FBVytoQixHQUNuQjU4QixFQUFPNDhCLGlCQUFtQixDQUN4QnJRLFVBQVdxUSxHQUdidUcsR0FBVUssY0FBYzVHLEVBQWtCLENBQ3hDL3VCLE9BQVErMUIsR0FBV00sU0FDbkIzWCxVQUFXcVgsR0FBV00sV0FDckIsSUFLUGxrQyxFQUFPeEwsUUFBVXdMLEVBQU94TCxRQUFVdEosS0FBS3FKLFNBQVNDLFFBQVUsT0FBT3pCLGNBR2pFLElBQUlveEMsRUFBaUJoekMsR0FBV28yQixHQUFNTyxNQUNwQzMyQixFQUFRcStCLE9BQ1JyK0IsRUFBUTZPLEVBQU94TCxTQUdqQnJELEdBQVdvMkIsR0FBTTM3QixRQUNmLENBQUMsU0FBVSxNQUFPLE9BQVEsT0FBUSxNQUFPLFFBQVMsV0FDakQ0SSxXQUNRckQsRUFBUXFELEVBQU8sSUFJMUJ3TCxFQUFPN08sUUFBVTRnQyxHQUFlbGdDLE9BQU9zeUMsRUFBZ0JoekMsR0FHdkQsTUFBTWl6QyxFQUEwQixHQUNoQyxJQUFJQyxHQUFpQyxFQUNyQ241QyxLQUFLNjRDLGFBQWF6dkMsUUFBUTFJLFNBQVEsU0FBb0MwNEMsR0FDakMsbUJBQXhCQSxFQUFZcFgsVUFBMEQsSUFBaENvWCxFQUFZcFgsUUFBUWx0QixLQUlyRXFrQyxFQUFpQ0EsR0FBa0NDLEVBQVlyWCxZQUUvRW1YLEVBQXdCcnZCLFFBQVF1dkIsRUFBWXZYLFVBQVd1WCxFQUFZdFgsVUFDckUsSUFFQSxNQUFNdVgsRUFBMkIsR0FLakMsSUFBSUMsRUFKSnQ1QyxLQUFLNjRDLGFBQWExeUMsU0FBU3pGLFNBQVEsU0FBa0MwNEMsR0FDbkVDLEVBQXlCNXpDLEtBQUsyekMsRUFBWXZYLFVBQVd1WCxFQUFZdFgsU0FDbkUsSUFHQSxJQUNJeDVCLEVBREFELEVBQUksRUFHUixJQUFLOHdDLEVBQWdDLENBQ25DLE1BQU1JLEVBQVEsQ0FBQ3JDLEdBQWdCdjJDLEtBQUtYLFdBQU8yRixHQU8zQyxJQU5BNHpDLEVBQU0xdkIsUUFBUUksTUFBTXN2QixFQUFPTCxHQUMzQkssRUFBTTl6QyxLQUFLd2tCLE1BQU1zdkIsRUFBT0YsR0FDeEIvd0MsRUFBTWl4QyxFQUFNMTNDLE9BRVp5M0MsRUFBVTlGLFFBQVFsZ0IsUUFBUXhlLEdBRW5Cek0sRUFBSUMsR0FDVGd4QyxFQUFVQSxFQUFRanNDLEtBQUtrc0MsRUFBTWx4QyxLQUFNa3hDLEVBQU1seEMsTUFHM0MsT0FBT2l4QyxDQUNULENBRUFoeEMsRUFBTTR3QyxFQUF3QnIzQyxPQUU5QixJQUFJMjNDLEVBQVkxa0MsRUFJaEIsSUFGQXpNLEVBQUksRUFFR0EsRUFBSUMsR0FBSyxDQUNkLE1BQU1teEMsRUFBY1AsRUFBd0I3d0MsS0FDdENxeEMsRUFBYVIsRUFBd0I3d0MsS0FDM0MsSUFDRW14QyxFQUFZQyxFQUFZRCxFQUkxQixDQUhFLE1BQU96M0MsR0FDUDIzQyxFQUFXeDFDLEtBQUtsRSxLQUFNK0IsR0FDdEIsS0FDRixDQUNGLENBRUEsSUFDRXUzQyxFQUFVcEMsR0FBZ0JoekMsS0FBS2xFLEtBQU13NUMsRUFHdkMsQ0FGRSxNQUFPejNDLEdBQ1AsT0FBT3l4QyxRQUFRbk0sT0FBT3RsQyxFQUN4QixDQUtBLElBSEFzRyxFQUFJLEVBQ0pDLEVBQU0rd0MsRUFBeUJ4M0MsT0FFeEJ3RyxFQUFJQyxHQUNUZ3hDLEVBQVVBLEVBQVFqc0MsS0FBS2dzQyxFQUF5Qmh4QyxLQUFNZ3hDLEVBQXlCaHhDLE1BR2pGLE9BQU9peEMsQ0FDVCxDQUVBSyxPQUFPN2tDLEdBR0wsT0FBT29zQixHQURVcUcsSUFEakJ6eUIsRUFBU3NpQyxHQUFZcDNDLEtBQUtxSixTQUFVeUwsSUFDRTB5QixRQUFTMXlCLEVBQU9DLEtBQzVCRCxFQUFPM0wsT0FBUTJMLEVBQU80OEIsaUJBQ2xELEVBSUZyVixHQUFNMzdCLFFBQVEsQ0FBQyxTQUFVLE1BQU8sT0FBUSxZQUFZLFNBQTZCNEksR0FFL0VxdkMsTUFBTXIwQyxVQUFVZ0YsR0FBVSxTQUFTeUwsRUFBS0QsR0FDdEMsT0FBTzlVLEtBQUtvSixRQUFRZ3VDLEdBQVl0aUMsR0FBVSxDQUFDLEVBQUcsQ0FDNUN4TCxTQUNBeUwsTUFDQTFLLE1BQU95SyxHQUFVLENBQUMsR0FBR3pLLE9BRXpCLENBQ0YsSUFFQWd5QixHQUFNMzdCLFFBQVEsQ0FBQyxPQUFRLE1BQU8sVUFBVSxTQUErQjRJLEdBR3JFLFNBQVNzd0MsRUFBbUJDLEdBQzFCLE9BQU8sU0FBb0I5a0MsRUFBSzFLLEVBQU15SyxHQUNwQyxPQUFPOVUsS0FBS29KLFFBQVFndUMsR0FBWXRpQyxHQUFVLENBQUMsRUFBRyxDQUM1Q3hMLFNBQ0FyRCxRQUFTNHpDLEVBQVMsQ0FDaEIsZUFBZ0IsdUJBQ2QsQ0FBQyxFQUNMOWtDLE1BQ0ExSyxTQUVKLENBQ0YsQ0FFQXN1QyxNQUFNcjBDLFVBQVVnRixHQUFVc3dDLElBRTFCakIsTUFBTXIwQyxVQUFVZ0YsRUFBUyxRQUFVc3dDLEdBQW1CLEVBQ3hELElBRUEsTUFBTUUsR0FBVW5CLE1BU2hCLE1BQU1vQixZQUNKbHBCLFlBQVltcEIsR0FDVixHQUF3QixtQkFBYkEsRUFDVCxNQUFNLElBQUlwc0IsVUFBVSxnQ0FHdEIsSUFBSXFzQixFQUVKajZDLEtBQUtzNUMsUUFBVSxJQUFJOUYsU0FBUSxTQUF5QmxnQixHQUNsRDJtQixFQUFpQjNtQixDQUNuQixJQUVBLE1BQU15TSxFQUFRLy9CLEtBR2RBLEtBQUtzNUMsUUFBUWpzQyxNQUFLbXBDLElBQ2hCLElBQUt6VyxFQUFNbWEsV0FBWSxPQUV2QixJQUFJN3hDLEVBQUkwM0IsRUFBTW1hLFdBQVdyNEMsT0FFekIsS0FBT3dHLEtBQU0sR0FDWDAzQixFQUFNbWEsV0FBVzd4QyxHQUFHbXVDLEdBRXRCelcsRUFBTW1hLFdBQWEsSUFBSSxJQUl6Qmw2QyxLQUFLczVDLFFBQVFqc0MsS0FBTzhzQyxJQUNsQixJQUFJQyxFQUVKLE1BQU1kLEVBQVUsSUFBSTlGLFNBQVFsZ0IsSUFDMUJ5TSxFQUFNaVEsVUFBVTFjLEdBQ2hCOG1CLEVBQVc5bUIsQ0FBTyxJQUNqQmptQixLQUFLOHNDLEdBTVIsT0FKQWIsRUFBUTlDLE9BQVMsV0FDZnpXLEVBQU0xa0IsWUFBWSsrQixFQUNwQixFQUVPZCxDQUFPLEVBR2hCVSxHQUFTLFNBQWdCdnJDLEVBQVNxRyxFQUFRMUwsR0FDcEMyMkIsRUFBTWhrQixTQUtWZ2tCLEVBQU1oa0IsT0FBUyxJQUFJbXJCLEdBQWN6NEIsRUFBU3FHLEVBQVExTCxHQUNsRDZ3QyxFQUFlbGEsRUFBTWhrQixRQUN2QixHQUNGLENBS0FrN0IsbUJBQ0UsR0FBSWozQyxLQUFLK2IsT0FDUCxNQUFNL2IsS0FBSytiLE1BRWYsQ0FNQWkwQixVQUFVNEUsR0FDSjUwQyxLQUFLK2IsT0FDUDY0QixFQUFTNTBDLEtBQUsrYixRQUlaL2IsS0FBS2s2QyxXQUNQbDZDLEtBQUtrNkMsV0FBV3owQyxLQUFLbXZDLEdBRXJCNTBDLEtBQUtrNkMsV0FBYSxDQUFDdEYsRUFFdkIsQ0FNQXY1QixZQUFZdTVCLEdBQ1YsSUFBSzUwQyxLQUFLazZDLFdBQ1IsT0FFRixNQUFNeDRDLEVBQVExQixLQUFLazZDLFdBQVdyMUIsUUFBUSt2QixJQUN2QixJQUFYbHpDLEdBQ0YxQixLQUFLazZDLFdBQVduekIsT0FBT3JsQixFQUFPLEVBRWxDLENBTUF5a0MsZ0JBQ0UsSUFBSXFRLEVBSUosTUFBTyxDQUNMelcsTUFKWSxJQUFJZ2EsYUFBWSxTQUFrQjExQixHQUM5Q215QixFQUFTbnlCLENBQ1gsSUFHRW15QixTQUVKLEVBR0YsTUFBTTZELEdBQWdCTixZQXdDdEIsTUFBTU8sR0FBaUIsQ0FDckJDLFNBQVUsSUFDVkMsbUJBQW9CLElBQ3BCQyxXQUFZLElBQ1pDLFdBQVksSUFDWkMsR0FBSSxJQUNKQyxRQUFTLElBQ1RDLFNBQVUsSUFDVkMsNEJBQTZCLElBQzdCQyxVQUFXLElBQ1hDLGFBQWMsSUFDZEMsZUFBZ0IsSUFDaEJDLFlBQWEsSUFDYkMsZ0JBQWlCLElBQ2pCQyxPQUFRLElBQ1JDLGdCQUFpQixJQUNqQkMsaUJBQWtCLElBQ2xCQyxNQUFPLElBQ1BDLFNBQVUsSUFDVkMsWUFBYSxJQUNiQyxTQUFVLElBQ1ZDLE9BQVEsSUFDUkMsa0JBQW1CLElBQ25CQyxrQkFBbUIsSUFDbkJDLFdBQVksSUFDWkMsYUFBYyxJQUNkQyxnQkFBaUIsSUFDakJDLFVBQVcsSUFDWEMsU0FBVSxJQUNWQyxpQkFBa0IsSUFDbEJDLGNBQWUsSUFDZkMsNEJBQTZCLElBQzdCQyxlQUFnQixJQUNoQkMsU0FBVSxJQUNWQyxLQUFNLElBQ05DLGVBQWdCLElBQ2hCQyxtQkFBb0IsSUFDcEJDLGdCQUFpQixJQUNqQkMsV0FBWSxJQUNaQyxxQkFBc0IsSUFDdEJDLG9CQUFxQixJQUNyQkMsa0JBQW1CLElBQ25CQyxVQUFXLElBQ1hDLG1CQUFvQixJQUNwQkMsb0JBQXFCLElBQ3JCQyxPQUFRLElBQ1JDLGlCQUFrQixJQUNsQkMsU0FBVSxJQUNWQyxnQkFBaUIsSUFDakJDLHFCQUFzQixJQUN0QkMsZ0JBQWlCLElBQ2pCQyw0QkFBNkIsSUFDN0JDLDJCQUE0QixJQUM1QkMsb0JBQXFCLElBQ3JCQyxlQUFnQixJQUNoQkMsV0FBWSxJQUNaQyxtQkFBb0IsSUFDcEJDLGVBQWdCLElBQ2hCQyx3QkFBeUIsSUFDekJDLHNCQUF1QixJQUN2QkMsb0JBQXFCLElBQ3JCQyxhQUFjLElBQ2RDLFlBQWEsSUFDYkMsOEJBQStCLEtBR2pDNzlDLE9BQU9xWSxRQUFReWhDLElBQWdCNTVDLFNBQVEsRUFBRUwsRUFBS29FLE1BQzVDNjFDLEdBQWU3MUMsR0FBU3BFLENBQUcsSUFHN0IsTUFBTWkrQyxHQUFtQmhFLEdBNEJ6QixNQUFNaUUsR0FuQk4sU0FBU0MsRUFBZUMsR0FDdEIsTUFBTXRqQixFQUFVLElBQUkyZSxHQUFRMkUsR0FDdEJDLEVBQVcvOUMsRUFBS201QyxHQUFReDFDLFVBQVU4RSxRQUFTK3hCLEdBYWpELE9BVkFrQixHQUFNbFMsT0FBT3UwQixFQUFVNUUsR0FBUXgxQyxVQUFXNjJCLEVBQVMsQ0FBQ1AsWUFBWSxJQUdoRXlCLEdBQU1sUyxPQUFPdTBCLEVBQVV2akIsRUFBUyxLQUFNLENBQUNQLFlBQVksSUFHbkQ4akIsRUFBU254QyxPQUFTLFNBQWdCcXJDLEdBQ2hDLE9BQU80RixFQUFlcEgsR0FBWXFILEVBQWU3RixHQUNuRCxFQUVPOEYsQ0FDVCxDQUdjRixDQUFlamEsSUFHN0JnYSxHQUFNNUYsTUFBUW1CLEdBR2R5RSxHQUFNclgsY0FBZ0JBLEdBQ3RCcVgsR0FBTXhFLFlBQWNNLEdBQ3BCa0UsR0FBTXZYLFNBQVdBLEdBQ2pCdVgsR0FBTTFXLFFBQVVBLEdBQ2hCMFcsR0FBTXBlLFdBQWFBLEdBR25Cb2UsR0FBTW5mLFdBQWFBLEdBR25CbWYsR0FBTUksT0FBU0osR0FBTXJYLGNBR3JCcVgsR0FBTS9PLElBQU0sU0FBYW9QLEdBQ3ZCLE9BQU9wTCxRQUFRaEUsSUFBSW9QLEVBQ3JCLEVBRUFMLEdBQU1wdUIsT0ExSU4sU0FBZ0J0dkIsR0FDZCxPQUFPLFNBQWMrOEIsR0FDbkIsT0FBTy84QixFQUFTb3BCLE1BQU0sS0FBTTJULEVBQzlCLENBQ0YsRUF5SUEyZ0IsR0FBTU0sYUFoSU4sU0FBc0JDLEdBQ3BCLE9BQU96aUIsR0FBTWxDLFNBQVMya0IsS0FBc0MsSUFBekJBLEVBQVFELFlBQzdDLEVBaUlBTixHQUFNbkgsWUFBY0EsR0FFcEJtSCxHQUFNOTdCLGFBQWVva0IsR0FFckIwWCxHQUFNUSxXQUFhbGxCLEdBQVM0SSxHQUFlcEcsR0FBTWQsV0FBVzFCLEdBQVMsSUFBSWoyQixTQUFTaTJCLEdBQVNBLEdBRTNGMGtCLEdBQU1TLFdBQWFwSSxHQUVuQjJILEdBQU1qRSxlQUFpQmdFLEdBRXZCQyxHQUFNM3hDLFFBQVUyeEMsR0FFaEIxK0MsRUFBT0QsUUFBVTIrQyxrejlJQ3BySWJVLEVBQTJCLENBQUMsRUFHaEMsU0FBU0MsRUFBb0JDLEdBRTVCLElBQUlDLEVBQWVILEVBQXlCRSxHQUM1QyxRQUFxQng1QyxJQUFqQnk1QyxFQUNILE9BQU9BLEVBQWF4L0MsUUFHckIsSUFBSUMsRUFBU28vQyxFQUF5QkUsR0FBWSxDQUNqRHB0QyxHQUFJb3RDLEVBQ0pySyxRQUFRLEVBQ1JsMUMsUUFBUyxDQUFDLEdBVVgsT0FOQXkvQyxFQUFvQkYsR0FBVWo3QyxLQUFLckUsRUFBT0QsUUFBU0MsRUFBUUEsRUFBT0QsUUFBU3MvQyxHQUczRXIvQyxFQUFPaTFDLFFBQVMsRUFHVGoxQyxFQUFPRCxPQUNmLENDekJBcy9DLEVBQW9CSSxJQUFPei9DLElBQzFCQSxFQUFPMC9DLE1BQVEsR0FDVjEvQyxFQUFPMi9DLFdBQVUzL0MsRUFBTzIvQyxTQUFXLElBQ2pDMy9DLEdDQVIsSUFBSTQvQyxFQUFzQlAsRUFBb0IsMEJ6R085QyIsInNvdXJjZXMiOlsid2VicGFjazovL21haWxndW4vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYXN5bmNraXQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9saWIvYWJvcnQuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9saWIvYXN5bmMuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9saWIvZGVmZXIuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9saWIvaXRlcmF0ZS5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2FzeW5ja2l0L2xpYi9zdGF0ZS5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2FzeW5ja2l0L2xpYi90ZXJtaW5hdG9yLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYXN5bmNraXQvcGFyYWxsZWwuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9zZXJpYWwuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9hc3luY2tpdC9zZXJpYWxPcmRlcmVkLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYXhpb3Mvbm9kZV9tb2R1bGVzL2Zvcm0tZGF0YS9saWIvZm9ybV9kYXRhLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYXhpb3Mvbm9kZV9tb2R1bGVzL2Zvcm0tZGF0YS9saWIvcG9wdWxhdGUuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL0RvbWFpbnMvZG9tYWluLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9Eb21haW5zL2RvbWFpbnNDbGllbnQudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL0RvbWFpbnMvZG9tYWluc0NyZWRlbnRpYWxzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9Eb21haW5zL2RvbWFpbnNUYWdzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9Eb21haW5zL2RvbWFpbnNUZW1wbGF0ZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL0V2ZW50cy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvSVBQb29scy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvSVBzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9NYWlsZ3VuQ2xpZW50LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9NYWlsaW5nTGlzdHMvbWFpbExpc3RNZW1iZXJzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9NYWlsaW5nTGlzdHMvbWFpbGluZ0xpc3RzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9NZXNzYWdlcy50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvUm91dGVzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9TdGF0cy9TdGF0c0NsaWVudC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvU3RhdHMvU3RhdHNDb250YWluZXIudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL1N1YmFjY291bnRzLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9TdXBwcmVzc2lvbnMvQm91bmNlLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9TdXBwcmVzc2lvbnMvQ29tcGxhaW50LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9TdXBwcmVzc2lvbnMvU3VwcHJlc3Npb24udHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL1N1cHByZXNzaW9ucy9TdXBwcmVzc2lvbnNDbGllbnQudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL1N1cHByZXNzaW9ucy9VbnN1YnNjcmliZS50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvU3VwcHJlc3Npb25zL1doaXRlTGlzdC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvVmFsaWRhdGlvbnMvbXVsdGlwbGVWYWxpZGF0aW9uLnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvQ2xhc3Nlcy9WYWxpZGF0aW9ucy92YWxpZGF0ZS50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvV2ViaG9va3MudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL2NvbW1vbi9FcnJvci50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvY29tbW9uL0Zvcm1EYXRhQnVpbGRlci50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0NsYXNzZXMvY29tbW9uL05hdmlnYXRpb25UaHJ1UGFnZXMudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9DbGFzc2VzL2NvbW1vbi9SZXF1ZXN0LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvRW51bXMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL0NvbW1vbi9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvRG9tYWlucy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvRXZlbnRDbGllbnQvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL0lQUG9vbHMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL0lQcy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvTWFpbGd1bkNsaWVudC9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvTWFpbGluZ0xpc3RzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvSW50ZXJmYWNlcy9NZXNzYWdlcy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvUm91dGVzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvSW50ZXJmYWNlcy9TdGF0cy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvU3ViYWNjb3VudHMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL0ludGVyZmFjZXMvVmFsaWRhdGlvbnMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9JbnRlcmZhY2VzL1dlYmhvb2tzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvSW50ZXJmYWNlcy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL0NvbW1vbi9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL0RvbWFpbnMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9UeXBlcy9FdmVudHMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9UeXBlcy9JUFBvb2xzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvSVBzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvTWFpbGd1bkNsaWVudC9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL01haWxpbmdMaXN0cy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL01lc3NhZ2VzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvUm91dGVzL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvU3RhdHMvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9UeXBlcy9TdWJhY2NvdW50cy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL1N1cHByZXNzaW9ucy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL1R5cGVzL1ZhbGlkYXRpb25zL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9saWIvVHlwZXMvV2ViaG9va3MvaW5kZXgudHMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL2xpYi9UeXBlcy9pbmRleC50cyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbGliL2luZGV4LnRzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvYmFzZS02NC9iYXNlNjQuanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9jb21iaW5lZC1zdHJlYW0vbGliL2NvbWJpbmVkX3N0cmVhbS5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RlYnVnL3NyYy9icm93c2VyLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvZGVidWcvc3JjL2NvbW1vbi5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RlYnVnL3NyYy9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2RlYnVnL3NyYy9ub2RlLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvZGVsYXllZC1zdHJlYW0vbGliL2RlbGF5ZWRfc3RyZWFtLmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvZm9sbG93LXJlZGlyZWN0cy9kZWJ1Zy5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2ZvbGxvdy1yZWRpcmVjdHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9oYXMtZmxhZy9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL21pbWUtZGIvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9taW1lLXR5cGVzL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvbXMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi8uL25vZGVfbW9kdWxlcy9wcm94eS1mcm9tLWVudi9pbmRleC5qcyIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL3N1cHBvcnRzLWNvbG9yL2luZGV4LmpzIiwid2VicGFjazovL21haWxndW4vLi9ub2RlX21vZHVsZXMvdXJsLWpvaW4vbGliL3VybC1qb2luLmpzIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImFzc2VydFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImV2ZW50c1wiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImZzXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwiaHR0cFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcImh0dHBzXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwib3NcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuL2V4dGVybmFsIG5vZGUtY29tbW9uanMgXCJwYXRoXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwic3RyZWFtXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwidHR5XCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwidXJsXCIiLCJ3ZWJwYWNrOi8vbWFpbGd1bi9leHRlcm5hbCBub2RlLWNvbW1vbmpzIFwidXRpbFwiIiwid2VicGFjazovL21haWxndW4vZXh0ZXJuYWwgbm9kZS1jb21tb25qcyBcInpsaWJcIiIsIndlYnBhY2s6Ly9tYWlsZ3VuLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2Rpc3Qvbm9kZS9heGlvcy5janMiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9tYWlsZ3VuL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vbWFpbGd1bi93ZWJwYWNrL3N0YXJ0dXAiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wibWFpbGd1blwiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJtYWlsZ3VuXCJdID0gZmFjdG9yeSgpO1xufSkodGhpcywgKCkgPT4ge1xucmV0dXJuICIsIm1vZHVsZS5leHBvcnRzID1cbntcbiAgcGFyYWxsZWwgICAgICA6IHJlcXVpcmUoJy4vcGFyYWxsZWwuanMnKSxcbiAgc2VyaWFsICAgICAgICA6IHJlcXVpcmUoJy4vc2VyaWFsLmpzJyksXG4gIHNlcmlhbE9yZGVyZWQgOiByZXF1aXJlKCcuL3NlcmlhbE9yZGVyZWQuanMnKVxufTtcbiIsIi8vIEFQSVxubW9kdWxlLmV4cG9ydHMgPSBhYm9ydDtcblxuLyoqXG4gKiBBYm9ydHMgbGVmdG92ZXIgYWN0aXZlIGpvYnNcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gc3RhdGUgLSBjdXJyZW50IHN0YXRlIG9iamVjdFxuICovXG5mdW5jdGlvbiBhYm9ydChzdGF0ZSlcbntcbiAgT2JqZWN0LmtleXMoc3RhdGUuam9icykuZm9yRWFjaChjbGVhbi5iaW5kKHN0YXRlKSk7XG5cbiAgLy8gcmVzZXQgbGVmdG92ZXIgam9ic1xuICBzdGF0ZS5qb2JzID0ge307XG59XG5cbi8qKlxuICogQ2xlYW5zIHVwIGxlZnRvdmVyIGpvYiBieSBpbnZva2luZyBhYm9ydCBmdW5jdGlvbiBmb3IgdGhlIHByb3ZpZGVkIGpvYiBpZFxuICpcbiAqIEB0aGlzICBzdGF0ZVxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBrZXkgLSBqb2IgaWQgdG8gYWJvcnRcbiAqL1xuZnVuY3Rpb24gY2xlYW4oa2V5KVxue1xuICBpZiAodHlwZW9mIHRoaXMuam9ic1trZXldID09ICdmdW5jdGlvbicpXG4gIHtcbiAgICB0aGlzLmpvYnNba2V5XSgpO1xuICB9XG59XG4iLCJ2YXIgZGVmZXIgPSByZXF1aXJlKCcuL2RlZmVyLmpzJyk7XG5cbi8vIEFQSVxubW9kdWxlLmV4cG9ydHMgPSBhc3luYztcblxuLyoqXG4gKiBSdW5zIHByb3ZpZGVkIGNhbGxiYWNrIGFzeW5jaHJvbm91c2x5XG4gKiBldmVuIGlmIGNhbGxiYWNrIGl0c2VsZiBpcyBub3RcbiAqXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gY2FsbGJhY2sgdG8gaW52b2tlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IC0gYXVnbWVudGVkIGNhbGxiYWNrXG4gKi9cbmZ1bmN0aW9uIGFzeW5jKGNhbGxiYWNrKVxue1xuICB2YXIgaXNBc3luYyA9IGZhbHNlO1xuXG4gIC8vIGNoZWNrIGlmIGFzeW5jIGhhcHBlbmVkXG4gIGRlZmVyKGZ1bmN0aW9uKCkgeyBpc0FzeW5jID0gdHJ1ZTsgfSk7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIGFzeW5jX2NhbGxiYWNrKGVyciwgcmVzdWx0KVxuICB7XG4gICAgaWYgKGlzQXN5bmMpXG4gICAge1xuICAgICAgY2FsbGJhY2soZXJyLCByZXN1bHQpO1xuICAgIH1cbiAgICBlbHNlXG4gICAge1xuICAgICAgZGVmZXIoZnVuY3Rpb24gbmV4dFRpY2tfY2FsbGJhY2soKVxuICAgICAge1xuICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH07XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGRlZmVyO1xuXG4vKipcbiAqIFJ1bnMgcHJvdmlkZWQgZnVuY3Rpb24gb24gbmV4dCBpdGVyYXRpb24gb2YgdGhlIGV2ZW50IGxvb3BcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBmbiAtIGZ1bmN0aW9uIHRvIHJ1blxuICovXG5mdW5jdGlvbiBkZWZlcihmbilcbntcbiAgdmFyIG5leHRUaWNrID0gdHlwZW9mIHNldEltbWVkaWF0ZSA9PSAnZnVuY3Rpb24nXG4gICAgPyBzZXRJbW1lZGlhdGVcbiAgICA6IChcbiAgICAgIHR5cGVvZiBwcm9jZXNzID09ICdvYmplY3QnICYmIHR5cGVvZiBwcm9jZXNzLm5leHRUaWNrID09ICdmdW5jdGlvbidcbiAgICAgID8gcHJvY2Vzcy5uZXh0VGlja1xuICAgICAgOiBudWxsXG4gICAgKTtcblxuICBpZiAobmV4dFRpY2spXG4gIHtcbiAgICBuZXh0VGljayhmbik7XG4gIH1cbiAgZWxzZVxuICB7XG4gICAgc2V0VGltZW91dChmbiwgMCk7XG4gIH1cbn1cbiIsInZhciBhc3luYyA9IHJlcXVpcmUoJy4vYXN5bmMuanMnKVxuICAsIGFib3J0ID0gcmVxdWlyZSgnLi9hYm9ydC5qcycpXG4gIDtcblxuLy8gQVBJXG5tb2R1bGUuZXhwb3J0cyA9IGl0ZXJhdGU7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlYWNoIGpvYiBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge2FycmF5fG9iamVjdH0gbGlzdCAtIGFycmF5IG9yIG9iamVjdCAobmFtZWQgbGlzdCkgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBpdGVyYXRvciAtIGl0ZXJhdG9yIHRvIHJ1blxuICogQHBhcmFtIHtvYmplY3R9IHN0YXRlIC0gY3VycmVudCBqb2Igc3RhdHVzXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGludm9rZWQgd2hlbiBhbGwgZWxlbWVudHMgcHJvY2Vzc2VkXG4gKi9cbmZ1bmN0aW9uIGl0ZXJhdGUobGlzdCwgaXRlcmF0b3IsIHN0YXRlLCBjYWxsYmFjaylcbntcbiAgLy8gc3RvcmUgY3VycmVudCBpbmRleFxuICB2YXIga2V5ID0gc3RhdGVbJ2tleWVkTGlzdCddID8gc3RhdGVbJ2tleWVkTGlzdCddW3N0YXRlLmluZGV4XSA6IHN0YXRlLmluZGV4O1xuXG4gIHN0YXRlLmpvYnNba2V5XSA9IHJ1bkpvYihpdGVyYXRvciwga2V5LCBsaXN0W2tleV0sIGZ1bmN0aW9uKGVycm9yLCBvdXRwdXQpXG4gIHtcbiAgICAvLyBkb24ndCByZXBlYXQgeW91cnNlbGZcbiAgICAvLyBza2lwIHNlY29uZGFyeSBjYWxsYmFja3NcbiAgICBpZiAoIShrZXkgaW4gc3RhdGUuam9icykpXG4gICAge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGNsZWFuIHVwIGpvYnNcbiAgICBkZWxldGUgc3RhdGUuam9ic1trZXldO1xuXG4gICAgaWYgKGVycm9yKVxuICAgIHtcbiAgICAgIC8vIGRvbid0IHByb2Nlc3MgcmVzdCBvZiB0aGUgcmVzdWx0c1xuICAgICAgLy8gc3RvcCBzdGlsbCBhY3RpdmUgam9ic1xuICAgICAgLy8gYW5kIHJlc2V0IHRoZSBsaXN0XG4gICAgICBhYm9ydChzdGF0ZSk7XG4gICAgfVxuICAgIGVsc2VcbiAgICB7XG4gICAgICBzdGF0ZS5yZXN1bHRzW2tleV0gPSBvdXRwdXQ7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuIHNhbHZhZ2VkIHJlc3VsdHNcbiAgICBjYWxsYmFjayhlcnJvciwgc3RhdGUucmVzdWx0cyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJ1bnMgaXRlcmF0b3Igb3ZlciBwcm92aWRlZCBqb2IgZWxlbWVudFxuICpcbiAqIEBwYXJhbSAgIHtmdW5jdGlvbn0gaXRlcmF0b3IgLSBpdGVyYXRvciB0byBpbnZva2VcbiAqIEBwYXJhbSAgIHtzdHJpbmd8bnVtYmVyfSBrZXkgLSBrZXkvaW5kZXggb2YgdGhlIGVsZW1lbnQgaW4gdGhlIGxpc3Qgb2Ygam9ic1xuICogQHBhcmFtICAge21peGVkfSBpdGVtIC0gam9iIGRlc2NyaXB0aW9uXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gaW52b2tlZCBhZnRlciBpdGVyYXRvciBpcyBkb25lIHdpdGggdGhlIGpvYlxuICogQHJldHVybnMge2Z1bmN0aW9ufG1peGVkfSAtIGpvYiBhYm9ydCBmdW5jdGlvbiBvciBzb21ldGhpbmcgZWxzZVxuICovXG5mdW5jdGlvbiBydW5Kb2IoaXRlcmF0b3IsIGtleSwgaXRlbSwgY2FsbGJhY2spXG57XG4gIHZhciBhYm9ydGVyO1xuXG4gIC8vIGFsbG93IHNob3J0Y3V0IGlmIGl0ZXJhdG9yIGV4cGVjdHMgb25seSB0d28gYXJndW1lbnRzXG4gIGlmIChpdGVyYXRvci5sZW5ndGggPT0gMilcbiAge1xuICAgIGFib3J0ZXIgPSBpdGVyYXRvcihpdGVtLCBhc3luYyhjYWxsYmFjaykpO1xuICB9XG4gIC8vIG90aGVyd2lzZSBnbyB3aXRoIGZ1bGwgdGhyZWUgYXJndW1lbnRzXG4gIGVsc2VcbiAge1xuICAgIGFib3J0ZXIgPSBpdGVyYXRvcihpdGVtLCBrZXksIGFzeW5jKGNhbGxiYWNrKSk7XG4gIH1cblxuICByZXR1cm4gYWJvcnRlcjtcbn1cbiIsIi8vIEFQSVxubW9kdWxlLmV4cG9ydHMgPSBzdGF0ZTtcblxuLyoqXG4gKiBDcmVhdGVzIGluaXRpYWwgc3RhdGUgb2JqZWN0XG4gKiBmb3IgaXRlcmF0aW9uIG92ZXIgbGlzdFxuICpcbiAqIEBwYXJhbSAgIHthcnJheXxvYmplY3R9IGxpc3QgLSBsaXN0IHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtICAge2Z1bmN0aW9ufG51bGx9IHNvcnRNZXRob2QgLSBmdW5jdGlvbiB0byB1c2UgZm9yIGtleXMgc29ydCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGBudWxsYCB0byBrZWVwIHRoZW0gYXMgaXNcbiAqIEByZXR1cm5zIHtvYmplY3R9IC0gaW5pdGlhbCBzdGF0ZSBvYmplY3RcbiAqL1xuZnVuY3Rpb24gc3RhdGUobGlzdCwgc29ydE1ldGhvZClcbntcbiAgdmFyIGlzTmFtZWRMaXN0ID0gIUFycmF5LmlzQXJyYXkobGlzdClcbiAgICAsIGluaXRTdGF0ZSA9XG4gICAge1xuICAgICAgaW5kZXggICAgOiAwLFxuICAgICAga2V5ZWRMaXN0OiBpc05hbWVkTGlzdCB8fCBzb3J0TWV0aG9kID8gT2JqZWN0LmtleXMobGlzdCkgOiBudWxsLFxuICAgICAgam9icyAgICAgOiB7fSxcbiAgICAgIHJlc3VsdHMgIDogaXNOYW1lZExpc3QgPyB7fSA6IFtdLFxuICAgICAgc2l6ZSAgICAgOiBpc05hbWVkTGlzdCA/IE9iamVjdC5rZXlzKGxpc3QpLmxlbmd0aCA6IGxpc3QubGVuZ3RoXG4gICAgfVxuICAgIDtcblxuICBpZiAoc29ydE1ldGhvZClcbiAge1xuICAgIC8vIHNvcnQgYXJyYXkga2V5cyBiYXNlZCBvbiBpdCdzIHZhbHVlc1xuICAgIC8vIHNvcnQgb2JqZWN0J3Mga2V5cyBqdXN0IG9uIG93biBtZXJpdFxuICAgIGluaXRTdGF0ZS5rZXllZExpc3Quc29ydChpc05hbWVkTGlzdCA/IHNvcnRNZXRob2QgOiBmdW5jdGlvbihhLCBiKVxuICAgIHtcbiAgICAgIHJldHVybiBzb3J0TWV0aG9kKGxpc3RbYV0sIGxpc3RbYl0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGluaXRTdGF0ZTtcbn1cbiIsInZhciBhYm9ydCA9IHJlcXVpcmUoJy4vYWJvcnQuanMnKVxuICAsIGFzeW5jID0gcmVxdWlyZSgnLi9hc3luYy5qcycpXG4gIDtcblxuLy8gQVBJXG5tb2R1bGUuZXhwb3J0cyA9IHRlcm1pbmF0b3I7XG5cbi8qKlxuICogVGVybWluYXRlcyBqb2JzIGluIHRoZSBhdHRhY2hlZCBzdGF0ZSBjb250ZXh0XG4gKlxuICogQHRoaXMgIEFzeW5jS2l0U3RhdGUjXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGZpbmFsIGNhbGxiYWNrIHRvIGludm9rZSBhZnRlciB0ZXJtaW5hdGlvblxuICovXG5mdW5jdGlvbiB0ZXJtaW5hdG9yKGNhbGxiYWNrKVxue1xuICBpZiAoIU9iamVjdC5rZXlzKHRoaXMuam9icykubGVuZ3RoKVxuICB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZmFzdCBmb3J3YXJkIGl0ZXJhdGlvbiBpbmRleFxuICB0aGlzLmluZGV4ID0gdGhpcy5zaXplO1xuXG4gIC8vIGFib3J0IGpvYnNcbiAgYWJvcnQodGhpcyk7XG5cbiAgLy8gc2VuZCBiYWNrIHJlc3VsdHMgd2UgaGF2ZSBzbyBmYXJcbiAgYXN5bmMoY2FsbGJhY2spKG51bGwsIHRoaXMucmVzdWx0cyk7XG59XG4iLCJ2YXIgaXRlcmF0ZSAgICA9IHJlcXVpcmUoJy4vbGliL2l0ZXJhdGUuanMnKVxuICAsIGluaXRTdGF0ZSAgPSByZXF1aXJlKCcuL2xpYi9zdGF0ZS5qcycpXG4gICwgdGVybWluYXRvciA9IHJlcXVpcmUoJy4vbGliL3Rlcm1pbmF0b3IuanMnKVxuICA7XG5cbi8vIFB1YmxpYyBBUElcbm1vZHVsZS5leHBvcnRzID0gcGFyYWxsZWw7XG5cbi8qKlxuICogUnVucyBpdGVyYXRvciBvdmVyIHByb3ZpZGVkIGFycmF5IGVsZW1lbnRzIGluIHBhcmFsbGVsXG4gKlxuICogQHBhcmFtICAge2FycmF5fG9iamVjdH0gbGlzdCAtIGFycmF5IG9yIG9iamVjdCAobmFtZWQgbGlzdCkgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGl0ZXJhdG9yIC0gaXRlcmF0b3IgdG8gcnVuXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGNhbGxiYWNrIC0gaW52b2tlZCB3aGVuIGFsbCBlbGVtZW50cyBwcm9jZXNzZWRcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gLSBqb2JzIHRlcm1pbmF0b3JcbiAqL1xuZnVuY3Rpb24gcGFyYWxsZWwobGlzdCwgaXRlcmF0b3IsIGNhbGxiYWNrKVxue1xuICB2YXIgc3RhdGUgPSBpbml0U3RhdGUobGlzdCk7XG5cbiAgd2hpbGUgKHN0YXRlLmluZGV4IDwgKHN0YXRlWydrZXllZExpc3QnXSB8fCBsaXN0KS5sZW5ndGgpXG4gIHtcbiAgICBpdGVyYXRlKGxpc3QsIGl0ZXJhdG9yLCBzdGF0ZSwgZnVuY3Rpb24oZXJyb3IsIHJlc3VsdClcbiAgICB7XG4gICAgICBpZiAoZXJyb3IpXG4gICAgICB7XG4gICAgICAgIGNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGxvb2tzIGxpa2UgaXQncyB0aGUgbGFzdCBvbmVcbiAgICAgIGlmIChPYmplY3Qua2V5cyhzdGF0ZS5qb2JzKS5sZW5ndGggPT09IDApXG4gICAgICB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIHN0YXRlLnJlc3VsdHMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBzdGF0ZS5pbmRleCsrO1xuICB9XG5cbiAgcmV0dXJuIHRlcm1pbmF0b3IuYmluZChzdGF0ZSwgY2FsbGJhY2spO1xufVxuIiwidmFyIHNlcmlhbE9yZGVyZWQgPSByZXF1aXJlKCcuL3NlcmlhbE9yZGVyZWQuanMnKTtcblxuLy8gUHVibGljIEFQSVxubW9kdWxlLmV4cG9ydHMgPSBzZXJpYWw7XG5cbi8qKlxuICogUnVucyBpdGVyYXRvciBvdmVyIHByb3ZpZGVkIGFycmF5IGVsZW1lbnRzIGluIHNlcmllc1xuICpcbiAqIEBwYXJhbSAgIHthcnJheXxvYmplY3R9IGxpc3QgLSBhcnJheSBvciBvYmplY3QgKG5hbWVkIGxpc3QpIHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtICAge2Z1bmN0aW9ufSBpdGVyYXRvciAtIGl0ZXJhdG9yIHRvIHJ1blxuICogQHBhcmFtICAge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGludm9rZWQgd2hlbiBhbGwgZWxlbWVudHMgcHJvY2Vzc2VkXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IC0gam9icyB0ZXJtaW5hdG9yXG4gKi9cbmZ1bmN0aW9uIHNlcmlhbChsaXN0LCBpdGVyYXRvciwgY2FsbGJhY2spXG57XG4gIHJldHVybiBzZXJpYWxPcmRlcmVkKGxpc3QsIGl0ZXJhdG9yLCBudWxsLCBjYWxsYmFjayk7XG59XG4iLCJ2YXIgaXRlcmF0ZSAgICA9IHJlcXVpcmUoJy4vbGliL2l0ZXJhdGUuanMnKVxuICAsIGluaXRTdGF0ZSAgPSByZXF1aXJlKCcuL2xpYi9zdGF0ZS5qcycpXG4gICwgdGVybWluYXRvciA9IHJlcXVpcmUoJy4vbGliL3Rlcm1pbmF0b3IuanMnKVxuICA7XG5cbi8vIFB1YmxpYyBBUElcbm1vZHVsZS5leHBvcnRzID0gc2VyaWFsT3JkZXJlZDtcbi8vIHNvcnRpbmcgaGVscGVyc1xubW9kdWxlLmV4cG9ydHMuYXNjZW5kaW5nICA9IGFzY2VuZGluZztcbm1vZHVsZS5leHBvcnRzLmRlc2NlbmRpbmcgPSBkZXNjZW5kaW5nO1xuXG4vKipcbiAqIFJ1bnMgaXRlcmF0b3Igb3ZlciBwcm92aWRlZCBzb3J0ZWQgYXJyYXkgZWxlbWVudHMgaW4gc2VyaWVzXG4gKlxuICogQHBhcmFtICAge2FycmF5fG9iamVjdH0gbGlzdCAtIGFycmF5IG9yIG9iamVjdCAobmFtZWQgbGlzdCkgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IGl0ZXJhdG9yIC0gaXRlcmF0b3IgdG8gcnVuXG4gKiBAcGFyYW0gICB7ZnVuY3Rpb259IHNvcnRNZXRob2QgLSBjdXN0b20gc29ydCBmdW5jdGlvblxuICogQHBhcmFtICAge2Z1bmN0aW9ufSBjYWxsYmFjayAtIGludm9rZWQgd2hlbiBhbGwgZWxlbWVudHMgcHJvY2Vzc2VkXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IC0gam9icyB0ZXJtaW5hdG9yXG4gKi9cbmZ1bmN0aW9uIHNlcmlhbE9yZGVyZWQobGlzdCwgaXRlcmF0b3IsIHNvcnRNZXRob2QsIGNhbGxiYWNrKVxue1xuICB2YXIgc3RhdGUgPSBpbml0U3RhdGUobGlzdCwgc29ydE1ldGhvZCk7XG5cbiAgaXRlcmF0ZShsaXN0LCBpdGVyYXRvciwgc3RhdGUsIGZ1bmN0aW9uIGl0ZXJhdG9ySGFuZGxlcihlcnJvciwgcmVzdWx0KVxuICB7XG4gICAgaWYgKGVycm9yKVxuICAgIHtcbiAgICAgIGNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN0YXRlLmluZGV4Kys7XG5cbiAgICAvLyBhcmUgd2UgdGhlcmUgeWV0P1xuICAgIGlmIChzdGF0ZS5pbmRleCA8IChzdGF0ZVsna2V5ZWRMaXN0J10gfHwgbGlzdCkubGVuZ3RoKVxuICAgIHtcbiAgICAgIGl0ZXJhdGUobGlzdCwgaXRlcmF0b3IsIHN0YXRlLCBpdGVyYXRvckhhbmRsZXIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGRvbmUgaGVyZVxuICAgIGNhbGxiYWNrKG51bGwsIHN0YXRlLnJlc3VsdHMpO1xuICB9KTtcblxuICByZXR1cm4gdGVybWluYXRvci5iaW5kKHN0YXRlLCBjYWxsYmFjayk7XG59XG5cbi8qXG4gKiAtLSBTb3J0IG1ldGhvZHNcbiAqL1xuXG4vKipcbiAqIHNvcnQgaGVscGVyIHRvIHNvcnQgYXJyYXkgZWxlbWVudHMgaW4gYXNjZW5kaW5nIG9yZGVyXG4gKlxuICogQHBhcmFtICAge21peGVkfSBhIC0gYW4gaXRlbSB0byBjb21wYXJlXG4gKiBAcGFyYW0gICB7bWl4ZWR9IGIgLSBhbiBpdGVtIHRvIGNvbXBhcmVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IC0gY29tcGFyaXNvbiByZXN1bHRcbiAqL1xuZnVuY3Rpb24gYXNjZW5kaW5nKGEsIGIpXG57XG4gIHJldHVybiBhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMDtcbn1cblxuLyoqXG4gKiBzb3J0IGhlbHBlciB0byBzb3J0IGFycmF5IGVsZW1lbnRzIGluIGRlc2NlbmRpbmcgb3JkZXJcbiAqXG4gKiBAcGFyYW0gICB7bWl4ZWR9IGEgLSBhbiBpdGVtIHRvIGNvbXBhcmVcbiAqIEBwYXJhbSAgIHttaXhlZH0gYiAtIGFuIGl0ZW0gdG8gY29tcGFyZVxuICogQHJldHVybnMge251bWJlcn0gLSBjb21wYXJpc29uIHJlc3VsdFxuICovXG5mdW5jdGlvbiBkZXNjZW5kaW5nKGEsIGIpXG57XG4gIHJldHVybiAtMSAqIGFzY2VuZGluZyhhLCBiKTtcbn1cbiIsInZhciBDb21iaW5lZFN0cmVhbSA9IHJlcXVpcmUoJ2NvbWJpbmVkLXN0cmVhbScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbnZhciBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xudmFyIGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbnZhciBwYXJzZVVybCA9IHJlcXVpcmUoJ3VybCcpLnBhcnNlO1xudmFyIGZzID0gcmVxdWlyZSgnZnMnKTtcbnZhciBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKS5TdHJlYW07XG52YXIgbWltZSA9IHJlcXVpcmUoJ21pbWUtdHlwZXMnKTtcbnZhciBhc3luY2tpdCA9IHJlcXVpcmUoJ2FzeW5ja2l0Jyk7XG52YXIgcG9wdWxhdGUgPSByZXF1aXJlKCcuL3BvcHVsYXRlLmpzJyk7XG5cbi8vIFB1YmxpYyBBUElcbm1vZHVsZS5leHBvcnRzID0gRm9ybURhdGE7XG5cbi8vIG1ha2UgaXQgYSBTdHJlYW1cbnV0aWwuaW5oZXJpdHMoRm9ybURhdGEsIENvbWJpbmVkU3RyZWFtKTtcblxuLyoqXG4gKiBDcmVhdGUgcmVhZGFibGUgXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCIgc3RyZWFtcy5cbiAqIENhbiBiZSB1c2VkIHRvIHN1Ym1pdCBmb3Jtc1xuICogYW5kIGZpbGUgdXBsb2FkcyB0byBvdGhlciB3ZWIgYXBwbGljYXRpb25zLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBQcm9wZXJ0aWVzIHRvIGJlIGFkZGVkL292ZXJyaWRlbiBmb3IgRm9ybURhdGEgYW5kIENvbWJpbmVkU3RyZWFtXG4gKi9cbmZ1bmN0aW9uIEZvcm1EYXRhKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEZvcm1EYXRhKSkge1xuICAgIHJldHVybiBuZXcgRm9ybURhdGEob3B0aW9ucyk7XG4gIH1cblxuICB0aGlzLl9vdmVyaGVhZExlbmd0aCA9IDA7XG4gIHRoaXMuX3ZhbHVlTGVuZ3RoID0gMDtcbiAgdGhpcy5fdmFsdWVzVG9NZWFzdXJlID0gW107XG5cbiAgQ29tYmluZWRTdHJlYW0uY2FsbCh0aGlzKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgZm9yICh2YXIgb3B0aW9uIGluIG9wdGlvbnMpIHtcbiAgICB0aGlzW29wdGlvbl0gPSBvcHRpb25zW29wdGlvbl07XG4gIH1cbn1cblxuRm9ybURhdGEuTElORV9CUkVBSyA9ICdcXHJcXG4nO1xuRm9ybURhdGEuREVGQVVMVF9DT05URU5UX1RZUEUgPSAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJztcblxuRm9ybURhdGEucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uKGZpZWxkLCB2YWx1ZSwgb3B0aW9ucykge1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIGFsbG93IGZpbGVuYW1lIGFzIHNpbmdsZSBvcHRpb25cbiAgaWYgKHR5cGVvZiBvcHRpb25zID09ICdzdHJpbmcnKSB7XG4gICAgb3B0aW9ucyA9IHtmaWxlbmFtZTogb3B0aW9uc307XG4gIH1cblxuICB2YXIgYXBwZW5kID0gQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLmFwcGVuZC5iaW5kKHRoaXMpO1xuXG4gIC8vIGFsbCB0aGF0IHN0cmVhbXkgYnVzaW5lc3MgY2FuJ3QgaGFuZGxlIG51bWJlcnNcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgIHZhbHVlID0gJycgKyB2YWx1ZTtcbiAgfVxuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mZWxpeGdlL25vZGUtZm9ybS1kYXRhL2lzc3Vlcy8zOFxuICBpZiAodXRpbC5pc0FycmF5KHZhbHVlKSkge1xuICAgIC8vIFBsZWFzZSBjb252ZXJ0IHlvdXIgYXJyYXkgaW50byBzdHJpbmdcbiAgICAvLyB0aGUgd2F5IHdlYiBzZXJ2ZXIgZXhwZWN0cyBpdFxuICAgIHRoaXMuX2Vycm9yKG5ldyBFcnJvcignQXJyYXlzIGFyZSBub3Qgc3VwcG9ydGVkLicpKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgaGVhZGVyID0gdGhpcy5fbXVsdGlQYXJ0SGVhZGVyKGZpZWxkLCB2YWx1ZSwgb3B0aW9ucyk7XG4gIHZhciBmb290ZXIgPSB0aGlzLl9tdWx0aVBhcnRGb290ZXIoKTtcblxuICBhcHBlbmQoaGVhZGVyKTtcbiAgYXBwZW5kKHZhbHVlKTtcbiAgYXBwZW5kKGZvb3Rlcik7XG5cbiAgLy8gcGFzcyBhbG9uZyBvcHRpb25zLmtub3duTGVuZ3RoXG4gIHRoaXMuX3RyYWNrTGVuZ3RoKGhlYWRlciwgdmFsdWUsIG9wdGlvbnMpO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLl90cmFja0xlbmd0aCA9IGZ1bmN0aW9uKGhlYWRlciwgdmFsdWUsIG9wdGlvbnMpIHtcbiAgdmFyIHZhbHVlTGVuZ3RoID0gMDtcblxuICAvLyB1c2VkIHcvIGdldExlbmd0aFN5bmMoKSwgd2hlbiBsZW5ndGggaXMga25vd24uXG4gIC8vIGUuZy4gZm9yIHN0cmVhbWluZyBkaXJlY3RseSBmcm9tIGEgcmVtb3RlIHNlcnZlcixcbiAgLy8gdy8gYSBrbm93biBmaWxlIGEgc2l6ZSwgYW5kIG5vdCB3YW50aW5nIHRvIHdhaXQgZm9yXG4gIC8vIGluY29taW5nIGZpbGUgdG8gZmluaXNoIHRvIGdldCBpdHMgc2l6ZS5cbiAgaWYgKG9wdGlvbnMua25vd25MZW5ndGggIT0gbnVsbCkge1xuICAgIHZhbHVlTGVuZ3RoICs9ICtvcHRpb25zLmtub3duTGVuZ3RoO1xuICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICB2YWx1ZUxlbmd0aCA9IHZhbHVlLmxlbmd0aDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsdWVMZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aCh2YWx1ZSk7XG4gIH1cblxuICB0aGlzLl92YWx1ZUxlbmd0aCArPSB2YWx1ZUxlbmd0aDtcblxuICAvLyBAY2hlY2sgd2h5IGFkZCBDUkxGPyBkb2VzIHRoaXMgYWNjb3VudCBmb3IgY3VzdG9tL211bHRpcGxlIENSTEZzP1xuICB0aGlzLl9vdmVyaGVhZExlbmd0aCArPVxuICAgIEJ1ZmZlci5ieXRlTGVuZ3RoKGhlYWRlcikgK1xuICAgIEZvcm1EYXRhLkxJTkVfQlJFQUsubGVuZ3RoO1xuXG4gIC8vIGVtcHR5IG9yIGVpdGhlciBkb2Vzbid0IGhhdmUgcGF0aCBvciBub3QgYW4gaHR0cCByZXNwb25zZSBvciBub3QgYSBzdHJlYW1cbiAgaWYgKCF2YWx1ZSB8fCAoICF2YWx1ZS5wYXRoICYmICEodmFsdWUucmVhZGFibGUgJiYgdmFsdWUuaGFzT3duUHJvcGVydHkoJ2h0dHBWZXJzaW9uJykpICYmICEodmFsdWUgaW5zdGFuY2VvZiBTdHJlYW0pKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIG5vIG5lZWQgdG8gYm90aGVyIHdpdGggdGhlIGxlbmd0aFxuICBpZiAoIW9wdGlvbnMua25vd25MZW5ndGgpIHtcbiAgICB0aGlzLl92YWx1ZXNUb01lYXN1cmUucHVzaCh2YWx1ZSk7XG4gIH1cbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS5fbGVuZ3RoUmV0cmlldmVyID0gZnVuY3Rpb24odmFsdWUsIGNhbGxiYWNrKSB7XG5cbiAgaWYgKHZhbHVlLmhhc093blByb3BlcnR5KCdmZCcpKSB7XG5cbiAgICAvLyB0YWtlIHJlYWQgcmFuZ2UgaW50byBhIGFjY291bnRcbiAgICAvLyBgZW5kYCA9IEluZmluaXR5IOKAkz4gcmVhZCBmaWxlIHRpbGwgdGhlIGVuZFxuICAgIC8vXG4gICAgLy8gVE9ETzogTG9va3MgbGlrZSB0aGVyZSBpcyBidWcgaW4gTm9kZSBmcy5jcmVhdGVSZWFkU3RyZWFtXG4gICAgLy8gaXQgZG9lc24ndCByZXNwZWN0IGBlbmRgIG9wdGlvbnMgd2l0aG91dCBgc3RhcnRgIG9wdGlvbnNcbiAgICAvLyBGaXggaXQgd2hlbiBub2RlIGZpeGVzIGl0LlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qb3llbnQvbm9kZS9pc3N1ZXMvNzgxOVxuICAgIGlmICh2YWx1ZS5lbmQgIT0gdW5kZWZpbmVkICYmIHZhbHVlLmVuZCAhPSBJbmZpbml0eSAmJiB2YWx1ZS5zdGFydCAhPSB1bmRlZmluZWQpIHtcblxuICAgICAgLy8gd2hlbiBlbmQgc3BlY2lmaWVkXG4gICAgICAvLyBubyBuZWVkIHRvIGNhbGN1bGF0ZSByYW5nZVxuICAgICAgLy8gaW5jbHVzaXZlLCBzdGFydHMgd2l0aCAwXG4gICAgICBjYWxsYmFjayhudWxsLCB2YWx1ZS5lbmQgKyAxIC0gKHZhbHVlLnN0YXJ0ID8gdmFsdWUuc3RhcnQgOiAwKSk7XG5cbiAgICAvLyBub3QgdGhhdCBmYXN0IHNub29weVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBzdGlsbCBuZWVkIHRvIGZldGNoIGZpbGUgc2l6ZSBmcm9tIGZzXG4gICAgICBmcy5zdGF0KHZhbHVlLnBhdGgsIGZ1bmN0aW9uKGVyciwgc3RhdCkge1xuXG4gICAgICAgIHZhciBmaWxlU2l6ZTtcblxuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyB1cGRhdGUgZmluYWwgc2l6ZSBiYXNlZCBvbiB0aGUgcmFuZ2Ugb3B0aW9uc1xuICAgICAgICBmaWxlU2l6ZSA9IHN0YXQuc2l6ZSAtICh2YWx1ZS5zdGFydCA/IHZhbHVlLnN0YXJ0IDogMCk7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIGZpbGVTaXplKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAvLyBvciBodHRwIHJlc3BvbnNlXG4gIH0gZWxzZSBpZiAodmFsdWUuaGFzT3duUHJvcGVydHkoJ2h0dHBWZXJzaW9uJykpIHtcbiAgICBjYWxsYmFjayhudWxsLCArdmFsdWUuaGVhZGVyc1snY29udGVudC1sZW5ndGgnXSk7XG5cbiAgLy8gb3IgcmVxdWVzdCBzdHJlYW0gaHR0cDovL2dpdGh1Yi5jb20vbWlrZWFsL3JlcXVlc3RcbiAgfSBlbHNlIGlmICh2YWx1ZS5oYXNPd25Qcm9wZXJ0eSgnaHR0cE1vZHVsZScpKSB7XG4gICAgLy8gd2FpdCB0aWxsIHJlc3BvbnNlIGNvbWUgYmFja1xuICAgIHZhbHVlLm9uKCdyZXNwb25zZScsIGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgICB2YWx1ZS5wYXVzZSgpO1xuICAgICAgY2FsbGJhY2sobnVsbCwgK3Jlc3BvbnNlLmhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ10pO1xuICAgIH0pO1xuICAgIHZhbHVlLnJlc3VtZSgpO1xuXG4gIC8vIHNvbWV0aGluZyBlbHNlXG4gIH0gZWxzZSB7XG4gICAgY2FsbGJhY2soJ1Vua25vd24gc3RyZWFtJyk7XG4gIH1cbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS5fbXVsdGlQYXJ0SGVhZGVyID0gZnVuY3Rpb24oZmllbGQsIHZhbHVlLCBvcHRpb25zKSB7XG4gIC8vIGN1c3RvbSBoZWFkZXIgc3BlY2lmaWVkIChhcyBzdHJpbmcpP1xuICAvLyBpdCBiZWNvbWVzIHJlc3BvbnNpYmxlIGZvciBib3VuZGFyeVxuICAvLyAoZS5nLiB0byBoYW5kbGUgZXh0cmEgQ1JMRnMgb24gLk5FVCBzZXJ2ZXJzKVxuICBpZiAodHlwZW9mIG9wdGlvbnMuaGVhZGVyID09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG9wdGlvbnMuaGVhZGVyO1xuICB9XG5cbiAgdmFyIGNvbnRlbnREaXNwb3NpdGlvbiA9IHRoaXMuX2dldENvbnRlbnREaXNwb3NpdGlvbih2YWx1ZSwgb3B0aW9ucyk7XG4gIHZhciBjb250ZW50VHlwZSA9IHRoaXMuX2dldENvbnRlbnRUeXBlKHZhbHVlLCBvcHRpb25zKTtcblxuICB2YXIgY29udGVudHMgPSAnJztcbiAgdmFyIGhlYWRlcnMgID0ge1xuICAgIC8vIGFkZCBjdXN0b20gZGlzcG9zaXRpb24gYXMgdGhpcmQgZWxlbWVudCBvciBrZWVwIGl0IHR3byBlbGVtZW50cyBpZiBub3RcbiAgICAnQ29udGVudC1EaXNwb3NpdGlvbic6IFsnZm9ybS1kYXRhJywgJ25hbWU9XCInICsgZmllbGQgKyAnXCInXS5jb25jYXQoY29udGVudERpc3Bvc2l0aW9uIHx8IFtdKSxcbiAgICAvLyBpZiBubyBjb250ZW50IHR5cGUuIGFsbG93IGl0IHRvIGJlIGVtcHR5IGFycmF5XG4gICAgJ0NvbnRlbnQtVHlwZSc6IFtdLmNvbmNhdChjb250ZW50VHlwZSB8fCBbXSlcbiAgfTtcblxuICAvLyBhbGxvdyBjdXN0b20gaGVhZGVycy5cbiAgaWYgKHR5cGVvZiBvcHRpb25zLmhlYWRlciA9PSAnb2JqZWN0Jykge1xuICAgIHBvcHVsYXRlKGhlYWRlcnMsIG9wdGlvbnMuaGVhZGVyKTtcbiAgfVxuXG4gIHZhciBoZWFkZXI7XG4gIGZvciAodmFyIHByb3AgaW4gaGVhZGVycykge1xuICAgIGlmICghaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWU7XG4gICAgaGVhZGVyID0gaGVhZGVyc1twcm9wXTtcblxuICAgIC8vIHNraXAgbnVsbGlzaCBoZWFkZXJzLlxuICAgIGlmIChoZWFkZXIgPT0gbnVsbCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gY29udmVydCBhbGwgaGVhZGVycyB0byBhcnJheXMuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGhlYWRlcikpIHtcbiAgICAgIGhlYWRlciA9IFtoZWFkZXJdO1xuICAgIH1cblxuICAgIC8vIGFkZCBub24tZW1wdHkgaGVhZGVycy5cbiAgICBpZiAoaGVhZGVyLmxlbmd0aCkge1xuICAgICAgY29udGVudHMgKz0gcHJvcCArICc6ICcgKyBoZWFkZXIuam9pbignOyAnKSArIEZvcm1EYXRhLkxJTkVfQlJFQUs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICctLScgKyB0aGlzLmdldEJvdW5kYXJ5KCkgKyBGb3JtRGF0YS5MSU5FX0JSRUFLICsgY29udGVudHMgKyBGb3JtRGF0YS5MSU5FX0JSRUFLO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLl9nZXRDb250ZW50RGlzcG9zaXRpb24gPSBmdW5jdGlvbih2YWx1ZSwgb3B0aW9ucykge1xuXG4gIHZhciBmaWxlbmFtZVxuICAgICwgY29udGVudERpc3Bvc2l0aW9uXG4gICAgO1xuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5maWxlcGF0aCA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBjdXN0b20gZmlsZXBhdGggZm9yIHJlbGF0aXZlIHBhdGhzXG4gICAgZmlsZW5hbWUgPSBwYXRoLm5vcm1hbGl6ZShvcHRpb25zLmZpbGVwYXRoKS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG4gIH0gZWxzZSBpZiAob3B0aW9ucy5maWxlbmFtZSB8fCB2YWx1ZS5uYW1lIHx8IHZhbHVlLnBhdGgpIHtcbiAgICAvLyBjdXN0b20gZmlsZW5hbWUgdGFrZSBwcmVjZWRlbmNlXG4gICAgLy8gZm9ybWlkYWJsZSBhbmQgdGhlIGJyb3dzZXIgYWRkIGEgbmFtZSBwcm9wZXJ0eVxuICAgIC8vIGZzLSBhbmQgcmVxdWVzdC0gc3RyZWFtcyBoYXZlIHBhdGggcHJvcGVydHlcbiAgICBmaWxlbmFtZSA9IHBhdGguYmFzZW5hbWUob3B0aW9ucy5maWxlbmFtZSB8fCB2YWx1ZS5uYW1lIHx8IHZhbHVlLnBhdGgpO1xuICB9IGVsc2UgaWYgKHZhbHVlLnJlYWRhYmxlICYmIHZhbHVlLmhhc093blByb3BlcnR5KCdodHRwVmVyc2lvbicpKSB7XG4gICAgLy8gb3IgdHJ5IGh0dHAgcmVzcG9uc2VcbiAgICBmaWxlbmFtZSA9IHBhdGguYmFzZW5hbWUodmFsdWUuY2xpZW50Ll9odHRwTWVzc2FnZS5wYXRoIHx8ICcnKTtcbiAgfVxuXG4gIGlmIChmaWxlbmFtZSkge1xuICAgIGNvbnRlbnREaXNwb3NpdGlvbiA9ICdmaWxlbmFtZT1cIicgKyBmaWxlbmFtZSArICdcIic7XG4gIH1cblxuICByZXR1cm4gY29udGVudERpc3Bvc2l0aW9uO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLl9nZXRDb250ZW50VHlwZSA9IGZ1bmN0aW9uKHZhbHVlLCBvcHRpb25zKSB7XG5cbiAgLy8gdXNlIGN1c3RvbSBjb250ZW50LXR5cGUgYWJvdmUgYWxsXG4gIHZhciBjb250ZW50VHlwZSA9IG9wdGlvbnMuY29udGVudFR5cGU7XG5cbiAgLy8gb3IgdHJ5IGBuYW1lYCBmcm9tIGZvcm1pZGFibGUsIGJyb3dzZXJcbiAgaWYgKCFjb250ZW50VHlwZSAmJiB2YWx1ZS5uYW1lKSB7XG4gICAgY29udGVudFR5cGUgPSBtaW1lLmxvb2t1cCh2YWx1ZS5uYW1lKTtcbiAgfVxuXG4gIC8vIG9yIHRyeSBgcGF0aGAgZnJvbSBmcy0sIHJlcXVlc3QtIHN0cmVhbXNcbiAgaWYgKCFjb250ZW50VHlwZSAmJiB2YWx1ZS5wYXRoKSB7XG4gICAgY29udGVudFR5cGUgPSBtaW1lLmxvb2t1cCh2YWx1ZS5wYXRoKTtcbiAgfVxuXG4gIC8vIG9yIGlmIGl0J3MgaHR0cC1yZXBvbnNlXG4gIGlmICghY29udGVudFR5cGUgJiYgdmFsdWUucmVhZGFibGUgJiYgdmFsdWUuaGFzT3duUHJvcGVydHkoJ2h0dHBWZXJzaW9uJykpIHtcbiAgICBjb250ZW50VHlwZSA9IHZhbHVlLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddO1xuICB9XG5cbiAgLy8gb3IgZ3Vlc3MgaXQgZnJvbSB0aGUgZmlsZXBhdGggb3IgZmlsZW5hbWVcbiAgaWYgKCFjb250ZW50VHlwZSAmJiAob3B0aW9ucy5maWxlcGF0aCB8fCBvcHRpb25zLmZpbGVuYW1lKSkge1xuICAgIGNvbnRlbnRUeXBlID0gbWltZS5sb29rdXAob3B0aW9ucy5maWxlcGF0aCB8fCBvcHRpb25zLmZpbGVuYW1lKTtcbiAgfVxuXG4gIC8vIGZhbGxiYWNrIHRvIHRoZSBkZWZhdWx0IGNvbnRlbnQgdHlwZSBpZiBgdmFsdWVgIGlzIG5vdCBzaW1wbGUgdmFsdWVcbiAgaWYgKCFjb250ZW50VHlwZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcpIHtcbiAgICBjb250ZW50VHlwZSA9IEZvcm1EYXRhLkRFRkFVTFRfQ09OVEVOVF9UWVBFO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRlbnRUeXBlO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLl9tdWx0aVBhcnRGb290ZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG5leHQpIHtcbiAgICB2YXIgZm9vdGVyID0gRm9ybURhdGEuTElORV9CUkVBSztcblxuICAgIHZhciBsYXN0UGFydCA9ICh0aGlzLl9zdHJlYW1zLmxlbmd0aCA9PT0gMCk7XG4gICAgaWYgKGxhc3RQYXJ0KSB7XG4gICAgICBmb290ZXIgKz0gdGhpcy5fbGFzdEJvdW5kYXJ5KCk7XG4gICAgfVxuXG4gICAgbmV4dChmb290ZXIpO1xuICB9LmJpbmQodGhpcyk7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuX2xhc3RCb3VuZGFyeSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gJy0tJyArIHRoaXMuZ2V0Qm91bmRhcnkoKSArICctLScgKyBGb3JtRGF0YS5MSU5FX0JSRUFLO1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLmdldEhlYWRlcnMgPSBmdW5jdGlvbih1c2VySGVhZGVycykge1xuICB2YXIgaGVhZGVyO1xuICB2YXIgZm9ybUhlYWRlcnMgPSB7XG4gICAgJ2NvbnRlbnQtdHlwZSc6ICdtdWx0aXBhcnQvZm9ybS1kYXRhOyBib3VuZGFyeT0nICsgdGhpcy5nZXRCb3VuZGFyeSgpXG4gIH07XG5cbiAgZm9yIChoZWFkZXIgaW4gdXNlckhlYWRlcnMpIHtcbiAgICBpZiAodXNlckhlYWRlcnMuaGFzT3duUHJvcGVydHkoaGVhZGVyKSkge1xuICAgICAgZm9ybUhlYWRlcnNbaGVhZGVyLnRvTG93ZXJDYXNlKCldID0gdXNlckhlYWRlcnNbaGVhZGVyXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZm9ybUhlYWRlcnM7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuc2V0Qm91bmRhcnkgPSBmdW5jdGlvbihib3VuZGFyeSkge1xuICB0aGlzLl9ib3VuZGFyeSA9IGJvdW5kYXJ5O1xufTtcblxuRm9ybURhdGEucHJvdG90eXBlLmdldEJvdW5kYXJ5ID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5fYm91bmRhcnkpIHtcbiAgICB0aGlzLl9nZW5lcmF0ZUJvdW5kYXJ5KCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fYm91bmRhcnk7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuZ2V0QnVmZmVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkYXRhQnVmZmVyID0gbmV3IEJ1ZmZlci5hbGxvYyggMCApO1xuICB2YXIgYm91bmRhcnkgPSB0aGlzLmdldEJvdW5kYXJ5KCk7XG5cbiAgLy8gQ3JlYXRlIHRoZSBmb3JtIGNvbnRlbnQuIEFkZCBMaW5lIGJyZWFrcyB0byB0aGUgZW5kIG9mIGRhdGEuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0aGlzLl9zdHJlYW1zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9zdHJlYW1zW2ldICE9PSAnZnVuY3Rpb24nKSB7XG5cbiAgICAgIC8vIEFkZCBjb250ZW50IHRvIHRoZSBidWZmZXIuXG4gICAgICBpZihCdWZmZXIuaXNCdWZmZXIodGhpcy5fc3RyZWFtc1tpXSkpIHtcbiAgICAgICAgZGF0YUJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoIFtkYXRhQnVmZmVyLCB0aGlzLl9zdHJlYW1zW2ldXSk7XG4gICAgICB9ZWxzZSB7XG4gICAgICAgIGRhdGFCdWZmZXIgPSBCdWZmZXIuY29uY2F0KCBbZGF0YUJ1ZmZlciwgQnVmZmVyLmZyb20odGhpcy5fc3RyZWFtc1tpXSldKTtcbiAgICAgIH1cblxuICAgICAgLy8gQWRkIGJyZWFrIGFmdGVyIGNvbnRlbnQuXG4gICAgICBpZiAodHlwZW9mIHRoaXMuX3N0cmVhbXNbaV0gIT09ICdzdHJpbmcnIHx8IHRoaXMuX3N0cmVhbXNbaV0uc3Vic3RyaW5nKCAyLCBib3VuZGFyeS5sZW5ndGggKyAyICkgIT09IGJvdW5kYXJ5KSB7XG4gICAgICAgIGRhdGFCdWZmZXIgPSBCdWZmZXIuY29uY2F0KCBbZGF0YUJ1ZmZlciwgQnVmZmVyLmZyb20oRm9ybURhdGEuTElORV9CUkVBSyldICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQWRkIHRoZSBmb290ZXIgYW5kIHJldHVybiB0aGUgQnVmZmVyIG9iamVjdC5cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoIFtkYXRhQnVmZmVyLCBCdWZmZXIuZnJvbSh0aGlzLl9sYXN0Qm91bmRhcnkoKSldICk7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuX2dlbmVyYXRlQm91bmRhcnkgPSBmdW5jdGlvbigpIHtcbiAgLy8gVGhpcyBnZW5lcmF0ZXMgYSA1MCBjaGFyYWN0ZXIgYm91bmRhcnkgc2ltaWxhciB0byB0aG9zZSB1c2VkIGJ5IEZpcmVmb3guXG4gIC8vIFRoZXkgYXJlIG9wdGltaXplZCBmb3IgYm95ZXItbW9vcmUgcGFyc2luZy5cbiAgdmFyIGJvdW5kYXJ5ID0gJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNDsgaSsrKSB7XG4gICAgYm91bmRhcnkgKz0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTApLnRvU3RyaW5nKDE2KTtcbiAgfVxuXG4gIHRoaXMuX2JvdW5kYXJ5ID0gYm91bmRhcnk7XG59O1xuXG4vLyBOb3RlOiBnZXRMZW5ndGhTeW5jIERPRVNOJ1QgY2FsY3VsYXRlIHN0cmVhbXMgbGVuZ3RoXG4vLyBBcyB3b3JrYXJvdW5kIG9uZSBjYW4gY2FsY3VsYXRlIGZpbGUgc2l6ZSBtYW51YWxseVxuLy8gYW5kIGFkZCBpdCBhcyBrbm93bkxlbmd0aCBvcHRpb25cbkZvcm1EYXRhLnByb3RvdHlwZS5nZXRMZW5ndGhTeW5jID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrbm93bkxlbmd0aCA9IHRoaXMuX292ZXJoZWFkTGVuZ3RoICsgdGhpcy5fdmFsdWVMZW5ndGg7XG5cbiAgLy8gRG9uJ3QgZ2V0IGNvbmZ1c2VkLCB0aGVyZSBhcmUgMyBcImludGVybmFsXCIgc3RyZWFtcyBmb3IgZWFjaCBrZXl2YWwgcGFpclxuICAvLyBzbyBpdCBiYXNpY2FsbHkgY2hlY2tzIGlmIHRoZXJlIGlzIGFueSB2YWx1ZSBhZGRlZCB0byB0aGUgZm9ybVxuICBpZiAodGhpcy5fc3RyZWFtcy5sZW5ndGgpIHtcbiAgICBrbm93bkxlbmd0aCArPSB0aGlzLl9sYXN0Qm91bmRhcnkoKS5sZW5ndGg7XG4gIH1cblxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZm9ybS1kYXRhL2Zvcm0tZGF0YS9pc3N1ZXMvNDBcbiAgaWYgKCF0aGlzLmhhc0tub3duTGVuZ3RoKCkpIHtcbiAgICAvLyBTb21lIGFzeW5jIGxlbmd0aCByZXRyaWV2ZXJzIGFyZSBwcmVzZW50XG4gICAgLy8gdGhlcmVmb3JlIHN5bmNocm9ub3VzIGxlbmd0aCBjYWxjdWxhdGlvbiBpcyBmYWxzZS5cbiAgICAvLyBQbGVhc2UgdXNlIGdldExlbmd0aChjYWxsYmFjaykgdG8gZ2V0IHByb3BlciBsZW5ndGhcbiAgICB0aGlzLl9lcnJvcihuZXcgRXJyb3IoJ0Nhbm5vdCBjYWxjdWxhdGUgcHJvcGVyIGxlbmd0aCBpbiBzeW5jaHJvbm91cyB3YXkuJykpO1xuICB9XG5cbiAgcmV0dXJuIGtub3duTGVuZ3RoO1xufTtcblxuLy8gUHVibGljIEFQSSB0byBjaGVjayBpZiBsZW5ndGggb2YgYWRkZWQgdmFsdWVzIGlzIGtub3duXG4vLyBodHRwczovL2dpdGh1Yi5jb20vZm9ybS1kYXRhL2Zvcm0tZGF0YS9pc3N1ZXMvMTk2XG4vLyBodHRwczovL2dpdGh1Yi5jb20vZm9ybS1kYXRhL2Zvcm0tZGF0YS9pc3N1ZXMvMjYyXG5Gb3JtRGF0YS5wcm90b3R5cGUuaGFzS25vd25MZW5ndGggPSBmdW5jdGlvbigpIHtcbiAgdmFyIGhhc0tub3duTGVuZ3RoID0gdHJ1ZTtcblxuICBpZiAodGhpcy5fdmFsdWVzVG9NZWFzdXJlLmxlbmd0aCkge1xuICAgIGhhc0tub3duTGVuZ3RoID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gaGFzS25vd25MZW5ndGg7XG59O1xuXG5Gb3JtRGF0YS5wcm90b3R5cGUuZ2V0TGVuZ3RoID0gZnVuY3Rpb24oY2IpIHtcbiAgdmFyIGtub3duTGVuZ3RoID0gdGhpcy5fb3ZlcmhlYWRMZW5ndGggKyB0aGlzLl92YWx1ZUxlbmd0aDtcblxuICBpZiAodGhpcy5fc3RyZWFtcy5sZW5ndGgpIHtcbiAgICBrbm93bkxlbmd0aCArPSB0aGlzLl9sYXN0Qm91bmRhcnkoKS5sZW5ndGg7XG4gIH1cblxuICBpZiAoIXRoaXMuX3ZhbHVlc1RvTWVhc3VyZS5sZW5ndGgpIHtcbiAgICBwcm9jZXNzLm5leHRUaWNrKGNiLmJpbmQodGhpcywgbnVsbCwga25vd25MZW5ndGgpKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBhc3luY2tpdC5wYXJhbGxlbCh0aGlzLl92YWx1ZXNUb01lYXN1cmUsIHRoaXMuX2xlbmd0aFJldHJpZXZlciwgZnVuY3Rpb24oZXJyLCB2YWx1ZXMpIHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBjYihlcnIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uKGxlbmd0aCkge1xuICAgICAga25vd25MZW5ndGggKz0gbGVuZ3RoO1xuICAgIH0pO1xuXG4gICAgY2IobnVsbCwga25vd25MZW5ndGgpO1xuICB9KTtcbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS5zdWJtaXQgPSBmdW5jdGlvbihwYXJhbXMsIGNiKSB7XG4gIHZhciByZXF1ZXN0XG4gICAgLCBvcHRpb25zXG4gICAgLCBkZWZhdWx0cyA9IHttZXRob2Q6ICdwb3N0J31cbiAgICA7XG5cbiAgLy8gcGFyc2UgcHJvdmlkZWQgdXJsIGlmIGl0J3Mgc3RyaW5nXG4gIC8vIG9yIHRyZWF0IGl0IGFzIG9wdGlvbnMgb2JqZWN0XG4gIGlmICh0eXBlb2YgcGFyYW1zID09ICdzdHJpbmcnKSB7XG5cbiAgICBwYXJhbXMgPSBwYXJzZVVybChwYXJhbXMpO1xuICAgIG9wdGlvbnMgPSBwb3B1bGF0ZSh7XG4gICAgICBwb3J0OiBwYXJhbXMucG9ydCxcbiAgICAgIHBhdGg6IHBhcmFtcy5wYXRobmFtZSxcbiAgICAgIGhvc3Q6IHBhcmFtcy5ob3N0bmFtZSxcbiAgICAgIHByb3RvY29sOiBwYXJhbXMucHJvdG9jb2xcbiAgICB9LCBkZWZhdWx0cyk7XG5cbiAgLy8gdXNlIGN1c3RvbSBwYXJhbXNcbiAgfSBlbHNlIHtcblxuICAgIG9wdGlvbnMgPSBwb3B1bGF0ZShwYXJhbXMsIGRlZmF1bHRzKTtcbiAgICAvLyBpZiBubyBwb3J0IHByb3ZpZGVkIHVzZSBkZWZhdWx0IG9uZVxuICAgIGlmICghb3B0aW9ucy5wb3J0KSB7XG4gICAgICBvcHRpb25zLnBvcnQgPSBvcHRpb25zLnByb3RvY29sID09ICdodHRwczonID8gNDQzIDogODA7XG4gICAgfVxuICB9XG5cbiAgLy8gcHV0IHRoYXQgZ29vZCBjb2RlIGluIGdldEhlYWRlcnMgdG8gc29tZSB1c2VcbiAgb3B0aW9ucy5oZWFkZXJzID0gdGhpcy5nZXRIZWFkZXJzKHBhcmFtcy5oZWFkZXJzKTtcblxuICAvLyBodHRwcyBpZiBzcGVjaWZpZWQsIGZhbGxiYWNrIHRvIGh0dHAgaW4gYW55IG90aGVyIGNhc2VcbiAgaWYgKG9wdGlvbnMucHJvdG9jb2wgPT0gJ2h0dHBzOicpIHtcbiAgICByZXF1ZXN0ID0gaHR0cHMucmVxdWVzdChvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXF1ZXN0ID0gaHR0cC5yZXF1ZXN0KG9wdGlvbnMpO1xuICB9XG5cbiAgLy8gZ2V0IGNvbnRlbnQgbGVuZ3RoIGFuZCBmaXJlIGF3YXlcbiAgdGhpcy5nZXRMZW5ndGgoZnVuY3Rpb24oZXJyLCBsZW5ndGgpIHtcbiAgICBpZiAoZXJyICYmIGVyciAhPT0gJ1Vua25vd24gc3RyZWFtJykge1xuICAgICAgdGhpcy5fZXJyb3IoZXJyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBhZGQgY29udGVudCBsZW5ndGhcbiAgICBpZiAobGVuZ3RoKSB7XG4gICAgICByZXF1ZXN0LnNldEhlYWRlcignQ29udGVudC1MZW5ndGgnLCBsZW5ndGgpO1xuICAgIH1cblxuICAgIHRoaXMucGlwZShyZXF1ZXN0KTtcbiAgICBpZiAoY2IpIHtcbiAgICAgIHZhciBvblJlc3BvbnNlO1xuXG4gICAgICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbiAoZXJyb3IsIHJlc3BvbmNlKSB7XG4gICAgICAgIHJlcXVlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgY2FsbGJhY2spO1xuICAgICAgICByZXF1ZXN0LnJlbW92ZUxpc3RlbmVyKCdyZXNwb25zZScsIG9uUmVzcG9uc2UpO1xuXG4gICAgICAgIHJldHVybiBjYi5jYWxsKHRoaXMsIGVycm9yLCByZXNwb25jZSk7XG4gICAgICB9O1xuXG4gICAgICBvblJlc3BvbnNlID0gY2FsbGJhY2suYmluZCh0aGlzLCBudWxsKTtcblxuICAgICAgcmVxdWVzdC5vbignZXJyb3InLCBjYWxsYmFjayk7XG4gICAgICByZXF1ZXN0Lm9uKCdyZXNwb25zZScsIG9uUmVzcG9uc2UpO1xuICAgIH1cbiAgfS5iaW5kKHRoaXMpKTtcblxuICByZXR1cm4gcmVxdWVzdDtcbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS5fZXJyb3IgPSBmdW5jdGlvbihlcnIpIHtcbiAgaWYgKCF0aGlzLmVycm9yKSB7XG4gICAgdGhpcy5lcnJvciA9IGVycjtcbiAgICB0aGlzLnBhdXNlKCk7XG4gICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIH1cbn07XG5cbkZvcm1EYXRhLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICdbb2JqZWN0IEZvcm1EYXRhXSc7XG59O1xuIiwiLy8gcG9wdWxhdGVzIG1pc3NpbmcgdmFsdWVzXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGRzdCwgc3JjKSB7XG5cbiAgT2JqZWN0LmtleXMoc3JjKS5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApXG4gIHtcbiAgICBkc3RbcHJvcF0gPSBkc3RbcHJvcF0gfHwgc3JjW3Byb3BdO1xuICB9KTtcblxuICByZXR1cm4gZHN0O1xufTtcbiIsImltcG9ydCB7XG4gIEROU1JlY29yZCxcbiAgRG9tYWluRGF0YSxcbiAgRG9tYWluU2hvcnREYXRhLFxuICBURG9tYWluXG59IGZyb20gJy4uLy4uL1R5cGVzL0RvbWFpbnMnO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvbWFpbiBpbXBsZW1lbnRzIFREb21haW4ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHJlcXVpcmVfdGxzOiBib29sZWFuO1xuICBza2lwX3ZlcmlmaWNhdGlvbjogYm9vbGVhbjtcbiAgc3RhdGU6IHN0cmluZztcbiAgd2lsZGNhcmQ6IGJvb2xlYW47XG4gIHNwYW1fYWN0aW9uOiBzdHJpbmc7XG4gIGNyZWF0ZWRfYXQ6IHN0cmluZztcbiAgc210cF9wYXNzd29yZDogc3RyaW5nO1xuICBzbXRwX2xvZ2luOiBzdHJpbmc7XG4gIHR5cGU6IHN0cmluZztcbiAgcmVjZWl2aW5nX2Ruc19yZWNvcmRzOiBETlNSZWNvcmRbXSB8IG51bGw7XG4gIHNlbmRpbmdfZG5zX3JlY29yZHM6IEROU1JlY29yZFtdIHwgbnVsbDtcbiAgaWQ/OiBzdHJpbmc7XG4gIGlzX2Rpc2FibGVkPzogYm9vbGVhbjtcbiAgd2ViX3ByZWZpeD86IHN0cmluZztcbiAgd2ViX3NjaGVtZT86IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBkYXRhOiBEb21haW5TaG9ydERhdGEgfCBEb21haW5EYXRhLFxuICAgIHJlY2VpdmluZz86IEROU1JlY29yZFtdIHwgbnVsbCxcbiAgICBzZW5kaW5nPzogRE5TUmVjb3JkW10gfCBudWxsXG4gICkge1xuICAgIHRoaXMubmFtZSA9IGRhdGEubmFtZTtcbiAgICB0aGlzLnJlcXVpcmVfdGxzID0gZGF0YS5yZXF1aXJlX3RscztcbiAgICB0aGlzLnNraXBfdmVyaWZpY2F0aW9uID0gZGF0YS5za2lwX3ZlcmlmaWNhdGlvbjtcbiAgICB0aGlzLnN0YXRlID0gZGF0YS5zdGF0ZTtcbiAgICB0aGlzLndpbGRjYXJkID0gZGF0YS53aWxkY2FyZDtcbiAgICB0aGlzLnNwYW1fYWN0aW9uID0gZGF0YS5zcGFtX2FjdGlvbjtcbiAgICB0aGlzLmNyZWF0ZWRfYXQgPSBkYXRhLmNyZWF0ZWRfYXQ7XG4gICAgdGhpcy5zbXRwX3Bhc3N3b3JkID0gZGF0YS5zbXRwX3Bhc3N3b3JkO1xuICAgIHRoaXMuc210cF9sb2dpbiA9IGRhdGEuc210cF9sb2dpbjtcbiAgICB0aGlzLnR5cGUgPSBkYXRhLnR5cGU7XG4gICAgdGhpcy5yZWNlaXZpbmdfZG5zX3JlY29yZHMgPSByZWNlaXZpbmcgfHwgbnVsbDtcbiAgICB0aGlzLnNlbmRpbmdfZG5zX3JlY29yZHMgPSBzZW5kaW5nIHx8IG51bGw7XG4gICAgLypcbiAgICAgIGRvbWFpbiBsaXN0IGhhcyBzaG9ydGVyIHJlc3BvbnNlIHRoZW4gZ2V0LCBjcmVhdGUsIGFuZCB1cGRhdGUgbWV0aG9kcy5cbiAgICAqL1xuXG4gICAgY29uc3QgZHluYW1pY0tleXM6IChrZXlvZiBEb21haW5EYXRhKVtdID0gWydpZCcsICdpc19kaXNhYmxlZCcsICd3ZWJfcHJlZml4JywgJ3dlYl9zY2hlbWUnXTtcblxuICAgIGNvbnN0IGR5bmFtaWNQcm9wZXJ0aWVzID0gZHluYW1pY0tleXMucmVkdWNlKChhY2MsIHByb3BlcnR5TmFtZSkgPT4ge1xuICAgICAgaWYgKHByb3BlcnR5TmFtZSBpbiBkYXRhKSB7XG4gICAgICAgIGNvbnN0IHByb3AgPSBwcm9wZXJ0eU5hbWUgYXMga2V5b2YgRG9tYWluO1xuICAgICAgICBhY2NbcHJvcF0gPSAoZGF0YSBhcyBEb21haW5EYXRhKVtwcm9wZXJ0eU5hbWVdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBSZWNvcmQ8a2V5b2YgRG9tYWluLCBzdHJpbmcgfCBib29sZWFuPik7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBkeW5hbWljUHJvcGVydGllcyk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCB7XG4gIElEb21haW5UZW1wbGF0ZXNDbGllbnQsXG4gIElEb21haW5UYWdzQ2xpZW50LFxuICBJRG9tYWluQ3JlZGVudGlhbHMsXG4gIElEb21haW5zQ2xpZW50XG59IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvRG9tYWlucyc7XG5cbmltcG9ydCB7IEFQSVJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vVHlwZXMvQ29tbW9uL0FwaVJlc3BvbnNlJztcbmltcG9ydCBBUElFcnJvciBmcm9tICcuLi9jb21tb24vRXJyb3InO1xuaW1wb3J0IHsgQVBJRXJyb3JPcHRpb25zIH0gZnJvbSAnLi4vLi4vVHlwZXMvQ29tbW9uJztcblxuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5pbXBvcnQgRG9tYWluQ3JlZGVudGlhbHNDbGllbnQgZnJvbSAnLi9kb21haW5zQ3JlZGVudGlhbHMnO1xuaW1wb3J0IERvbWFpblRlbXBsYXRlc0NsaWVudCBmcm9tICcuL2RvbWFpbnNUZW1wbGF0ZXMnO1xuaW1wb3J0IERvbWFpblRhZ3NDbGllbnQgZnJvbSAnLi9kb21haW5zVGFncyc7XG5pbXBvcnQge1xuICBEZXN0cm95ZWREb21haW5SZXNwb25zZSxcbiAgTWVzc2FnZVJlc3BvbnNlLFxuICBEb21haW5MaXN0UmVzcG9uc2VEYXRhLFxuICBEb21haW5SZXNwb25zZURhdGEsXG4gIERvbWFpblRyYWNraW5nUmVzcG9uc2UsXG4gIERvbWFpblRyYWNraW5nRGF0YSxcbiAgVXBkYXRlRG9tYWluVHJhY2tpbmdSZXNwb25zZSxcbiAgVXBkYXRlZE9wZW5UcmFja2luZyxcbiAgRG9tYWluc1F1ZXJ5LFxuICBEb21haW5JbmZvLFxuICBDb25uZWN0aW9uU2V0dGluZ3MsXG4gIENvbm5lY3Rpb25TZXR0aW5nc1Jlc3BvbnNlLFxuICBVcGRhdGVkQ29ubmVjdGlvblNldHRpbmdzLFxuICBVcGRhdGVkQ29ubmVjdGlvblNldHRpbmdzUmVzLFxuICBPcGVuVHJhY2tpbmdJbmZvLFxuICBDbGlja1RyYWNraW5nSW5mbyxcbiAgVW5zdWJzY3JpYmVUcmFja2luZ0luZm8sXG4gIFJlcGxhY2VtZW50Rm9yUG9vbCxcbiAgREtJTUF1dGhvcml0eUluZm8sXG4gIFVwZGF0ZWRES0lNQXV0aG9yaXR5LFxuICBVcGRhdGVkREtJTUF1dGhvcml0eVJlc3BvbnNlLFxuICBES0lNU2VsZWN0b3JJbmZvLFxuICBVcGRhdGVkREtJTVNlbGVjdG9yUmVzcG9uc2UsXG4gIFdlYlByZWZpeEluZm8sXG4gIFVwZGF0ZWRXZWJQcmVmaXhSZXNwb25zZSxcbiAgVERvbWFpbixcbiAgRG9tYWluVXBkYXRlSW5mbyxcbiAgRG9tYWluVXBkYXRlSW5mb1JlcSxcbiAgRG9tYWluSW5mb1JlcSxcbiAgQm9vbFRvU3RyaW5nLFxufSBmcm9tICcuLi8uLi9UeXBlcy9Eb21haW5zJztcbmltcG9ydCBEb21haW4gZnJvbSAnLi9kb21haW4nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb21haW5zQ2xpZW50IGltcGxlbWVudHMgSURvbWFpbnNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuICBwdWJsaWMgZG9tYWluQ3JlZGVudGlhbHM6IElEb21haW5DcmVkZW50aWFscztcbiAgcHVibGljIGRvbWFpblRlbXBsYXRlczogSURvbWFpblRlbXBsYXRlc0NsaWVudDtcbiAgcHVibGljIGRvbWFpblRhZ3M6IElEb21haW5UYWdzQ2xpZW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlcXVlc3Q6IFJlcXVlc3QsXG4gICAgZG9tYWluQ3JlZGVudGlhbHNDbGllbnQ6IERvbWFpbkNyZWRlbnRpYWxzQ2xpZW50LFxuICAgIGRvbWFpblRlbXBsYXRlc0NsaWVudDogRG9tYWluVGVtcGxhdGVzQ2xpZW50LFxuICAgIGRvbWFpblRhZ3NDbGllbnQ6IERvbWFpblRhZ3NDbGllbnRcbiAgKSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLmRvbWFpbkNyZWRlbnRpYWxzID0gZG9tYWluQ3JlZGVudGlhbHNDbGllbnQ7XG4gICAgdGhpcy5kb21haW5UZW1wbGF0ZXMgPSBkb21haW5UZW1wbGF0ZXNDbGllbnQ7XG4gICAgdGhpcy5kb21haW5UYWdzID0gZG9tYWluVGFnc0NsaWVudDtcbiAgfVxuXG4gIHByaXZhdGUgX2hhbmRsZUJvb2xWYWx1ZXMoXG4gICAgZGF0YTogRG9tYWluSW5mbyB8IERvbWFpblVwZGF0ZUluZm9cbiAgKTogRG9tYWluSW5mb1JlcSB8IERvbWFpblVwZGF0ZUluZm9SZXEge1xuICAgIGNvbnN0IHByb3BzRm9yUmVwbGFjZW1lbnQgPSBkYXRhIGFzIEJvb2xUb1N0cmluZztcbiAgICBjb25zdCByZXBsYWNlZFByb3BzID0gT2JqZWN0LmtleXMocHJvcHNGb3JSZXBsYWNlbWVudCkucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgICAgY29uc3QgcHJvcCA9IGtleSBhcyBrZXlvZiBCb29sVG9TdHJpbmc7XG4gICAgICBpZiAodHlwZW9mIHByb3BzRm9yUmVwbGFjZW1lbnRbcHJvcF0gPT09ICdib29sZWFuJykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHByb3BzRm9yUmVwbGFjZW1lbnRbcHJvcF0gYXMgYm9vbGVhbjtcbiAgICAgICAgYWNjW3Byb3BdID0gKHZhbHVlLnRvU3RyaW5nKCkgPT09ICd0cnVlJykgPyAndHJ1ZScgOiAnZmFsc2UnO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBSZWNvcmQ8a2V5b2YgQm9vbFRvU3RyaW5nLCAndHJ1ZSd8ICdmYWxzZSc+KTtcbiAgICByZXR1cm4geyAuLi5kYXRhLCAuLi5yZXBsYWNlZFByb3BzIH0gYXMgRG9tYWluVXBkYXRlSW5mb1JlcSB8IERvbWFpbkluZm9SZXE7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZU1lc3NhZ2UocmVzcG9uc2U6IERlc3Ryb3llZERvbWFpblJlc3BvbnNlKSA6IE1lc3NhZ2VSZXNwb25zZSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRG9tYWluTGlzdChyZXNwb25zZTogRG9tYWluTGlzdFJlc3BvbnNlRGF0YSk6IFREb21haW5bXSB7XG4gICAgaWYgKHJlc3BvbnNlLmJvZHkgJiYgcmVzcG9uc2UuYm9keS5pdGVtcykge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkuaXRlbXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHJldHVybiBuZXcgRG9tYWluKGl0ZW0pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHByaXZhdGUgX3BhcnNlRG9tYWluKHJlc3BvbnNlOiBEb21haW5SZXNwb25zZURhdGEpOiBURG9tYWluIHtcbiAgICByZXR1cm4gbmV3IERvbWFpbihcbiAgICAgIHJlc3BvbnNlLmJvZHkuZG9tYWluLFxuICAgICAgcmVzcG9uc2UuYm9keS5yZWNlaXZpbmdfZG5zX3JlY29yZHMsXG4gICAgICByZXNwb25zZS5ib2R5LnNlbmRpbmdfZG5zX3JlY29yZHNcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VUcmFja2luZ1NldHRpbmdzKHJlc3BvbnNlOiBEb21haW5UcmFja2luZ1Jlc3BvbnNlKSA6IERvbWFpblRyYWNraW5nRGF0YSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkudHJhY2tpbmc7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVRyYWNraW5nVXBkYXRlKHJlc3BvbnNlOiBVcGRhdGVEb21haW5UcmFja2luZ1Jlc3BvbnNlKSA6VXBkYXRlZE9wZW5UcmFja2luZyB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gIH1cblxuICBsaXN0KHF1ZXJ5PzogRG9tYWluc1F1ZXJ5KTogUHJvbWlzZTxURG9tYWluW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCgnL3YzL2RvbWFpbnMnLCBxdWVyeSlcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5wYXJzZURvbWFpbkxpc3QocmVzIGFzIERvbWFpbkxpc3RSZXNwb25zZURhdGEpKTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZykgOiBQcm9taXNlPFREb21haW4+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgL3YzL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VEb21haW4ocmVzIGFzIERvbWFpblJlc3BvbnNlRGF0YSkpO1xuICB9XG5cbiAgY3JlYXRlKGRhdGE6IERvbWFpbkluZm8pIDogUHJvbWlzZTxURG9tYWluPiB7XG4gICAgY29uc3QgcG9zdE9iaiA9IHRoaXMuX2hhbmRsZUJvb2xWYWx1ZXMoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKCcvdjMvZG9tYWlucycsIHBvc3RPYmopXG4gICAgICAudGhlbigocmVzIDogQVBJUmVzcG9uc2UpID0+IHRoaXMuX3BhcnNlRG9tYWluKHJlcyBhcyBEb21haW5SZXNwb25zZURhdGEpKTtcbiAgfVxuXG4gIHVwZGF0ZShkb21haW46IHN0cmluZywgZGF0YTogRG9tYWluVXBkYXRlSW5mbykgOiBQcm9taXNlPFREb21haW4+IHtcbiAgICBjb25zdCBwdXREYXRhID0gdGhpcy5faGFuZGxlQm9vbFZhbHVlcyhkYXRhKTtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRChgL3YzL2RvbWFpbnMvJHtkb21haW59YCwgcHV0RGF0YSlcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VEb21haW4ocmVzIGFzIERvbWFpblJlc3BvbnNlRGF0YSkpO1xuICB9XG5cbiAgdmVyaWZ5KGRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTxURG9tYWluPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS92ZXJpZnlgKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURvbWFpbihyZXMgYXMgRG9tYWluUmVzcG9uc2VEYXRhKSk7XG4gIH1cblxuICBkZXN0cm95KGRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTxNZXNzYWdlUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YzL2RvbWFpbnMvJHtkb21haW59YClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VNZXNzYWdlKHJlcyBhcyBEZXN0cm95ZWREb21haW5SZXNwb25zZSkpO1xuICB9XG5cbiAgZ2V0Q29ubmVjdGlvbihkb21haW46IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvblNldHRpbmdzPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYC92My9kb21haW5zLyR7ZG9tYWlufS9jb25uZWN0aW9uYClcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gcmVzIGFzIENvbm5lY3Rpb25TZXR0aW5nc1Jlc3BvbnNlKVxuICAgICAgLnRoZW4oKHJlczpDb25uZWN0aW9uU2V0dGluZ3NSZXNwb25zZSkgPT4gcmVzLmJvZHkuY29ubmVjdGlvbiBhcyBDb25uZWN0aW9uU2V0dGluZ3MpO1xuICB9XG5cbiAgdXBkYXRlQ29ubmVjdGlvbihkb21haW46IHN0cmluZywgZGF0YTogQ29ubmVjdGlvblNldHRpbmdzKTogUHJvbWlzZTxVcGRhdGVkQ29ubmVjdGlvblNldHRpbmdzPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS9jb25uZWN0aW9uYCwgZGF0YSlcbiAgICAgIC50aGVuKChyZXMgOiBBUElSZXNwb25zZSkgPT4gcmVzIGFzIFVwZGF0ZWRDb25uZWN0aW9uU2V0dGluZ3NSZXMpXG4gICAgICAudGhlbigocmVzOlVwZGF0ZWRDb25uZWN0aW9uU2V0dGluZ3NSZXMpID0+IHJlcy5ib2R5IGFzIFVwZGF0ZWRDb25uZWN0aW9uU2V0dGluZ3MpO1xuICB9XG5cbiAgLy8gVHJhY2tpbmdcblxuICBnZXRUcmFja2luZyhkb21haW46IHN0cmluZykgOiBQcm9taXNlPERvbWFpblRyYWNraW5nRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4oJy92My9kb21haW5zJywgZG9tYWluLCAndHJhY2tpbmcnKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlVHJhY2tpbmdTZXR0aW5ncyk7XG4gIH1cblxuICB1cGRhdGVUcmFja2luZyhcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgZGF0YTogT3BlblRyYWNraW5nSW5mbyB8IENsaWNrVHJhY2tpbmdJbmZvIHwgVW5zdWJzY3JpYmVUcmFja2luZ0luZm9cbiAgKTogUHJvbWlzZTxVcGRhdGVkT3BlblRyYWNraW5nPiB7XG4gICAgaWYgKHR5cGVvZiBkYXRhPy5hY3RpdmUgPT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHsgc3RhdHVzOiA0MDAsIHN0YXR1c1RleHQ6ICdSZWNlaXZlZCBib29sZWFuIHZhbHVlIGZvciBhY3RpdmUgcHJvcGVydHknLCBib2R5OiB7IG1lc3NhZ2U6ICdQcm9wZXJ0eSBcImFjdGl2ZVwiIG11c3QgY29udGFpbiBzdHJpbmcgdmFsdWUuJyB9IH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICd0cmFja2luZycsIHR5cGUpLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZVRyYWNraW5nVXBkYXRlKHJlcyBhcyBVcGRhdGVEb21haW5UcmFja2luZ1Jlc3BvbnNlKSk7XG4gIH1cblxuICAvLyBJUHNcblxuICBnZXRJcHMoZG9tYWluOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICdpcHMnKSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogQVBJUmVzcG9uc2UpID0+IHJlc3BvbnNlPy5ib2R5Py5pdGVtcyk7XG4gIH1cblxuICBhc3NpZ25JcChkb21haW46IHN0cmluZywgaXA6IHN0cmluZyk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICdpcHMnKSwgeyBpcCB9KTtcbiAgfVxuXG4gIGRlbGV0ZUlwKGRvbWFpbjogc3RyaW5nLCBpcDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKHVybGpvaW4oJy92My9kb21haW5zJywgZG9tYWluLCAnaXBzJywgaXApKTtcbiAgfVxuXG4gIGxpbmtJcFBvb2woZG9tYWluOiBzdHJpbmcsIHBvb2xJZDogc3RyaW5nKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjMvZG9tYWlucycsIGRvbWFpbiwgJ2lwcycpLCB7IHBvb2xfaWQ6IHBvb2xJZCB9KTtcbiAgfVxuXG4gIHVubGlua0lwUG9sbChkb21haW46IHN0cmluZywgcmVwbGFjZW1lbnQ6IFJlcGxhY2VtZW50Rm9yUG9vbCk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBsZXQgc2VhcmNoUGFyYW1zID0gJyc7XG4gICAgaWYgKHJlcGxhY2VtZW50LnBvb2xfaWQgJiYgcmVwbGFjZW1lbnQuaXApIHtcbiAgICAgIHRocm93IG5ldyBBUElFcnJvcihcbiAgICAgICAge1xuICAgICAgICAgIHN0YXR1czogNDAwLFxuICAgICAgICAgIHN0YXR1c1RleHQ6ICdUb28gbXVjaCBkYXRhIGZvciByZXBsYWNlbWVudCcsXG4gICAgICAgICAgYm9keTogeyBtZXNzYWdlOiAnUGxlYXNlIHNwZWNpZnkgZWl0aGVyIHBvb2xfaWQgb3IgaXAgKG5vdCBib3RoKScgfVxuICAgICAgICB9IGFzIEFQSUVycm9yT3B0aW9uc1xuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHJlcGxhY2VtZW50LnBvb2xfaWQpIHtcbiAgICAgIHNlYXJjaFBhcmFtcyA9IGA/cG9vbF9pZD0ke3JlcGxhY2VtZW50LnBvb2xfaWR9YDtcbiAgICB9IGVsc2UgaWYgKHJlcGxhY2VtZW50LmlwKSB7XG4gICAgICBzZWFyY2hQYXJhbXMgPSBgP2lwPSR7cmVwbGFjZW1lbnQuaXB9YDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICdpcHMnLCAnaXBfcG9vbCcsIHNlYXJjaFBhcmFtcykpO1xuICB9XG5cbiAgdXBkYXRlREtJTUF1dGhvcml0eShkb21haW46IHN0cmluZywgZGF0YTogREtJTUF1dGhvcml0eUluZm8pOiBQcm9taXNlPFVwZGF0ZWRES0lNQXV0aG9yaXR5PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS9ka2ltX2F1dGhvcml0eWAsIHt9LCB7IHF1ZXJ5OiBgc2VsZj0ke2RhdGEuc2VsZn1gIH0pXG4gICAgICAudGhlbigocmVzIDogQVBJUmVzcG9uc2UpID0+IHJlcyBhcyBVcGRhdGVkREtJTUF1dGhvcml0eVJlc3BvbnNlKVxuICAgICAgLnRoZW4oKHJlcyA6IFVwZGF0ZWRES0lNQXV0aG9yaXR5UmVzcG9uc2UpID0+IHJlcy5ib2R5IGFzIFVwZGF0ZWRES0lNQXV0aG9yaXR5KTtcbiAgfVxuXG4gIHVwZGF0ZURLSU1TZWxlY3Rvcihkb21haW46IHN0cmluZywgZGF0YTogREtJTVNlbGVjdG9ySW5mbyk6IFByb21pc2U8VXBkYXRlZERLSU1TZWxlY3RvclJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS9ka2ltX3NlbGVjdG9yYCwge30sIHsgcXVlcnk6IGBka2ltX3NlbGVjdG9yPSR7ZGF0YS5ka2ltU2VsZWN0b3J9YCB9KVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiByZXMgYXMgVXBkYXRlZERLSU1TZWxlY3RvclJlc3BvbnNlKTtcbiAgfVxuXG4gIHVwZGF0ZVdlYlByZWZpeChkb21haW46IHN0cmluZywgZGF0YTogV2ViUHJlZml4SW5mbyk6IFByb21pc2U8VXBkYXRlZFdlYlByZWZpeFJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQoYC92My9kb21haW5zLyR7ZG9tYWlufS93ZWJfcHJlZml4YCwge30sIHsgcXVlcnk6IGB3ZWJfcHJlZml4PSR7ZGF0YS53ZWJQcmVmaXh9YCB9KVxuICAgICAgLnRoZW4oKHJlcyA6IEFQSVJlc3BvbnNlKSA9PiByZXMgYXMgVXBkYXRlZFdlYlByZWZpeFJlc3BvbnNlKTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHsgQVBJUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24vQXBpUmVzcG9uc2UnO1xuaW1wb3J0IHsgSURvbWFpbkNyZWRlbnRpYWxzIH0gZnJvbSAnLi4vLi4vSW50ZXJmYWNlcy9Eb21haW5zJztcbmltcG9ydCB7XG4gIERvbWFpbkNyZWRlbnRpYWxzUmVzcG9uc2VEYXRhLFxuICBEb21haW5DcmVkZW50aWFsc0xpc3QsXG4gIENyZWF0ZWRVcGRhdGVkRG9tYWluQ3JlZGVudGlhbHNSZXNwb25zZSxcbiAgRG9tYWluQ3JlZGVudGlhbHNSZXN1bHQsXG4gIERlbGV0ZWREb21haW5DcmVkZW50aWFsc1Jlc3BvbnNlLFxuICBEb21haW5DcmVkZW50aWFsc1F1ZXJ5LFxuICBEb21haW5DcmVkZW50aWFscyxcbiAgVXBkYXRlRG9tYWluQ3JlZGVudGlhbHNEYXRhXG59IGZyb20gJy4uLy4uL1R5cGVzL0RvbWFpbnMnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb21haW5DcmVkZW50aWFsc0NsaWVudCBpbXBsZW1lbnRzIElEb21haW5DcmVkZW50aWFscyB7XG4gIGJhc2VSb3V0ZTogc3RyaW5nO1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My9kb21haW5zLyc7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZURvbWFpbkNyZWRlbnRpYWxzTGlzdChcbiAgICByZXNwb25zZTogRG9tYWluQ3JlZGVudGlhbHNSZXNwb25zZURhdGFcbiAgKTogRG9tYWluQ3JlZGVudGlhbHNMaXN0IHtcbiAgICByZXR1cm4ge1xuICAgICAgaXRlbXM6IHJlc3BvbnNlLmJvZHkuaXRlbXMsXG4gICAgICB0b3RhbENvdW50OiByZXNwb25zZS5ib2R5LnRvdGFsX2NvdW50XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgX3BhcnNlTWVzc2FnZVJlc3BvbnNlKFxuICAgIHJlc3BvbnNlOiBDcmVhdGVkVXBkYXRlZERvbWFpbkNyZWRlbnRpYWxzUmVzcG9uc2VcbiAgKTogRG9tYWluQ3JlZGVudGlhbHNSZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlXG4gICAgfSBhcyBEb21haW5DcmVkZW50aWFsc1Jlc3VsdDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VEZWxldGVkUmVzcG9uc2UoXG4gICAgcmVzcG9uc2U6RGVsZXRlZERvbWFpbkNyZWRlbnRpYWxzUmVzcG9uc2VcbiAgKTogRG9tYWluQ3JlZGVudGlhbHNSZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlLFxuICAgICAgc3BlYzogcmVzcG9uc2UuYm9keS5zcGVjXG4gICAgfSBhcyBEb21haW5DcmVkZW50aWFsc1Jlc3VsdDtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBsaXN0KGRvbWFpbjogc3RyaW5nLCBxdWVyeT86IERvbWFpbkNyZWRlbnRpYWxzUXVlcnkpOiBQcm9taXNlPERvbWFpbkNyZWRlbnRpYWxzTGlzdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy9jcmVkZW50aWFscycpLCBxdWVyeSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VEb21haW5DcmVkZW50aWFsc0xpc3QocmVzIGFzIERvbWFpbkNyZWRlbnRpYWxzUmVzcG9uc2VEYXRhKVxuICAgICAgKTtcbiAgfVxuXG4gIGNyZWF0ZShcbiAgICBkb21haW46IHN0cmluZyxcbiAgICBkYXRhOiBEb21haW5DcmVkZW50aWFsc1xuICApOiBQcm9taXNlPERvbWFpbkNyZWRlbnRpYWxzUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKGAke3RoaXMuYmFzZVJvdXRlfSR7ZG9tYWlufS9jcmVkZW50aWFsc2AsIGRhdGEpXG4gICAgICAudGhlbigocmVzOiBBUElSZXNwb25zZSkgPT4gdGhpcy5fcGFyc2VNZXNzYWdlUmVzcG9uc2UocmVzKSk7XG4gIH1cblxuICB1cGRhdGUoXG4gICAgZG9tYWluOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHNMb2dpbjogc3RyaW5nLFxuICAgIGRhdGE6IFVwZGF0ZURvbWFpbkNyZWRlbnRpYWxzRGF0YVxuICApOiBQcm9taXNlPERvbWFpbkNyZWRlbnRpYWxzUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9JHtkb21haW59L2NyZWRlbnRpYWxzLyR7Y3JlZGVudGlhbHNMb2dpbn1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlczogQVBJUmVzcG9uc2UpID0+IHRoaXMuX3BhcnNlTWVzc2FnZVJlc3BvbnNlKHJlcykpO1xuICB9XG5cbiAgZGVzdHJveShcbiAgICBkb21haW46IHN0cmluZyxcbiAgICBjcmVkZW50aWFsc0xvZ2luOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxEb21haW5DcmVkZW50aWFsc1Jlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKGAke3RoaXMuYmFzZVJvdXRlfSR7ZG9tYWlufS9jcmVkZW50aWFscy8ke2NyZWRlbnRpYWxzTG9naW59YClcbiAgICAgIC50aGVuKChyZXM6IEFQSVJlc3BvbnNlKSA9PiB0aGlzLl9wYXJzZURlbGV0ZWRSZXNwb25zZShyZXMpKTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IHsgQVBJUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24vQXBpUmVzcG9uc2UnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5pbXBvcnQge1xuICBJRG9tYWluVGFnU3RhdGlzdGljUmVzdWx0LFxuICBJRG9tYWluVGFnc0NsaWVudFxufSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL0RvbWFpbnMnO1xuaW1wb3J0IE5hdmlnYXRpb25UaHJ1UGFnZXMgZnJvbSAnLi4vY29tbW9uL05hdmlnYXRpb25UaHJ1UGFnZXMnO1xuaW1wb3J0IHsgUmVzb2x1dGlvbiB9IGZyb20gJy4uLy4uL0VudW1zJztcbmltcG9ydCB7XG4gIERvbWFpblRhZ3NJdGVtLFxuICBEb21haW5UYWdzSXRlbUluZm8sXG4gIERvbWFpblRhZ1N0YXRpc3RpY0l0ZW0sXG4gIERvbWFpblRhZ1N0YXRBUElSZXNwb25zZSxcbiAgRG9tYWluVGFnQVBJUmVzcG9uc2VTdGF0c0l0ZW0sXG4gIERvbWFpblRhZ3NMaXN0LFxuICBEb21haW5UYWdzUmVzcG9uc2VEYXRhLFxuICBEb21haW5UYWdzUXVlcnksXG4gIERvbWFpblRhZ3NNZXNzYWdlUmVzLFxuICBEb21haW5UYWdzU3RhdGlzdGljUXVlcnksXG4gIERvbWFpblRhZ0NvdW50cmllc0FnZ3JlZ2F0aW9uLFxuICBEb21haW5UYWdDb3VudHJpZXNBUElSZXNwb25zZSxcbiAgRG9tYWluVGFnUHJvdmlkZXJzQWdncmVnYXRpb24sXG4gIERvbWFpblRhZ1Byb3ZpZGVyc0FQSVJlc3BvbnNlLFxuICBEb21haW5UYWdEZXZpY2VzQWdncmVnYXRpb24sXG4gIERvbWFpblRhZ0RldmljZXNBUElSZXNwb25zZVxufSBmcm9tICcuLi8uLi9UeXBlcy9Eb21haW5zJztcblxuZXhwb3J0IGNsYXNzIERvbWFpblRhZyBpbXBsZW1lbnRzIERvbWFpblRhZ3NJdGVtIHtcbiAgdGFnOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICdmaXJzdC1zZWVuJzogRGF0ZTtcbiAgJ2xhc3Qtc2Vlbic6IERhdGU7XG5cbiAgY29uc3RydWN0b3IodGFnSW5mbzogRG9tYWluVGFnc0l0ZW1JbmZvKSB7XG4gICAgdGhpcy50YWcgPSB0YWdJbmZvLnRhZztcbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gdGFnSW5mby5kZXNjcmlwdGlvbjtcbiAgICB0aGlzWydmaXJzdC1zZWVuJ10gPSBuZXcgRGF0ZSh0YWdJbmZvWydmaXJzdC1zZWVuJ10pO1xuICAgIHRoaXNbJ2xhc3Qtc2VlbiddID0gbmV3IERhdGUodGFnSW5mb1snbGFzdC1zZWVuJ10pO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEb21haW5UYWdTdGF0aXN0aWMgaW1wbGVtZW50cyBJRG9tYWluVGFnU3RhdGlzdGljUmVzdWx0IHtcbiAgdGFnOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHN0YXJ0OiBEYXRlO1xuICBlbmQ6IERhdGU7XG4gIHJlc29sdXRpb246IFJlc29sdXRpb247XG4gIHN0YXRzOiBEb21haW5UYWdTdGF0aXN0aWNJdGVtW107XG5cbiAgY29uc3RydWN0b3IodGFnU3RhdGlzdGljSW5mbzogRG9tYWluVGFnU3RhdEFQSVJlc3BvbnNlKSB7XG4gICAgdGhpcy50YWcgPSB0YWdTdGF0aXN0aWNJbmZvLmJvZHkudGFnO1xuICAgIHRoaXMuZGVzY3JpcHRpb24gPSB0YWdTdGF0aXN0aWNJbmZvLmJvZHkuZGVzY3JpcHRpb247XG4gICAgdGhpcy5zdGFydCA9IG5ldyBEYXRlKHRhZ1N0YXRpc3RpY0luZm8uYm9keS5zdGFydCk7XG4gICAgdGhpcy5lbmQgPSBuZXcgRGF0ZSh0YWdTdGF0aXN0aWNJbmZvLmJvZHkuZW5kKTtcbiAgICB0aGlzLnJlc29sdXRpb24gPSB0YWdTdGF0aXN0aWNJbmZvLmJvZHkucmVzb2x1dGlvbjtcbiAgICB0aGlzLnN0YXRzID0gdGFnU3RhdGlzdGljSW5mby5ib2R5LnN0YXRzLm1hcChmdW5jdGlvbiAoc3RhdDogRG9tYWluVGFnQVBJUmVzcG9uc2VTdGF0c0l0ZW0pIHtcbiAgICAgIGNvbnN0IHJlcyA9IHsgLi4uc3RhdCwgdGltZTogbmV3IERhdGUoc3RhdC50aW1lKSB9O1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEb21haW5UYWdzQ2xpZW50XG4gIGV4dGVuZHMgTmF2aWdhdGlvblRocnVQYWdlczxEb21haW5UYWdzTGlzdD5cbiAgaW1wbGVtZW50cyBJRG9tYWluVGFnc0NsaWVudCB7XG4gIGJhc2VSb3V0ZTogc3RyaW5nO1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICBzdXBlcihyZXF1ZXN0KTtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMuYmFzZVJvdXRlID0gJy92My8nO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChcbiAgICByZXNwb25zZTogRG9tYWluVGFnc1Jlc3BvbnNlRGF0YSxcbiAgKTogRG9tYWluVGFnc0xpc3Qge1xuICAgIGNvbnN0IGRhdGEgPSB7fSBhcyBEb21haW5UYWdzTGlzdDtcbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoKHRhZ0luZm86IERvbWFpblRhZ3NJdGVtSW5mbykgPT4gbmV3IERvbWFpblRhZyh0YWdJbmZvKSk7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZSwgJz8nLCAndGFnJyk7XG4gICAgZGF0YS5zdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVRhZ1N0YXRpc3RpYyhcbiAgICByZXNwb25zZTogRG9tYWluVGFnU3RhdEFQSVJlc3BvbnNlXG4gICk6IElEb21haW5UYWdTdGF0aXN0aWNSZXN1bHQge1xuICAgIHJldHVybiBuZXcgRG9tYWluVGFnU3RhdGlzdGljKHJlc3BvbnNlKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3QoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5PzogRG9tYWluVGFnc1F1ZXJ5KTogUHJvbWlzZTxEb21haW5UYWdzTGlzdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RMaXN0V2l0aFBhZ2VzKHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90YWdzJyksIHF1ZXJ5KTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZywgdGFnOiBzdHJpbmcpOiBQcm9taXNlPERvbWFpblRhZ3NJdGVtPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RhZ3MnLCB0YWcpKVxuICAgICAgLnRoZW4oXG4gICAgICAgIChyZXM6IEFQSVJlc3BvbnNlKSA9PiBuZXcgRG9tYWluVGFnKHJlcy5ib2R5KVxuICAgICAgKTtcbiAgfVxuXG4gIHVwZGF0ZShkb21haW46IHN0cmluZywgdGFnOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiBzdHJpbmcpOiBQcm9taXNlPERvbWFpblRhZ3NNZXNzYWdlUmVzPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RhZ3MnLCB0YWcpLCBkZXNjcmlwdGlvbilcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBBUElSZXNwb25zZSkgPT4gcmVzLmJvZHkgYXMgRG9tYWluVGFnc01lc3NhZ2VSZXNcbiAgICAgICk7XG4gIH1cblxuICBkZXN0cm95KFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRhZzogc3RyaW5nXG4gICk6IFByb21pc2U8RG9tYWluVGFnc01lc3NhZ2VSZXM+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgJHt0aGlzLmJhc2VSb3V0ZX0ke2RvbWFpbn0vdGFncy8ke3RhZ31gKVxuICAgICAgLnRoZW4oKHJlczogQVBJUmVzcG9uc2UpID0+IChcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6IHJlcy5ib2R5Lm1lc3NhZ2UsXG4gICAgICAgICAgc3RhdHVzOiByZXMuc3RhdHVzXG4gICAgICAgIH0gYXMgRG9tYWluVGFnc01lc3NhZ2VSZXMpKTtcbiAgfVxuXG4gIHN0YXRpc3RpYyhkb21haW46IHN0cmluZywgdGFnOiBzdHJpbmcsIHF1ZXJ5OiBEb21haW5UYWdzU3RhdGlzdGljUXVlcnkpXG4gICAgOiBQcm9taXNlPERvbWFpblRhZ1N0YXRpc3RpYz4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90YWdzJywgdGFnLCAnc3RhdHMnKSwgcXVlcnkpXG4gICAgICAudGhlbihcbiAgICAgICAgKHJlczogQVBJUmVzcG9uc2UpID0+IHRoaXMuX3BhcnNlVGFnU3RhdGlzdGljKHJlcylcbiAgICAgICk7XG4gIH1cblxuICBjb3VudHJpZXMoZG9tYWluOiBzdHJpbmcsIHRhZzogc3RyaW5nKTogUHJvbWlzZTxEb21haW5UYWdDb3VudHJpZXNBZ2dyZWdhdGlvbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90YWdzJywgdGFnLCAnc3RhdHMvYWdncmVnYXRlcy9jb3VudHJpZXMnKSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBEb21haW5UYWdDb3VudHJpZXNBUElSZXNwb25zZSkgPT4gcmVzLmJvZHkgYXMgRG9tYWluVGFnQ291bnRyaWVzQWdncmVnYXRpb25cbiAgICAgICk7XG4gIH1cblxuICBwcm92aWRlcnMoZG9tYWluOiBzdHJpbmcsIHRhZzogc3RyaW5nKTogUHJvbWlzZTxEb21haW5UYWdQcm92aWRlcnNBZ2dyZWdhdGlvbj4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90YWdzJywgdGFnLCAnc3RhdHMvYWdncmVnYXRlcy9wcm92aWRlcnMnKSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBEb21haW5UYWdQcm92aWRlcnNBUElSZXNwb25zZSkgPT4gcmVzLmJvZHkgYXMgRG9tYWluVGFnUHJvdmlkZXJzQWdncmVnYXRpb25cbiAgICAgICk7XG4gIH1cblxuICBkZXZpY2VzKGRvbWFpbjogc3RyaW5nLCB0YWc6IHN0cmluZyk6IFByb21pc2U8RG9tYWluVGFnRGV2aWNlc0FnZ3JlZ2F0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RhZ3MnLCB0YWcsICdzdGF0cy9hZ2dyZWdhdGVzL2RldmljZXMnKSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBEb21haW5UYWdEZXZpY2VzQVBJUmVzcG9uc2UpID0+IHJlcy5ib2R5IGFzIERvbWFpblRhZ0RldmljZXNBZ2dyZWdhdGlvblxuICAgICAgKTtcbiAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5pbXBvcnQge1xuICBDcmVhdGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlLFxuICBDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25BUElSZXNwb25zZSxcbiAgQ3JlYXRlRG9tYWluVGVtcGxhdGVWZXJzaW9uUmVzdWx0LFxuICBEb21haW5UZW1wbGF0ZURhdGEsXG4gIERvbWFpblRlbXBsYXRlc1F1ZXJ5LFxuICBEb21haW5UZW1wbGF0ZVVwZGF0ZURhdGEsXG4gIERvbWFpblRlbXBsYXRlVXBkYXRlVmVyc2lvbkRhdGEsXG4gIERvbWFpblRlbXBsYXRlVmVyc2lvbkRhdGEsXG4gIEdldERvbWFpblRlbXBsYXRlQVBJUmVzcG9uc2UsXG4gIExpc3REb21haW5UZW1wbGF0ZXNBUElSZXNwb25zZSxcbiAgTGlzdERvbWFpblRlbXBsYXRlc1Jlc3VsdCxcbiAgTGlzdERvbWFpblRlbXBsYXRlVmVyc2lvbnNBUElSZXNwb25zZSxcbiAgTGlzdERvbWFpblRlbXBsYXRlVmVyc2lvbnNSZXN1bHQsXG4gIE11dGF0ZURvbWFpblRlbXBsYXRlVmVyc2lvbkFQSVJlc3BvbnNlLFxuICBNdXRhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQsXG4gIE5vdGlmaWNhdGlvbkFQSVJlc3BvbnNlLFxuICBOb3RpZmljYXRpb25SZXN1bHQsXG4gIFNob3J0VGVtcGxhdGVWZXJzaW9uLFxuICBUZW1wbGF0ZVF1ZXJ5LFxuICBUZW1wbGF0ZVZlcnNpb24sXG4gIFVwZGF0ZU9yRGVsZXRlRG9tYWluVGVtcGxhdGVBUElSZXNwb25zZSxcbiAgVXBkYXRlT3JEZWxldGVEb21haW5UZW1wbGF0ZVJlc3VsdFxufSBmcm9tICcuLi8uLi9UeXBlcy9Eb21haW5zJztcbmltcG9ydCBOYXZpZ2F0aW9uVGhydVBhZ2VzIGZyb20gJy4uL2NvbW1vbi9OYXZpZ2F0aW9uVGhydVBhZ2VzJztcbmltcG9ydCB7IElEb21haW5UZW1wbGF0ZSwgSURvbWFpblRlbXBsYXRlc0NsaWVudCB9IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvRG9tYWlucyc7XG5cbmV4cG9ydCBjbGFzcyBEb21haW5UZW1wbGF0ZUl0ZW0gaW1wbGVtZW50cyBJRG9tYWluVGVtcGxhdGUge1xuICBuYW1lIDogc3RyaW5nO1xuICBkZXNjcmlwdGlvbiA6IHN0cmluZztcbiAgY3JlYXRlZEF0IDogRGF0ZSB8ICcnO1xuICBjcmVhdGVkQnkgOiBzdHJpbmc7XG4gIGlkIDogc3RyaW5nO1xuICB2ZXJzaW9uPzogVGVtcGxhdGVWZXJzaW9uO1xuICB2ZXJzaW9ucz86IFNob3J0VGVtcGxhdGVWZXJzaW9uW107XG5cbiAgY29uc3RydWN0b3IoZG9tYWluVGVtcGxhdGVGcm9tQVBJOiBJRG9tYWluVGVtcGxhdGUpIHtcbiAgICB0aGlzLm5hbWUgPSBkb21haW5UZW1wbGF0ZUZyb21BUEkubmFtZTtcbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gZG9tYWluVGVtcGxhdGVGcm9tQVBJLmRlc2NyaXB0aW9uO1xuICAgIHRoaXMuY3JlYXRlZEF0ID0gZG9tYWluVGVtcGxhdGVGcm9tQVBJLmNyZWF0ZWRBdCA/IG5ldyBEYXRlKGRvbWFpblRlbXBsYXRlRnJvbUFQSS5jcmVhdGVkQXQpIDogJyc7XG4gICAgdGhpcy5jcmVhdGVkQnkgPSBkb21haW5UZW1wbGF0ZUZyb21BUEkuY3JlYXRlZEJ5O1xuICAgIHRoaXMuaWQgPSBkb21haW5UZW1wbGF0ZUZyb21BUEkuaWQ7XG5cbiAgICBpZiAoZG9tYWluVGVtcGxhdGVGcm9tQVBJLnZlcnNpb24pIHtcbiAgICAgIHRoaXMudmVyc2lvbiA9IGRvbWFpblRlbXBsYXRlRnJvbUFQSS52ZXJzaW9uO1xuICAgICAgaWYgKGRvbWFpblRlbXBsYXRlRnJvbUFQSS52ZXJzaW9uLmNyZWF0ZWRBdCkge1xuICAgICAgICB0aGlzLnZlcnNpb24uY3JlYXRlZEF0ID0gbmV3IERhdGUoZG9tYWluVGVtcGxhdGVGcm9tQVBJLnZlcnNpb24uY3JlYXRlZEF0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZG9tYWluVGVtcGxhdGVGcm9tQVBJLnZlcnNpb25zICYmIGRvbWFpblRlbXBsYXRlRnJvbUFQSS52ZXJzaW9ucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMudmVyc2lvbnMgPSBkb21haW5UZW1wbGF0ZUZyb21BUEkudmVyc2lvbnMubWFwKCh2ZXJzaW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHsgLi4udmVyc2lvbiB9O1xuICAgICAgICByZXN1bHQuY3JlYXRlZEF0ID0gbmV3IERhdGUodmVyc2lvbi5jcmVhdGVkQXQpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERvbWFpblRlbXBsYXRlc0NsaWVudFxuICBleHRlbmRzIE5hdmlnYXRpb25UaHJ1UGFnZXM8TGlzdERvbWFpblRlbXBsYXRlc1Jlc3VsdD5cbiAgaW1wbGVtZW50cyBJRG9tYWluVGVtcGxhdGVzQ2xpZW50IHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHN1cGVyKHJlcXVlc3QpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdGhpcy5iYXNlUm91dGUgPSAnL3YzLyc7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQ3JlYXRpb25SZXNwb25zZShkYXRhOiBDcmVhdGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlKTogSURvbWFpblRlbXBsYXRlIHtcbiAgICByZXR1cm4gbmV3IERvbWFpblRlbXBsYXRlSXRlbShkYXRhLmJvZHkudGVtcGxhdGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUNyZWF0aW9uVmVyc2lvblJlc3BvbnNlKFxuICAgIGRhdGE6IENyZWF0ZURvbWFpblRlbXBsYXRlVmVyc2lvbkFQSVJlc3BvbnNlXG4gICk6IENyZWF0ZURvbWFpblRlbXBsYXRlVmVyc2lvblJlc3VsdCB7XG4gICAgY29uc3QgcmVzdWx0OiBDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQgPSB7fSBhcyBDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQ7XG4gICAgcmVzdWx0LnN0YXR1cyA9IGRhdGEuc3RhdHVzO1xuICAgIHJlc3VsdC5tZXNzYWdlID0gZGF0YS5ib2R5Lm1lc3NhZ2U7XG4gICAgaWYgKGRhdGEuYm9keSAmJiBkYXRhLmJvZHkudGVtcGxhdGUpIHtcbiAgICAgIHJlc3VsdC50ZW1wbGF0ZSA9IG5ldyBEb21haW5UZW1wbGF0ZUl0ZW0oZGF0YS5ib2R5LnRlbXBsYXRlKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VNdXRhdGlvblJlc3BvbnNlKFxuICAgIGRhdGE6IFVwZGF0ZU9yRGVsZXRlRG9tYWluVGVtcGxhdGVBUElSZXNwb25zZVxuICApOiBVcGRhdGVPckRlbGV0ZURvbWFpblRlbXBsYXRlUmVzdWx0IHtcbiAgICBjb25zdCByZXN1bHQ6IFVwZGF0ZU9yRGVsZXRlRG9tYWluVGVtcGxhdGVSZXN1bHQgPSB7fSBhcyBVcGRhdGVPckRlbGV0ZURvbWFpblRlbXBsYXRlUmVzdWx0O1xuICAgIHJlc3VsdC5zdGF0dXMgPSBkYXRhLnN0YXR1cztcbiAgICByZXN1bHQubWVzc2FnZSA9IGRhdGEuYm9keS5tZXNzYWdlO1xuICAgIGlmIChkYXRhLmJvZHkgJiYgZGF0YS5ib2R5LnRlbXBsYXRlKSB7XG4gICAgICByZXN1bHQudGVtcGxhdGVOYW1lID0gZGF0YS5ib2R5LnRlbXBsYXRlLm5hbWU7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTm90aWZpY2F0aW9uUmVzcG9uc2UoZGF0YTogTm90aWZpY2F0aW9uQVBJUmVzcG9uc2UpOiBOb3RpZmljYXRpb25SZXN1bHQge1xuICAgIGNvbnN0IHJlc3VsdDogTm90aWZpY2F0aW9uUmVzdWx0ID0ge30gYXMgTm90aWZpY2F0aW9uUmVzdWx0O1xuICAgIHJlc3VsdC5zdGF0dXMgPSBkYXRhLnN0YXR1cztcbiAgICByZXN1bHQubWVzc2FnZSA9IGRhdGEuYm9keS5tZXNzYWdlO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTXV0YXRlVGVtcGxhdGVWZXJzaW9uUmVzcG9uc2UoXG4gICAgZGF0YTogTXV0YXRlRG9tYWluVGVtcGxhdGVWZXJzaW9uQVBJUmVzcG9uc2VcbiAgKTogTXV0YXRlRG9tYWluVGVtcGxhdGVWZXJzaW9uUmVzdWx0IHtcbiAgICBjb25zdCByZXN1bHQ6IE11dGF0ZURvbWFpblRlbXBsYXRlVmVyc2lvblJlc3VsdCA9IHt9IGFzIE11dGF0ZURvbWFpblRlbXBsYXRlVmVyc2lvblJlc3VsdDtcbiAgICByZXN1bHQuc3RhdHVzID0gZGF0YS5zdGF0dXM7XG4gICAgcmVzdWx0Lm1lc3NhZ2UgPSBkYXRhLmJvZHkubWVzc2FnZTtcbiAgICBpZiAoZGF0YS5ib2R5LnRlbXBsYXRlKSB7XG4gICAgICByZXN1bHQudGVtcGxhdGVOYW1lID0gZGF0YS5ib2R5LnRlbXBsYXRlLm5hbWU7XG4gICAgICByZXN1bHQudGVtcGxhdGVWZXJzaW9uID0geyB0YWc6IGRhdGEuYm9keS50ZW1wbGF0ZS52ZXJzaW9uLnRhZyB9O1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChyZXNwb25zZTogTGlzdERvbWFpblRlbXBsYXRlc0FQSVJlc3BvbnNlKTogTGlzdERvbWFpblRlbXBsYXRlc1Jlc3VsdCB7XG4gICAgY29uc3QgZGF0YSA9IHt9IGFzIExpc3REb21haW5UZW1wbGF0ZXNSZXN1bHQ7XG5cbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcy5tYXAoKGQ6IElEb21haW5UZW1wbGF0ZSkgPT4gbmV3IERvbWFpblRlbXBsYXRlSXRlbShkKSk7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZSwgJz8nLCAncCcpO1xuICAgIGRhdGEuc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTGlzdFRlbXBsYXRlVmVyc2lvbnMoXG4gICAgcmVzcG9uc2U6IExpc3REb21haW5UZW1wbGF0ZVZlcnNpb25zQVBJUmVzcG9uc2VcbiAgKTogTGlzdERvbWFpblRlbXBsYXRlVmVyc2lvbnNSZXN1bHQge1xuICAgIGNvbnN0IGRhdGEgPSB7fSBhcyBMaXN0RG9tYWluVGVtcGxhdGVWZXJzaW9uc1Jlc3VsdDtcblxuICAgIGRhdGEudGVtcGxhdGUgPSBuZXcgRG9tYWluVGVtcGxhdGVJdGVtKHJlc3BvbnNlLmJvZHkudGVtcGxhdGUpO1xuXG4gICAgZGF0YS5wYWdlcyA9IHRoaXMucGFyc2VQYWdlTGlua3MocmVzcG9uc2UsICc/JywgJ3AnKTtcblxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgYXN5bmMgbGlzdChkb21haW46IHN0cmluZywgcXVlcnk/OiBEb21haW5UZW1wbGF0ZXNRdWVyeSk6IFByb21pc2U8TGlzdERvbWFpblRlbXBsYXRlc1Jlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RMaXN0V2l0aFBhZ2VzKHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90ZW1wbGF0ZXMnKSwgcXVlcnkpO1xuICB9XG5cbiAgZ2V0KGRvbWFpbjogc3RyaW5nLCB0ZW1wbGF0ZU5hbWU6IHN0cmluZywgcXVlcnk/OiBUZW1wbGF0ZVF1ZXJ5KTogUHJvbWlzZTxJRG9tYWluVGVtcGxhdGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCh1cmxqb2luKHRoaXMuYmFzZVJvdXRlLCBkb21haW4sICcvdGVtcGxhdGVzLycsIHRlbXBsYXRlTmFtZSksIHF1ZXJ5KVxuICAgICAgLnRoZW4oXG4gICAgICAgIChyZXM6IEdldERvbWFpblRlbXBsYXRlQVBJUmVzcG9uc2UpID0+IG5ldyBEb21haW5UZW1wbGF0ZUl0ZW0ocmVzLmJvZHkudGVtcGxhdGUpXG4gICAgICApO1xuICB9XG5cbiAgY3JlYXRlKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIGRhdGE6IERvbWFpblRlbXBsYXRlRGF0YVxuICApOiBQcm9taXNlPElEb21haW5UZW1wbGF0ZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKHRoaXMuYmFzZVJvdXRlLCBkb21haW4sICcvdGVtcGxhdGVzJyksIGRhdGEpXG4gICAgICAudGhlbigocmVzOiBDcmVhdGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlQ3JlYXRpb25SZXNwb25zZShyZXMpKTtcbiAgfVxuXG4gIHVwZGF0ZShcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0ZW1wbGF0ZU5hbWU6IHN0cmluZyxcbiAgICBkYXRhOiBEb21haW5UZW1wbGF0ZVVwZGF0ZURhdGFcbiAgKTogUHJvbWlzZTxVcGRhdGVPckRlbGV0ZURvbWFpblRlbXBsYXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RlbXBsYXRlcy8nLCB0ZW1wbGF0ZU5hbWUpLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlczogVXBkYXRlT3JEZWxldGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlTXV0YXRpb25SZXNwb25zZShyZXMpKTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcsIHRlbXBsYXRlTmFtZTogc3RyaW5nKTogUHJvbWlzZTxVcGRhdGVPckRlbGV0ZURvbWFpblRlbXBsYXRlUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RlbXBsYXRlcy8nLCB0ZW1wbGF0ZU5hbWUpKVxuICAgICAgLnRoZW4oKHJlczogVXBkYXRlT3JEZWxldGVEb21haW5UZW1wbGF0ZUFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlTXV0YXRpb25SZXNwb25zZShyZXMpKTtcbiAgfVxuXG4gIGRlc3Ryb3lBbGwoZG9tYWluOiBzdHJpbmcpOiBQcm9taXNlPE5vdGlmaWNhdGlvblJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZGVsZXRlKHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90ZW1wbGF0ZXMnKSlcbiAgICAgIC50aGVuKChyZXM6IE5vdGlmaWNhdGlvbkFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlTm90aWZpY2F0aW9uUmVzcG9uc2UocmVzKSk7XG4gIH1cblxuICBjcmVhdGVWZXJzaW9uKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nLFxuICAgIGRhdGE6IERvbWFpblRlbXBsYXRlVmVyc2lvbkRhdGFcbiAgKTogUHJvbWlzZTxDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RlbXBsYXRlcy8nLCB0ZW1wbGF0ZU5hbWUsICcvdmVyc2lvbnMnKSwgZGF0YSlcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzOiBDcmVhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25BUElSZXNwb25zZSkgPT4gdGhpcy5wYXJzZUNyZWF0aW9uVmVyc2lvblJlc3BvbnNlKHJlcylcbiAgICAgICk7XG4gIH1cblxuICBnZXRWZXJzaW9uKGRvbWFpbjogc3RyaW5nLCB0ZW1wbGF0ZU5hbWU6IHN0cmluZywgdGFnOiBzdHJpbmcpOiBQcm9taXNlPElEb21haW5UZW1wbGF0ZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90ZW1wbGF0ZXMvJywgdGVtcGxhdGVOYW1lLCAnL3ZlcnNpb25zLycsIHRhZykpXG4gICAgICAudGhlbihcbiAgICAgICAgKHJlczogR2V0RG9tYWluVGVtcGxhdGVBUElSZXNwb25zZSkgPT4gbmV3IERvbWFpblRlbXBsYXRlSXRlbShyZXMuYm9keS50ZW1wbGF0ZSlcbiAgICAgICk7XG4gIH1cblxuICB1cGRhdGVWZXJzaW9uKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nLFxuICAgIHRhZzogc3RyaW5nLFxuICAgIGRhdGE6IERvbWFpblRlbXBsYXRlVXBkYXRlVmVyc2lvbkRhdGFcbiAgKTogUHJvbWlzZTxNdXRhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25SZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKHRoaXMuYmFzZVJvdXRlLCBkb21haW4sICcvdGVtcGxhdGVzLycsIHRlbXBsYXRlTmFtZSwgJy92ZXJzaW9ucy8nLCB0YWcpLCBkYXRhKVxuICAgICAgLnRoZW4oXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIChyZXM6IE11dGF0ZURvbWFpblRlbXBsYXRlVmVyc2lvbkFQSVJlc3BvbnNlKSA9PiB0aGlzLnBhcnNlTXV0YXRlVGVtcGxhdGVWZXJzaW9uUmVzcG9uc2UocmVzKVxuICAgICAgKTtcbiAgfVxuXG4gIGRlc3Ryb3lWZXJzaW9uKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nLFxuICAgIHRhZzogc3RyaW5nXG4gICk6IFByb21pc2U8TXV0YXRlRG9tYWluVGVtcGxhdGVWZXJzaW9uUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbih0aGlzLmJhc2VSb3V0ZSwgZG9tYWluLCAnL3RlbXBsYXRlcy8nLCB0ZW1wbGF0ZU5hbWUsICcvdmVyc2lvbnMvJywgdGFnKSlcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAudGhlbigocmVzOiBNdXRhdGVEb21haW5UZW1wbGF0ZVZlcnNpb25BUElSZXNwb25zZSkgPT4gdGhpcy5wYXJzZU11dGF0ZVRlbXBsYXRlVmVyc2lvblJlc3BvbnNlKHJlcykpO1xuICB9XG5cbiAgbGlzdFZlcnNpb25zKFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHRlbXBsYXRlTmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5PzogRG9tYWluVGVtcGxhdGVzUXVlcnlcbiAgKTogUHJvbWlzZTxMaXN0RG9tYWluVGVtcGxhdGVWZXJzaW9uc1Jlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4odGhpcy5iYXNlUm91dGUsIGRvbWFpbiwgJy90ZW1wbGF0ZXMnLCB0ZW1wbGF0ZU5hbWUsICcvdmVyc2lvbnMnKSwgcXVlcnkpXG4gICAgICAudGhlbihcbiAgICAgICAgKHJlczogTGlzdERvbWFpblRlbXBsYXRlVmVyc2lvbnNBUElSZXNwb25zZSkgPT4gdGhpcy5wYXJzZUxpc3RUZW1wbGF0ZVZlcnNpb25zKHJlcylcbiAgICAgICk7XG4gIH1cbn1cbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBOYXZpZ2F0aW9uVGhydVBhZ2VzIGZyb20gJy4vY29tbW9uL05hdmlnYXRpb25UaHJ1UGFnZXMnO1xuaW1wb3J0IHtcbiAgRXZlbnRzTGlzdCxcbiAgRXZlbnRzUXVlcnksXG4gIEV2ZW50c1Jlc3BvbnNlLFxufSBmcm9tICcuLi9UeXBlcy9FdmVudHMnO1xuXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7IElFdmVudENsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFdmVudENsaWVudFxuICBleHRlbmRzIE5hdmlnYXRpb25UaHJ1UGFnZXM8RXZlbnRzTGlzdD5cbiAgaW1wbGVtZW50cyBJRXZlbnRDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICBzdXBlcihyZXF1ZXN0KTtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChcbiAgICByZXNwb25zZTogRXZlbnRzUmVzcG9uc2UsXG4gICk6IEV2ZW50c0xpc3Qge1xuICAgIGNvbnN0IGRhdGEgPSB7fSBhcyBFdmVudHNMaXN0O1xuICAgIGRhdGEuaXRlbXMgPSByZXNwb25zZS5ib2R5Lml0ZW1zO1xuXG4gICAgZGF0YS5wYWdlcyA9IHRoaXMucGFyc2VQYWdlTGlua3MocmVzcG9uc2UsICcvJyk7XG4gICAgZGF0YS5zdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyBnZXQoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5PzogRXZlbnRzUXVlcnkpIDogUHJvbWlzZTxFdmVudHNMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdExpc3RXaXRoUGFnZXModXJsam9pbignL3YzJywgZG9tYWluLCAnZXZlbnRzJyksIHF1ZXJ5KTtcbiAgfVxufVxuIiwiLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL2NvbW1vbi9SZXF1ZXN0JztcblxuaW1wb3J0IHtcbiAgSXBQb29sQ3JlYXRlRGF0YSxcbiAgSXBQb29sQ3JlYXRlUmVzcG9uc2UsXG4gIElwUG9vbENyZWF0ZVJlc3VsdCxcbiAgSXBQb29sRGVsZXRlRGF0YSxcbiAgSXBQb29sTGlzdFJlc3BvbnNlLFxuICBJcFBvb2xMaXN0UmVzdWx0LFxuICBJcFBvb2xNZXNzYWdlUmVzcG9uc2UsXG4gIElwUG9vbE1lc3NhZ2VSZXN1bHQsXG4gIElwUG9vbFVwZGF0ZURhdGEsXG59IGZyb20gJy4uL1R5cGVzL0lQUG9vbHMnO1xuaW1wb3J0IHsgSUlQUG9vbHNDbGllbnQgfSBmcm9tICcuLi9JbnRlcmZhY2VzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSXBQb29sc0NsaWVudCBpbXBsZW1lbnRzIElJUFBvb2xzQ2xpZW50IHtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIGxpc3QoKTogUHJvbWlzZTxJcFBvb2xMaXN0UmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoJy92MS9pcF9wb29scycpXG4gICAgICAudGhlbigocmVzcG9uc2U6IElwUG9vbExpc3RSZXNwb25zZSkgPT4gdGhpcy5wYXJzZUlwUG9vbHNSZXNwb25zZShyZXNwb25zZSkpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlKGRhdGE6IElwUG9vbENyZWF0ZURhdGEpOiBQcm9taXNlPElwUG9vbENyZWF0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlOiBJcFBvb2xDcmVhdGVSZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKCcvdjEvaXBfcG9vbHMnLCBkYXRhKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAuLi5yZXNwb25zZS5ib2R5XG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZShwb29sSWQ6IHN0cmluZywgZGF0YTogSXBQb29sVXBkYXRlRGF0YSk6IFByb21pc2U8SXBQb29sTWVzc2FnZVJlc3VsdD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlOiBJcFBvb2xNZXNzYWdlUmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QucGF0Y2hXaXRoRkQoYC92MS9pcF9wb29scy8ke3Bvb2xJZH1gLCBkYXRhKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAuLi5yZXNwb25zZS5ib2R5XG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZShwb29sSWQ6IHN0cmluZywgZGF0YTogSXBQb29sRGVsZXRlRGF0YSk6IFByb21pc2U8SXBQb29sTWVzc2FnZVJlc3VsdD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlOklwUG9vbE1lc3NhZ2VSZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdC5kZWxldGUoYC92MS9pcF9wb29scy8ke3Bvb2xJZH1gLCBkYXRhKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAuLi5yZXNwb25zZS5ib2R5XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJcFBvb2xzUmVzcG9uc2UocmVzcG9uc2U6IElwUG9vbExpc3RSZXNwb25zZSk6IElwUG9vbExpc3RSZXN1bHQge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIC4uLnJlc3BvbnNlLmJvZHlcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgTWdSZXF1ZXN0IGZyb20gJy4vY29tbW9uL1JlcXVlc3QnO1xuaW1wb3J0IHsgSXBEYXRhLCBJUHNMaXN0UXVlcnksIElwc0xpc3RSZXNwb25zZUJvZHkgfSBmcm9tICcuLi9UeXBlcy9JUHMnO1xuaW1wb3J0IHsgSUlQc0NsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJcHNDbGllbnQgaW1wbGVtZW50cyBJSVBzQ2xpZW50IHtcbiAgcmVxdWVzdDogTWdSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IE1nUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBhc3luYyBsaXN0KHF1ZXJ5PzogSVBzTGlzdFF1ZXJ5KTogUHJvbWlzZTxJcHNMaXN0UmVzcG9uc2VCb2R5PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvaXBzJywgcXVlcnkpO1xuICAgIHJldHVybiB0aGlzLnBhcnNlSXBzUmVzcG9uc2U8SXBzTGlzdFJlc3BvbnNlQm9keT4ocmVzcG9uc2UpO1xuICB9XG5cbiAgYXN5bmMgZ2V0KGlwOiBzdHJpbmcpOiBQcm9taXNlPElwRGF0YT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yZXF1ZXN0LmdldChgL3YzL2lwcy8ke2lwfWApO1xuICAgIHJldHVybiB0aGlzLnBhcnNlSXBzUmVzcG9uc2U8SXBEYXRhPihyZXNwb25zZSk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlSXBzUmVzcG9uc2U8VD4ocmVzcG9uc2U6IHsgYm9keTogVCB9KTogVCB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHk7XG4gIH1cbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi9jb21tb24vUmVxdWVzdCc7XG5pbXBvcnQgeyBNYWlsZ3VuQ2xpZW50T3B0aW9ucywgSW5wdXRGb3JtRGF0YSwgUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuLi9UeXBlcyc7XG5cbmltcG9ydCBEb21haW5zQ2xpZW50IGZyb20gJy4vRG9tYWlucy9kb21haW5zQ2xpZW50JztcbmltcG9ydCBFdmVudENsaWVudCBmcm9tICcuL0V2ZW50cyc7XG5pbXBvcnQgU3RhdHNDbGllbnQgZnJvbSAnLi9TdGF0cy9TdGF0c0NsaWVudCc7XG5pbXBvcnQgU3VwcHJlc3Npb25DbGllbnQgZnJvbSAnLi9TdXBwcmVzc2lvbnMvU3VwcHJlc3Npb25zQ2xpZW50JztcbmltcG9ydCBXZWJob29rc0NsaWVudCBmcm9tICcuL1dlYmhvb2tzJztcbmltcG9ydCBNZXNzYWdlc0NsaWVudCBmcm9tICcuL01lc3NhZ2VzJztcbmltcG9ydCBSb3V0ZXNDbGllbnQgZnJvbSAnLi9Sb3V0ZXMnO1xuaW1wb3J0IFZhbGlkYXRlQ2xpZW50IGZyb20gJy4vVmFsaWRhdGlvbnMvdmFsaWRhdGUnO1xuaW1wb3J0IElwc0NsaWVudCBmcm9tICcuL0lQcyc7XG5pbXBvcnQgSXBQb29sc0NsaWVudCBmcm9tICcuL0lQUG9vbHMnO1xuaW1wb3J0IE1haWxpbmdMaXN0c0NsaWVudCBmcm9tICcuL01haWxpbmdMaXN0cy9tYWlsaW5nTGlzdHMnO1xuaW1wb3J0IE1haWxMaXN0c01lbWJlcnMgZnJvbSAnLi9NYWlsaW5nTGlzdHMvbWFpbExpc3RNZW1iZXJzJztcbmltcG9ydCBEb21haW5DcmVkZW50aWFsc0NsaWVudCBmcm9tICcuL0RvbWFpbnMvZG9tYWluc0NyZWRlbnRpYWxzJztcbmltcG9ydCBNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQgZnJvbSAnLi9WYWxpZGF0aW9ucy9tdWx0aXBsZVZhbGlkYXRpb24nO1xuaW1wb3J0IERvbWFpblRlbXBsYXRlc0NsaWVudCBmcm9tICcuL0RvbWFpbnMvZG9tYWluc1RlbXBsYXRlcyc7XG5pbXBvcnQgRG9tYWluVGFnc0NsaWVudCBmcm9tICcuL0RvbWFpbnMvZG9tYWluc1RhZ3MnO1xuaW1wb3J0IFN1YmFjY291bnRzQ2xpZW50IGZyb20gJy4vU3ViYWNjb3VudHMnO1xuXG5pbXBvcnQge1xuICBJRG9tYWluc0NsaWVudCxcbiAgSVdlYkhvb2tzQ2xpZW50LFxuICBJTWFpbGd1bkNsaWVudCxcbiAgSU1haWxpbmdMaXN0c0NsaWVudCxcbiAgSUV2ZW50Q2xpZW50LFxuICBJU3RhdHNDbGllbnQsXG4gIElTdXBwcmVzc2lvbkNsaWVudCxcbiAgSU1lc3NhZ2VzQ2xpZW50LFxuICBJUm91dGVzQ2xpZW50LFxuICBJVmFsaWRhdGlvbkNsaWVudCxcbiAgSUlQc0NsaWVudCxcbiAgSUlQUG9vbHNDbGllbnQsXG4gIElTdWJhY2NvdW50c0NsaWVudCxcbn0gZnJvbSAnLi4vSW50ZXJmYWNlcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1haWxndW5DbGllbnQgaW1wbGVtZW50cyBJTWFpbGd1bkNsaWVudCB7XG4gIHByaXZhdGUgcmVxdWVzdDtcblxuICBwdWJsaWMgZG9tYWluczogSURvbWFpbnNDbGllbnQ7XG4gIHB1YmxpYyB3ZWJob29rczogSVdlYkhvb2tzQ2xpZW50O1xuICBwdWJsaWMgZXZlbnRzOiBJRXZlbnRDbGllbnQ7XG4gIHB1YmxpYyBzdGF0czogSVN0YXRzQ2xpZW50O1xuICBwdWJsaWMgc3VwcHJlc3Npb25zOiBJU3VwcHJlc3Npb25DbGllbnQ7XG4gIHB1YmxpYyBtZXNzYWdlczogSU1lc3NhZ2VzQ2xpZW50O1xuICBwdWJsaWMgcm91dGVzOiBJUm91dGVzQ2xpZW50O1xuICBwdWJsaWMgdmFsaWRhdGU6IElWYWxpZGF0aW9uQ2xpZW50O1xuICBwdWJsaWMgaXBzOiBJSVBzQ2xpZW50O1xuICBwdWJsaWMgaXBfcG9vbHM6IElJUFBvb2xzQ2xpZW50O1xuICBwdWJsaWMgbGlzdHM6IElNYWlsaW5nTGlzdHNDbGllbnQ7XG4gIHB1YmxpYyBzdWJhY2NvdW50czogSVN1YmFjY291bnRzQ2xpZW50O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE1haWxndW5DbGllbnRPcHRpb25zLCBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YSkge1xuICAgIGNvbnN0IGNvbmZpZzogUmVxdWVzdE9wdGlvbnMgPSB7IC4uLm9wdGlvbnMgfSBhcyBSZXF1ZXN0T3B0aW9ucztcblxuICAgIGlmICghY29uZmlnLnVybCkge1xuICAgICAgY29uZmlnLnVybCA9ICdodHRwczovL2FwaS5tYWlsZ3VuLm5ldCc7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcudXNlcm5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGFyYW1ldGVyIFwidXNlcm5hbWVcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLmtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJhbWV0ZXIgXCJrZXlcIiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICB0aGlzLnJlcXVlc3QgPSBuZXcgUmVxdWVzdChjb25maWcsIGZvcm1EYXRhKTtcbiAgICBjb25zdCBtYWlsTGlzdHNNZW1iZXJzID0gbmV3IE1haWxMaXN0c01lbWJlcnModGhpcy5yZXF1ZXN0KTtcbiAgICBjb25zdCBkb21haW5DcmVkZW50aWFsc0NsaWVudCA9IG5ldyBEb21haW5DcmVkZW50aWFsc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIGNvbnN0IGRvbWFpblRlbXBsYXRlc0NsaWVudCA9IG5ldyBEb21haW5UZW1wbGF0ZXNDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICBjb25zdCBkb21haW5UYWdzQ2xpZW50ID0gbmV3IERvbWFpblRhZ3NDbGllbnQodGhpcy5yZXF1ZXN0KTtcbiAgICBjb25zdCBtdWx0aXBsZVZhbGlkYXRpb25DbGllbnQgPSBuZXcgTXVsdGlwbGVWYWxpZGF0aW9uQ2xpZW50KHRoaXMucmVxdWVzdCk7XG5cbiAgICB0aGlzLmRvbWFpbnMgPSBuZXcgRG9tYWluc0NsaWVudChcbiAgICAgIHRoaXMucmVxdWVzdCxcbiAgICAgIGRvbWFpbkNyZWRlbnRpYWxzQ2xpZW50LFxuICAgICAgZG9tYWluVGVtcGxhdGVzQ2xpZW50LFxuICAgICAgZG9tYWluVGFnc0NsaWVudFxuICAgICk7XG4gICAgdGhpcy53ZWJob29rcyA9IG5ldyBXZWJob29rc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuZXZlbnRzID0gbmV3IEV2ZW50Q2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5zdGF0cyA9IG5ldyBTdGF0c0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuc3VwcHJlc3Npb25zID0gbmV3IFN1cHByZXNzaW9uQ2xpZW50KHRoaXMucmVxdWVzdCk7XG4gICAgdGhpcy5tZXNzYWdlcyA9IG5ldyBNZXNzYWdlc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMucm91dGVzID0gbmV3IFJvdXRlc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuaXBzID0gbmV3IElwc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMuaXBfcG9vbHMgPSBuZXcgSXBQb29sc0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICAgIHRoaXMubGlzdHMgPSBuZXcgTWFpbGluZ0xpc3RzQ2xpZW50KHRoaXMucmVxdWVzdCwgbWFpbExpc3RzTWVtYmVycyk7XG4gICAgdGhpcy52YWxpZGF0ZSA9IG5ldyBWYWxpZGF0ZUNsaWVudCh0aGlzLnJlcXVlc3QsIG11bHRpcGxlVmFsaWRhdGlvbkNsaWVudCk7XG4gICAgdGhpcy5zdWJhY2NvdW50cyA9IG5ldyBTdWJhY2NvdW50c0NsaWVudCh0aGlzLnJlcXVlc3QpO1xuICB9XG5cbiAgc2V0U3ViYWNjb3VudChzdWJhY2NvdW50SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMucmVxdWVzdD8uc2V0U3ViYWNjb3VudEhlYWRlcihzdWJhY2NvdW50SWQpO1xuICB9XG5cbiAgcmVzZXRTdWJhY2NvdW50KCk6IHZvaWQge1xuICAgIHRoaXMucmVxdWVzdD8ucmVzZXRTdWJhY2NvdW50SGVhZGVyKCk7XG4gIH1cbn1cbiIsImltcG9ydCBSZXF1ZXN0IGZyb20gJy4uL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7XG4gIE1haWxMaXN0TWVtYmVyc1F1ZXJ5LFxuICBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnMsXG4gIE1haWxMaXN0TWVtYmVyLFxuICBNdWx0aXBsZU1lbWJlcnNEYXRhLFxuICBNdWx0aXBsZU1lbWJlcnNSZXFEYXRhLFxuICBEZWxldGVkTWVtYmVyLFxuICBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnNSZXEsXG4gIE5ld011bHRpcGxlTWVtYmVyc1Jlc3BvbnNlLFxuICBNYWlsTGlzdE1lbWJlcnNSZXN1bHQsXG4gIE1haWxMaXN0TWVtYmVyc1Jlc3BvbnNlXG59IGZyb20gJy4uLy4uL1R5cGVzL01haWxpbmdMaXN0cyc7XG5pbXBvcnQgTmF2aWdhdGlvblRocnVQYWdlcyBmcm9tICcuLi9jb21tb24vTmF2aWdhdGlvblRocnVQYWdlcyc7XG5pbXBvcnQgeyBJTWFpbExpc3RzTWVtYmVycyB9IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvTWFpbGluZ0xpc3RzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFpbExpc3RzTWVtYmVyc1xuICBleHRlbmRzIE5hdmlnYXRpb25UaHJ1UGFnZXM8TWFpbExpc3RNZW1iZXJzUmVzdWx0PlxuICBpbXBsZW1lbnRzIElNYWlsTGlzdHNNZW1iZXJzIHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHN1cGVyKHJlcXVlc3QpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdGhpcy5iYXNlUm91dGUgPSAnL3YzL2xpc3RzJztcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tBbmRVcGRhdGVEYXRhKGRhdGE6IENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVycykge1xuICAgIGNvbnN0IG5ld0RhdGEgPSB7IC4uLmRhdGEgfTtcblxuICAgIGlmICh0eXBlb2YgZGF0YS52YXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgbmV3RGF0YS52YXJzID0gSlNPTi5zdHJpbmdpZnkobmV3RGF0YS52YXJzKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGRhdGEuc3Vic2NyaWJlZCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBuZXdEYXRhLnN1YnNjcmliZWQgPSBkYXRhLnN1YnNjcmliZWQgPyAneWVzJyA6ICdubyc7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ld0RhdGEgYXMgQ3JlYXRlVXBkYXRlTWFpbExpc3RNZW1iZXJzUmVxO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChcbiAgICByZXNwb25zZTogTWFpbExpc3RNZW1iZXJzUmVzcG9uc2UsXG4gICk6IE1haWxMaXN0TWVtYmVyc1Jlc3VsdCB7XG4gICAgY29uc3QgZGF0YSA9IHt9IGFzIE1haWxMaXN0TWVtYmVyc1Jlc3VsdDtcbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcztcblxuICAgIGRhdGEucGFnZXMgPSB0aGlzLnBhcnNlUGFnZUxpbmtzKHJlc3BvbnNlLCAnPycsICdhZGRyZXNzJyk7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyBsaXN0TWVtYmVycyhcbiAgICBtYWlsTGlzdEFkZHJlc3M6IHN0cmluZyxcbiAgICBxdWVyeT86IE1haWxMaXN0TWVtYmVyc1F1ZXJ5XG4gICk6IFByb21pc2U8TWFpbExpc3RNZW1iZXJzUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdExpc3RXaXRoUGFnZXMoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzL3BhZ2VzYCwgcXVlcnkpO1xuICB9XG5cbiAgZ2V0TWVtYmVyKG1haWxMaXN0QWRkcmVzczogc3RyaW5nLCBtYWlsTGlzdE1lbWJlckFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8TWFpbExpc3RNZW1iZXI+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMvJHttYWlsTGlzdE1lbWJlckFkZHJlc3N9YClcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5tZW1iZXIgYXMgTWFpbExpc3RNZW1iZXIpO1xuICB9XG5cbiAgY3JlYXRlTWVtYmVyKFxuICAgIG1haWxMaXN0QWRkcmVzczogc3RyaW5nLFxuICAgIGRhdGE6IENyZWF0ZVVwZGF0ZU1haWxMaXN0TWVtYmVyc1xuICApOiBQcm9taXNlPE1haWxMaXN0TWVtYmVyPiB7XG4gICAgY29uc3QgcmVxRGF0YSA9IHRoaXMuY2hlY2tBbmRVcGRhdGVEYXRhKGRhdGEpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnNgLCByZXFEYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5Lm1lbWJlciBhcyBNYWlsTGlzdE1lbWJlcik7XG4gIH1cblxuICBjcmVhdGVNZW1iZXJzKFxuICAgIG1haWxMaXN0QWRkcmVzczogc3RyaW5nLFxuICAgIGRhdGE6IE11bHRpcGxlTWVtYmVyc0RhdGFcbiAgKTogUHJvbWlzZTxOZXdNdWx0aXBsZU1lbWJlcnNSZXNwb25zZT4ge1xuICAgIGNvbnN0IG5ld0RhdGE6IE11bHRpcGxlTWVtYmVyc1JlcURhdGEgPSB7XG4gICAgICBtZW1iZXJzOiBBcnJheS5pc0FycmF5KGRhdGEubWVtYmVycykgPyBKU09OLnN0cmluZ2lmeShkYXRhLm1lbWJlcnMpIDogZGF0YS5tZW1iZXJzLFxuICAgICAgdXBzZXJ0OiBkYXRhLnVwc2VydFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzLmpzb25gLCBuZXdEYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5IGFzIE5ld011bHRpcGxlTWVtYmVyc1Jlc3BvbnNlKTtcbiAgfVxuXG4gIHVwZGF0ZU1lbWJlcihcbiAgICBtYWlsTGlzdEFkZHJlc3M6IHN0cmluZyxcbiAgICBtYWlsTGlzdE1lbWJlckFkZHJlc3M6IHN0cmluZyxcbiAgICBkYXRhOiBDcmVhdGVVcGRhdGVNYWlsTGlzdE1lbWJlcnNcbiAgKTogUHJvbWlzZTxNYWlsTGlzdE1lbWJlcj4ge1xuICAgIGNvbnN0IHJlcURhdGEgPSB0aGlzLmNoZWNrQW5kVXBkYXRlRGF0YShkYXRhKTtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L21lbWJlcnMvJHttYWlsTGlzdE1lbWJlckFkZHJlc3N9YCwgcmVxRGF0YSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5tZW1iZXIgYXMgTWFpbExpc3RNZW1iZXIpO1xuICB9XG5cbiAgZGVzdHJveU1lbWJlcihtYWlsTGlzdEFkZHJlc3M6IHN0cmluZywgbWFpbExpc3RNZW1iZXJBZGRyZXNzOiBzdHJpbmcpIDogUHJvbWlzZTxEZWxldGVkTWVtYmVyPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS9tZW1iZXJzLyR7bWFpbExpc3RNZW1iZXJBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgRGVsZXRlZE1lbWJlcik7XG4gIH1cbn1cbiIsImltcG9ydCBSZXF1ZXN0IGZyb20gJy4uL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7XG4gIExpc3RzUXVlcnksXG4gIENyZWF0ZVVwZGF0ZUxpc3QsXG4gIERlc3Ryb3llZExpc3QsXG4gIE1haWxpbmdMaXN0LFxuICBNYWlsaW5nTGlzdFZhbGlkYXRpb25BcGlSZXNwb25zZSxcbiAgU3RhcnRWYWxpZGF0aW9uUmVzdWx0LFxuICBNYWlsaW5nTGlzdFZhbGlkYXRpb25SZXN1bHQsXG4gIE1haWxpbmdMaXN0Q2FuY2VsVmFsaWRhdGlvblJlc3VsdCxcbiAgTWFpbGluZ0xpc3RSZXN1bHQsXG4gIE1haWxpbmdMaXN0QXBpUmVzcG9uc2Vcbn0gZnJvbSAnLi4vLi4vVHlwZXMvTWFpbGluZ0xpc3RzJztcbmltcG9ydCB7IElNYWlsTGlzdHNNZW1iZXJzIH0gZnJvbSAnLi4vLi4vSW50ZXJmYWNlcy9NYWlsaW5nTGlzdHMvTWFpbGluZ0xpc3RNZW1iZXJzJztcbmltcG9ydCBOYXZpZ2F0aW9uVGhydVBhZ2VzIGZyb20gJy4uL2NvbW1vbi9OYXZpZ2F0aW9uVGhydVBhZ2VzJztcbmltcG9ydCB7IElNYWlsaW5nTGlzdHNDbGllbnQgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFpbGluZ0xpc3RzQ2xpZW50XG4gIGV4dGVuZHMgTmF2aWdhdGlvblRocnVQYWdlczxNYWlsaW5nTGlzdFJlc3VsdD5cbiAgaW1wbGVtZW50cyBJTWFpbGluZ0xpc3RzQ2xpZW50IHtcbiAgYmFzZVJvdXRlOiBzdHJpbmc7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG4gIHB1YmxpYyBtZW1iZXJzOiBJTWFpbExpc3RzTWVtYmVycztcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0LCBtZW1iZXJzOiBJTWFpbExpc3RzTWVtYmVycykge1xuICAgIHN1cGVyKHJlcXVlc3QpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdGhpcy5iYXNlUm91dGUgPSAnL3YzL2xpc3RzJztcbiAgICB0aGlzLm1lbWJlcnMgPSBtZW1iZXJzO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVZhbGlkYXRpb25SZXN1bHQoXG4gICAgc3RhdHVzOiBudW1iZXIsXG4gICAgZGF0YTogTWFpbGluZ0xpc3RWYWxpZGF0aW9uQXBpUmVzcG9uc2VcbiAgKTogTWFpbGluZ0xpc3RWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzLFxuICAgICAgdmFsaWRhdGlvblJlc3VsdDoge1xuICAgICAgICAuLi5kYXRhLFxuICAgICAgICBjcmVhdGVkX2F0OiBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRfYXQgKiAxMDAwKSAvLyBhZGQgbWlsbGlzZWNvbmQgdG8gVW5peCB0aW1lc3RhbXBcbiAgICAgIH1cbiAgICB9IGFzIE1haWxpbmdMaXN0VmFsaWRhdGlvblJlc3VsdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUxpc3QocmVzcG9uc2U6IE1haWxpbmdMaXN0QXBpUmVzcG9uc2UpOiBNYWlsaW5nTGlzdFJlc3VsdCB7XG4gICAgY29uc3QgZGF0YSA9IHt9IGFzIE1haWxpbmdMaXN0UmVzdWx0O1xuXG4gICAgZGF0YS5pdGVtcyA9IHJlc3BvbnNlLmJvZHkuaXRlbXM7XG5cbiAgICBkYXRhLnBhZ2VzID0gdGhpcy5wYXJzZVBhZ2VMaW5rcyhyZXNwb25zZSwgJz8nLCAnYWRkcmVzcycpO1xuICAgIGRhdGEuc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyBsaXN0KHF1ZXJ5PzogTGlzdHNRdWVyeSk6IFByb21pc2U8TWFpbGluZ0xpc3RSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0TGlzdFdpdGhQYWdlcyhgJHt0aGlzLmJhc2VSb3V0ZX0vcGFnZXNgLCBxdWVyeSk7XG4gIH1cblxuICBnZXQobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBjcmVhdGUoZGF0YTogQ3JlYXRlVXBkYXRlTGlzdCk6IFByb21pc2U8TWFpbGluZ0xpc3Q+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQodGhpcy5iYXNlUm91dGUsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICB1cGRhdGUobWFpbExpc3RBZGRyZXNzOiBzdHJpbmcsIGRhdGE6IENyZWF0ZVVwZGF0ZUxpc3QpOiBQcm9taXNlPE1haWxpbmdMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWAsIGRhdGEpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkubGlzdCBhcyBNYWlsaW5nTGlzdCk7XG4gIH1cblxuICBkZXN0cm95KG1haWxMaXN0QWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxEZXN0cm95ZWRMaXN0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkgYXMgRGVzdHJveWVkTGlzdCk7XG4gIH1cblxuICB2YWxpZGF0ZShtYWlsTGlzdEFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8U3RhcnRWYWxpZGF0aW9uUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0KGAke3RoaXMuYmFzZVJvdXRlfS8ke21haWxMaXN0QWRkcmVzc30vdmFsaWRhdGVgLCB7fSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gKHtcbiAgICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAgIC4uLnJlc3BvbnNlLmJvZHlcbiAgICAgIH0pIGFzIFN0YXJ0VmFsaWRhdGlvblJlc3VsdCk7XG4gIH1cblxuICB2YWxpZGF0aW9uUmVzdWx0KG1haWxMaXN0QWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxNYWlsaW5nTGlzdFZhbGlkYXRpb25SZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldChgJHt0aGlzLmJhc2VSb3V0ZX0vJHttYWlsTGlzdEFkZHJlc3N9L3ZhbGlkYXRlYClcbiAgICAgIC50aGVuKFxuICAgICAgICAocmVzcG9uc2UpID0+IHRoaXMucGFyc2VWYWxpZGF0aW9uUmVzdWx0KFxuICAgICAgICAgIHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgICAgICAgcmVzcG9uc2UuYm9keSBhcyBNYWlsaW5nTGlzdFZhbGlkYXRpb25BcGlSZXNwb25zZVxuICAgICAgICApXG4gICAgICApO1xuICB9XG5cbiAgY2FuY2VsVmFsaWRhdGlvbihtYWlsTGlzdEFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8TWFpbGluZ0xpc3RDYW5jZWxWYWxpZGF0aW9uUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUoYCR7dGhpcy5iYXNlUm91dGV9LyR7bWFpbExpc3RBZGRyZXNzfS92YWxpZGF0ZWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+ICh7XG4gICAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICBtZXNzYWdlOiByZXNwb25zZS5ib2R5Lm1lc3NhZ2VcbiAgICAgIH0gYXMgTWFpbGluZ0xpc3RDYW5jZWxWYWxpZGF0aW9uUmVzdWx0KSk7XG4gIH1cbn1cbiIsImltcG9ydCBBUElFcnJvciBmcm9tICcuL2NvbW1vbi9FcnJvcic7XG5pbXBvcnQge1xuICBBUElFcnJvck9wdGlvbnMsXG4gIE1haWxndW5NZXNzYWdlRGF0YSxcbiAgTWVzc2FnZXNTZW5kQVBJUmVzcG9uc2UsXG4gIE1lc3NhZ2VzU2VuZFJlc3VsdFxufSBmcm9tICcuLi9UeXBlcyc7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7IElNZXNzYWdlc0NsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXNzYWdlc0NsaWVudCBpbXBsZW1lbnRzIElNZXNzYWdlc0NsaWVudCB7XG4gIHJlcXVlc3Q6IFJlcXVlc3Q7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBwcml2YXRlIHByZXBhcmVCb29sZWFuVmFsdWVzKGRhdGE6IE1haWxndW5NZXNzYWdlRGF0YSk6IE1haWxndW5NZXNzYWdlRGF0YSB7XG4gICAgY29uc3QgeWVzTm9Qcm9wZXJ0aWVzID0gbmV3IFNldChbXG4gICAgICAnbzp0ZXN0bW9kZScsXG4gICAgICAndDp0ZXh0JyxcbiAgICAgICdvOmRraW0nLFxuICAgICAgJ286dHJhY2tpbmcnLFxuICAgICAgJ286dHJhY2tpbmctY2xpY2tzJyxcbiAgICAgICdvOnRyYWNraW5nLW9wZW5zJyxcbiAgICAgICdvOnJlcXVpcmUtdGxzJyxcbiAgICAgICdvOnNraXAtdmVyaWZpY2F0aW9uJ1xuICAgIF0pO1xuXG4gICAgaWYgKCFkYXRhIHx8IE9iamVjdC5rZXlzKGRhdGEpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgICAgc3RhdHVzOiA0MDAsXG4gICAgICAgIG1lc3NhZ2U6ICdNZXNzYWdlIGRhdGEgb2JqZWN0IGNhbiBub3QgYmUgZW1wdHknXG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhkYXRhKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICBpZiAoeWVzTm9Qcm9wZXJ0aWVzLmhhcyhrZXkpICYmIHR5cGVvZiBkYXRhW2tleV0gPT09ICdib29sZWFuJykge1xuICAgICAgICBhY2Nba2V5XSA9IGRhdGFba2V5XSA/ICd5ZXMnIDogJ25vJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjY1trZXldID0gZGF0YVtrZXldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBNYWlsZ3VuTWVzc2FnZURhdGEpO1xuICB9XG5cbiAgX3BhcnNlUmVzcG9uc2UocmVzcG9uc2U6IE1lc3NhZ2VzU2VuZEFQSVJlc3BvbnNlKTogTWVzc2FnZXNTZW5kUmVzdWx0IHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXG4gICAgICAuLi5yZXNwb25zZS5ib2R5XG4gICAgfTtcbiAgfVxuXG4gIGNyZWF0ZShkb21haW46IHN0cmluZywgZGF0YTogTWFpbGd1bk1lc3NhZ2VEYXRhKTogUHJvbWlzZTxNZXNzYWdlc1NlbmRSZXN1bHQ+IHtcbiAgICBpZiAoZGF0YS5tZXNzYWdlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYC92My8ke2RvbWFpbn0vbWVzc2FnZXMubWltZWAsIGRhdGEpXG4gICAgICAgIC50aGVuKHRoaXMuX3BhcnNlUmVzcG9uc2UpO1xuICAgIH1cblxuICAgIGNvbnN0IG1vZGlmaWVkRGF0YSA9IHRoaXMucHJlcGFyZUJvb2xlYW5WYWx1ZXMoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKGAvdjMvJHtkb21haW59L21lc3NhZ2VzYCwgbW9kaWZpZWREYXRhKVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VSZXNwb25zZSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IElSb3V0ZXNDbGllbnQgfSBmcm9tICcuLi9JbnRlcmZhY2VzJztcbmltcG9ydCB7XG4gIENyZWF0ZVVwZGF0ZVJvdXRlRGF0YSwgRGVzdHJveVJvdXRlUmVzcG9uc2UsIFJvdXRlLCBSb3V0ZXNMaXN0UXVlcnksIFVwZGF0ZVJvdXRlUmVzcG9uc2Vcbn0gZnJvbSAnLi4vVHlwZXMvUm91dGVzJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vY29tbW9uL1JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSb3V0ZXNDbGllbnQgaW1wbGVtZW50cyBJUm91dGVzQ2xpZW50IHtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgfVxuXG4gIGxpc3QocXVlcnk6IFJvdXRlc0xpc3RRdWVyeSk6IFByb21pc2U8Um91dGVbXT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvcm91dGVzJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkuaXRlbXMpO1xuICB9XG5cbiAgZ2V0KGlkOiBzdHJpbmcpOiBQcm9taXNlPFJvdXRlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYC92My9yb3V0ZXMvJHtpZH1gKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5LnJvdXRlKTtcbiAgfVxuXG4gIGNyZWF0ZShkYXRhOiBDcmVhdGVVcGRhdGVSb3V0ZURhdGEpOiBQcm9taXNlPFJvdXRlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wb3N0V2l0aEZEKCcvdjMvcm91dGVzJywgZGF0YSlcbiAgICAgIC50aGVuKChyZXNwb25zZSkgPT4gcmVzcG9uc2UuYm9keS5yb3V0ZSk7XG4gIH1cblxuICB1cGRhdGUoaWQ6IHN0cmluZywgZGF0YTogQ3JlYXRlVXBkYXRlUm91dGVEYXRhKTogUHJvbWlzZTxVcGRhdGVSb3V0ZVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5wdXRXaXRoRkQoYC92My9yb3V0ZXMvJHtpZH1gLCBkYXRhKVxuICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5ib2R5KTtcbiAgfVxuXG4gIGRlc3Ryb3koaWQ6IHN0cmluZyk6IFByb21pc2U8RGVzdHJveVJvdXRlUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmRlbGV0ZShgL3YzL3JvdXRlcy8ke2lkfWApXG4gICAgICAudGhlbigocmVzcG9uc2UpID0+IHJlc3BvbnNlLmJvZHkpO1xuICB9XG59XG4iLCJpbXBvcnQgdXJsam9pbiBmcm9tICd1cmwtam9pbic7XG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuLi9jb21tb24vUmVxdWVzdCc7XG5pbXBvcnQgeyBTdGF0c1F1ZXJ5LCBTdGF0c09wdGlvbnMgfSBmcm9tICcuLi8uLi9UeXBlcy9TdGF0cyc7XG5pbXBvcnQgeyBJTG9nZ2VyIH0gZnJvbSAnLi4vLi4vSW50ZXJmYWNlcy9Db21tb24nO1xuaW1wb3J0IFN0YXRzQ29udGFpbmVyIGZyb20gJy4vU3RhdHNDb250YWluZXInO1xuaW1wb3J0IHsgSVN0YXRzQ2xpZW50LCBJU3RhdHNDb250YWluZXIgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N0YXRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3RhdHNDbGllbnQgaW1wbGVtZW50cyBJU3RhdHNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuICBwcml2YXRlIGxvZ2dlcjogSUxvZ2dlcjtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0LCBsb2dnZXI6IElMb2dnZXIgPSBjb25zb2xlKSB7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLmxvZ2dlciA9IGxvZ2dlcjtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydERhdGVUb1VUQyhrZXk6c3RyaW5nLCBpbnB1dERhdGU6IERhdGUpOiBBcnJheTxzdHJpbmc+IHtcbiAgICAvKlxuICAgICAgQmVjYXVzZSBcIm5ldyBEYXRlKCcyMDIyLTEyLTI1VDAwOjAwOjAwLjAwMFonKVwiIGJlY29tZXMgXCJTdW4gRGVjIDI1IDIwMjIgMDI6MDA6MDAgR01UKzAyMDBcIlxuICAgICAgKHBsdXMgMiBob3VycyBmcm9tIHRoZSB0aW1lem9uZSlcbiAgICAgIGFuZCBiZWNhdXNlIGZvciBBUEksIHdlIG5lZWQgdG8gcHJvdmlkZSB0aGUgZGF0ZSBpbiB0aGUgZXhwZWN0ZWQgZm9ybWF0XG4gICAgICBleDogJ1RodSwgMTMgT2N0IDIwMTEgMTg6MDI6MDAgKzAwMDAnLlxuICAgICAgSGVyZSB3ZSB0cnkgYXV0by1jb252ZXJ0IHRoZW0gdG8gVVRDXG4gICAgKi9cbiAgICB0aGlzLmxvZ2dlci53YXJuKGBEYXRlOlwiJHtpbnB1dERhdGV9XCIgd2FzIGF1dG8tY29udmVydGVkIHRvIFVUQyB0aW1lIHpvbmUuXG5WYWx1ZSBcIiR7aW5wdXREYXRlLnRvVVRDU3RyaW5nKCl9XCIgd2lsbCBiZSB1c2VkIGZvciByZXF1ZXN0LlxuQ29uc2lkZXIgdXNpbmcgc3RpbmcgdHlwZSBmb3IgcHJvcGVydHkgXCIke2tleX1cIiB0byBhdm9pZCBhdXRvLWNvbnZlcnRpbmdgKTtcbiAgICByZXR1cm4gW2tleSwgaW5wdXREYXRlLnRvVVRDU3RyaW5nKCldO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmVwYXJlU2VhcmNoUGFyYW1zKHF1ZXJ5OiBTdGF0c1F1ZXJ5IHwgdW5kZWZpbmVkKTogQXJyYXk8QXJyYXk8c3RyaW5nPj4ge1xuICAgIGxldCBzZWFyY2hQYXJhbXMgPSBbXSBhcyBBcnJheTxBcnJheTxzdHJpbmc+PjtcbiAgICBpZiAodHlwZW9mIHF1ZXJ5ID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoKSB7XG4gICAgICBzZWFyY2hQYXJhbXMgPSBPYmplY3QuZW50cmllcyhxdWVyeSkucmVkdWNlKChhcnJheVdpdGhQYWlycywgY3VycmVudFBhaXIpID0+IHtcbiAgICAgICAgY29uc3QgW2tleSwgdmFsdWVdID0gY3VycmVudFBhaXI7XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCkgeyAvLyBldmVudDogWydkZWxpdmVyZWQnLCAnYWNjZXB0ZWQnXVxuICAgICAgICAgIGNvbnN0IHJlcGVhdGVkUHJvcGVydHkgPSB2YWx1ZS5tYXAoKGl0ZW0pID0+IFtrZXksIGl0ZW1dKTtcbiAgICAgICAgICByZXR1cm4gWy4uLmFycmF5V2l0aFBhaXJzLCAuLi5yZXBlYXRlZFByb3BlcnR5XTsgLy8gW1tldmVudCxkZWxpdmVyZWRdLCBbZXZlbnQsYWNjZXB0ZWRdXVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgIGFycmF5V2l0aFBhaXJzLnB1c2godGhpcy5jb252ZXJ0RGF0ZVRvVVRDKGtleSwgdmFsdWUpKTtcbiAgICAgICAgICByZXR1cm4gYXJyYXlXaXRoUGFpcnM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGFycmF5V2l0aFBhaXJzLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcnJheVdpdGhQYWlycztcbiAgICAgIH0sIFtdIGFzIEFycmF5PEFycmF5PHN0cmluZz4+KTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VhcmNoUGFyYW1zO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVN0YXRzKHJlc3BvbnNlOiB7IGJvZHk6IFN0YXRzT3B0aW9ucyB9KTogSVN0YXRzQ29udGFpbmVyIHtcbiAgICByZXR1cm4gbmV3IFN0YXRzQ29udGFpbmVyKHJlc3BvbnNlLmJvZHkpO1xuICB9XG5cbiAgZ2V0RG9tYWluKGRvbWFpbjogc3RyaW5nLCBxdWVyeT86IFN0YXRzUXVlcnkpOiBQcm9taXNlPElTdGF0c0NvbnRhaW5lcj4ge1xuICAgIGNvbnN0IHNlYXJjaFBhcmFtcyA9IHRoaXMucHJlcGFyZVNlYXJjaFBhcmFtcyhxdWVyeSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbignL3YzJywgZG9tYWluLCAnc3RhdHMvdG90YWwnKSwgc2VhcmNoUGFyYW1zKVxuICAgICAgLnRoZW4odGhpcy5wYXJzZVN0YXRzKTtcbiAgfVxuXG4gIGdldEFjY291bnQocXVlcnk/OiBTdGF0c1F1ZXJ5KTogUHJvbWlzZTxJU3RhdHNDb250YWluZXI+IHtcbiAgICBjb25zdCBzZWFyY2hQYXJhbXMgPSB0aGlzLnByZXBhcmVTZWFyY2hQYXJhbXMocXVlcnkpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KCcvdjMvc3RhdHMvdG90YWwnLCBzZWFyY2hQYXJhbXMpXG4gICAgICAudGhlbih0aGlzLnBhcnNlU3RhdHMpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBJU3RhdHNDb250YWluZXIgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N0YXRzJztcbmltcG9ydCB7IFN0YXQsIFN0YXRzT3B0aW9ucyB9IGZyb20gJy4uLy4uL1R5cGVzL1N0YXRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3RhdHNDb250YWluZXIgaW1wbGVtZW50cyBJU3RhdHNDb250YWluZXIge1xuICAgIHN0YXJ0OiBEYXRlO1xuICAgIGVuZDogRGF0ZTtcbiAgICByZXNvbHV0aW9uOiBzdHJpbmc7XG4gICAgc3RhdHM6IFN0YXRbXTtcbiAgICBjb25zdHJ1Y3RvcihkYXRhOiBTdGF0c09wdGlvbnMpIHtcbiAgICAgIHRoaXMuc3RhcnQgPSBuZXcgRGF0ZShkYXRhLnN0YXJ0KTtcbiAgICAgIHRoaXMuZW5kID0gbmV3IERhdGUoZGF0YS5lbmQpO1xuICAgICAgdGhpcy5yZXNvbHV0aW9uID0gZGF0YS5yZXNvbHV0aW9uO1xuICAgICAgdGhpcy5zdGF0cyA9IGRhdGEuc3RhdHMubWFwKGZ1bmN0aW9uIChzdGF0OiBTdGF0KSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IHsgLi4uc3RhdCB9O1xuICAgICAgICByZXMudGltZSA9IG5ldyBEYXRlKHN0YXQudGltZSk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9KTtcbiAgICB9XG59XG4iLCJpbXBvcnQgUmVxdWVzdCBmcm9tICcuL2NvbW1vbi9SZXF1ZXN0JztcbmltcG9ydCB7IElTdWJhY2NvdW50c0NsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMnO1xuaW1wb3J0IHtcbiAgU3ViYWNjb3VudExpc3RSZXNwb25zZURhdGEsXG4gIFN1YmFjY291bnRSZXNwb25zZURhdGEsXG4gIFN1YmFjY291bnRzUXVlcnksXG59IGZyb20gJy4uL1R5cGVzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3ViYWNjb3VudHNDbGllbnQgaW1wbGVtZW50cyBJU3ViYWNjb3VudHNDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuICBzdGF0aWMgU1VCQUNDT1VOVF9IRUFERVIgPSAnWC1NYWlsZ3VuLU9uLUJlaGFsZi1PZic7XG5cbiAgY29uc3RydWN0b3IocmVxdWVzdDogUmVxdWVzdCkge1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBsaXN0KHF1ZXJ5PzogU3ViYWNjb3VudHNRdWVyeSk6IFByb21pc2U8U3ViYWNjb3VudExpc3RSZXNwb25zZURhdGE+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LmdldCgnL3Y1L2FjY291bnRzL3N1YmFjY291bnRzJywgcXVlcnkpXG4gICAgICAudGhlbigocmVzKSA9PiByZXMuYm9keSk7XG4gIH1cblxuICBnZXQoaWQ6c3RyaW5nKTogUHJvbWlzZTxTdWJhY2NvdW50UmVzcG9uc2VEYXRhPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQoYC92NS9hY2NvdW50cy9zdWJhY2NvdW50cy8ke2lkfWApXG4gICAgICAudGhlbigocmVzKSA9PiByZXMuYm9keSk7XG4gIH1cblxuICBjcmVhdGUobmFtZTpzdHJpbmcpOiBQcm9taXNlPFN1YmFjY291bnRSZXNwb25zZURhdGE+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoJy92NS9hY2NvdW50cy9zdWJhY2NvdW50cycsIHsgbmFtZSB9KVxuICAgICAgLnRoZW4oKHJlcykgPT4gcmVzLmJvZHkpO1xuICB9XG5cbiAgZW5hYmxlKGlkOnN0cmluZyk6IFByb21pc2U8U3ViYWNjb3VudFJlc3BvbnNlRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdChgL3Y1L2FjY291bnRzL3N1YmFjY291bnRzLyR7aWR9L2VuYWJsZWApXG4gICAgICAudGhlbigocmVzKSA9PiByZXMuYm9keSk7XG4gIH1cblxuICBkaXNhYmxlKGlkOnN0cmluZyk6IFByb21pc2U8U3ViYWNjb3VudFJlc3BvbnNlRGF0YT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdChgL3Y1L2FjY291bnRzL3N1YmFjY291bnRzLyR7aWR9L2Rpc2FibGVgKVxuICAgICAgLnRoZW4oKHJlcykgPT4gcmVzLmJvZHkpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBTdXBwcmVzc2lvbk1vZGVscyB9IGZyb20gJy4uLy4uL0VudW1zJztcbmltcG9ydCB7IElCb3VuY2UgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBCb3VuY2VEYXRhIH0gZnJvbSAnLi4vLi4vVHlwZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCBTdXBwcmVzc2lvbiBmcm9tICcuL1N1cHByZXNzaW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQm91bmNlIGV4dGVuZHMgU3VwcHJlc3Npb24gaW1wbGVtZW50cyBJQm91bmNlIHtcbiAgICBhZGRyZXNzOiBzdHJpbmc7XG4gICAgY29kZTogbnVtYmVyO1xuICAgIGVycm9yOiBzdHJpbmc7XG4gICAgLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4gICAgY3JlYXRlZF9hdDogRGF0ZTtcblxuICAgIGNvbnN0cnVjdG9yKGRhdGE6IEJvdW5jZURhdGEpIHtcbiAgICAgIHN1cGVyKFN1cHByZXNzaW9uTW9kZWxzLkJPVU5DRVMpO1xuICAgICAgdGhpcy5hZGRyZXNzID0gZGF0YS5hZGRyZXNzO1xuICAgICAgdGhpcy5jb2RlID0gK2RhdGEuY29kZTtcbiAgICAgIHRoaXMuZXJyb3IgPSBkYXRhLmVycm9yO1xuICAgICAgdGhpcy5jcmVhdGVkX2F0ID0gbmV3IERhdGUoZGF0YS5jcmVhdGVkX2F0KTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBTdXBwcmVzc2lvbk1vZGVscyB9IGZyb20gJy4uLy4uL0VudW1zJztcbmltcG9ydCB7IElDb21wbGFpbnQgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBDb21wbGFpbnREYXRhIH0gZnJvbSAnLi4vLi4vVHlwZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCBTdXBwcmVzc2lvbiBmcm9tICcuL1N1cHByZXNzaW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29tcGxhaW50IGV4dGVuZHMgU3VwcHJlc3Npb24gaW1wbGVtZW50cyBJQ29tcGxhaW50IHtcbiAgICBhZGRyZXNzOiBzdHJpbmc7XG4gICAgLyogZXNsaW50LWRpc2FibGUgY2FtZWxjYXNlICovXG4gICAgY3JlYXRlZF9hdDogRGF0ZTtcbiAgICBjb25zdHJ1Y3RvcihkYXRhOiBDb21wbGFpbnREYXRhKSB7XG4gICAgICBzdXBlcihTdXBwcmVzc2lvbk1vZGVscy5DT01QTEFJTlRTKTtcbiAgICAgIHRoaXMuYWRkcmVzcyA9IGRhdGEuYWRkcmVzcztcbiAgICAgIHRoaXMuY3JlYXRlZF9hdCA9IG5ldyBEYXRlKGRhdGEuY3JlYXRlZF9hdCk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgU3VwcHJlc3Npb25Nb2RlbHMgfSBmcm9tICcuLi8uLi9FbnVtcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN1cHByZXNzaW9uIHtcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgY29uc3RydWN0b3IodHlwZTogU3VwcHJlc3Npb25Nb2RlbHMpIHtcbiAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgfVxufVxuIiwiaW1wb3J0IHVybGpvaW4gZnJvbSAndXJsLWpvaW4nO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cblxuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5pbXBvcnQgQVBJRXJyb3IgZnJvbSAnLi4vY29tbW9uL0Vycm9yJztcbmltcG9ydCBOYXZpZ2F0aW9uVGhydVBhZ2VzIGZyb20gJy4uL2NvbW1vbi9OYXZpZ2F0aW9uVGhydVBhZ2VzJztcbmltcG9ydCBCb3VuY2UgZnJvbSAnLi9Cb3VuY2UnO1xuaW1wb3J0IENvbXBsYWludCBmcm9tICcuL0NvbXBsYWludCc7XG5pbXBvcnQgVW5zdWJzY3JpYmUgZnJvbSAnLi9VbnN1YnNjcmliZSc7XG5pbXBvcnQgV2hpdGVMaXN0IGZyb20gJy4vV2hpdGVMaXN0JztcbmltcG9ydCBTdXBwcmVzc2lvbiBmcm9tICcuL1N1cHByZXNzaW9uJztcbmltcG9ydCB7XG4gIElCb3VuY2UsXG4gIElDb21wbGFpbnQsXG4gIElTdXBwcmVzc2lvbkNsaWVudCxcbiAgSVVuc3Vic2NyaWJlLFxuICBJV2hpdGVMaXN0XG59IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCB7XG4gIFN1cHByZXNzaW9uTGlzdCxcbiAgU3VwcHJlc3Npb25MaXN0UmVzcG9uc2UsXG4gIFN1cHByZXNzaW9uRGF0YVR5cGUsXG4gIFN1cHByZXNzaW9uQ3JlYXRpb25EYXRhLFxuICBTdXBwcmVzc2lvbkNyZWF0aW9uUmVzdWx0LFxuICBTdXBwcmVzc2lvbkNyZWF0aW9uUmVzcG9uc2UsXG4gIFN1cHByZXNzaW9uTGlzdFF1ZXJ5LFxuICBTdXBwcmVzc2lvblJlc3BvbnNlLFxuICBTdXBwcmVzc2lvbkRlc3Ryb3lSZXN1bHQsXG4gIFN1cHByZXNzaW9uRGVzdHJveVJlc3BvbnNlXG59IGZyb20gJy4uLy4uL1R5cGVzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBBUElFcnJvck9wdGlvbnMgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24nO1xuXG5jb25zdCBjcmVhdGVPcHRpb25zID0ge1xuICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3VwcHJlc3Npb25DbGllbnRcbiAgZXh0ZW5kcyBOYXZpZ2F0aW9uVGhydVBhZ2VzPFN1cHByZXNzaW9uTGlzdD5cbiAgaW1wbGVtZW50cyBJU3VwcHJlc3Npb25DbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuICBtb2RlbHM6IG9iamVjdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gICAgc3VwZXIocmVxdWVzdCk7XG4gICAgdGhpcy5yZXF1ZXN0ID0gcmVxdWVzdDtcbiAgICB0aGlzLm1vZGVscyA9IHtcbiAgICAgIGJvdW5jZXM6IEJvdW5jZSxcbiAgICAgIGNvbXBsYWludHM6IENvbXBsYWludCxcbiAgICAgIHVuc3Vic2NyaWJlczogVW5zdWJzY3JpYmUsXG4gICAgICB3aGl0ZWxpc3RzOiBXaGl0ZUxpc3QsXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUxpc3QoXG4gICAgcmVzcG9uc2U6IFN1cHByZXNzaW9uTGlzdFJlc3BvbnNlLFxuICAgIE1vZGVsOiB7XG4gICAgICBuZXcoZGF0YTogU3VwcHJlc3Npb25EYXRhVHlwZSk6XG4gICAgICBJQm91bmNlIHwgSUNvbXBsYWludCB8IElVbnN1YnNjcmliZSB8IElXaGl0ZUxpc3RcbiAgICB9XG4gICk6IFN1cHByZXNzaW9uTGlzdCB7XG4gICAgY29uc3QgZGF0YSA9IHt9IGFzIFN1cHByZXNzaW9uTGlzdDtcbiAgICBkYXRhLml0ZW1zID0gcmVzcG9uc2UuYm9keS5pdGVtcz8ubWFwKChpdGVtKSA9PiBuZXcgTW9kZWwoaXRlbSkpIHx8IFtdO1xuXG4gICAgZGF0YS5wYWdlcyA9IHRoaXMucGFyc2VQYWdlTGlua3MocmVzcG9uc2UsICc/JywgJ2FkZHJlc3MnKTtcbiAgICBkYXRhLnN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIF9wYXJzZUl0ZW08VCBleHRlbmRzIFN1cHByZXNzaW9uPihcbiAgICBkYXRhIDogU3VwcHJlc3Npb25EYXRhVHlwZSxcbiAgICBNb2RlbDoge1xuICAgICAgbmV3KGRhdGFUeXBlOiBTdXBwcmVzc2lvbkRhdGFUeXBlKTpUXG4gICAgfVxuICApOiBUIHtcbiAgICByZXR1cm4gbmV3IE1vZGVsKGRhdGEpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVXaGl0ZUxpc3QoXG4gICAgZG9tYWluOiBzdHJpbmcsXG4gICAgZGF0YTogU3VwcHJlc3Npb25DcmVhdGlvbkRhdGEgfCBTdXBwcmVzc2lvbkNyZWF0aW9uRGF0YVtdLFxuICAgIGlzRGF0YUFycmF5OiBib29sZWFuXG4gICk6IFByb21pc2U8U3VwcHJlc3Npb25DcmVhdGlvblJlc3VsdD4ge1xuICAgIGlmIChpc0RhdGFBcnJheSkge1xuICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgICAgc3RhdHVzOiA0MDAsXG4gICAgICAgIHN0YXR1c1RleHQ6ICdEYXRhIHByb3BlcnR5IHNob3VsZCBiZSBhbiBvYmplY3QnLFxuICAgICAgICBib2R5OiB7XG4gICAgICAgICAgbWVzc2FnZTogJ1doaXRlbGlzdFxcJ3MgY3JlYXRpb24gcHJvY2VzcyBkb2VzIG5vdCBzdXBwb3J0IG11bHRpcGxlIGNyZWF0aW9ucy4gRGF0YSBwcm9wZXJ0eSBzaG91bGQgYmUgYW4gb2JqZWN0J1xuICAgICAgICB9XG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAgIC5wb3N0V2l0aEZEKHVybGpvaW4oJ3YzJywgZG9tYWluLCAnd2hpdGVsaXN0cycpLCBkYXRhKVxuICAgICAgLnRoZW4odGhpcy5wcmVwYXJlUmVzcG9uc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVVbnN1YnNjcmliZShcbiAgICBkb21haW46IHN0cmluZyxcbiAgICBkYXRhOiBTdXBwcmVzc2lvbkNyZWF0aW9uRGF0YSB8IFN1cHByZXNzaW9uQ3JlYXRpb25EYXRhW11cbiAgKTogUHJvbWlzZTxTdXBwcmVzc2lvbkNyZWF0aW9uUmVzdWx0PiB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHsgLy8gVXNlciBwcm92aWRlZCBhbiBhcnJheVxuICAgICAgY29uc3QgaXNDb250YWluc1RhZyA9IGRhdGEuc29tZSgodW5zdWJzY3JpYmU6IFN1cHByZXNzaW9uQ3JlYXRpb25EYXRhKSA9PiB1bnN1YnNjcmliZS50YWcpO1xuICAgICAgaWYgKGlzQ29udGFpbnNUYWcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgICAgICBzdGF0dXM6IDQwMCxcbiAgICAgICAgICBzdGF0dXNUZXh0OiAnVGFnIHByb3BlcnR5IHNob3VsZCBub3QgYmUgdXNlZCBmb3IgY3JlYXRpbmcgbXVsdGlwbGUgdW5zdWJzY3JpYmVzLicsXG4gICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgbWVzc2FnZTogJ1RhZyBwcm9wZXJ0eSBjYW4gYmUgdXNlZCBvbmx5IGlmIG9uZSB1bnN1YnNjcmliZSBwcm92aWRlZCBhcyBzZWNvbmQgYXJndW1lbnQgb2YgY3JlYXRlIG1ldGhvZC4gUGxlYXNlIHVzZSB0YWdzIGluc3RlYWQuJ1xuICAgICAgICAgIH1cbiAgICAgICAgfSBhcyBBUElFcnJvck9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdFxuICAgICAgICAucG9zdCh1cmxqb2luKCd2MycsIGRvbWFpbiwgJ3Vuc3Vic2NyaWJlcycpLCBKU09OLnN0cmluZ2lmeShkYXRhKSwgY3JlYXRlT3B0aW9ucylcbiAgICAgICAgLnRoZW4odGhpcy5wcmVwYXJlUmVzcG9uc2UpO1xuICAgIH1cblxuICAgIGlmIChkYXRhPy50YWdzKSB7XG4gICAgICB0aHJvdyBuZXcgQVBJRXJyb3Ioe1xuICAgICAgICBzdGF0dXM6IDQwMCxcbiAgICAgICAgc3RhdHVzVGV4dDogJ1RhZ3MgcHJvcGVydHkgc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBjcmVhdGluZyBvbmUgdW5zdWJzY3JpYmUuJyxcbiAgICAgICAgYm9keToge1xuICAgICAgICAgIG1lc3NhZ2U6ICdUYWdzIHByb3BlcnR5IGNhbiBiZSB1c2VkIGlmIHlvdSBwcm92aWRlcyBhbiBhcnJheSBvZiB1bnN1YnNjcmliZXMgYXMgc2Vjb25kIGFyZ3VtZW50IG9mIGNyZWF0ZSBtZXRob2QuIFBsZWFzZSB1c2UgdGFnIGluc3RlYWQnXG4gICAgICAgIH1cbiAgICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YS50YWcpKSB7XG4gICAgICB0aHJvdyBuZXcgQVBJRXJyb3Ioe1xuICAgICAgICBzdGF0dXM6IDQwMCxcbiAgICAgICAgc3RhdHVzVGV4dDogJ1RhZyBwcm9wZXJ0eSBjYW4gbm90IGJlIGFuIGFycmF5JyxcbiAgICAgICAgYm9keToge1xuICAgICAgICAgIG1lc3NhZ2U6ICdQbGVhc2UgdXNlIGFycmF5IG9mIHVuc3Vic2NyaWJlcyBhcyBzZWNvbmQgYXJndW1lbnQgb2YgY3JlYXRlIG1ldGhvZCB0byBiZSBhYmxlIHRvIHByb3ZpZGUgZmV3IHRhZ3MnXG4gICAgICAgIH1cbiAgICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgICB9XG4gICAgLyogV2UgbmVlZCBGb3JtIERhdGEgZm9yIHVuc3Vic2NyaWJlcyBpZiB3ZSB3YW50IHRvIHN1cHBvcnQgdGhlIFwidGFnXCIgcHJvcGVydHkgKi9cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAucG9zdFdpdGhGRCh1cmxqb2luKCd2MycsIGRvbWFpbiwgJ3Vuc3Vic2NyaWJlcycpLCBkYXRhKVxuICAgICAgLnRoZW4odGhpcy5wcmVwYXJlUmVzcG9uc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRNb2RlbCh0eXBlOiBzdHJpbmcpIHtcbiAgICBpZiAodHlwZSBpbiB0aGlzLm1vZGVscykge1xuICAgICAgcmV0dXJuIHRoaXMubW9kZWxzW3R5cGUgYXMga2V5b2YgdHlwZW9mIHRoaXMubW9kZWxzXTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgIHN0YXR1czogNDAwLFxuICAgICAgc3RhdHVzVGV4dDogJ1Vua25vd24gdHlwZSB2YWx1ZScsXG4gICAgICBib2R5OiB7IG1lc3NhZ2U6ICdUeXBlIG1heSBiZSBvbmx5IG9uZSBvZiBbYm91bmNlcywgY29tcGxhaW50cywgdW5zdWJzY3JpYmVzLCB3aGl0ZWxpc3RzXScgfVxuICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJlcGFyZVJlc3BvbnNlKHJlc3BvbnNlOiBTdXBwcmVzc2lvbkNyZWF0aW9uUmVzcG9uc2UpOiBTdXBwcmVzc2lvbkNyZWF0aW9uUmVzdWx0IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZTogcmVzcG9uc2UuYm9keS5tZXNzYWdlLFxuICAgICAgdHlwZTogcmVzcG9uc2UuYm9keS50eXBlIHx8ICcnLFxuICAgICAgdmFsdWU6IHJlc3BvbnNlLmJvZHkudmFsdWUgfHwgJycsXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1c1xuICAgIH07XG4gIH1cblxuICBhc3luYyBsaXN0KFxuICAgIGRvbWFpbjogc3RyaW5nLFxuICAgIHR5cGU6IHN0cmluZyxcbiAgICBxdWVyeT86IFN1cHByZXNzaW9uTGlzdFF1ZXJ5XG4gICk6IFByb21pc2U8U3VwcHJlc3Npb25MaXN0PiB7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLmdldE1vZGVsKHR5cGUpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RMaXN0V2l0aFBhZ2VzKHVybGpvaW4oJ3YzJywgZG9tYWluLCB0eXBlKSwgcXVlcnksIG1vZGVsKTtcbiAgfVxuXG4gIGdldChcbiAgICBkb21haW46IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcsXG4gICAgYWRkcmVzczogc3RyaW5nXG4gICk6IFByb21pc2U8SUJvdW5jZSB8IElDb21wbGFpbnQgfCBJVW5zdWJzY3JpYmUgfCBJV2hpdGVMaXN0PiB7XG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLmdldE1vZGVsKHR5cGUpO1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3RcbiAgICAgIC5nZXQodXJsam9pbigndjMnLCBkb21haW4sIHR5cGUsIGVuY29kZVVSSUNvbXBvbmVudChhZGRyZXNzKSkpXG4gICAgICAudGhlbigocmVzcG9uc2U6IFN1cHByZXNzaW9uUmVzcG9uc2UpID0+IHRoaXMuX3BhcnNlSXRlbTx0eXBlb2YgbW9kZWw+KHJlc3BvbnNlLmJvZHksIG1vZGVsKSk7XG4gIH1cblxuICBjcmVhdGUoXG4gICAgZG9tYWluOiBzdHJpbmcsXG4gICAgdHlwZTogc3RyaW5nLFxuICAgIGRhdGE6IFN1cHByZXNzaW9uQ3JlYXRpb25EYXRhIHwgU3VwcHJlc3Npb25DcmVhdGlvbkRhdGFbXVxuICApOiBQcm9taXNlPFN1cHByZXNzaW9uQ3JlYXRpb25SZXN1bHQ+IHtcbiAgICB0aGlzLmdldE1vZGVsKHR5cGUpO1xuICAgIC8vIHN1cHBvcnRzIGFkZGluZyBtdWx0aXBsZSBzdXBwcmVzc2lvbnMgYnkgZGVmYXVsdFxuICAgIGxldCBwb3N0RGF0YTtcbiAgICBjb25zdCBpc0RhdGFBcnJheSA9IEFycmF5LmlzQXJyYXkoZGF0YSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3doaXRlbGlzdHMnKSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVXaGl0ZUxpc3QoZG9tYWluLCBkYXRhLCBpc0RhdGFBcnJheSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICd1bnN1YnNjcmliZXMnKSB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVVbnN1YnNjcmliZShkb21haW4sIGRhdGEpO1xuICAgIH1cblxuICAgIGlmICghaXNEYXRhQXJyYXkpIHtcbiAgICAgIHBvc3REYXRhID0gW2RhdGFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3N0RGF0YSA9IFsuLi5kYXRhXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0XG4gICAgICAucG9zdCh1cmxqb2luKCd2MycsIGRvbWFpbiwgdHlwZSksIEpTT04uc3RyaW5naWZ5KHBvc3REYXRhKSwgY3JlYXRlT3B0aW9ucylcbiAgICAgIC50aGVuKHRoaXMucHJlcGFyZVJlc3BvbnNlKTtcbiAgfVxuXG4gIGRlc3Ryb3koXG4gICAgZG9tYWluOiBzdHJpbmcsXG4gICAgdHlwZTogc3RyaW5nLFxuICAgIGFkZHJlc3M6IHN0cmluZ1xuICApOiBQcm9taXNlPFN1cHByZXNzaW9uRGVzdHJveVJlc3VsdD4ge1xuICAgIHRoaXMuZ2V0TW9kZWwodHlwZSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFxuICAgICAgLmRlbGV0ZSh1cmxqb2luKCd2MycsIGRvbWFpbiwgdHlwZSwgZW5jb2RlVVJJQ29tcG9uZW50KGFkZHJlc3MpKSlcbiAgICAgIC50aGVuKChyZXNwb25zZTogU3VwcHJlc3Npb25EZXN0cm95UmVzcG9uc2UpID0+ICh7XG4gICAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLmJvZHkubWVzc2FnZSxcbiAgICAgICAgdmFsdWU6IHJlc3BvbnNlLmJvZHkudmFsdWUgfHwgJycsXG4gICAgICAgIGFkZHJlc3M6IHJlc3BvbnNlLmJvZHkuYWRkcmVzcyB8fCAnJyxcbiAgICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXNcbiAgICAgIH0pKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN1cHByZXNzaW9uQ2xpZW50O1xuIiwiaW1wb3J0IHsgU3VwcHJlc3Npb25Nb2RlbHMgfSBmcm9tICcuLi8uLi9FbnVtcyc7XG5pbXBvcnQgeyBJVW5zdWJzY3JpYmUgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBVbnN1YnNjcmliZURhdGEgfSBmcm9tICcuLi8uLi9UeXBlcy9TdXBwcmVzc2lvbnMnO1xuXG5pbXBvcnQgU3VwcHJlc3Npb24gZnJvbSAnLi9TdXBwcmVzc2lvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFVuc3Vic2NyaWJlIGV4dGVuZHMgU3VwcHJlc3Npb24gaW1wbGVtZW50cyBJVW5zdWJzY3JpYmUge1xuICAgIGFkZHJlc3M6IHN0cmluZztcbiAgICB0YWdzOiBzdHJpbmdbXTtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjYW1lbGNhc2UgKi9cbiAgICBjcmVhdGVkX2F0OiBEYXRlO1xuXG4gICAgY29uc3RydWN0b3IoZGF0YTogVW5zdWJzY3JpYmVEYXRhKSB7XG4gICAgICBzdXBlcihTdXBwcmVzc2lvbk1vZGVscy5VTlNVQlNDUklCRVMpO1xuICAgICAgdGhpcy5hZGRyZXNzID0gZGF0YS5hZGRyZXNzO1xuICAgICAgdGhpcy50YWdzID0gZGF0YS50YWdzO1xuICAgICAgdGhpcy5jcmVhdGVkX2F0ID0gbmV3IERhdGUoZGF0YS5jcmVhdGVkX2F0KTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBTdXBwcmVzc2lvbk1vZGVscyB9IGZyb20gJy4uLy4uL0VudW1zJztcbmltcG9ydCB7IElXaGl0ZUxpc3QgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1N1cHByZXNzaW9ucyc7XG5pbXBvcnQgeyBXaGl0ZUxpc3REYXRhIH0gZnJvbSAnLi4vLi4vVHlwZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCBTdXBwcmVzc2lvbiBmcm9tICcuL1N1cHByZXNzaW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2hpdGVMaXN0IGV4dGVuZHMgU3VwcHJlc3Npb24gaW1wbGVtZW50cyBJV2hpdGVMaXN0IHtcbiAgICB2YWx1ZTogc3RyaW5nO1xuICAgIHJlYXNvbjogc3RyaW5nO1xuICAgIGNyZWF0ZWRBdDogRGF0ZTtcblxuICAgIGNvbnN0cnVjdG9yKGRhdGE6IFdoaXRlTGlzdERhdGEpIHtcbiAgICAgIHN1cGVyKFN1cHByZXNzaW9uTW9kZWxzLldISVRFTElTVFMpO1xuICAgICAgdGhpcy52YWx1ZSA9IGRhdGEudmFsdWU7XG4gICAgICB0aGlzLnJlYXNvbiA9IGRhdGEucmVhc29uO1xuICAgICAgdGhpcy5jcmVhdGVkQXQgPSBuZXcgRGF0ZShkYXRhLmNyZWF0ZWRBdCk7XG4gICAgfVxufVxuIiwiaW1wb3J0IE5hdmlnYXRpb25UaHJ1UGFnZXMgZnJvbSAnLi4vY29tbW9uL05hdmlnYXRpb25UaHJ1UGFnZXMnO1xuaW1wb3J0IHsgQVBJUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24vQXBpUmVzcG9uc2UnO1xuXG5pbXBvcnQgUmVxdWVzdCBmcm9tICcuLi9jb21tb24vUmVxdWVzdCc7XG5pbXBvcnQgeyBJTXVsdGlwbGVWYWxpZGF0aW9uQ2xpZW50IH0gZnJvbSAnLi4vLi4vSW50ZXJmYWNlcy9WYWxpZGF0aW9ucyc7XG5pbXBvcnQge1xuICBNdWx0aXBsZVZhbGlkYXRpb25Kb2JSZXN1bHQsXG4gIE11bHRpcGxlVmFsaWRhdGlvbkpvYkRhdGEsXG4gIE11bHRpcGxlVmFsaWRhdGlvbkpvYnNMaXN0UmVzdWx0LFxuICBNdWx0aXBsZVZhbGlkYXRpb25Kb2JzTGlzdFJlc3BvbnNlLFxuICBNdWx0aXBsZVZhbGlkYXRpb25Kb2JzTGlzdFF1ZXJ5LFxuICBNdWx0aXBsZVZhbGlkYXRpb25DcmVhdGlvbkRhdGEsXG4gIENyZWF0ZWRNdWx0aXBsZVZhbGlkYXRpb25Kb2IsXG4gIE11bHRpcGxlVmFsaWRhdGlvbkNyZWF0aW9uRGF0YVVwZGF0ZWQsXG4gIENhbmNlbGVkTXVsdGlwbGVWYWxpZGF0aW9uSm9iXG59IGZyb20gJy4uLy4uL1R5cGVzL1ZhbGlkYXRpb25zL011bHRpcGxlVmFsaWRhdGlvbic7XG5cbmV4cG9ydCBjbGFzcyBNdWx0aXBsZVZhbGlkYXRpb25Kb2IgaW1wbGVtZW50cyBNdWx0aXBsZVZhbGlkYXRpb25Kb2JSZXN1bHQge1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIGlkOiBzdHJpbmc7XG4gIHF1YW50aXR5OiBudW1iZXJcbiAgcmVjb3Jkc1Byb2Nlc3NlZDogbnVtYmVyIHwgbnVsbDtcbiAgc3RhdHVzOiBzdHJpbmc7XG4gIGRvd25sb2FkVXJsPzoge1xuICAgIGNzdjogc3RyaW5nO1xuICAgIGpzb246IHN0cmluZztcbiAgfTtcblxuICByZXNwb25zZVN0YXR1c0NvZGU6IG51bWJlcjtcbiAgc3VtbWFyeT86IHtcbiAgICAgIHJlc3VsdDoge1xuICAgICAgICAgIGNhdGNoQWxsOiBudW1iZXI7XG4gICAgICAgICAgZGVsaXZlcmFibGU6IG51bWJlcjtcbiAgICAgICAgICBkb05vdFNlbmQ6IG51bWJlcjtcbiAgICAgICAgICB1bmRlbGl2ZXJhYmxlOiBudW1iZXI7XG4gICAgICAgICAgdW5rbm93bjogbnVtYmVyO1xuICAgICAgfTtcbiAgICAgIHJpc2s6IHtcbiAgICAgICAgICBoaWdoOiBudW1iZXI7XG4gICAgICAgICAgbG93OiBudW1iZXI7XG4gICAgICAgICAgbWVkaXVtOiBudW1iZXI7XG4gICAgICAgICAgdW5rbm93bjogbnVtYmVyO1xuICAgICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoZGF0YTogTXVsdGlwbGVWYWxpZGF0aW9uSm9iRGF0YSwgcmVzcG9uc2VTdGF0dXNDb2RlOiBudW1iZXIpIHtcbiAgICB0aGlzLmNyZWF0ZWRBdCA9IG5ldyBEYXRlKGRhdGEuY3JlYXRlZF9hdCk7XG4gICAgdGhpcy5pZCA9IGRhdGEuaWQ7XG4gICAgdGhpcy5xdWFudGl0eSA9IGRhdGEucXVhbnRpdHk7XG4gICAgdGhpcy5yZWNvcmRzUHJvY2Vzc2VkID0gZGF0YS5yZWNvcmRzX3Byb2Nlc3NlZDtcbiAgICB0aGlzLnN0YXR1cyA9IGRhdGEuc3RhdHVzO1xuICAgIHRoaXMucmVzcG9uc2VTdGF0dXNDb2RlID0gcmVzcG9uc2VTdGF0dXNDb2RlO1xuICAgIGlmIChkYXRhLmRvd25sb2FkX3VybCkge1xuICAgICAgdGhpcy5kb3dubG9hZFVybCA9IHtcbiAgICAgICAgY3N2OiBkYXRhLmRvd25sb2FkX3VybD8uY3N2LFxuICAgICAgICBqc29uOiBkYXRhLmRvd25sb2FkX3VybD8uanNvblxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGRhdGEuc3VtbWFyeSkge1xuICAgICAgdGhpcy5zdW1tYXJ5ID0ge1xuICAgICAgICByZXN1bHQ6IHtcbiAgICAgICAgICBjYXRjaEFsbDogZGF0YS5zdW1tYXJ5LnJlc3VsdC5jYXRjaF9hbGwsXG4gICAgICAgICAgZGVsaXZlcmFibGU6IGRhdGEuc3VtbWFyeS5yZXN1bHQuZGVsaXZlcmFibGUsXG4gICAgICAgICAgZG9Ob3RTZW5kOiBkYXRhLnN1bW1hcnkucmVzdWx0LmRvX25vdF9zZW5kLFxuICAgICAgICAgIHVuZGVsaXZlcmFibGU6IGRhdGEuc3VtbWFyeS5yZXN1bHQudW5kZWxpdmVyYWJsZSxcbiAgICAgICAgICB1bmtub3duOiBkYXRhLnN1bW1hcnkucmVzdWx0LnVua25vd25cbiAgICAgICAgfSxcbiAgICAgICAgcmlzazoge1xuICAgICAgICAgIGhpZ2g6IGRhdGEuc3VtbWFyeS5yaXNrLmhpZ2gsXG4gICAgICAgICAgbG93OiBkYXRhLnN1bW1hcnkucmlzay5sb3csXG4gICAgICAgICAgbWVkaXVtOiBkYXRhLnN1bW1hcnkucmlzay5tZWRpdW0sXG4gICAgICAgICAgdW5rbm93bjogZGF0YS5zdW1tYXJ5LnJpc2sudW5rbm93blxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNdWx0aXBsZVZhbGlkYXRpb25DbGllbnRcbiAgZXh0ZW5kcyBOYXZpZ2F0aW9uVGhydVBhZ2VzPE11bHRpcGxlVmFsaWRhdGlvbkpvYnNMaXN0UmVzdWx0PlxuICBpbXBsZW1lbnRzIElNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVJlc3BvbnNlPFQ+KHJlc3BvbnNlOiBBUElSZXNwb25zZSk6IFQge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIC4uLnJlc3BvbnNlPy5ib2R5XG4gICAgfSBhcyBUO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlTGlzdChyZXNwb25zZTogTXVsdGlwbGVWYWxpZGF0aW9uSm9ic0xpc3RSZXNwb25zZSlcbiAgICA6IE11bHRpcGxlVmFsaWRhdGlvbkpvYnNMaXN0UmVzdWx0IHtcbiAgICBjb25zdCBkYXRhID0ge30gYXMgTXVsdGlwbGVWYWxpZGF0aW9uSm9ic0xpc3RSZXN1bHQ7XG5cbiAgICBkYXRhLmpvYnMgPSByZXNwb25zZS5ib2R5LmpvYnMubWFwKChqb2IpID0+IG5ldyBNdWx0aXBsZVZhbGlkYXRpb25Kb2Ioam9iLCByZXNwb25zZS5zdGF0dXMpKTtcblxuICAgIGRhdGEucGFnZXMgPSB0aGlzLnBhcnNlUGFnZUxpbmtzKHJlc3BvbnNlLCAnPycsICdwaXZvdCcpO1xuICAgIGRhdGEudG90YWwgPSByZXNwb25zZS5ib2R5LnRvdGFsO1xuICAgIGRhdGEuc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyBsaXN0KHF1ZXJ5PzogTXVsdGlwbGVWYWxpZGF0aW9uSm9ic0xpc3RRdWVyeSk6IFByb21pc2U8TXVsdGlwbGVWYWxpZGF0aW9uSm9ic0xpc3RSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0TGlzdFdpdGhQYWdlcygnL3Y0L2FkZHJlc3MvdmFsaWRhdGUvYnVsaycsIHF1ZXJ5KTtcbiAgfVxuXG4gIGFzeW5jIGdldChsaXN0SWQ6IHN0cmluZyk6IFByb21pc2U8TXVsdGlwbGVWYWxpZGF0aW9uSm9iPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QuZ2V0KGAvdjQvYWRkcmVzcy92YWxpZGF0ZS9idWxrLyR7bGlzdElkfWApO1xuICAgIHJldHVybiBuZXcgTXVsdGlwbGVWYWxpZGF0aW9uSm9iKHJlc3BvbnNlLmJvZHksIHJlc3BvbnNlLnN0YXR1cyk7XG4gIH1cblxuICBhc3luYyBjcmVhdGUoXG4gICAgbGlzdElkOiBzdHJpbmcsXG4gICAgZGF0YTogTXVsdGlwbGVWYWxpZGF0aW9uQ3JlYXRpb25EYXRhXG4gICk6IFByb21pc2U8Q3JlYXRlZE11bHRpcGxlVmFsaWRhdGlvbkpvYj4ge1xuICAgIGNvbnN0IG11bHRpcGxlVmFsaWRhdGlvbkRhdGE6IE11bHRpcGxlVmFsaWRhdGlvbkNyZWF0aW9uRGF0YVVwZGF0ZWQgPSB7XG4gICAgICBtdWx0aXBsZVZhbGlkYXRpb25GaWxlOiB7XG4gICAgICAgIC4uLmRhdGE/LmZpbGVcbiAgICAgIH0sXG4gICAgICAuLi5kYXRhXG4gICAgfTtcbiAgICBkZWxldGUgbXVsdGlwbGVWYWxpZGF0aW9uRGF0YS5maWxlO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yZXF1ZXN0LnBvc3RXaXRoRkQoYC92NC9hZGRyZXNzL3ZhbGlkYXRlL2J1bGsvJHtsaXN0SWR9YCwgbXVsdGlwbGVWYWxpZGF0aW9uRGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2U8Q3JlYXRlZE11bHRpcGxlVmFsaWRhdGlvbkpvYj4ocmVzcG9uc2UpO1xuICB9XG5cbiAgYXN5bmMgZGVzdHJveShsaXN0SWQ6IHN0cmluZyk6IFByb21pc2U8Q2FuY2VsZWRNdWx0aXBsZVZhbGlkYXRpb25Kb2I+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdC5kZWxldGUoYC92NC9hZGRyZXNzL3ZhbGlkYXRlL2J1bGsvJHtsaXN0SWR9YCk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlUmVzcG9uc2U8Q2FuY2VsZWRNdWx0aXBsZVZhbGlkYXRpb25Kb2I+KHJlc3BvbnNlKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgSVZhbGlkYXRpb25DbGllbnQsIElNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQgfSBmcm9tICcuLi8uLi9JbnRlcmZhY2VzL1ZhbGlkYXRpb25zJztcbmltcG9ydCB7IFZhbGlkYXRpb25RdWVyeSwgVmFsaWRhdGlvblJlc3VsdCwgVmFsaWRhdGlvblJlc3BvbnNlIH0gZnJvbSAnLi4vLi4vVHlwZXMvVmFsaWRhdGlvbnMnO1xuaW1wb3J0IFJlcXVlc3QgZnJvbSAnLi4vY29tbW9uL1JlcXVlc3QnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWYWxpZGF0ZUNsaWVudCBpbXBsZW1lbnRzIElWYWxpZGF0aW9uQ2xpZW50IHtcbiAgcHVibGljIG11bHRpcGxlVmFsaWRhdGlvbjtcbiAgcmVxdWVzdDogUmVxdWVzdDtcblxuICBjb25zdHJ1Y3RvcihyZXF1ZXN0OiBSZXF1ZXN0LCBtdWx0aXBsZVZhbGlkYXRpb25DbGllbnQ6IElNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICAgIHRoaXMubXVsdGlwbGVWYWxpZGF0aW9uID0gbXVsdGlwbGVWYWxpZGF0aW9uQ2xpZW50O1xuICB9XG5cbiAgYXN5bmMgZ2V0KGFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8VmFsaWRhdGlvblJlc3VsdD4ge1xuICAgIGNvbnN0IHF1ZXJ5OiBWYWxpZGF0aW9uUXVlcnkgPSB7IGFkZHJlc3MgfTtcbiAgICBjb25zdCByZXN1bHQ6IFZhbGlkYXRpb25SZXNwb25zZSA9IGF3YWl0IHRoaXMucmVxdWVzdC5nZXQoJy92NC9hZGRyZXNzL3ZhbGlkYXRlJywgcXVlcnkpO1xuICAgIHJldHVybiByZXN1bHQuYm9keSBhcyBWYWxpZGF0aW9uUmVzdWx0O1xuICB9XG59XG4iLCJpbXBvcnQgdXJsam9pbiBmcm9tICd1cmwtam9pbic7XG5pbXBvcnQgeyBXZWJob29rc0lkcyB9IGZyb20gJy4uL0VudW1zJztcbmltcG9ydCB7IElXZWJIb29rc0NsaWVudCB9IGZyb20gJy4uL0ludGVyZmFjZXMvV2ViaG9va3MnO1xuXG5pbXBvcnQge1xuICBXZWJob29rVmFsaWRhdGlvblJlc3BvbnNlLFxuICBXZWJob29rTGlzdCxcbiAgV2ViaG9va1Jlc3BvbnNlLFxuICBXZWJob29rc1F1ZXJ5LFxuICBXZWJob29rUmVzdWx0XG59IGZyb20gJy4uL1R5cGVzL1dlYmhvb2tzJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vY29tbW9uL1JlcXVlc3QnO1xuXG5leHBvcnQgY2xhc3MgV2ViaG9vayBpbXBsZW1lbnRzIFdlYmhvb2tSZXN1bHQge1xuICBpZDogc3RyaW5nO1xuICB1cmw6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgdXJsczogc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgdXJsOiBzdHJpbmcgfCB1bmRlZmluZWQsIHVybHM6IHN0cmluZ1tdKSB7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMudXJsID0gdXJsO1xuICAgIHRoaXMudXJscyA9IHVybHM7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2ViaG9va3NDbGllbnQgaW1wbGVtZW50cyBJV2ViSG9va3NDbGllbnQge1xuICByZXF1ZXN0OiBSZXF1ZXN0O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q6IFJlcXVlc3QpIHtcbiAgICB0aGlzLnJlcXVlc3QgPSByZXF1ZXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VXZWJob29rTGlzdChyZXNwb25zZTogeyBib2R5OiB7IHdlYmhvb2tzOiBXZWJob29rTGlzdCB9IH0pOiBXZWJob29rTGlzdCB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmJvZHkud2ViaG9va3M7XG4gIH1cblxuICBfcGFyc2VXZWJob29rV2l0aElEKGlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHJlc3BvbnNlOiBXZWJob29rUmVzcG9uc2UpOiBXZWJob29rUmVzdWx0IHtcbiAgICAgIGNvbnN0IHdlYmhvb2tSZXNwb25zZSA9IHJlc3BvbnNlPy5ib2R5Py53ZWJob29rO1xuICAgICAgbGV0IHVybCA9IHdlYmhvb2tSZXNwb25zZT8udXJsO1xuICAgICAgbGV0IHVybHMgPSB3ZWJob29rUmVzcG9uc2U/LnVybHM7XG4gICAgICBpZiAoIXVybCkge1xuICAgICAgICB1cmwgPSB1cmxzICYmIHVybHMubGVuZ3RoXG4gICAgICAgICAgPyB1cmxzWzBdXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBpZiAoKCF1cmxzIHx8IHVybHMubGVuZ3RoID09PSAwKSAmJiB1cmwpIHtcbiAgICAgICAgdXJscyA9IFt1cmxdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBXZWJob29rKGlkLCB1cmwsIHVybHMgYXMgc3RyaW5nW10pO1xuICAgIH07XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVdlYmhvb2tUZXN0KHJlc3BvbnNlOiB7IGJvZHk6IHsgY29kZTogbnVtYmVyLCBtZXNzYWdlOiBzdHJpbmcgfSB9KVxuICA6IHtjb2RlOiBudW1iZXIsIG1lc3NhZ2U6c3RyaW5nfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvZGU6IHJlc3BvbnNlLmJvZHkuY29kZSxcbiAgICAgIG1lc3NhZ2U6IHJlc3BvbnNlLmJvZHkubWVzc2FnZVxuICAgIH0gYXMgV2ViaG9va1ZhbGlkYXRpb25SZXNwb25zZTtcbiAgfVxuXG4gIGxpc3QoZG9tYWluOiBzdHJpbmcsIHF1ZXJ5OiBXZWJob29rc1F1ZXJ5KTogUHJvbWlzZTxXZWJob29rTGlzdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QuZ2V0KHVybGpvaW4oJy92My9kb21haW5zJywgZG9tYWluLCAnd2ViaG9va3MnKSwgcXVlcnkpXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tMaXN0KTtcbiAgfVxuXG4gIGdldChkb21haW46IHN0cmluZywgaWQ6IFdlYmhvb2tzSWRzKTogUHJvbWlzZTxXZWJob29rUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5nZXQodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG5cbiAgY3JlYXRlKGRvbWFpbjogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcsXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgdGVzdCA9IGZhbHNlKTogUHJvbWlzZTxXZWJob29rUmVzdWx0IHwgV2ViaG9va1ZhbGlkYXRpb25SZXNwb25zZT4ge1xuICAgIGlmICh0ZXN0KSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKCcvdjMvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJywgaWQsICd0ZXN0JyksIHsgdXJsIH0pXG4gICAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1Rlc3QpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlcXVlc3QucG9zdFdpdGhGRCh1cmxqb2luKCcvdjMvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJyksIHsgaWQsIHVybCB9KVxuICAgICAgLnRoZW4odGhpcy5fcGFyc2VXZWJob29rV2l0aElEKGlkKSk7XG4gIH1cblxuICB1cGRhdGUoZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcsIHVybFZhbHVlczogc3RyaW5nIHwgc3RyaW5nW10pOiBQcm9taXNlPFdlYmhvb2tSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0LnB1dFdpdGhGRCh1cmxqb2luKCcvdjMvZG9tYWlucycsIGRvbWFpbiwgJ3dlYmhvb2tzJywgaWQpLCB7IHVybDogdXJsVmFsdWVzIH0pXG4gICAgICAudGhlbih0aGlzLl9wYXJzZVdlYmhvb2tXaXRoSUQoaWQpKTtcbiAgfVxuXG4gIGRlc3Ryb3koZG9tYWluOiBzdHJpbmcsIGlkOiBzdHJpbmcpIDogUHJvbWlzZTxXZWJob29rUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdC5kZWxldGUodXJsam9pbignL3YzL2RvbWFpbnMnLCBkb21haW4sICd3ZWJob29rcycsIGlkKSlcbiAgICAgIC50aGVuKHRoaXMuX3BhcnNlV2ViaG9va1dpdGhJRChpZCkpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBBUElFcnJvck9wdGlvbnMsIEFQSUVycm9yVHlwZSB9IGZyb20gJy4uLy4uL1R5cGVzL0NvbW1vbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFQSUVycm9yIGV4dGVuZHMgRXJyb3IgaW1wbGVtZW50cyBBUElFcnJvclR5cGUge1xuICBwdWJsaWMgc3RhdHVzOiBudW1iZXIgO1xuICBwdWJsaWMgc3RhY2s6IHN0cmluZztcbiAgcHVibGljIGRldGFpbHM6IHN0cmluZztcbiAgcHVibGljIHR5cGU6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcih7XG4gICAgc3RhdHVzLFxuICAgIHN0YXR1c1RleHQsXG4gICAgbWVzc2FnZSxcbiAgICBib2R5ID0ge31cbiAgfTogQVBJRXJyb3JPcHRpb25zKSB7XG4gICAgbGV0IGJvZHlNZXNzYWdlID0gJyc7XG4gICAgbGV0IGVycm9yID0gJyc7XG4gICAgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgYm9keU1lc3NhZ2UgPSBib2R5O1xuICAgIH0gZWxzZSB7XG4gICAgICBib2R5TWVzc2FnZSA9IGJvZHk/Lm1lc3NhZ2UgfHwgJyc7XG4gICAgICBlcnJvciA9IGJvZHk/LmVycm9yIHx8ICcnO1xuICAgIH1cbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5zdGFjayA9ICcnO1xuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgZXJyb3IgfHwgc3RhdHVzVGV4dCB8fCAnJztcbiAgICB0aGlzLmRldGFpbHMgPSBib2R5TWVzc2FnZTtcbiAgICB0aGlzLnR5cGUgPSAnTWFpbGd1bkFQSUVycm9yJztcbiAgfVxufVxuIiwiaW1wb3J0ICogYXMgTm9kZUZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5pbXBvcnQgeyBBUElFcnJvck9wdGlvbnMsIElucHV0Rm9ybURhdGEgfSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24nO1xuaW1wb3J0IEFQSUVycm9yIGZyb20gJy4vRXJyb3InO1xuXG5jbGFzcyBGb3JtRGF0YUJ1aWxkZXIge1xuICBwcml2YXRlIEZvcm1EYXRhQ29uc3RydWN0b3I6IElucHV0Rm9ybURhdGE7XG4gIGNvbnN0cnVjdG9yKEZvcm1EYXRhQ29uc3RydWN0b3I6IElucHV0Rm9ybURhdGEpIHtcbiAgICB0aGlzLkZvcm1EYXRhQ29uc3RydWN0b3IgPSBGb3JtRGF0YUNvbnN0cnVjdG9yO1xuICB9XG5cbiAgcHVibGljIGNyZWF0ZUZvcm1EYXRhKGRhdGE6IGFueSk6IE5vZGVGb3JtRGF0YSB8IEZvcm1EYXRhIHtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgZGF0YSBvYmplY3QnKTtcbiAgICB9XG4gICAgY29uc3QgZm9ybURhdGE6IE5vZGVGb3JtRGF0YSB8IEZvcm1EYXRhID0gT2JqZWN0LmtleXMoZGF0YSlcbiAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gZGF0YVtrZXldOyB9KVxuICAgICAgLnJlZHVjZSgoZm9ybURhdGFBY2M6IE5vZGVGb3JtRGF0YSB8IEZvcm1EYXRhLCBrZXkpID0+IHtcbiAgICAgICAgY29uc3QgZmlsZUtleXMgPSBbJ2F0dGFjaG1lbnQnLCAnaW5saW5lJywgJ211bHRpcGxlVmFsaWRhdGlvbkZpbGUnXTtcbiAgICAgICAgaWYgKGZpbGVLZXlzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICB0aGlzLmFkZEZpbGVzVG9GRChrZXksIGRhdGFba2V5XSwgZm9ybURhdGFBY2MpO1xuICAgICAgICAgIHJldHVybiBmb3JtRGF0YUFjYztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXkgPT09ICdtZXNzYWdlJykgeyAvLyBtaW1lIG1lc3NhZ2VcbiAgICAgICAgICB0aGlzLmFkZE1pbWVEYXRhVG9GRChrZXksIGRhdGFba2V5XSwgZm9ybURhdGFBY2MpO1xuICAgICAgICAgIHJldHVybiBmb3JtRGF0YUFjYztcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYWRkQ29tbW9uUHJvcGVydHlUb0ZEKGtleSwgZGF0YVtrZXldLCBmb3JtRGF0YUFjYyk7XG4gICAgICAgIHJldHVybiBmb3JtRGF0YUFjYztcbiAgICAgIH0sIG5ldyB0aGlzLkZvcm1EYXRhQ29uc3RydWN0b3IoKSk7XG4gICAgcmV0dXJuIGZvcm1EYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0Zvcm1EYXRhUGFja2FnZShmb3JtRGF0YUluc3RhbmNlOiBOb2RlRm9ybURhdGEgfCBGb3JtRGF0YSlcbiAgOiBib29sZWFuIHtcbiAgICByZXR1cm4gKDxOb2RlRm9ybURhdGE+Zm9ybURhdGFJbnN0YW5jZSkuZ2V0SGVhZGVycyAhPT0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRBdHRhY2htZW50T3B0aW9ucyhpdGVtOiB7XG4gICAgZmlsZW5hbWU/OiBzdHJpbmc7XG4gICAgY29udGVudFR5cGU/IDogc3RyaW5nO1xuICAgIGtub3duTGVuZ3RoPzogbnVtYmVyO1xuICB9KToge1xuICAgIGZpbGVuYW1lPzogc3RyaW5nLFxuICAgIGNvbnRlbnRUeXBlPzogc3RyaW5nLFxuICAgIGtub3duTGVuZ3RoPzogbnVtYmVyXG4gIH0ge1xuICAgIGlmICh0eXBlb2YgaXRlbSAhPT0gJ29iamVjdCcgfHwgdGhpcy5pc1N0cmVhbShpdGVtKSkgcmV0dXJuIHt9O1xuICAgIGNvbnN0IHtcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgY29udGVudFR5cGUsXG4gICAgICBrbm93bkxlbmd0aFxuICAgIH0gPSBpdGVtO1xuICAgIHJldHVybiB7XG4gICAgICAuLi4oZmlsZW5hbWUgPyB7IGZpbGVuYW1lIH0gOiB7IGZpbGVuYW1lOiAnZmlsZScgfSksXG4gICAgICAuLi4oY29udGVudFR5cGUgJiYgeyBjb250ZW50VHlwZSB9KSxcbiAgICAgIC4uLihrbm93bkxlbmd0aCAmJiB7IGtub3duTGVuZ3RoIH0pXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkTWltZURhdGFUb0ZEKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGRhdGE6IEJ1ZmZlciB8IEJsb2IgfCBzdHJpbmcsXG4gICAgZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgKTogdm9pZCB7XG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykgeyAvLyBpZiBzdHJpbmcgb25seSB0d28gcGFyYW1ldGVycyBzaG91bGQgYmUgdXNlZC5cbiAgICAgIGZvcm1EYXRhSW5zdGFuY2UuYXBwZW5kKGtleSwgZGF0YSBhcyBzdHJpbmcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzRm9ybURhdGFQYWNrYWdlKGZvcm1EYXRhSW5zdGFuY2UpKSB7IC8vIGZvcm0tZGF0YSBwYWNrYWdlIGlzIHVzZWRcbiAgICAgIGNvbnN0IG5vZGVGb3JtRGF0YSA9IGZvcm1EYXRhSW5zdGFuY2UgYXMgTm9kZUZvcm1EYXRhO1xuICAgICAgbm9kZUZvcm1EYXRhLmFwcGVuZChrZXksIGRhdGEsIHsgZmlsZW5hbWU6ICdNaW1lTWVzc2FnZScgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBCbG9iICE9PSB1bmRlZmluZWQpIHsgLy8gZWl0aGVyIG5vZGUgPiAxOCBvciBicm93c2VyXG4gICAgICBjb25zdCBicm93c2VyRm9ybURhdGEgPSBmb3JtRGF0YUluc3RhbmNlIGFzIEZvcm1EYXRhOyAvLyBCcm93c2VyIGNvbXBsaWFudCBGb3JtRGF0YVxuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBCbG9iKSB7XG4gICAgICAgIGJyb3dzZXJGb3JtRGF0YS5hcHBlbmQoa2V5LCBkYXRhLCAnTWltZU1lc3NhZ2UnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBCdWZmZXIgIT09ICd1bmRlZmluZWQnKSB7IC8vIG5vZGUgZW52aXJvbm1lbnRcbiAgICAgICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkge1xuICAgICAgICAgIGNvbnN0IGJsb2JJbnN0YW5jZSA9IG5ldyBCbG9iKFtkYXRhXSk7XG4gICAgICAgICAgYnJvd3NlckZvcm1EYXRhLmFwcGVuZChrZXksIGJsb2JJbnN0YW5jZSwgJ01pbWVNZXNzYWdlJyk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEFQSUVycm9yKHtcbiAgICAgIHN0YXR1czogNDAwLFxuICAgICAgc3RhdHVzVGV4dDogYFVua25vd24gZGF0YSB0eXBlIGZvciAke2tleX0gcHJvcGVydHlgLFxuICAgICAgYm9keTogJ1RoZSBtaW1lIGRhdGEgc2hvdWxkIGhhdmUgdHlwZSBvZiBCdWZmZXIsIFN0cmluZyBvciBCbG9iJ1xuICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkRmlsZXNUb0ZEKFxuICAgIHByb3BlcnR5TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBhbnksXG4gICAgZm9ybURhdGFJbnN0YW5jZTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgYXBwZW5kRmlsZVRvRkQgPSAoXG4gICAgICBvcmlnaW5hbEtleTogc3RyaW5nLFxuICAgICAgb2JqOiBhbnksXG4gICAgICBmb3JtRGF0YTogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgICApOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IGtleSA9IG9yaWdpbmFsS2V5ID09PSAnbXVsdGlwbGVWYWxpZGF0aW9uRmlsZScgPyAnZmlsZScgOiBvcmlnaW5hbEtleTtcbiAgICAgIGNvbnN0IGlzU3RyZWFtRGF0YSA9IHRoaXMuaXNTdHJlYW0ob2JqKTtcbiAgICAgIGNvbnN0IG9iakRhdGEgPSBpc1N0cmVhbURhdGEgPyBvYmogOiBvYmouZGF0YTtcbiAgICAgIC8vIGdldEF0dGFjaG1lbnRPcHRpb25zIHNob3VsZCBiZSBjYWxsZWQgd2l0aCBvYmogcGFyYW1ldGVyIHRvIHByZXZlbnQgbG9vc2luZyBmaWxlbmFtZVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZ2V0QXR0YWNobWVudE9wdGlvbnMob2JqKTtcblxuICAgICAgaWYgKHRoaXMuaXNGb3JtRGF0YVBhY2thZ2UoZm9ybURhdGEpKSB7XG4gICAgICAgIGNvbnN0IGZkID0gZm9ybURhdGEgYXMgTm9kZUZvcm1EYXRhO1xuICAgICAgICBjb25zdCBkYXRhID0gdHlwZW9mIG9iakRhdGEgPT09ICdzdHJpbmcnID8gQnVmZmVyLmZyb20ob2JqRGF0YSkgOiBvYmpEYXRhO1xuICAgICAgICBmZC5hcHBlbmQoa2V5LCBkYXRhLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIEJsb2IgIT09IHVuZGVmaW5lZCkgeyAvLyBlaXRoZXIgbm9kZSA+IDE4IG9yIGJyb3dzZXJcbiAgICAgICAgY29uc3QgYnJvd3NlckZvcm1EYXRhID0gZm9ybURhdGFJbnN0YW5jZSBhcyBGb3JtRGF0YTsgLy8gQnJvd3NlciBjb21wbGlhbnQgRm9ybURhdGFcbiAgICAgICAgaWYgKHR5cGVvZiBvYmpEYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNvbnN0IGJsb2JJbnN0YW5jZSA9IG5ldyBCbG9iKFtvYmpEYXRhXSk7XG4gICAgICAgICAgYnJvd3NlckZvcm1EYXRhLmFwcGVuZChrZXksIGJsb2JJbnN0YW5jZSwgb3B0aW9ucy5maWxlbmFtZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvYmpEYXRhIGluc3RhbmNlb2YgQmxvYikge1xuICAgICAgICAgIGJyb3dzZXJGb3JtRGF0YS5hcHBlbmQoa2V5LCBvYmpEYXRhLCBvcHRpb25zLmZpbGVuYW1lKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBCdWZmZXIgIT09ICd1bmRlZmluZWQnKSB7IC8vIG5vZGUgZW52aXJvbm1lbnRcbiAgICAgICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iakRhdGEpKSB7XG4gICAgICAgICAgICBjb25zdCBibG9iSW5zdGFuY2UgPSBuZXcgQmxvYihbb2JqRGF0YV0pO1xuICAgICAgICAgICAgYnJvd3NlckZvcm1EYXRhLmFwcGVuZChrZXksIGJsb2JJbnN0YW5jZSwgb3B0aW9ucy5maWxlbmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgdmFsdWUuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICBhcHBlbmRGaWxlVG9GRChwcm9wZXJ0eU5hbWUsIGl0ZW0sIGZvcm1EYXRhSW5zdGFuY2UpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGVuZEZpbGVUb0ZEKHByb3BlcnR5TmFtZSwgdmFsdWUsIGZvcm1EYXRhSW5zdGFuY2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNTdHJlYW0oZGF0YTogYW55KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgZGF0YS5waXBlID09PSAnZnVuY3Rpb24nO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRDb21tb25Qcm9wZXJ0eVRvRkQoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdmFsdWU6IGFueSxcbiAgICBmb3JtRGF0YUFjYzogTm9kZUZvcm1EYXRhIHwgRm9ybURhdGFcbiAgKTogdm9pZCB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtOiBhbnkpIHtcbiAgICAgICAgZm9ybURhdGFBY2MuYXBwZW5kKGtleSwgaXRlbSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgIGZvcm1EYXRhQWNjLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICB9XG4gIH1cbn1cbmV4cG9ydCBkZWZhdWx0IEZvcm1EYXRhQnVpbGRlcjtcbiIsImltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBBUElFcnJvciBmcm9tICcuL0Vycm9yJztcblxuaW1wb3J0IHtcbiAgUGFnZXNMaXN0QWNjdW11bGF0b3IsXG4gIFBhcnNlZFBhZ2UsXG4gIFBhcnNlZFBhZ2VzTGlzdCxcbiAgUXVlcnlXaXRoUGFnZSxcbiAgUmVzcG9uc2VXaXRoUGFnaW5nLFxuICBVcGRhdGVkVXJsQW5kUXVlcnksXG4gIEFQSUVycm9yT3B0aW9uc1xufSBmcm9tICcuLi8uLi9UeXBlcy9Db21tb24nO1xuaW1wb3J0IHtcbiAgSUJvdW5jZSxcbiAgSUNvbXBsYWludCxcbiAgSVVuc3Vic2NyaWJlLFxuICBJV2hpdGVMaXN0XG59IGZyb20gJy4uLy4uL0ludGVyZmFjZXMvU3VwcHJlc3Npb25zJztcbmltcG9ydCBSZXF1ZXN0IGZyb20gJy4vUmVxdWVzdCc7XG5pbXBvcnQge1xuICBTdXBwcmVzc2lvbkRhdGFUeXBlXG59IGZyb20gJy4uLy4uL1R5cGVzL1N1cHByZXNzaW9ucyc7XG5cbmV4cG9ydCBkZWZhdWx0IGFic3RyYWN0IGNsYXNzIE5hdmlnYXRpb25UaHJ1UGFnZXMgPFQ+IHtcbiAgcmVxdWVzdD86IFJlcXVlc3Q7XG4gIGNvbnN0cnVjdG9yKHJlcXVlc3Q/OiBSZXF1ZXN0KSB7XG4gICAgaWYgKHJlcXVlc3QpIHtcbiAgICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlUGFnZShcbiAgICBpZDogc3RyaW5nLFxuICAgIHBhZ2VVcmw6IHN0cmluZyxcbiAgICB1cmxTZXBhcmF0b3I6IHN0cmluZyxcbiAgICBpdGVyYXRvck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZFxuICApIDogUGFyc2VkUGFnZSB7XG4gICAgY29uc3QgcGFyc2VkVXJsID0gbmV3IFVSTChwYWdlVXJsKTtcbiAgICBjb25zdCB7IHNlYXJjaFBhcmFtcyB9ID0gcGFyc2VkVXJsO1xuXG4gICAgY29uc3QgcGFnZVZhbHVlID0gcGFnZVVybCAmJiB0eXBlb2YgcGFnZVVybCA9PT0gJ3N0cmluZycgPyBwYWdlVXJsLnNwbGl0KHVybFNlcGFyYXRvcikucG9wKCkgfHwgJycgOiAnJztcbiAgICBsZXQgaXRlcmF0b3JQb3NpdGlvbiA9IG51bGw7XG4gICAgaWYgKGl0ZXJhdG9yTmFtZSkge1xuICAgICAgaXRlcmF0b3JQb3NpdGlvbiA9IHNlYXJjaFBhcmFtcy5oYXMoaXRlcmF0b3JOYW1lKVxuICAgICAgICA/IHNlYXJjaFBhcmFtcy5nZXQoaXRlcmF0b3JOYW1lKVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGlkLFxuICAgICAgcGFnZTogdXJsU2VwYXJhdG9yID09PSAnPycgPyBgPyR7cGFnZVZhbHVlfWAgOiBwYWdlVmFsdWUsXG4gICAgICBpdGVyYXRvclBvc2l0aW9uLFxuICAgICAgdXJsOiBwYWdlVXJsXG4gICAgfSBhcyBQYXJzZWRQYWdlO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlUGFnZUxpbmtzKFxuICAgIHJlc3BvbnNlOiBSZXNwb25zZVdpdGhQYWdpbmcsXG4gICAgdXJsU2VwYXJhdG9yOiBzdHJpbmcsXG4gICAgaXRlcmF0b3JOYW1lPzogc3RyaW5nXG4gICk6IFBhcnNlZFBhZ2VzTGlzdCB7XG4gICAgY29uc3QgcGFnZXMgPSBPYmplY3QuZW50cmllcyhyZXNwb25zZS5ib2R5LnBhZ2luZyk7XG4gICAgcmV0dXJuIHBhZ2VzLnJlZHVjZShcbiAgICAgIChhY2M6IFBhZ2VzTGlzdEFjY3VtdWxhdG9yLCBbaWQsIHBhZ2VVcmxdOiBbIGlkOiBzdHJpbmcsIHBhZ2VVcmw6IHN0cmluZ10pID0+IHtcbiAgICAgICAgYWNjW2lkXSA9IHRoaXMucGFyc2VQYWdlKGlkLCBwYWdlVXJsLCB1cmxTZXBhcmF0b3IsIGl0ZXJhdG9yTmFtZSk7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCB7fVxuICAgICkgYXMgdW5rbm93biBhcyBQYXJzZWRQYWdlc0xpc3Q7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVVybEFuZFF1ZXJ5KGNsaWVudFVybDogc3RyaW5nLCBxdWVyeT86IFF1ZXJ5V2l0aFBhZ2UpOiBVcGRhdGVkVXJsQW5kUXVlcnkge1xuICAgIGxldCB1cmwgPSBjbGllbnRVcmw7XG4gICAgY29uc3QgcXVlcnlDb3B5ID0geyAuLi5xdWVyeSB9O1xuICAgIGlmIChxdWVyeUNvcHkucGFnZSkge1xuICAgICAgdXJsID0gdXJsam9pbihjbGllbnRVcmwsIHF1ZXJ5Q29weS5wYWdlKTtcbiAgICAgIGRlbGV0ZSBxdWVyeUNvcHkucGFnZTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHVybCxcbiAgICAgIHVwZGF0ZWRRdWVyeTogcXVlcnlDb3B5XG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyByZXF1ZXN0TGlzdFdpdGhQYWdlcyhjbGllbnRVcmw6c3RyaW5nLCBxdWVyeT86IFF1ZXJ5V2l0aFBhZ2UsIE1vZGVsPzoge1xuICAgIG5ldyhkYXRhOiBTdXBwcmVzc2lvbkRhdGFUeXBlKTpcbiAgICBJQm91bmNlIHwgSUNvbXBsYWludCB8IElVbnN1YnNjcmliZSB8IElXaGl0ZUxpc3RcbiAgfSk6IFByb21pc2U8VD4ge1xuICAgIGNvbnN0IHsgdXJsLCB1cGRhdGVkUXVlcnkgfSA9IHRoaXMudXBkYXRlVXJsQW5kUXVlcnkoY2xpZW50VXJsLCBxdWVyeSk7XG4gICAgaWYgKHRoaXMucmVxdWVzdCkge1xuICAgICAgY29uc3QgcmVzcG9uc2U6IFJlc3BvbnNlV2l0aFBhZ2luZyA9IGF3YWl0IHRoaXMucmVxdWVzdC5nZXQodXJsLCB1cGRhdGVkUXVlcnkpO1xuICAgICAgLy8gTW9kZWwgaGVyZSBpcyB1c3VhbGx5IHVuZGVmaW5lZCBleGNlcHQgZm9yIFN1cHByZXNzaW9uIENsaWVudFxuICAgICAgcmV0dXJuIHRoaXMucGFyc2VMaXN0KHJlc3BvbnNlLCBNb2RlbCk7XG4gICAgfVxuICAgIHRocm93IG5ldyBBUElFcnJvcih7XG4gICAgICBzdGF0dXM6IDUwMCxcbiAgICAgIHN0YXR1c1RleHQ6ICdSZXF1ZXN0IHByb3BlcnR5IGlzIGVtcHR5JyxcbiAgICAgIGJvZHk6IHsgbWVzc2FnZTogJycgfVxuICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwYXJzZUxpc3QocmVzcG9uc2U6IFJlc3BvbnNlV2l0aFBhZ2luZywgTW9kZWw/OiB7XG4gICAgbmV3KGRhdGE6IFN1cHByZXNzaW9uRGF0YVR5cGUpOlxuICAgIElCb3VuY2UgfCBJQ29tcGxhaW50IHwgSVVuc3Vic2NyaWJlIHwgSVdoaXRlTGlzdFxuICB9KTogVDtcbn1cbiIsImltcG9ydCAqIGFzIGJhc2U2NCBmcm9tICdiYXNlLTY0JztcbmltcG9ydCB1cmxqb2luIGZyb20gJ3VybC1qb2luJztcbmltcG9ydCBheGlvcywge1xuICBBeGlvc0Vycm9yLFxuICBBeGlvc1Jlc3BvbnNlLFxuICBBeGlvc0hlYWRlcnMsXG4gIFJhd0F4aW9zUmVxdWVzdEhlYWRlcnMsXG4gIEF4aW9zUHJveHlDb25maWcsXG59IGZyb20gJ2F4aW9zJztcbmltcG9ydCAqIGFzIE5vZGVGb3JtRGF0YSBmcm9tICdmb3JtLWRhdGEnO1xuaW1wb3J0IEFQSUVycm9yIGZyb20gJy4vRXJyb3InO1xuaW1wb3J0IHtcbiAgT25DYWxsUmVxdWVzdE9wdGlvbnMsXG4gIFJlcXVlc3RPcHRpb25zLFxuICBBUElFcnJvck9wdGlvbnMsXG4gIElucHV0Rm9ybURhdGEsXG4gIEFQSVJlc3BvbnNlLFxuICBJcFBvb2xEZWxldGVEYXRhXG59IGZyb20gJy4uLy4uL1R5cGVzJztcblxuaW1wb3J0IEZvcm1EYXRhQnVpbGRlciBmcm9tICcuL0Zvcm1EYXRhQnVpbGRlcic7XG5pbXBvcnQgU3ViYWNjb3VudHNDbGllbnQgZnJvbSAnLi4vU3ViYWNjb3VudHMnO1xuXG5jbGFzcyBSZXF1ZXN0IHtcbiAgcHJpdmF0ZSB1c2VybmFtZTogc3RyaW5nO1xuICBwcml2YXRlIGtleTogc3RyaW5nO1xuICBwcml2YXRlIHVybDogc3RyaW5nO1xuICBwcml2YXRlIHRpbWVvdXQ6IG51bWJlcjtcbiAgcHJpdmF0ZSBoZWFkZXJzOiBBeGlvc0hlYWRlcnM7XG4gIHByaXZhdGUgZm9ybURhdGFCdWlsZGVyOiBGb3JtRGF0YUJ1aWxkZXI7XG4gIHByaXZhdGUgbWF4Qm9keUxlbmd0aDogbnVtYmVyO1xuICBwcml2YXRlIHByb3h5OiBBeGlvc1Byb3h5Q29uZmlnIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFJlcXVlc3RPcHRpb25zLCBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YSkge1xuICAgIHRoaXMudXNlcm5hbWUgPSBvcHRpb25zLnVzZXJuYW1lO1xuICAgIHRoaXMua2V5ID0gb3B0aW9ucy5rZXk7XG4gICAgdGhpcy51cmwgPSBvcHRpb25zLnVybCBhcyBzdHJpbmc7XG4gICAgdGhpcy50aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0O1xuICAgIHRoaXMuaGVhZGVycyA9IHRoaXMubWFrZUhlYWRlcnNGcm9tT2JqZWN0KG9wdGlvbnMuaGVhZGVycyk7XG4gICAgdGhpcy5mb3JtRGF0YUJ1aWxkZXIgPSBuZXcgRm9ybURhdGFCdWlsZGVyKGZvcm1EYXRhKTtcbiAgICB0aGlzLm1heEJvZHlMZW5ndGggPSA1MjQyODgwMDsgLy8gNTAgTUJcbiAgICB0aGlzLnByb3h5ID0gb3B0aW9ucz8ucHJveHk7XG4gIH1cblxuICBhc3luYyByZXF1ZXN0KFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHVybDogc3RyaW5nLFxuICAgIG9uQ2FsbE9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duIHwgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPlxuICApOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgY29uc3Qgb3B0aW9uczogT25DYWxsUmVxdWVzdE9wdGlvbnMgPSB7IC4uLm9uQ2FsbE9wdGlvbnMgfTtcbiAgICBkZWxldGUgb3B0aW9ucz8uaGVhZGVycztcbiAgICBjb25zdCByZXF1ZXN0SGVhZGVycyA9IHRoaXMuam9pbkFuZFRyYW5zZm9ybUhlYWRlcnMob25DYWxsT3B0aW9ucyk7XG4gICAgY29uc3QgcGFyYW1zID0geyAuLi5vcHRpb25zIH07XG5cbiAgICBpZiAob3B0aW9ucz8ucXVlcnkgJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob3B0aW9ucz8ucXVlcnkpLmxlbmd0aCA+IDApIHtcbiAgICAgIHBhcmFtcy5wYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKG9wdGlvbnMucXVlcnkpO1xuICAgICAgZGVsZXRlIHBhcmFtcy5xdWVyeTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8uYm9keSkge1xuICAgICAgY29uc3QgYm9keSA9IG9wdGlvbnM/LmJvZHk7XG4gICAgICBwYXJhbXMuZGF0YSA9IGJvZHk7XG4gICAgICBkZWxldGUgcGFyYW1zLmJvZHk7XG4gICAgfVxuICAgIGxldCByZXNwb25zZTogQXhpb3NSZXNwb25zZTtcbiAgICBjb25zdCB1cmxWYWx1ZSA9IHVybGpvaW4odGhpcy51cmwsIHVybCk7XG5cbiAgICB0cnkge1xuICAgICAgcmVzcG9uc2UgPSBhd2FpdCBheGlvcy5yZXF1ZXN0KHtcbiAgICAgICAgbWV0aG9kOiBtZXRob2QudG9Mb2NhbGVVcHBlckNhc2UoKSxcbiAgICAgICAgdGltZW91dDogdGhpcy50aW1lb3V0LFxuICAgICAgICB1cmw6IHVybFZhbHVlLFxuICAgICAgICBoZWFkZXJzOiByZXF1ZXN0SGVhZGVycyxcbiAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICBtYXhCb2R5TGVuZ3RoOiB0aGlzLm1heEJvZHlMZW5ndGgsXG4gICAgICAgIHByb3h5OiB0aGlzLnByb3h5LFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBjb25zdCBlcnJvclJlc3BvbnNlID0gZXJyIGFzIEF4aW9zRXJyb3I7XG5cbiAgICAgIHRocm93IG5ldyBBUElFcnJvcih7XG4gICAgICAgIHN0YXR1czogZXJyb3JSZXNwb25zZT8ucmVzcG9uc2U/LnN0YXR1cyB8fCA0MDAsXG4gICAgICAgIHN0YXR1c1RleHQ6IGVycm9yUmVzcG9uc2U/LnJlc3BvbnNlPy5zdGF0dXNUZXh0IHx8IGVycm9yUmVzcG9uc2UuY29kZSxcbiAgICAgICAgYm9keTogZXJyb3JSZXNwb25zZT8ucmVzcG9uc2U/LmRhdGEgfHwgZXJyb3JSZXNwb25zZS5tZXNzYWdlXG4gICAgICB9IGFzIEFQSUVycm9yT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5nZXRSZXNwb25zZUJvZHkocmVzcG9uc2UpO1xuICAgIHJldHVybiByZXMgYXMgQVBJUmVzcG9uc2U7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldFJlc3BvbnNlQm9keShyZXNwb25zZTogQXhpb3NSZXNwb25zZSk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXMgPSB7XG4gICAgICBib2R5OiB7fSxcbiAgICAgIHN0YXR1czogcmVzcG9uc2U/LnN0YXR1c1xuICAgIH0gYXMgQVBJUmVzcG9uc2U7XG5cbiAgICBpZiAodHlwZW9mIHJlc3BvbnNlLmRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAocmVzcG9uc2UuZGF0YSA9PT0gJ01haWxndW4gTWFnbmlmaWNlbnQgQVBJJykge1xuICAgICAgICB0aHJvdyBuZXcgQVBJRXJyb3Ioe1xuICAgICAgICAgIHN0YXR1czogNDAwLFxuICAgICAgICAgIHN0YXR1c1RleHQ6ICdJbmNvcnJlY3QgdXJsJyxcbiAgICAgICAgICBib2R5OiByZXNwb25zZS5kYXRhXG4gICAgICAgIH0gYXMgQVBJRXJyb3JPcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJlcy5ib2R5ID0ge1xuICAgICAgICBtZXNzYWdlOiByZXNwb25zZS5kYXRhXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMuYm9keSA9IHJlc3BvbnNlLmRhdGE7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBwcml2YXRlIGpvaW5BbmRUcmFuc2Zvcm1IZWFkZXJzKFxuICAgIG9uQ2FsbE9wdGlvbnM/OiBPbkNhbGxSZXF1ZXN0T3B0aW9uc1xuICApOiBBeGlvc0hlYWRlcnMge1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXJzID0gbmV3IEF4aW9zSGVhZGVycygpO1xuXG4gICAgY29uc3QgYmFzaWMgPSBiYXNlNjQuZW5jb2RlKGAke3RoaXMudXNlcm5hbWV9OiR7dGhpcy5rZXl9YCk7XG4gICAgcmVxdWVzdEhlYWRlcnMuc2V0QXV0aG9yaXphdGlvbihgQmFzaWMgJHtiYXNpY31gKTtcbiAgICByZXF1ZXN0SGVhZGVycy5zZXQodGhpcy5oZWFkZXJzKTtcblxuICAgIGNvbnN0IHJlY2VpdmVkT25DYWxsSGVhZGVycyA9IG9uQ2FsbE9wdGlvbnMgJiYgb25DYWxsT3B0aW9ucy5oZWFkZXJzO1xuICAgIGNvbnN0IG9uQ2FsbEhlYWRlcnMgPSB0aGlzLm1ha2VIZWFkZXJzRnJvbU9iamVjdChyZWNlaXZlZE9uQ2FsbEhlYWRlcnMpO1xuICAgIHJlcXVlc3RIZWFkZXJzLnNldChvbkNhbGxIZWFkZXJzKTtcbiAgICByZXR1cm4gcmVxdWVzdEhlYWRlcnM7XG4gIH1cblxuICBwcml2YXRlIG1ha2VIZWFkZXJzRnJvbU9iamVjdChcbiAgICBoZWFkZXJzT2JqZWN0OiBSYXdBeGlvc1JlcXVlc3RIZWFkZXJzID0ge31cbiAgKTogQXhpb3NIZWFkZXJzIHtcbiAgICBsZXQgcmVxdWVzdEhlYWRlcnMgPSBuZXcgQXhpb3NIZWFkZXJzKCk7XG4gICAgcmVxdWVzdEhlYWRlcnMgPSBPYmplY3QuZW50cmllcyhoZWFkZXJzT2JqZWN0KS5yZWR1Y2UoXG4gICAgICAoaGVhZGVyc0FjY3VtdWxhdG9yOiBBeGlvc0hlYWRlcnMsIGN1cnJlbnRQYWlyKSA9PiB7XG4gICAgICAgIGNvbnN0IFtrZXksIHZhbHVlXSA9IGN1cnJlbnRQYWlyO1xuICAgICAgICBoZWFkZXJzQWNjdW11bGF0b3Iuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICByZXR1cm4gaGVhZGVyc0FjY3VtdWxhdG9yO1xuICAgICAgfSwgcmVxdWVzdEhlYWRlcnNcbiAgICApO1xuICAgIHJldHVybiByZXF1ZXN0SGVhZGVycztcbiAgfVxuXG4gIHNldFN1YmFjY291bnRIZWFkZXIoc3ViYWNjb3VudElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBoZWFkZXJzID0gdGhpcy5tYWtlSGVhZGVyc0Zyb21PYmplY3Qoe1xuICAgICAgLi4udGhpcy5oZWFkZXJzLFxuICAgICAgW1N1YmFjY291bnRzQ2xpZW50LlNVQkFDQ09VTlRfSEVBREVSXTogc3ViYWNjb3VudElkXG4gICAgfSk7XG4gICAgdGhpcy5oZWFkZXJzLnNldChoZWFkZXJzKTtcbiAgfVxuXG4gIHJlc2V0U3ViYWNjb3VudEhlYWRlcigpOiB2b2lkIHtcbiAgICB0aGlzLmhlYWRlcnMuZGVsZXRlKFN1YmFjY291bnRzQ2xpZW50LlNVQkFDQ09VTlRfSEVBREVSKTtcbiAgfVxuXG4gIHF1ZXJ5KFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHVybDogc3RyaW5nLFxuICAgIHF1ZXJ5PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBBcnJheTxBcnJheTxzdHJpbmc+PixcbiAgICBvcHRpb25zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QobWV0aG9kLCB1cmwsIHsgcXVlcnksIC4uLm9wdGlvbnMgfSk7XG4gIH1cblxuICBjb21tYW5kKFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHVybDogc3RyaW5nLFxuICAgIGRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10gfCBzdHJpbmcgfCBOb2RlRm9ybURhdGEgfCBGb3JtRGF0YSxcbiAgICBvcHRpb25zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgYWRkRGVmYXVsdEhlYWRlcnMgPSB0cnVlXG4gICk6IFByb21pc2U8QVBJUmVzcG9uc2U+IHtcbiAgICBsZXQgaGVhZGVycyA9IHt9O1xuICAgIGlmIChhZGREZWZhdWx0SGVhZGVycykge1xuICAgICAgaGVhZGVycyA9IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnIH07XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgLi4uaGVhZGVycyxcbiAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAuLi5vcHRpb25zXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KFxuICAgICAgbWV0aG9kLFxuICAgICAgdXJsLFxuICAgICAgcmVxdWVzdE9wdGlvbnNcbiAgICApO1xuICB9XG5cbiAgZ2V0KFxuICAgIHVybDogc3RyaW5nLFxuICAgIHF1ZXJ5PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBBcnJheTxBcnJheTxzdHJpbmc+PixcbiAgICBvcHRpb25zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnF1ZXJ5KCdnZXQnLCB1cmwsIHF1ZXJ5LCBvcHRpb25zKTtcbiAgfVxuXG4gIHBvc3QoXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgZGF0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICApOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncG9zdCcsIHVybCwgZGF0YSwgb3B0aW9ucyk7XG4gIH1cblxuICBwb3N0V2l0aEZEKFxuICAgIHVybDogc3RyaW5nLFxuICAgIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXVxuICApOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLmZvcm1EYXRhQnVpbGRlci5jcmVhdGVGb3JtRGF0YShkYXRhKTtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kKCdwb3N0JywgdXJsLCBmb3JtRGF0YSwge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ211bHRpcGFydC9mb3JtLWRhdGEnIH1cbiAgICB9LCBmYWxzZSk7XG4gIH1cblxuICBwdXRXaXRoRkQodXJsOiBzdHJpbmcsIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUHJvbWlzZTxBUElSZXNwb25zZT4ge1xuICAgIGNvbnN0IGZvcm1EYXRhID0gdGhpcy5mb3JtRGF0YUJ1aWxkZXIuY3JlYXRlRm9ybURhdGEoZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncHV0JywgdXJsLCBmb3JtRGF0YSwge1xuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ211bHRpcGFydC9mb3JtLWRhdGEnIH1cbiAgICB9LCBmYWxzZSk7XG4gIH1cblxuICBwYXRjaFdpdGhGRCh1cmw6IHN0cmluZywgZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgY29uc3QgZm9ybURhdGEgPSB0aGlzLmZvcm1EYXRhQnVpbGRlci5jcmVhdGVGb3JtRGF0YShkYXRhKTtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kKCdwYXRjaCcsIHVybCwgZm9ybURhdGEsIHtcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdtdWx0aXBhcnQvZm9ybS1kYXRhJyB9XG4gICAgfSwgZmFsc2UpO1xuICB9XG5cbiAgcHV0KHVybDogc3RyaW5nLCBkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBzdHJpbmcsIG9wdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgncHV0JywgdXJsLCBkYXRhLCBvcHRpb25zKTtcbiAgfVxuXG4gIGRlbGV0ZSh1cmw6IHN0cmluZywgZGF0YT86IElwUG9vbERlbGV0ZURhdGEpOiBQcm9taXNlPEFQSVJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZCgnZGVsZXRlJywgdXJsLCBkYXRhKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0O1xuIiwiZXhwb3J0IGVudW0gUmVzb2x1dGlvbiB7XG4gICAgSE9VUiA9ICdob3VyJyxcbiAgICBEQVkgPSAnZGF5JyxcbiAgICBNT05USCA9ICdtb250aCdcbn1cblxuZXhwb3J0IGVudW0gU3VwcHJlc3Npb25Nb2RlbHMge1xuICAgIEJPVU5DRVMgPSAnYm91bmNlcycsXG4gICAgQ09NUExBSU5UUyA9ICdjb21wbGFpbnRzJyxcbiAgICBVTlNVQlNDUklCRVMgPSAndW5zdWJzY3JpYmVzJyxcbiAgICBXSElURUxJU1RTID0gJ3doaXRlbGlzdHMnXG59XG5cbmV4cG9ydCBlbnVtIFdlYmhvb2tzSWRzIHtcbiAgICBDTElDS0VEID0gJ2NsaWNrZWQnLFxuICAgIENPTVBMQUlORUQgPSAnY29tcGxhaW5lZCcsXG4gICAgREVMSVZFUkVEID0gJ2RlbGl2ZXJlZCcsXG4gICAgT1BFTkVEID0gJ29wZW5lZCcsXG4gICAgUEVSTUFORU5UX0ZBSUwgPSAncGVybWFuZW50X2ZhaWwnLFxuICAgIFRFTVBPUkFSWV9GQUlMID0gJ3RlbXBvcmFyeV9mYWlsJyxcbiAgICBVTlNVQlNDUklCRUQgPSAndW5zdWJzY3JpYmUnLFxufVxuXG5leHBvcnQgZW51bSBZZXNObyB7XG4gICAgWUVTID0gJ3llcycsXG4gICAgTk8gPSAnbm8nXG59XG4iLCJleHBvcnQgKiBmcm9tICcuL0xvZ2dlcic7XG4iLCJleHBvcnQgKiBmcm9tICcuL0RvbWFpbkNyZWRlbnRpYWxzJztcbmV4cG9ydCAqIGZyb20gJy4vRG9tYWluVGFncyc7XG5leHBvcnQgKiBmcm9tICcuL0RvbWFpblRlbXBsYXRlcyc7XG5leHBvcnQgKiBmcm9tICcuL0RvbWFpbnNDbGllbnQnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9JRXZlbnRDbGllbnQnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9JSVBQb29sc0NsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lJUHNDbGllbnQnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9JTWFpbGd1bkNsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL01haWxpbmdMaXN0TWVtYmVycyc7XG5leHBvcnQgKiBmcm9tICcuL01haWxpbmdMaXN0c0NsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lNZXNzYWdlc0NsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lSb3V0ZXNDbGllbnQnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9TdGF0c0NsaWVudCc7XG5leHBvcnQgKiBmcm9tICcuL1N0YXRzQ29udGFpbmVyJztcbiIsImV4cG9ydCAqIGZyb20gJy4vSVN1YmFjY291bnRzQ2xpZW50JztcbiIsImV4cG9ydCAqIGZyb20gJy4vQm91bmNlJztcbmV4cG9ydCAqIGZyb20gJy4vQ29tcGxhaW50JztcbmV4cG9ydCAqIGZyb20gJy4vVW5zdWJzY3JpYmUnO1xuZXhwb3J0ICogZnJvbSAnLi9XaGl0ZUxpc3QnO1xuZXhwb3J0ICogZnJvbSAnLi9JU3VwcHJlc3Npb25zQ2xpZW50JztcbiIsImV4cG9ydCAqIGZyb20gJy4vTXVsdGlwbGVWYWxpZGF0aW9uJztcbmV4cG9ydCAqIGZyb20gJy4vVmFsaWRhdGlvbic7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lXZWJIb29rc0NsaWVudCc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0NvbW1vbic7XG5leHBvcnQgKiBmcm9tICcuL0RvbWFpbnMnO1xuZXhwb3J0ICogZnJvbSAnLi9NYWlsZ3VuQ2xpZW50JztcbmV4cG9ydCAqIGZyb20gJy4vTWFpbGluZ0xpc3RzJztcbmV4cG9ydCAqIGZyb20gJy4vU3RhdHMnO1xuZXhwb3J0ICogZnJvbSAnLi9TdXBwcmVzc2lvbnMnO1xuZXhwb3J0ICogZnJvbSAnLi9WYWxpZGF0aW9ucyc7XG5leHBvcnQgKiBmcm9tICcuL0V2ZW50Q2xpZW50JztcbmV4cG9ydCAqIGZyb20gJy4vV2ViaG9va3MnO1xuZXhwb3J0ICogZnJvbSAnLi9NZXNzYWdlcyc7XG5leHBvcnQgKiBmcm9tICcuL1JvdXRlcyc7XG5leHBvcnQgKiBmcm9tICcuL0lQcyc7XG5leHBvcnQgKiBmcm9tICcuL0lQUG9vbHMnO1xuZXhwb3J0ICogZnJvbSAnLi9TdWJhY2NvdW50cyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0Vycm9yJztcbmV4cG9ydCAqIGZyb20gJy4vQXBpUmVzcG9uc2UnO1xuZXhwb3J0ICogZnJvbSAnLi9Gb3JtRGF0YSc7XG5leHBvcnQgKiBmcm9tICcuL05hdmlnYXRpb25UaHJ1UGFnZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9SZXF1ZXN0T3B0aW9ucyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0RvbWFpbkNyZWRlbnRpYWxzJztcbmV4cG9ydCAqIGZyb20gJy4vRG9tYWlucyc7XG5leHBvcnQgKiBmcm9tICcuL0RvbWFpblRhZ3MnO1xuZXhwb3J0ICogZnJvbSAnLi9Eb21haW5UZW1wbGF0ZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9Eb21haW5UcmFja2luZyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0V2ZW50cyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0lwUG9vbHMnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9JUHMnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9NYWlsZ3VuQ2xpZW50T3B0aW9ucyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL01haWxpbmdMaXN0TWVtYmVycyc7XG5leHBvcnQgKiBmcm9tICcuL01haWxpbmdMaXN0cyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL01lc3NhZ2VzJztcbiIsImV4cG9ydCAqIGZyb20gJy4vUm91dGVzJztcbiIsImV4cG9ydCAqIGZyb20gJy4vU3RhdHMnO1xuIiwiZXhwb3J0ICogZnJvbSAnLi9TdWJhY2NvdW50cyc7XG4iLCJleHBvcnQgKiBmcm9tICcuL0JvdW5jZSc7XG5leHBvcnQgKiBmcm9tICcuL0NvbXBsYWludCc7XG5leHBvcnQgKiBmcm9tICcuL1N1cHByZXNzaW9ucyc7XG5leHBvcnQgKiBmcm9tICcuL1Vuc3Vic2NyaWJlJztcbmV4cG9ydCAqIGZyb20gJy4vV2hpdGVMaXN0JztcbiIsImV4cG9ydCAqIGZyb20gJy4vTXVsdGlwbGVWYWxpZGF0aW9uJztcbmV4cG9ydCAqIGZyb20gJy4vVmFsaWRhdGlvbic7XG4iLCJleHBvcnQgKiBmcm9tICcuL1dlYmhvb2tzJztcbiIsImV4cG9ydCAqIGZyb20gJy4vQ29tbW9uJztcbmV4cG9ydCAqIGZyb20gJy4vRG9tYWlucyc7XG5leHBvcnQgKiBmcm9tICcuL0V2ZW50cyc7XG5leHBvcnQgKiBmcm9tICcuL0lQUG9vbHMnO1xuZXhwb3J0ICogZnJvbSAnLi9JUHMnO1xuZXhwb3J0ICogZnJvbSAnLi9NYWlsZ3VuQ2xpZW50JztcbmV4cG9ydCAqIGZyb20gJy4vTWFpbGluZ0xpc3RzJztcbmV4cG9ydCAqIGZyb20gJy4vTWVzc2FnZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9Sb3V0ZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9TdGF0cyc7XG5leHBvcnQgKiBmcm9tICcuL1N1YmFjY291bnRzJztcbmV4cG9ydCAqIGZyb20gJy4vU3VwcHJlc3Npb25zJztcbmV4cG9ydCAqIGZyb20gJy4vVmFsaWRhdGlvbnMnO1xuZXhwb3J0ICogZnJvbSAnLi9XZWJob29rcyc7XG4iLCJpbXBvcnQgTWFpbGd1bkNsaWVudCBmcm9tICcuL0NsYXNzZXMvTWFpbGd1bkNsaWVudCc7XG5pbXBvcnQgeyBJTWFpbGd1bkNsaWVudCB9IGZyb20gJy4vSW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBJbnB1dEZvcm1EYXRhLCBNYWlsZ3VuQ2xpZW50T3B0aW9ucyB9IGZyb20gJy4vVHlwZXMnO1xuXG5leHBvcnQgKiBhcyBFbnVtcyBmcm9tICcuL0VudW1zJztcbmV4cG9ydCAqIGZyb20gJy4vVHlwZXMnO1xuZXhwb3J0ICogYXMgSW50ZXJmYWNlcyBmcm9tICcuL0ludGVyZmFjZXMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNYWlsZ3VuIHtcbiAgc3RhdGljIGdldCBkZWZhdWx0KCk6IHR5cGVvZiBNYWlsZ3VuIHsgcmV0dXJuIHRoaXM7IH1cbiAgcHJpdmF0ZSBmb3JtRGF0YTogSW5wdXRGb3JtRGF0YVxuXG4gIGNvbnN0cnVjdG9yKEZvcm1EYXRhOiBJbnB1dEZvcm1EYXRhKSB7XG4gICAgdGhpcy5mb3JtRGF0YSA9IEZvcm1EYXRhO1xuICB9XG5cbiAgY2xpZW50KG9wdGlvbnM6IE1haWxndW5DbGllbnRPcHRpb25zKSA6IElNYWlsZ3VuQ2xpZW50IHtcbiAgICByZXR1cm4gbmV3IE1haWxndW5DbGllbnQob3B0aW9ucywgdGhpcy5mb3JtRGF0YSk7XG4gIH1cbn1cbiIsIi8qISBodHRwczovL210aHMuYmUvYmFzZTY0IHYxLjAuMCBieSBAbWF0aGlhcyB8IE1JVCBsaWNlbnNlICovXG47KGZ1bmN0aW9uKHJvb3QpIHtcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZXMgYGV4cG9ydHNgLlxuXHR2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzO1xuXG5cdC8vIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLlxuXHR2YXIgZnJlZU1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmXG5cdFx0bW9kdWxlLmV4cG9ydHMgPT0gZnJlZUV4cG9ydHMgJiYgbW9kdWxlO1xuXG5cdC8vIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgLCBmcm9tIE5vZGUuanMgb3IgQnJvd3NlcmlmaWVkIGNvZGUsIGFuZCB1c2Vcblx0Ly8gaXQgYXMgYHJvb3RgLlxuXHR2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuXHRpZiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwpIHtcblx0XHRyb290ID0gZnJlZUdsb2JhbDtcblx0fVxuXG5cdC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cdHZhciBJbnZhbGlkQ2hhcmFjdGVyRXJyb3IgPSBmdW5jdGlvbihtZXNzYWdlKSB7XG5cdFx0dGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcblx0fTtcblx0SW52YWxpZENoYXJhY3RlckVycm9yLnByb3RvdHlwZSA9IG5ldyBFcnJvcjtcblx0SW52YWxpZENoYXJhY3RlckVycm9yLnByb3RvdHlwZS5uYW1lID0gJ0ludmFsaWRDaGFyYWN0ZXJFcnJvcic7XG5cblx0dmFyIGVycm9yID0gZnVuY3Rpb24obWVzc2FnZSkge1xuXHRcdC8vIE5vdGU6IHRoZSBlcnJvciBtZXNzYWdlcyB1c2VkIHRocm91Z2hvdXQgdGhpcyBmaWxlIG1hdGNoIHRob3NlIHVzZWQgYnlcblx0XHQvLyB0aGUgbmF0aXZlIGBhdG9iYC9gYnRvYWAgaW1wbGVtZW50YXRpb24gaW4gQ2hyb21pdW0uXG5cdFx0dGhyb3cgbmV3IEludmFsaWRDaGFyYWN0ZXJFcnJvcihtZXNzYWdlKTtcblx0fTtcblxuXHR2YXIgVEFCTEUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cdC8vIGh0dHA6Ly93aGF0d2cub3JnL2h0bWwvY29tbW9uLW1pY3Jvc3ludGF4ZXMuaHRtbCNzcGFjZS1jaGFyYWN0ZXJcblx0dmFyIFJFR0VYX1NQQUNFX0NIQVJBQ1RFUlMgPSAvW1xcdFxcblxcZlxcciBdL2c7XG5cblx0Ly8gYGRlY29kZWAgaXMgZGVzaWduZWQgdG8gYmUgZnVsbHkgY29tcGF0aWJsZSB3aXRoIGBhdG9iYCBhcyBkZXNjcmliZWQgaW4gdGhlXG5cdC8vIEhUTUwgU3RhbmRhcmQuIGh0dHA6Ly93aGF0d2cub3JnL2h0bWwvd2ViYXBwYXBpcy5odG1sI2RvbS13aW5kb3diYXNlNjQtYXRvYlxuXHQvLyBUaGUgb3B0aW1pemVkIGJhc2U2NC1kZWNvZGluZyBhbGdvcml0aG0gdXNlZCBpcyBiYXNlZCBvbiBAYXRr4oCZcyBleGNlbGxlbnRcblx0Ly8gaW1wbGVtZW50YXRpb24uIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL2F0ay8xMDIwMzk2XG5cdHZhciBkZWNvZGUgPSBmdW5jdGlvbihpbnB1dCkge1xuXHRcdGlucHV0ID0gU3RyaW5nKGlucHV0KVxuXHRcdFx0LnJlcGxhY2UoUkVHRVhfU1BBQ0VfQ0hBUkFDVEVSUywgJycpO1xuXHRcdHZhciBsZW5ndGggPSBpbnB1dC5sZW5ndGg7XG5cdFx0aWYgKGxlbmd0aCAlIDQgPT0gMCkge1xuXHRcdFx0aW5wdXQgPSBpbnB1dC5yZXBsYWNlKC89PT8kLywgJycpO1xuXHRcdFx0bGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuXHRcdH1cblx0XHRpZiAoXG5cdFx0XHRsZW5ndGggJSA0ID09IDEgfHxcblx0XHRcdC8vIGh0dHA6Ly93aGF0d2cub3JnL0MjYWxwaGFudW1lcmljLWFzY2lpLWNoYXJhY3RlcnNcblx0XHRcdC9bXithLXpBLVowLTkvXS8udGVzdChpbnB1dClcblx0XHQpIHtcblx0XHRcdGVycm9yKFxuXHRcdFx0XHQnSW52YWxpZCBjaGFyYWN0ZXI6IHRoZSBzdHJpbmcgdG8gYmUgZGVjb2RlZCBpcyBub3QgY29ycmVjdGx5IGVuY29kZWQuJ1xuXHRcdFx0KTtcblx0XHR9XG5cdFx0dmFyIGJpdENvdW50ZXIgPSAwO1xuXHRcdHZhciBiaXRTdG9yYWdlO1xuXHRcdHZhciBidWZmZXI7XG5cdFx0dmFyIG91dHB1dCA9ICcnO1xuXHRcdHZhciBwb3NpdGlvbiA9IC0xO1xuXHRcdHdoaWxlICgrK3Bvc2l0aW9uIDwgbGVuZ3RoKSB7XG5cdFx0XHRidWZmZXIgPSBUQUJMRS5pbmRleE9mKGlucHV0LmNoYXJBdChwb3NpdGlvbikpO1xuXHRcdFx0Yml0U3RvcmFnZSA9IGJpdENvdW50ZXIgJSA0ID8gYml0U3RvcmFnZSAqIDY0ICsgYnVmZmVyIDogYnVmZmVyO1xuXHRcdFx0Ly8gVW5sZXNzIHRoaXMgaXMgdGhlIGZpcnN0IG9mIGEgZ3JvdXAgb2YgNCBjaGFyYWN0ZXJz4oCmXG5cdFx0XHRpZiAoYml0Q291bnRlcisrICUgNCkge1xuXHRcdFx0XHQvLyDigKZjb252ZXJ0IHRoZSBmaXJzdCA4IGJpdHMgdG8gYSBzaW5nbGUgQVNDSUkgY2hhcmFjdGVyLlxuXHRcdFx0XHRvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShcblx0XHRcdFx0XHQweEZGICYgYml0U3RvcmFnZSA+PiAoLTIgKiBiaXRDb3VudGVyICYgNilcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fTtcblxuXHQvLyBgZW5jb2RlYCBpcyBkZXNpZ25lZCB0byBiZSBmdWxseSBjb21wYXRpYmxlIHdpdGggYGJ0b2FgIGFzIGRlc2NyaWJlZCBpbiB0aGVcblx0Ly8gSFRNTCBTdGFuZGFyZDogaHR0cDovL3doYXR3Zy5vcmcvaHRtbC93ZWJhcHBhcGlzLmh0bWwjZG9tLXdpbmRvd2Jhc2U2NC1idG9hXG5cdHZhciBlbmNvZGUgPSBmdW5jdGlvbihpbnB1dCkge1xuXHRcdGlucHV0ID0gU3RyaW5nKGlucHV0KTtcblx0XHRpZiAoL1teXFwwLVxceEZGXS8udGVzdChpbnB1dCkpIHtcblx0XHRcdC8vIE5vdGU6IG5vIG5lZWQgdG8gc3BlY2lhbC1jYXNlIGFzdHJhbCBzeW1ib2xzIGhlcmUsIGFzIHN1cnJvZ2F0ZXMgYXJlXG5cdFx0XHQvLyBtYXRjaGVkLCBhbmQgdGhlIGlucHV0IGlzIHN1cHBvc2VkIHRvIG9ubHkgY29udGFpbiBBU0NJSSBhbnl3YXkuXG5cdFx0XHRlcnJvcihcblx0XHRcdFx0J1RoZSBzdHJpbmcgdG8gYmUgZW5jb2RlZCBjb250YWlucyBjaGFyYWN0ZXJzIG91dHNpZGUgb2YgdGhlICcgK1xuXHRcdFx0XHQnTGF0aW4xIHJhbmdlLidcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHZhciBwYWRkaW5nID0gaW5wdXQubGVuZ3RoICUgMztcblx0XHR2YXIgb3V0cHV0ID0gJyc7XG5cdFx0dmFyIHBvc2l0aW9uID0gLTE7XG5cdFx0dmFyIGE7XG5cdFx0dmFyIGI7XG5cdFx0dmFyIGM7XG5cdFx0dmFyIGJ1ZmZlcjtcblx0XHQvLyBNYWtlIHN1cmUgYW55IHBhZGRpbmcgaXMgaGFuZGxlZCBvdXRzaWRlIG9mIHRoZSBsb29wLlxuXHRcdHZhciBsZW5ndGggPSBpbnB1dC5sZW5ndGggLSBwYWRkaW5nO1xuXG5cdFx0d2hpbGUgKCsrcG9zaXRpb24gPCBsZW5ndGgpIHtcblx0XHRcdC8vIFJlYWQgdGhyZWUgYnl0ZXMsIGkuZS4gMjQgYml0cy5cblx0XHRcdGEgPSBpbnB1dC5jaGFyQ29kZUF0KHBvc2l0aW9uKSA8PCAxNjtcblx0XHRcdGIgPSBpbnB1dC5jaGFyQ29kZUF0KCsrcG9zaXRpb24pIDw8IDg7XG5cdFx0XHRjID0gaW5wdXQuY2hhckNvZGVBdCgrK3Bvc2l0aW9uKTtcblx0XHRcdGJ1ZmZlciA9IGEgKyBiICsgYztcblx0XHRcdC8vIFR1cm4gdGhlIDI0IGJpdHMgaW50byBmb3VyIGNodW5rcyBvZiA2IGJpdHMgZWFjaCwgYW5kIGFwcGVuZCB0aGVcblx0XHRcdC8vIG1hdGNoaW5nIGNoYXJhY3RlciBmb3IgZWFjaCBvZiB0aGVtIHRvIHRoZSBvdXRwdXQuXG5cdFx0XHRvdXRwdXQgKz0gKFxuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDE4ICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDEyICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDYgJiAweDNGKSArXG5cdFx0XHRcdFRBQkxFLmNoYXJBdChidWZmZXIgJiAweDNGKVxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRpZiAocGFkZGluZyA9PSAyKSB7XG5cdFx0XHRhID0gaW5wdXQuY2hhckNvZGVBdChwb3NpdGlvbikgPDwgODtcblx0XHRcdGIgPSBpbnB1dC5jaGFyQ29kZUF0KCsrcG9zaXRpb24pO1xuXHRcdFx0YnVmZmVyID0gYSArIGI7XG5cdFx0XHRvdXRwdXQgKz0gKFxuXHRcdFx0XHRUQUJMRS5jaGFyQXQoYnVmZmVyID4+IDEwKSArXG5cdFx0XHRcdFRBQkxFLmNoYXJBdCgoYnVmZmVyID4+IDQpICYgMHgzRikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoKGJ1ZmZlciA8PCAyKSAmIDB4M0YpICtcblx0XHRcdFx0Jz0nXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSBpZiAocGFkZGluZyA9PSAxKSB7XG5cdFx0XHRidWZmZXIgPSBpbnB1dC5jaGFyQ29kZUF0KHBvc2l0aW9uKTtcblx0XHRcdG91dHB1dCArPSAoXG5cdFx0XHRcdFRBQkxFLmNoYXJBdChidWZmZXIgPj4gMikgK1xuXHRcdFx0XHRUQUJMRS5jaGFyQXQoKGJ1ZmZlciA8PCA0KSAmIDB4M0YpICtcblx0XHRcdFx0Jz09J1xuXHRcdFx0KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9O1xuXG5cdHZhciBiYXNlNjQgPSB7XG5cdFx0J2VuY29kZSc6IGVuY29kZSxcblx0XHQnZGVjb2RlJzogZGVjb2RlLFxuXHRcdCd2ZXJzaW9uJzogJzEuMC4wJ1xuXHR9O1xuXG5cdC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIHNwZWNpZmljIGNvbmRpdGlvbiBwYXR0ZXJuc1xuXHQvLyBsaWtlIHRoZSBmb2xsb3dpbmc6XG5cdGlmIChcblx0XHR0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJlxuXHRcdGRlZmluZS5hbWRcblx0KSB7XG5cdFx0ZGVmaW5lKGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGJhc2U2NDtcblx0XHR9KTtcblx0fVx0ZWxzZSBpZiAoZnJlZUV4cG9ydHMgJiYgIWZyZWVFeHBvcnRzLm5vZGVUeXBlKSB7XG5cdFx0aWYgKGZyZWVNb2R1bGUpIHsgLy8gaW4gTm9kZS5qcyBvciBSaW5nb0pTIHYwLjguMCtcblx0XHRcdGZyZWVNb2R1bGUuZXhwb3J0cyA9IGJhc2U2NDtcblx0XHR9IGVsc2UgeyAvLyBpbiBOYXJ3aGFsIG9yIFJpbmdvSlMgdjAuNy4wLVxuXHRcdFx0Zm9yICh2YXIga2V5IGluIGJhc2U2NCkge1xuXHRcdFx0XHRiYXNlNjQuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAoZnJlZUV4cG9ydHNba2V5XSA9IGJhc2U2NFtrZXldKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSB7IC8vIGluIFJoaW5vIG9yIGEgd2ViIGJyb3dzZXJcblx0XHRyb290LmJhc2U2NCA9IGJhc2U2NDtcblx0fVxuXG59KHRoaXMpKTtcbiIsInZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpLlN0cmVhbTtcbnZhciBEZWxheWVkU3RyZWFtID0gcmVxdWlyZSgnZGVsYXllZC1zdHJlYW0nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBDb21iaW5lZFN0cmVhbTtcbmZ1bmN0aW9uIENvbWJpbmVkU3RyZWFtKCkge1xuICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuICB0aGlzLmRhdGFTaXplID0gMDtcbiAgdGhpcy5tYXhEYXRhU2l6ZSA9IDIgKiAxMDI0ICogMTAyNDtcbiAgdGhpcy5wYXVzZVN0cmVhbXMgPSB0cnVlO1xuXG4gIHRoaXMuX3JlbGVhc2VkID0gZmFsc2U7XG4gIHRoaXMuX3N0cmVhbXMgPSBbXTtcbiAgdGhpcy5fY3VycmVudFN0cmVhbSA9IG51bGw7XG4gIHRoaXMuX2luc2lkZUxvb3AgPSBmYWxzZTtcbiAgdGhpcy5fcGVuZGluZ05leHQgPSBmYWxzZTtcbn1cbnV0aWwuaW5oZXJpdHMoQ29tYmluZWRTdHJlYW0sIFN0cmVhbSk7XG5cbkNvbWJpbmVkU3RyZWFtLmNyZWF0ZSA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgdmFyIGNvbWJpbmVkU3RyZWFtID0gbmV3IHRoaXMoKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgZm9yICh2YXIgb3B0aW9uIGluIG9wdGlvbnMpIHtcbiAgICBjb21iaW5lZFN0cmVhbVtvcHRpb25dID0gb3B0aW9uc1tvcHRpb25dO1xuICB9XG5cbiAgcmV0dXJuIGNvbWJpbmVkU3RyZWFtO1xufTtcblxuQ29tYmluZWRTdHJlYW0uaXNTdHJlYW1MaWtlID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHJldHVybiAodHlwZW9mIHN0cmVhbSAhPT0gJ2Z1bmN0aW9uJylcbiAgICAmJiAodHlwZW9mIHN0cmVhbSAhPT0gJ3N0cmluZycpXG4gICAgJiYgKHR5cGVvZiBzdHJlYW0gIT09ICdib29sZWFuJylcbiAgICAmJiAodHlwZW9mIHN0cmVhbSAhPT0gJ251bWJlcicpXG4gICAgJiYgKCFCdWZmZXIuaXNCdWZmZXIoc3RyZWFtKSk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHZhciBpc1N0cmVhbUxpa2UgPSBDb21iaW5lZFN0cmVhbS5pc1N0cmVhbUxpa2Uoc3RyZWFtKTtcblxuICBpZiAoaXNTdHJlYW1MaWtlKSB7XG4gICAgaWYgKCEoc3RyZWFtIGluc3RhbmNlb2YgRGVsYXllZFN0cmVhbSkpIHtcbiAgICAgIHZhciBuZXdTdHJlYW0gPSBEZWxheWVkU3RyZWFtLmNyZWF0ZShzdHJlYW0sIHtcbiAgICAgICAgbWF4RGF0YVNpemU6IEluZmluaXR5LFxuICAgICAgICBwYXVzZVN0cmVhbTogdGhpcy5wYXVzZVN0cmVhbXMsXG4gICAgICB9KTtcbiAgICAgIHN0cmVhbS5vbignZGF0YScsIHRoaXMuX2NoZWNrRGF0YVNpemUuYmluZCh0aGlzKSk7XG4gICAgICBzdHJlYW0gPSBuZXdTdHJlYW07XG4gICAgfVxuXG4gICAgdGhpcy5faGFuZGxlRXJyb3JzKHN0cmVhbSk7XG5cbiAgICBpZiAodGhpcy5wYXVzZVN0cmVhbXMpIHtcbiAgICAgIHN0cmVhbS5wYXVzZSgpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuX3N0cmVhbXMucHVzaChzdHJlYW0pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgb3B0aW9ucykge1xuICBTdHJlYW0ucHJvdG90eXBlLnBpcGUuY2FsbCh0aGlzLCBkZXN0LCBvcHRpb25zKTtcbiAgdGhpcy5yZXN1bWUoKTtcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX2dldE5leHQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fY3VycmVudFN0cmVhbSA9IG51bGw7XG5cbiAgaWYgKHRoaXMuX2luc2lkZUxvb3ApIHtcbiAgICB0aGlzLl9wZW5kaW5nTmV4dCA9IHRydWU7XG4gICAgcmV0dXJuOyAvLyBkZWZlciBjYWxsXG4gIH1cblxuICB0aGlzLl9pbnNpZGVMb29wID0gdHJ1ZTtcbiAgdHJ5IHtcbiAgICBkbyB7XG4gICAgICB0aGlzLl9wZW5kaW5nTmV4dCA9IGZhbHNlO1xuICAgICAgdGhpcy5fcmVhbEdldE5leHQoKTtcbiAgICB9IHdoaWxlICh0aGlzLl9wZW5kaW5nTmV4dCk7XG4gIH0gZmluYWxseSB7XG4gICAgdGhpcy5faW5zaWRlTG9vcCA9IGZhbHNlO1xuICB9XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX3JlYWxHZXROZXh0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzdHJlYW0gPSB0aGlzLl9zdHJlYW1zLnNoaWZ0KCk7XG5cblxuICBpZiAodHlwZW9mIHN0cmVhbSA9PSAndW5kZWZpbmVkJykge1xuICAgIHRoaXMuZW5kKCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBzdHJlYW0gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLl9waXBlTmV4dChzdHJlYW0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBnZXRTdHJlYW0gPSBzdHJlYW07XG4gIGdldFN0cmVhbShmdW5jdGlvbihzdHJlYW0pIHtcbiAgICB2YXIgaXNTdHJlYW1MaWtlID0gQ29tYmluZWRTdHJlYW0uaXNTdHJlYW1MaWtlKHN0cmVhbSk7XG4gICAgaWYgKGlzU3RyZWFtTGlrZSkge1xuICAgICAgc3RyZWFtLm9uKCdkYXRhJywgdGhpcy5fY2hlY2tEYXRhU2l6ZS5iaW5kKHRoaXMpKTtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9ycyhzdHJlYW0pO1xuICAgIH1cblxuICAgIHRoaXMuX3BpcGVOZXh0KHN0cmVhbSk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX3BpcGVOZXh0ID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHRoaXMuX2N1cnJlbnRTdHJlYW0gPSBzdHJlYW07XG5cbiAgdmFyIGlzU3RyZWFtTGlrZSA9IENvbWJpbmVkU3RyZWFtLmlzU3RyZWFtTGlrZShzdHJlYW0pO1xuICBpZiAoaXNTdHJlYW1MaWtlKSB7XG4gICAgc3RyZWFtLm9uKCdlbmQnLCB0aGlzLl9nZXROZXh0LmJpbmQodGhpcykpO1xuICAgIHN0cmVhbS5waXBlKHRoaXMsIHtlbmQ6IGZhbHNlfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHZhbHVlID0gc3RyZWFtO1xuICB0aGlzLndyaXRlKHZhbHVlKTtcbiAgdGhpcy5fZ2V0TmV4dCgpO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLl9oYW5kbGVFcnJvcnMgPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzdHJlYW0ub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyKSB7XG4gICAgc2VsZi5fZW1pdEVycm9yKGVycik7XG4gIH0pO1xufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oZGF0YSkge1xuICB0aGlzLmVtaXQoJ2RhdGEnLCBkYXRhKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMucGF1c2VTdHJlYW1zKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYodGhpcy5wYXVzZVN0cmVhbXMgJiYgdGhpcy5fY3VycmVudFN0cmVhbSAmJiB0eXBlb2YodGhpcy5fY3VycmVudFN0cmVhbS5wYXVzZSkgPT0gJ2Z1bmN0aW9uJykgdGhpcy5fY3VycmVudFN0cmVhbS5wYXVzZSgpO1xuICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5fcmVsZWFzZWQpIHtcbiAgICB0aGlzLl9yZWxlYXNlZCA9IHRydWU7XG4gICAgdGhpcy53cml0YWJsZSA9IHRydWU7XG4gICAgdGhpcy5fZ2V0TmV4dCgpO1xuICB9XG5cbiAgaWYodGhpcy5wYXVzZVN0cmVhbXMgJiYgdGhpcy5fY3VycmVudFN0cmVhbSAmJiB0eXBlb2YodGhpcy5fY3VycmVudFN0cmVhbS5yZXN1bWUpID09ICdmdW5jdGlvbicpIHRoaXMuX2N1cnJlbnRTdHJlYW0ucmVzdW1lKCk7XG4gIHRoaXMuZW1pdCgncmVzdW1lJyk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3Jlc2V0KCk7XG4gIHRoaXMuZW1pdCgnZW5kJyk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9yZXNldCgpO1xuICB0aGlzLmVtaXQoJ2Nsb3NlJyk7XG59O1xuXG5Db21iaW5lZFN0cmVhbS5wcm90b3R5cGUuX3Jlc2V0ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgdGhpcy5fc3RyZWFtcyA9IFtdO1xuICB0aGlzLl9jdXJyZW50U3RyZWFtID0gbnVsbDtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fY2hlY2tEYXRhU2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl91cGRhdGVEYXRhU2l6ZSgpO1xuICBpZiAodGhpcy5kYXRhU2l6ZSA8PSB0aGlzLm1heERhdGFTaXplKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG1lc3NhZ2UgPVxuICAgICdEZWxheWVkU3RyZWFtI21heERhdGFTaXplIG9mICcgKyB0aGlzLm1heERhdGFTaXplICsgJyBieXRlcyBleGNlZWRlZC4nO1xuICB0aGlzLl9lbWl0RXJyb3IobmV3IEVycm9yKG1lc3NhZ2UpKTtcbn07XG5cbkNvbWJpbmVkU3RyZWFtLnByb3RvdHlwZS5fdXBkYXRlRGF0YVNpemUgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5kYXRhU2l6ZSA9IDA7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9zdHJlYW1zLmZvckVhY2goZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgaWYgKCFzdHJlYW0uZGF0YVNpemUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLmRhdGFTaXplICs9IHN0cmVhbS5kYXRhU2l6ZTtcbiAgfSk7XG5cbiAgaWYgKHRoaXMuX2N1cnJlbnRTdHJlYW0gJiYgdGhpcy5fY3VycmVudFN0cmVhbS5kYXRhU2l6ZSkge1xuICAgIHRoaXMuZGF0YVNpemUgKz0gdGhpcy5fY3VycmVudFN0cmVhbS5kYXRhU2l6ZTtcbiAgfVxufTtcblxuQ29tYmluZWRTdHJlYW0ucHJvdG90eXBlLl9lbWl0RXJyb3IgPSBmdW5jdGlvbihlcnIpIHtcbiAgdGhpcy5fcmVzZXQoKTtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG59O1xuIiwiLyogZXNsaW50LWVudiBicm93c2VyICovXG5cbi8qKlxuICogVGhpcyBpcyB0aGUgd2ViIGJyb3dzZXIgaW1wbGVtZW50YXRpb24gb2YgYGRlYnVnKClgLlxuICovXG5cbmV4cG9ydHMuZm9ybWF0QXJncyA9IGZvcm1hdEFyZ3M7XG5leHBvcnRzLnNhdmUgPSBzYXZlO1xuZXhwb3J0cy5sb2FkID0gbG9hZDtcbmV4cG9ydHMudXNlQ29sb3JzID0gdXNlQ29sb3JzO1xuZXhwb3J0cy5zdG9yYWdlID0gbG9jYWxzdG9yYWdlKCk7XG5leHBvcnRzLmRlc3Ryb3kgPSAoKCkgPT4ge1xuXHRsZXQgd2FybmVkID0gZmFsc2U7XG5cblx0cmV0dXJuICgpID0+IHtcblx0XHRpZiAoIXdhcm5lZCkge1xuXHRcdFx0d2FybmVkID0gdHJ1ZTtcblx0XHRcdGNvbnNvbGUud2FybignSW5zdGFuY2UgbWV0aG9kIGBkZWJ1Zy5kZXN0cm95KClgIGlzIGRlcHJlY2F0ZWQgYW5kIG5vIGxvbmdlciBkb2VzIGFueXRoaW5nLiBJdCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIG5leHQgbWFqb3IgdmVyc2lvbiBvZiBgZGVidWdgLicpO1xuXHRcdH1cblx0fTtcbn0pKCk7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuXHQnIzAwMDBDQycsXG5cdCcjMDAwMEZGJyxcblx0JyMwMDMzQ0MnLFxuXHQnIzAwMzNGRicsXG5cdCcjMDA2NkNDJyxcblx0JyMwMDY2RkYnLFxuXHQnIzAwOTlDQycsXG5cdCcjMDA5OUZGJyxcblx0JyMwMENDMDAnLFxuXHQnIzAwQ0MzMycsXG5cdCcjMDBDQzY2Jyxcblx0JyMwMENDOTknLFxuXHQnIzAwQ0NDQycsXG5cdCcjMDBDQ0ZGJyxcblx0JyMzMzAwQ0MnLFxuXHQnIzMzMDBGRicsXG5cdCcjMzMzM0NDJyxcblx0JyMzMzMzRkYnLFxuXHQnIzMzNjZDQycsXG5cdCcjMzM2NkZGJyxcblx0JyMzMzk5Q0MnLFxuXHQnIzMzOTlGRicsXG5cdCcjMzNDQzAwJyxcblx0JyMzM0NDMzMnLFxuXHQnIzMzQ0M2NicsXG5cdCcjMzNDQzk5Jyxcblx0JyMzM0NDQ0MnLFxuXHQnIzMzQ0NGRicsXG5cdCcjNjYwMENDJyxcblx0JyM2NjAwRkYnLFxuXHQnIzY2MzNDQycsXG5cdCcjNjYzM0ZGJyxcblx0JyM2NkNDMDAnLFxuXHQnIzY2Q0MzMycsXG5cdCcjOTkwMENDJyxcblx0JyM5OTAwRkYnLFxuXHQnIzk5MzNDQycsXG5cdCcjOTkzM0ZGJyxcblx0JyM5OUNDMDAnLFxuXHQnIzk5Q0MzMycsXG5cdCcjQ0MwMDAwJyxcblx0JyNDQzAwMzMnLFxuXHQnI0NDMDA2NicsXG5cdCcjQ0MwMDk5Jyxcblx0JyNDQzAwQ0MnLFxuXHQnI0NDMDBGRicsXG5cdCcjQ0MzMzAwJyxcblx0JyNDQzMzMzMnLFxuXHQnI0NDMzM2NicsXG5cdCcjQ0MzMzk5Jyxcblx0JyNDQzMzQ0MnLFxuXHQnI0NDMzNGRicsXG5cdCcjQ0M2NjAwJyxcblx0JyNDQzY2MzMnLFxuXHQnI0NDOTkwMCcsXG5cdCcjQ0M5OTMzJyxcblx0JyNDQ0NDMDAnLFxuXHQnI0NDQ0MzMycsXG5cdCcjRkYwMDAwJyxcblx0JyNGRjAwMzMnLFxuXHQnI0ZGMDA2NicsXG5cdCcjRkYwMDk5Jyxcblx0JyNGRjAwQ0MnLFxuXHQnI0ZGMDBGRicsXG5cdCcjRkYzMzAwJyxcblx0JyNGRjMzMzMnLFxuXHQnI0ZGMzM2NicsXG5cdCcjRkYzMzk5Jyxcblx0JyNGRjMzQ0MnLFxuXHQnI0ZGMzNGRicsXG5cdCcjRkY2NjAwJyxcblx0JyNGRjY2MzMnLFxuXHQnI0ZGOTkwMCcsXG5cdCcjRkY5OTMzJyxcblx0JyNGRkNDMDAnLFxuXHQnI0ZGQ0MzMydcbl07XG5cbi8qKlxuICogQ3VycmVudGx5IG9ubHkgV2ViS2l0LWJhc2VkIFdlYiBJbnNwZWN0b3JzLCBGaXJlZm94ID49IHYzMSxcbiAqIGFuZCB0aGUgRmlyZWJ1ZyBleHRlbnNpb24gKGFueSBGaXJlZm94IHZlcnNpb24pIGFyZSBrbm93blxuICogdG8gc3VwcG9ydCBcIiVjXCIgQ1NTIGN1c3RvbWl6YXRpb25zLlxuICpcbiAqIFRPRE86IGFkZCBhIGBsb2NhbFN0b3JhZ2VgIHZhcmlhYmxlIHRvIGV4cGxpY2l0bHkgZW5hYmxlL2Rpc2FibGUgY29sb3JzXG4gKi9cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbXBsZXhpdHlcbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcblx0Ly8gTkI6IEluIGFuIEVsZWN0cm9uIHByZWxvYWQgc2NyaXB0LCBkb2N1bWVudCB3aWxsIGJlIGRlZmluZWQgYnV0IG5vdCBmdWxseVxuXHQvLyBpbml0aWFsaXplZC4gU2luY2Ugd2Uga25vdyB3ZSdyZSBpbiBDaHJvbWUsIHdlJ2xsIGp1c3QgZGV0ZWN0IHRoaXMgY2FzZVxuXHQvLyBleHBsaWNpdGx5XG5cdGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cucHJvY2VzcyAmJiAod2luZG93LnByb2Nlc3MudHlwZSA9PT0gJ3JlbmRlcmVyJyB8fCB3aW5kb3cucHJvY2Vzcy5fX253anMpKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvLyBJbnRlcm5ldCBFeHBsb3JlciBhbmQgRWRnZSBkbyBub3Qgc3VwcG9ydCBjb2xvcnMuXG5cdGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiBuYXZpZ2F0b3IudXNlckFnZW50ICYmIG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvKGVkZ2V8dHJpZGVudClcXC8oXFxkKykvKSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdC8vIElzIHdlYmtpdD8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTY0NTk2MDYvMzc2NzczXG5cdC8vIGRvY3VtZW50IGlzIHVuZGVmaW5lZCBpbiByZWFjdC1uYXRpdmU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC1uYXRpdmUvcHVsbC8xNjMyXG5cdHJldHVybiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5XZWJraXRBcHBlYXJhbmNlKSB8fFxuXHRcdC8vIElzIGZpcmVidWc/IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM5ODEyMC8zNzY3NzNcblx0XHQodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmNvbnNvbGUgJiYgKHdpbmRvdy5jb25zb2xlLmZpcmVidWcgfHwgKHdpbmRvdy5jb25zb2xlLmV4Y2VwdGlvbiAmJiB3aW5kb3cuY29uc29sZS50YWJsZSkpKSB8fFxuXHRcdC8vIElzIGZpcmVmb3ggPj0gdjMxP1xuXHRcdC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvVG9vbHMvV2ViX0NvbnNvbGUjU3R5bGluZ19tZXNzYWdlc1xuXHRcdCh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiBuYXZpZ2F0b3IudXNlckFnZW50ICYmIG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvZmlyZWZveFxcLyhcXGQrKS8pICYmIHBhcnNlSW50KFJlZ0V4cC4kMSwgMTApID49IDMxKSB8fFxuXHRcdC8vIERvdWJsZSBjaGVjayB3ZWJraXQgaW4gdXNlckFnZW50IGp1c3QgaW4gY2FzZSB3ZSBhcmUgaW4gYSB3b3JrZXJcblx0XHQodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCAmJiBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goL2FwcGxld2Via2l0XFwvKFxcZCspLykpO1xufVxuXG4vKipcbiAqIENvbG9yaXplIGxvZyBhcmd1bWVudHMgaWYgZW5hYmxlZC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGZvcm1hdEFyZ3MoYXJncykge1xuXHRhcmdzWzBdID0gKHRoaXMudXNlQ29sb3JzID8gJyVjJyA6ICcnKSArXG5cdFx0dGhpcy5uYW1lc3BhY2UgK1xuXHRcdCh0aGlzLnVzZUNvbG9ycyA/ICcgJWMnIDogJyAnKSArXG5cdFx0YXJnc1swXSArXG5cdFx0KHRoaXMudXNlQ29sb3JzID8gJyVjICcgOiAnICcpICtcblx0XHQnKycgKyBtb2R1bGUuZXhwb3J0cy5odW1hbml6ZSh0aGlzLmRpZmYpO1xuXG5cdGlmICghdGhpcy51c2VDb2xvcnMpIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRjb25zdCBjID0gJ2NvbG9yOiAnICsgdGhpcy5jb2xvcjtcblx0YXJncy5zcGxpY2UoMSwgMCwgYywgJ2NvbG9yOiBpbmhlcml0Jyk7XG5cblx0Ly8gVGhlIGZpbmFsIFwiJWNcIiBpcyBzb21ld2hhdCB0cmlja3ksIGJlY2F1c2UgdGhlcmUgY291bGQgYmUgb3RoZXJcblx0Ly8gYXJndW1lbnRzIHBhc3NlZCBlaXRoZXIgYmVmb3JlIG9yIGFmdGVyIHRoZSAlYywgc28gd2UgbmVlZCB0b1xuXHQvLyBmaWd1cmUgb3V0IHRoZSBjb3JyZWN0IGluZGV4IHRvIGluc2VydCB0aGUgQ1NTIGludG9cblx0bGV0IGluZGV4ID0gMDtcblx0bGV0IGxhc3RDID0gMDtcblx0YXJnc1swXS5yZXBsYWNlKC8lW2EtekEtWiVdL2csIG1hdGNoID0+IHtcblx0XHRpZiAobWF0Y2ggPT09ICclJScpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0aW5kZXgrKztcblx0XHRpZiAobWF0Y2ggPT09ICclYycpIHtcblx0XHRcdC8vIFdlIG9ubHkgYXJlIGludGVyZXN0ZWQgaW4gdGhlICpsYXN0KiAlY1xuXHRcdFx0Ly8gKHRoZSB1c2VyIG1heSBoYXZlIHByb3ZpZGVkIHRoZWlyIG93bilcblx0XHRcdGxhc3RDID0gaW5kZXg7XG5cdFx0fVxuXHR9KTtcblxuXHRhcmdzLnNwbGljZShsYXN0QywgMCwgYyk7XG59XG5cbi8qKlxuICogSW52b2tlcyBgY29uc29sZS5kZWJ1ZygpYCB3aGVuIGF2YWlsYWJsZS5cbiAqIE5vLW9wIHdoZW4gYGNvbnNvbGUuZGVidWdgIGlzIG5vdCBhIFwiZnVuY3Rpb25cIi5cbiAqIElmIGBjb25zb2xlLmRlYnVnYCBpcyBub3QgYXZhaWxhYmxlLCBmYWxscyBiYWNrXG4gKiB0byBgY29uc29sZS5sb2dgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cbmV4cG9ydHMubG9nID0gY29uc29sZS5kZWJ1ZyB8fCBjb25zb2xlLmxvZyB8fCAoKCkgPT4ge30pO1xuXG4vKipcbiAqIFNhdmUgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc2F2ZShuYW1lc3BhY2VzKSB7XG5cdHRyeSB7XG5cdFx0aWYgKG5hbWVzcGFjZXMpIHtcblx0XHRcdGV4cG9ydHMuc3RvcmFnZS5zZXRJdGVtKCdkZWJ1ZycsIG5hbWVzcGFjZXMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRleHBvcnRzLnN0b3JhZ2UucmVtb3ZlSXRlbSgnZGVidWcnKTtcblx0XHR9XG5cdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0Ly8gU3dhbGxvd1xuXHRcdC8vIFhYWCAoQFFpeC0pIHNob3VsZCB3ZSBiZSBsb2dnaW5nIHRoZXNlP1xuXHR9XG59XG5cbi8qKlxuICogTG9hZCBgbmFtZXNwYWNlc2AuXG4gKlxuICogQHJldHVybiB7U3RyaW5nfSByZXR1cm5zIHRoZSBwcmV2aW91c2x5IHBlcnNpc3RlZCBkZWJ1ZyBtb2Rlc1xuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGxvYWQoKSB7XG5cdGxldCByO1xuXHR0cnkge1xuXHRcdHIgPSBleHBvcnRzLnN0b3JhZ2UuZ2V0SXRlbSgnZGVidWcnKTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHQvLyBTd2FsbG93XG5cdFx0Ly8gWFhYIChAUWl4LSkgc2hvdWxkIHdlIGJlIGxvZ2dpbmcgdGhlc2U/XG5cdH1cblxuXHQvLyBJZiBkZWJ1ZyBpc24ndCBzZXQgaW4gTFMsIGFuZCB3ZSdyZSBpbiBFbGVjdHJvbiwgdHJ5IHRvIGxvYWQgJERFQlVHXG5cdGlmICghciAmJiB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ2VudicgaW4gcHJvY2Vzcykge1xuXHRcdHIgPSBwcm9jZXNzLmVudi5ERUJVRztcblx0fVxuXG5cdHJldHVybiByO1xufVxuXG4vKipcbiAqIExvY2Fsc3RvcmFnZSBhdHRlbXB0cyB0byByZXR1cm4gdGhlIGxvY2Fsc3RvcmFnZS5cbiAqXG4gKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHNhZmFyaSB0aHJvd3NcbiAqIHdoZW4gYSB1c2VyIGRpc2FibGVzIGNvb2tpZXMvbG9jYWxzdG9yYWdlXG4gKiBhbmQgeW91IGF0dGVtcHQgdG8gYWNjZXNzIGl0LlxuICpcbiAqIEByZXR1cm4ge0xvY2FsU3RvcmFnZX1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvY2Fsc3RvcmFnZSgpIHtcblx0dHJ5IHtcblx0XHQvLyBUVk1MS2l0IChBcHBsZSBUViBKUyBSdW50aW1lKSBkb2VzIG5vdCBoYXZlIGEgd2luZG93IG9iamVjdCwganVzdCBsb2NhbFN0b3JhZ2UgaW4gdGhlIGdsb2JhbCBjb250ZXh0XG5cdFx0Ly8gVGhlIEJyb3dzZXIgYWxzbyBoYXMgbG9jYWxTdG9yYWdlIGluIHRoZSBnbG9iYWwgY29udGV4dC5cblx0XHRyZXR1cm4gbG9jYWxTdG9yYWdlO1xuXHR9IGNhdGNoIChlcnJvcikge1xuXHRcdC8vIFN3YWxsb3dcblx0XHQvLyBYWFggKEBRaXgtKSBzaG91bGQgd2UgYmUgbG9nZ2luZyB0aGVzZT9cblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY29tbW9uJykoZXhwb3J0cyk7XG5cbmNvbnN0IHtmb3JtYXR0ZXJzfSA9IG1vZHVsZS5leHBvcnRzO1xuXG4vKipcbiAqIE1hcCAlaiB0byBgSlNPTi5zdHJpbmdpZnkoKWAsIHNpbmNlIG5vIFdlYiBJbnNwZWN0b3JzIGRvIHRoYXQgYnkgZGVmYXVsdC5cbiAqL1xuXG5mb3JtYXR0ZXJzLmogPSBmdW5jdGlvbiAodikge1xuXHR0cnkge1xuXHRcdHJldHVybiBKU09OLnN0cmluZ2lmeSh2KTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRyZXR1cm4gJ1tVbmV4cGVjdGVkSlNPTlBhcnNlRXJyb3JdOiAnICsgZXJyb3IubWVzc2FnZTtcblx0fVxufTtcbiIsIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSBjb21tb24gbG9naWMgZm9yIGJvdGggdGhlIE5vZGUuanMgYW5kIHdlYiBicm93c2VyXG4gKiBpbXBsZW1lbnRhdGlvbnMgb2YgYGRlYnVnKClgLlxuICovXG5cbmZ1bmN0aW9uIHNldHVwKGVudikge1xuXHRjcmVhdGVEZWJ1Zy5kZWJ1ZyA9IGNyZWF0ZURlYnVnO1xuXHRjcmVhdGVEZWJ1Zy5kZWZhdWx0ID0gY3JlYXRlRGVidWc7XG5cdGNyZWF0ZURlYnVnLmNvZXJjZSA9IGNvZXJjZTtcblx0Y3JlYXRlRGVidWcuZGlzYWJsZSA9IGRpc2FibGU7XG5cdGNyZWF0ZURlYnVnLmVuYWJsZSA9IGVuYWJsZTtcblx0Y3JlYXRlRGVidWcuZW5hYmxlZCA9IGVuYWJsZWQ7XG5cdGNyZWF0ZURlYnVnLmh1bWFuaXplID0gcmVxdWlyZSgnbXMnKTtcblx0Y3JlYXRlRGVidWcuZGVzdHJveSA9IGRlc3Ryb3k7XG5cblx0T2JqZWN0LmtleXMoZW52KS5mb3JFYWNoKGtleSA9PiB7XG5cdFx0Y3JlYXRlRGVidWdba2V5XSA9IGVudltrZXldO1xuXHR9KTtcblxuXHQvKipcblx0KiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLCBhbmQgbmFtZXMgdG8gc2tpcC5cblx0Ki9cblxuXHRjcmVhdGVEZWJ1Zy5uYW1lcyA9IFtdO1xuXHRjcmVhdGVEZWJ1Zy5za2lwcyA9IFtdO1xuXG5cdC8qKlxuXHQqIE1hcCBvZiBzcGVjaWFsIFwiJW5cIiBoYW5kbGluZyBmdW5jdGlvbnMsIGZvciB0aGUgZGVidWcgXCJmb3JtYXRcIiBhcmd1bWVudC5cblx0KlxuXHQqIFZhbGlkIGtleSBuYW1lcyBhcmUgYSBzaW5nbGUsIGxvd2VyIG9yIHVwcGVyLWNhc2UgbGV0dGVyLCBpLmUuIFwiblwiIGFuZCBcIk5cIi5cblx0Ki9cblx0Y3JlYXRlRGVidWcuZm9ybWF0dGVycyA9IHt9O1xuXG5cdC8qKlxuXHQqIFNlbGVjdHMgYSBjb2xvciBmb3IgYSBkZWJ1ZyBuYW1lc3BhY2Vcblx0KiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlIFRoZSBuYW1lc3BhY2Ugc3RyaW5nIGZvciB0aGUgZGVidWcgaW5zdGFuY2UgdG8gYmUgY29sb3JlZFxuXHQqIEByZXR1cm4ge051bWJlcnxTdHJpbmd9IEFuIEFOU0kgY29sb3IgY29kZSBmb3IgdGhlIGdpdmVuIG5hbWVzcGFjZVxuXHQqIEBhcGkgcHJpdmF0ZVxuXHQqL1xuXHRmdW5jdGlvbiBzZWxlY3RDb2xvcihuYW1lc3BhY2UpIHtcblx0XHRsZXQgaGFzaCA9IDA7XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IG5hbWVzcGFjZS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aGFzaCA9ICgoaGFzaCA8PCA1KSAtIGhhc2gpICsgbmFtZXNwYWNlLmNoYXJDb2RlQXQoaSk7XG5cdFx0XHRoYXNoIHw9IDA7IC8vIENvbnZlcnQgdG8gMzJiaXQgaW50ZWdlclxuXHRcdH1cblxuXHRcdHJldHVybiBjcmVhdGVEZWJ1Zy5jb2xvcnNbTWF0aC5hYnMoaGFzaCkgJSBjcmVhdGVEZWJ1Zy5jb2xvcnMubGVuZ3RoXTtcblx0fVxuXHRjcmVhdGVEZWJ1Zy5zZWxlY3RDb2xvciA9IHNlbGVjdENvbG9yO1xuXG5cdC8qKlxuXHQqIENyZWF0ZSBhIGRlYnVnZ2VyIHdpdGggdGhlIGdpdmVuIGBuYW1lc3BhY2VgLlxuXHQqXG5cdCogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZVxuXHQqIEByZXR1cm4ge0Z1bmN0aW9ufVxuXHQqIEBhcGkgcHVibGljXG5cdCovXG5cdGZ1bmN0aW9uIGNyZWF0ZURlYnVnKG5hbWVzcGFjZSkge1xuXHRcdGxldCBwcmV2VGltZTtcblx0XHRsZXQgZW5hYmxlT3ZlcnJpZGUgPSBudWxsO1xuXHRcdGxldCBuYW1lc3BhY2VzQ2FjaGU7XG5cdFx0bGV0IGVuYWJsZWRDYWNoZTtcblxuXHRcdGZ1bmN0aW9uIGRlYnVnKC4uLmFyZ3MpIHtcblx0XHRcdC8vIERpc2FibGVkP1xuXHRcdFx0aWYgKCFkZWJ1Zy5lbmFibGVkKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3Qgc2VsZiA9IGRlYnVnO1xuXG5cdFx0XHQvLyBTZXQgYGRpZmZgIHRpbWVzdGFtcFxuXHRcdFx0Y29uc3QgY3VyciA9IE51bWJlcihuZXcgRGF0ZSgpKTtcblx0XHRcdGNvbnN0IG1zID0gY3VyciAtIChwcmV2VGltZSB8fCBjdXJyKTtcblx0XHRcdHNlbGYuZGlmZiA9IG1zO1xuXHRcdFx0c2VsZi5wcmV2ID0gcHJldlRpbWU7XG5cdFx0XHRzZWxmLmN1cnIgPSBjdXJyO1xuXHRcdFx0cHJldlRpbWUgPSBjdXJyO1xuXG5cdFx0XHRhcmdzWzBdID0gY3JlYXRlRGVidWcuY29lcmNlKGFyZ3NbMF0pO1xuXG5cdFx0XHRpZiAodHlwZW9mIGFyZ3NbMF0gIT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdC8vIEFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVPXG5cdFx0XHRcdGFyZ3MudW5zaGlmdCgnJU8nKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQXBwbHkgYW55IGBmb3JtYXR0ZXJzYCB0cmFuc2Zvcm1hdGlvbnNcblx0XHRcdGxldCBpbmRleCA9IDA7XG5cdFx0XHRhcmdzWzBdID0gYXJnc1swXS5yZXBsYWNlKC8lKFthLXpBLVolXSkvZywgKG1hdGNoLCBmb3JtYXQpID0+IHtcblx0XHRcdFx0Ly8gSWYgd2UgZW5jb3VudGVyIGFuIGVzY2FwZWQgJSB0aGVuIGRvbid0IGluY3JlYXNlIHRoZSBhcnJheSBpbmRleFxuXHRcdFx0XHRpZiAobWF0Y2ggPT09ICclJScpIHtcblx0XHRcdFx0XHRyZXR1cm4gJyUnO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGluZGV4Kys7XG5cdFx0XHRcdGNvbnN0IGZvcm1hdHRlciA9IGNyZWF0ZURlYnVnLmZvcm1hdHRlcnNbZm9ybWF0XTtcblx0XHRcdFx0aWYgKHR5cGVvZiBmb3JtYXR0ZXIgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0XHRjb25zdCB2YWwgPSBhcmdzW2luZGV4XTtcblx0XHRcdFx0XHRtYXRjaCA9IGZvcm1hdHRlci5jYWxsKHNlbGYsIHZhbCk7XG5cblx0XHRcdFx0XHQvLyBOb3cgd2UgbmVlZCB0byByZW1vdmUgYGFyZ3NbaW5kZXhdYCBzaW5jZSBpdCdzIGlubGluZWQgaW4gdGhlIGBmb3JtYXRgXG5cdFx0XHRcdFx0YXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuXHRcdFx0XHRcdGluZGV4LS07XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIG1hdGNoO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIEFwcGx5IGVudi1zcGVjaWZpYyBmb3JtYXR0aW5nIChjb2xvcnMsIGV0Yy4pXG5cdFx0XHRjcmVhdGVEZWJ1Zy5mb3JtYXRBcmdzLmNhbGwoc2VsZiwgYXJncyk7XG5cblx0XHRcdGNvbnN0IGxvZ0ZuID0gc2VsZi5sb2cgfHwgY3JlYXRlRGVidWcubG9nO1xuXHRcdFx0bG9nRm4uYXBwbHkoc2VsZiwgYXJncyk7XG5cdFx0fVxuXG5cdFx0ZGVidWcubmFtZXNwYWNlID0gbmFtZXNwYWNlO1xuXHRcdGRlYnVnLnVzZUNvbG9ycyA9IGNyZWF0ZURlYnVnLnVzZUNvbG9ycygpO1xuXHRcdGRlYnVnLmNvbG9yID0gY3JlYXRlRGVidWcuc2VsZWN0Q29sb3IobmFtZXNwYWNlKTtcblx0XHRkZWJ1Zy5leHRlbmQgPSBleHRlbmQ7XG5cdFx0ZGVidWcuZGVzdHJveSA9IGNyZWF0ZURlYnVnLmRlc3Ryb3k7IC8vIFhYWCBUZW1wb3JhcnkuIFdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCBtYWpvciByZWxlYXNlLlxuXG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGRlYnVnLCAnZW5hYmxlZCcsIHtcblx0XHRcdGVudW1lcmFibGU6IHRydWUsXG5cdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuXHRcdFx0Z2V0OiAoKSA9PiB7XG5cdFx0XHRcdGlmIChlbmFibGVPdmVycmlkZSAhPT0gbnVsbCkge1xuXHRcdFx0XHRcdHJldHVybiBlbmFibGVPdmVycmlkZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAobmFtZXNwYWNlc0NhY2hlICE9PSBjcmVhdGVEZWJ1Zy5uYW1lc3BhY2VzKSB7XG5cdFx0XHRcdFx0bmFtZXNwYWNlc0NhY2hlID0gY3JlYXRlRGVidWcubmFtZXNwYWNlcztcblx0XHRcdFx0XHRlbmFibGVkQ2FjaGUgPSBjcmVhdGVEZWJ1Zy5lbmFibGVkKG5hbWVzcGFjZSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gZW5hYmxlZENhY2hlO1xuXHRcdFx0fSxcblx0XHRcdHNldDogdiA9PiB7XG5cdFx0XHRcdGVuYWJsZU92ZXJyaWRlID0gdjtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIEVudi1zcGVjaWZpYyBpbml0aWFsaXphdGlvbiBsb2dpYyBmb3IgZGVidWcgaW5zdGFuY2VzXG5cdFx0aWYgKHR5cGVvZiBjcmVhdGVEZWJ1Zy5pbml0ID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRjcmVhdGVEZWJ1Zy5pbml0KGRlYnVnKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGVidWc7XG5cdH1cblxuXHRmdW5jdGlvbiBleHRlbmQobmFtZXNwYWNlLCBkZWxpbWl0ZXIpIHtcblx0XHRjb25zdCBuZXdEZWJ1ZyA9IGNyZWF0ZURlYnVnKHRoaXMubmFtZXNwYWNlICsgKHR5cGVvZiBkZWxpbWl0ZXIgPT09ICd1bmRlZmluZWQnID8gJzonIDogZGVsaW1pdGVyKSArIG5hbWVzcGFjZSk7XG5cdFx0bmV3RGVidWcubG9nID0gdGhpcy5sb2c7XG5cdFx0cmV0dXJuIG5ld0RlYnVnO1xuXHR9XG5cblx0LyoqXG5cdCogRW5hYmxlcyBhIGRlYnVnIG1vZGUgYnkgbmFtZXNwYWNlcy4gVGhpcyBjYW4gaW5jbHVkZSBtb2Rlc1xuXHQqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG5cdCpcblx0KiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuXHQqIEBhcGkgcHVibGljXG5cdCovXG5cdGZ1bmN0aW9uIGVuYWJsZShuYW1lc3BhY2VzKSB7XG5cdFx0Y3JlYXRlRGVidWcuc2F2ZShuYW1lc3BhY2VzKTtcblx0XHRjcmVhdGVEZWJ1Zy5uYW1lc3BhY2VzID0gbmFtZXNwYWNlcztcblxuXHRcdGNyZWF0ZURlYnVnLm5hbWVzID0gW107XG5cdFx0Y3JlYXRlRGVidWcuc2tpcHMgPSBbXTtcblxuXHRcdGxldCBpO1xuXHRcdGNvbnN0IHNwbGl0ID0gKHR5cGVvZiBuYW1lc3BhY2VzID09PSAnc3RyaW5nJyA/IG5hbWVzcGFjZXMgOiAnJykuc3BsaXQoL1tcXHMsXSsvKTtcblx0XHRjb25zdCBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdGlmICghc3BsaXRbaV0pIHtcblx0XHRcdFx0Ly8gaWdub3JlIGVtcHR5IHN0cmluZ3Ncblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdG5hbWVzcGFjZXMgPSBzcGxpdFtpXS5yZXBsYWNlKC9cXCovZywgJy4qPycpO1xuXG5cdFx0XHRpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG5cdFx0XHRcdGNyZWF0ZURlYnVnLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnNsaWNlKDEpICsgJyQnKSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjcmVhdGVEZWJ1Zy5uYW1lcy5wdXNoKG5ldyBSZWdFeHAoJ14nICsgbmFtZXNwYWNlcyArICckJykpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQqIERpc2FibGUgZGVidWcgb3V0cHV0LlxuXHQqXG5cdCogQHJldHVybiB7U3RyaW5nfSBuYW1lc3BhY2VzXG5cdCogQGFwaSBwdWJsaWNcblx0Ki9cblx0ZnVuY3Rpb24gZGlzYWJsZSgpIHtcblx0XHRjb25zdCBuYW1lc3BhY2VzID0gW1xuXHRcdFx0Li4uY3JlYXRlRGVidWcubmFtZXMubWFwKHRvTmFtZXNwYWNlKSxcblx0XHRcdC4uLmNyZWF0ZURlYnVnLnNraXBzLm1hcCh0b05hbWVzcGFjZSkubWFwKG5hbWVzcGFjZSA9PiAnLScgKyBuYW1lc3BhY2UpXG5cdFx0XS5qb2luKCcsJyk7XG5cdFx0Y3JlYXRlRGVidWcuZW5hYmxlKCcnKTtcblx0XHRyZXR1cm4gbmFtZXNwYWNlcztcblx0fVxuXG5cdC8qKlxuXHQqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gbW9kZSBuYW1lIGlzIGVuYWJsZWQsIGZhbHNlIG90aGVyd2lzZS5cblx0KlxuXHQqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG5cdCogQHJldHVybiB7Qm9vbGVhbn1cblx0KiBAYXBpIHB1YmxpY1xuXHQqL1xuXHRmdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcblx0XHRpZiAobmFtZVtuYW1lLmxlbmd0aCAtIDFdID09PSAnKicpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdGxldCBpO1xuXHRcdGxldCBsZW47XG5cblx0XHRmb3IgKGkgPSAwLCBsZW4gPSBjcmVhdGVEZWJ1Zy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0aWYgKGNyZWF0ZURlYnVnLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGZvciAoaSA9IDAsIGxlbiA9IGNyZWF0ZURlYnVnLm5hbWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRpZiAoY3JlYXRlRGVidWcubmFtZXNbaV0udGVzdChuYW1lKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0KiBDb252ZXJ0IHJlZ2V4cCB0byBuYW1lc3BhY2Vcblx0KlxuXHQqIEBwYXJhbSB7UmVnRXhwfSByZWd4ZXBcblx0KiBAcmV0dXJuIHtTdHJpbmd9IG5hbWVzcGFjZVxuXHQqIEBhcGkgcHJpdmF0ZVxuXHQqL1xuXHRmdW5jdGlvbiB0b05hbWVzcGFjZShyZWdleHApIHtcblx0XHRyZXR1cm4gcmVnZXhwLnRvU3RyaW5nKClcblx0XHRcdC5zdWJzdHJpbmcoMiwgcmVnZXhwLnRvU3RyaW5nKCkubGVuZ3RoIC0gMilcblx0XHRcdC5yZXBsYWNlKC9cXC5cXCpcXD8kLywgJyonKTtcblx0fVxuXG5cdC8qKlxuXHQqIENvZXJjZSBgdmFsYC5cblx0KlxuXHQqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuXHQqIEByZXR1cm4ge01peGVkfVxuXHQqIEBhcGkgcHJpdmF0ZVxuXHQqL1xuXHRmdW5jdGlvbiBjb2VyY2UodmFsKSB7XG5cdFx0aWYgKHZhbCBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRyZXR1cm4gdmFsLnN0YWNrIHx8IHZhbC5tZXNzYWdlO1xuXHRcdH1cblx0XHRyZXR1cm4gdmFsO1xuXHR9XG5cblx0LyoqXG5cdCogWFhYIERPIE5PVCBVU0UuIFRoaXMgaXMgYSB0ZW1wb3Jhcnkgc3R1YiBmdW5jdGlvbi5cblx0KiBYWFggSXQgV0lMTCBiZSByZW1vdmVkIGluIHRoZSBuZXh0IG1ham9yIHJlbGVhc2UuXG5cdCovXG5cdGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG5cdFx0Y29uc29sZS53YXJuKCdJbnN0YW5jZSBtZXRob2QgYGRlYnVnLmRlc3Ryb3koKWAgaXMgZGVwcmVjYXRlZCBhbmQgbm8gbG9uZ2VyIGRvZXMgYW55dGhpbmcuIEl0IHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCBtYWpvciB2ZXJzaW9uIG9mIGBkZWJ1Z2AuJyk7XG5cdH1cblxuXHRjcmVhdGVEZWJ1Zy5lbmFibGUoY3JlYXRlRGVidWcubG9hZCgpKTtcblxuXHRyZXR1cm4gY3JlYXRlRGVidWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0dXA7XG4iLCIvKipcbiAqIERldGVjdCBFbGVjdHJvbiByZW5kZXJlciAvIG53anMgcHJvY2Vzcywgd2hpY2ggaXMgbm9kZSwgYnV0IHdlIHNob3VsZFxuICogdHJlYXQgYXMgYSBicm93c2VyLlxuICovXG5cbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ3VuZGVmaW5lZCcgfHwgcHJvY2Vzcy50eXBlID09PSAncmVuZGVyZXInIHx8IHByb2Nlc3MuYnJvd3NlciA9PT0gdHJ1ZSB8fCBwcm9jZXNzLl9fbndqcykge1xuXHRtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vYnJvd3Nlci5qcycpO1xufSBlbHNlIHtcblx0bW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL25vZGUuanMnKTtcbn1cbiIsIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG5jb25zdCB0dHkgPSByZXF1aXJlKCd0dHknKTtcbmNvbnN0IHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbi8qKlxuICogVGhpcyBpcyB0aGUgTm9kZS5qcyBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKi9cblxuZXhwb3J0cy5pbml0ID0gaW5pdDtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5leHBvcnRzLmRlc3Ryb3kgPSB1dGlsLmRlcHJlY2F0ZShcblx0KCkgPT4ge30sXG5cdCdJbnN0YW5jZSBtZXRob2QgYGRlYnVnLmRlc3Ryb3koKWAgaXMgZGVwcmVjYXRlZCBhbmQgbm8gbG9uZ2VyIGRvZXMgYW55dGhpbmcuIEl0IHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmV4dCBtYWpvciB2ZXJzaW9uIG9mIGBkZWJ1Z2AuJ1xuKTtcblxuLyoqXG4gKiBDb2xvcnMuXG4gKi9cblxuZXhwb3J0cy5jb2xvcnMgPSBbNiwgMiwgMywgNCwgNSwgMV07XG5cbnRyeSB7XG5cdC8vIE9wdGlvbmFsIGRlcGVuZGVuY3kgKGFzIGluLCBkb2Vzbid0IG5lZWQgdG8gYmUgaW5zdGFsbGVkLCBOT1QgbGlrZSBvcHRpb25hbERlcGVuZGVuY2llcyBpbiBwYWNrYWdlLmpzb24pXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXNcblx0Y29uc3Qgc3VwcG9ydHNDb2xvciA9IHJlcXVpcmUoJ3N1cHBvcnRzLWNvbG9yJyk7XG5cblx0aWYgKHN1cHBvcnRzQ29sb3IgJiYgKHN1cHBvcnRzQ29sb3Iuc3RkZXJyIHx8IHN1cHBvcnRzQ29sb3IpLmxldmVsID49IDIpIHtcblx0XHRleHBvcnRzLmNvbG9ycyA9IFtcblx0XHRcdDIwLFxuXHRcdFx0MjEsXG5cdFx0XHQyNixcblx0XHRcdDI3LFxuXHRcdFx0MzIsXG5cdFx0XHQzMyxcblx0XHRcdDM4LFxuXHRcdFx0MzksXG5cdFx0XHQ0MCxcblx0XHRcdDQxLFxuXHRcdFx0NDIsXG5cdFx0XHQ0Myxcblx0XHRcdDQ0LFxuXHRcdFx0NDUsXG5cdFx0XHQ1Nixcblx0XHRcdDU3LFxuXHRcdFx0NjIsXG5cdFx0XHQ2Myxcblx0XHRcdDY4LFxuXHRcdFx0NjksXG5cdFx0XHQ3NCxcblx0XHRcdDc1LFxuXHRcdFx0NzYsXG5cdFx0XHQ3Nyxcblx0XHRcdDc4LFxuXHRcdFx0NzksXG5cdFx0XHQ4MCxcblx0XHRcdDgxLFxuXHRcdFx0OTIsXG5cdFx0XHQ5Myxcblx0XHRcdDk4LFxuXHRcdFx0OTksXG5cdFx0XHQxMTIsXG5cdFx0XHQxMTMsXG5cdFx0XHQxMjgsXG5cdFx0XHQxMjksXG5cdFx0XHQxMzQsXG5cdFx0XHQxMzUsXG5cdFx0XHQxNDgsXG5cdFx0XHQxNDksXG5cdFx0XHQxNjAsXG5cdFx0XHQxNjEsXG5cdFx0XHQxNjIsXG5cdFx0XHQxNjMsXG5cdFx0XHQxNjQsXG5cdFx0XHQxNjUsXG5cdFx0XHQxNjYsXG5cdFx0XHQxNjcsXG5cdFx0XHQxNjgsXG5cdFx0XHQxNjksXG5cdFx0XHQxNzAsXG5cdFx0XHQxNzEsXG5cdFx0XHQxNzIsXG5cdFx0XHQxNzMsXG5cdFx0XHQxNzgsXG5cdFx0XHQxNzksXG5cdFx0XHQxODQsXG5cdFx0XHQxODUsXG5cdFx0XHQxOTYsXG5cdFx0XHQxOTcsXG5cdFx0XHQxOTgsXG5cdFx0XHQxOTksXG5cdFx0XHQyMDAsXG5cdFx0XHQyMDEsXG5cdFx0XHQyMDIsXG5cdFx0XHQyMDMsXG5cdFx0XHQyMDQsXG5cdFx0XHQyMDUsXG5cdFx0XHQyMDYsXG5cdFx0XHQyMDcsXG5cdFx0XHQyMDgsXG5cdFx0XHQyMDksXG5cdFx0XHQyMTQsXG5cdFx0XHQyMTUsXG5cdFx0XHQyMjAsXG5cdFx0XHQyMjFcblx0XHRdO1xuXHR9XG59IGNhdGNoIChlcnJvcikge1xuXHQvLyBTd2FsbG93IC0gd2Ugb25seSBjYXJlIGlmIGBzdXBwb3J0cy1jb2xvcmAgaXMgYXZhaWxhYmxlOyBpdCBkb2Vzbid0IGhhdmUgdG8gYmUuXG59XG5cbi8qKlxuICogQnVpbGQgdXAgdGhlIGRlZmF1bHQgYGluc3BlY3RPcHRzYCBvYmplY3QgZnJvbSB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICpcbiAqICAgJCBERUJVR19DT0xPUlM9bm8gREVCVUdfREVQVEg9MTAgREVCVUdfU0hPV19ISURERU49ZW5hYmxlZCBub2RlIHNjcmlwdC5qc1xuICovXG5cbmV4cG9ydHMuaW5zcGVjdE9wdHMgPSBPYmplY3Qua2V5cyhwcm9jZXNzLmVudikuZmlsdGVyKGtleSA9PiB7XG5cdHJldHVybiAvXmRlYnVnXy9pLnRlc3Qoa2V5KTtcbn0pLnJlZHVjZSgob2JqLCBrZXkpID0+IHtcblx0Ly8gQ2FtZWwtY2FzZVxuXHRjb25zdCBwcm9wID0ga2V5XG5cdFx0LnN1YnN0cmluZyg2KVxuXHRcdC50b0xvd2VyQ2FzZSgpXG5cdFx0LnJlcGxhY2UoL18oW2Etel0pL2csIChfLCBrKSA9PiB7XG5cdFx0XHRyZXR1cm4gay50b1VwcGVyQ2FzZSgpO1xuXHRcdH0pO1xuXG5cdC8vIENvZXJjZSBzdHJpbmcgdmFsdWUgaW50byBKUyB2YWx1ZVxuXHRsZXQgdmFsID0gcHJvY2Vzcy5lbnZba2V5XTtcblx0aWYgKC9eKHllc3xvbnx0cnVlfGVuYWJsZWQpJC9pLnRlc3QodmFsKSkge1xuXHRcdHZhbCA9IHRydWU7XG5cdH0gZWxzZSBpZiAoL14obm98b2ZmfGZhbHNlfGRpc2FibGVkKSQvaS50ZXN0KHZhbCkpIHtcblx0XHR2YWwgPSBmYWxzZTtcblx0fSBlbHNlIGlmICh2YWwgPT09ICdudWxsJykge1xuXHRcdHZhbCA9IG51bGw7XG5cdH0gZWxzZSB7XG5cdFx0dmFsID0gTnVtYmVyKHZhbCk7XG5cdH1cblxuXHRvYmpbcHJvcF0gPSB2YWw7XG5cdHJldHVybiBvYmo7XG59LCB7fSk7XG5cbi8qKlxuICogSXMgc3Rkb3V0IGEgVFRZPyBDb2xvcmVkIG91dHB1dCBpcyBlbmFibGVkIHdoZW4gYHRydWVgLlxuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcblx0cmV0dXJuICdjb2xvcnMnIGluIGV4cG9ydHMuaW5zcGVjdE9wdHMgP1xuXHRcdEJvb2xlYW4oZXhwb3J0cy5pbnNwZWN0T3B0cy5jb2xvcnMpIDpcblx0XHR0dHkuaXNhdHR5KHByb2Nlc3Muc3RkZXJyLmZkKTtcbn1cblxuLyoqXG4gKiBBZGRzIEFOU0kgY29sb3IgZXNjYXBlIGNvZGVzIGlmIGVuYWJsZWQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBmb3JtYXRBcmdzKGFyZ3MpIHtcblx0Y29uc3Qge25hbWVzcGFjZTogbmFtZSwgdXNlQ29sb3JzfSA9IHRoaXM7XG5cblx0aWYgKHVzZUNvbG9ycykge1xuXHRcdGNvbnN0IGMgPSB0aGlzLmNvbG9yO1xuXHRcdGNvbnN0IGNvbG9yQ29kZSA9ICdcXHUwMDFCWzMnICsgKGMgPCA4ID8gYyA6ICc4OzU7JyArIGMpO1xuXHRcdGNvbnN0IHByZWZpeCA9IGAgICR7Y29sb3JDb2RlfTsxbSR7bmFtZX0gXFx1MDAxQlswbWA7XG5cblx0XHRhcmdzWzBdID0gcHJlZml4ICsgYXJnc1swXS5zcGxpdCgnXFxuJykuam9pbignXFxuJyArIHByZWZpeCk7XG5cdFx0YXJncy5wdXNoKGNvbG9yQ29kZSArICdtKycgKyBtb2R1bGUuZXhwb3J0cy5odW1hbml6ZSh0aGlzLmRpZmYpICsgJ1xcdTAwMUJbMG0nKTtcblx0fSBlbHNlIHtcblx0XHRhcmdzWzBdID0gZ2V0RGF0ZSgpICsgbmFtZSArICcgJyArIGFyZ3NbMF07XG5cdH1cbn1cblxuZnVuY3Rpb24gZ2V0RGF0ZSgpIHtcblx0aWYgKGV4cG9ydHMuaW5zcGVjdE9wdHMuaGlkZURhdGUpIHtcblx0XHRyZXR1cm4gJyc7XG5cdH1cblx0cmV0dXJuIG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSArICcgJztcbn1cblxuLyoqXG4gKiBJbnZva2VzIGB1dGlsLmZvcm1hdCgpYCB3aXRoIHRoZSBzcGVjaWZpZWQgYXJndW1lbnRzIGFuZCB3cml0ZXMgdG8gc3RkZXJyLlxuICovXG5cbmZ1bmN0aW9uIGxvZyguLi5hcmdzKSB7XG5cdHJldHVybiBwcm9jZXNzLnN0ZGVyci53cml0ZSh1dGlsLmZvcm1hdCguLi5hcmdzKSArICdcXG4nKTtcbn1cblxuLyoqXG4gKiBTYXZlIGBuYW1lc3BhY2VzYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNhdmUobmFtZXNwYWNlcykge1xuXHRpZiAobmFtZXNwYWNlcykge1xuXHRcdHByb2Nlc3MuZW52LkRFQlVHID0gbmFtZXNwYWNlcztcblx0fSBlbHNlIHtcblx0XHQvLyBJZiB5b3Ugc2V0IGEgcHJvY2Vzcy5lbnYgZmllbGQgdG8gbnVsbCBvciB1bmRlZmluZWQsIGl0IGdldHMgY2FzdCB0byB0aGVcblx0XHQvLyBzdHJpbmcgJ251bGwnIG9yICd1bmRlZmluZWQnLiBKdXN0IGRlbGV0ZSBpbnN0ZWFkLlxuXHRcdGRlbGV0ZSBwcm9jZXNzLmVudi5ERUJVRztcblx0fVxufVxuXG4vKipcbiAqIExvYWQgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJucyB0aGUgcHJldmlvdXNseSBwZXJzaXN0ZWQgZGVidWcgbW9kZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvYWQoKSB7XG5cdHJldHVybiBwcm9jZXNzLmVudi5ERUJVRztcbn1cblxuLyoqXG4gKiBJbml0IGxvZ2ljIGZvciBgZGVidWdgIGluc3RhbmNlcy5cbiAqXG4gKiBDcmVhdGUgYSBuZXcgYGluc3BlY3RPcHRzYCBvYmplY3QgaW4gY2FzZSBgdXNlQ29sb3JzYCBpcyBzZXRcbiAqIGRpZmZlcmVudGx5IGZvciBhIHBhcnRpY3VsYXIgYGRlYnVnYCBpbnN0YW5jZS5cbiAqL1xuXG5mdW5jdGlvbiBpbml0KGRlYnVnKSB7XG5cdGRlYnVnLmluc3BlY3RPcHRzID0ge307XG5cblx0Y29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGV4cG9ydHMuaW5zcGVjdE9wdHMpO1xuXHRmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0XHRkZWJ1Zy5pbnNwZWN0T3B0c1trZXlzW2ldXSA9IGV4cG9ydHMuaW5zcGVjdE9wdHNba2V5c1tpXV07XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2NvbW1vbicpKGV4cG9ydHMpO1xuXG5jb25zdCB7Zm9ybWF0dGVyc30gPSBtb2R1bGUuZXhwb3J0cztcblxuLyoqXG4gKiBNYXAgJW8gdG8gYHV0aWwuaW5zcGVjdCgpYCwgYWxsIG9uIGEgc2luZ2xlIGxpbmUuXG4gKi9cblxuZm9ybWF0dGVycy5vID0gZnVuY3Rpb24gKHYpIHtcblx0dGhpcy5pbnNwZWN0T3B0cy5jb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblx0cmV0dXJuIHV0aWwuaW5zcGVjdCh2LCB0aGlzLmluc3BlY3RPcHRzKVxuXHRcdC5zcGxpdCgnXFxuJylcblx0XHQubWFwKHN0ciA9PiBzdHIudHJpbSgpKVxuXHRcdC5qb2luKCcgJyk7XG59O1xuXG4vKipcbiAqIE1hcCAlTyB0byBgdXRpbC5pbnNwZWN0KClgLCBhbGxvd2luZyBtdWx0aXBsZSBsaW5lcyBpZiBuZWVkZWQuXG4gKi9cblxuZm9ybWF0dGVycy5PID0gZnVuY3Rpb24gKHYpIHtcblx0dGhpcy5pbnNwZWN0T3B0cy5jb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblx0cmV0dXJuIHV0aWwuaW5zcGVjdCh2LCB0aGlzLmluc3BlY3RPcHRzKTtcbn07XG4iLCJ2YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJykuU3RyZWFtO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRGVsYXllZFN0cmVhbTtcbmZ1bmN0aW9uIERlbGF5ZWRTdHJlYW0oKSB7XG4gIHRoaXMuc291cmNlID0gbnVsbDtcbiAgdGhpcy5kYXRhU2l6ZSA9IDA7XG4gIHRoaXMubWF4RGF0YVNpemUgPSAxMDI0ICogMTAyNDtcbiAgdGhpcy5wYXVzZVN0cmVhbSA9IHRydWU7XG5cbiAgdGhpcy5fbWF4RGF0YVNpemVFeGNlZWRlZCA9IGZhbHNlO1xuICB0aGlzLl9yZWxlYXNlZCA9IGZhbHNlO1xuICB0aGlzLl9idWZmZXJlZEV2ZW50cyA9IFtdO1xufVxudXRpbC5pbmhlcml0cyhEZWxheWVkU3RyZWFtLCBTdHJlYW0pO1xuXG5EZWxheWVkU3RyZWFtLmNyZWF0ZSA9IGZ1bmN0aW9uKHNvdXJjZSwgb3B0aW9ucykge1xuICB2YXIgZGVsYXllZFN0cmVhbSA9IG5ldyB0aGlzKCk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGZvciAodmFyIG9wdGlvbiBpbiBvcHRpb25zKSB7XG4gICAgZGVsYXllZFN0cmVhbVtvcHRpb25dID0gb3B0aW9uc1tvcHRpb25dO1xuICB9XG5cbiAgZGVsYXllZFN0cmVhbS5zb3VyY2UgPSBzb3VyY2U7XG5cbiAgdmFyIHJlYWxFbWl0ID0gc291cmNlLmVtaXQ7XG4gIHNvdXJjZS5lbWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgZGVsYXllZFN0cmVhbS5faGFuZGxlRW1pdChhcmd1bWVudHMpO1xuICAgIHJldHVybiByZWFsRW1pdC5hcHBseShzb3VyY2UsIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgc291cmNlLm9uKCdlcnJvcicsIGZ1bmN0aW9uKCkge30pO1xuICBpZiAoZGVsYXllZFN0cmVhbS5wYXVzZVN0cmVhbSkge1xuICAgIHNvdXJjZS5wYXVzZSgpO1xuICB9XG5cbiAgcmV0dXJuIGRlbGF5ZWRTdHJlYW07XG59O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRGVsYXllZFN0cmVhbS5wcm90b3R5cGUsICdyZWFkYWJsZScsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnNvdXJjZS5yZWFkYWJsZTtcbiAgfVxufSk7XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnNvdXJjZS5zZXRFbmNvZGluZy5hcHBseSh0aGlzLnNvdXJjZSwgYXJndW1lbnRzKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuX3JlbGVhc2VkKSB7XG4gICAgdGhpcy5yZWxlYXNlKCk7XG4gIH1cblxuICB0aGlzLnNvdXJjZS5yZXN1bWUoKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuc291cmNlLnBhdXNlKCk7XG59O1xuXG5EZWxheWVkU3RyZWFtLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3JlbGVhc2VkID0gdHJ1ZTtcblxuICB0aGlzLl9idWZmZXJlZEV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICB0aGlzLmVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0uYmluZCh0aGlzKSk7XG4gIHRoaXMuX2J1ZmZlcmVkRXZlbnRzID0gW107XG59O1xuXG5EZWxheWVkU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oKSB7XG4gIHZhciByID0gU3RyZWFtLnByb3RvdHlwZS5waXBlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIHRoaXMucmVzdW1lKCk7XG4gIHJldHVybiByO1xufTtcblxuRGVsYXllZFN0cmVhbS5wcm90b3R5cGUuX2hhbmRsZUVtaXQgPSBmdW5jdGlvbihhcmdzKSB7XG4gIGlmICh0aGlzLl9yZWxlYXNlZCkge1xuICAgIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoYXJnc1swXSA9PT0gJ2RhdGEnKSB7XG4gICAgdGhpcy5kYXRhU2l6ZSArPSBhcmdzWzFdLmxlbmd0aDtcbiAgICB0aGlzLl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCgpO1xuICB9XG5cbiAgdGhpcy5fYnVmZmVyZWRFdmVudHMucHVzaChhcmdzKTtcbn07XG5cbkRlbGF5ZWRTdHJlYW0ucHJvdG90eXBlLl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5fbWF4RGF0YVNpemVFeGNlZWRlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0aGlzLmRhdGFTaXplIDw9IHRoaXMubWF4RGF0YVNpemUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9tYXhEYXRhU2l6ZUV4Y2VlZGVkID0gdHJ1ZTtcbiAgdmFyIG1lc3NhZ2UgPVxuICAgICdEZWxheWVkU3RyZWFtI21heERhdGFTaXplIG9mICcgKyB0aGlzLm1heERhdGFTaXplICsgJyBieXRlcyBleGNlZWRlZC4nXG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IobWVzc2FnZSkpO1xufTtcbiIsInZhciBkZWJ1ZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghZGVidWcpIHtcbiAgICB0cnkge1xuICAgICAgLyogZXNsaW50IGdsb2JhbC1yZXF1aXJlOiBvZmYgKi9cbiAgICAgIGRlYnVnID0gcmVxdWlyZShcImRlYnVnXCIpKFwiZm9sbG93LXJlZGlyZWN0c1wiKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycm9yKSB7IC8qICovIH1cbiAgICBpZiAodHlwZW9mIGRlYnVnICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGRlYnVnID0gZnVuY3Rpb24gKCkgeyAvKiAqLyB9O1xuICAgIH1cbiAgfVxuICBkZWJ1Zy5hcHBseShudWxsLCBhcmd1bWVudHMpO1xufTtcbiIsInZhciB1cmwgPSByZXF1aXJlKFwidXJsXCIpO1xudmFyIFVSTCA9IHVybC5VUkw7XG52YXIgaHR0cCA9IHJlcXVpcmUoXCJodHRwXCIpO1xudmFyIGh0dHBzID0gcmVxdWlyZShcImh0dHBzXCIpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZShcInN0cmVhbVwiKS5Xcml0YWJsZTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKFwiYXNzZXJ0XCIpO1xudmFyIGRlYnVnID0gcmVxdWlyZShcIi4vZGVidWdcIik7XG5cbi8vIFdoZXRoZXIgdG8gdXNlIHRoZSBuYXRpdmUgVVJMIG9iamVjdCBvciB0aGUgbGVnYWN5IHVybCBtb2R1bGVcbnZhciB1c2VOYXRpdmVVUkwgPSBmYWxzZTtcbnRyeSB7XG4gIGFzc2VydChuZXcgVVJMKCkpO1xufVxuY2F0Y2ggKGVycm9yKSB7XG4gIHVzZU5hdGl2ZVVSTCA9IGVycm9yLmNvZGUgPT09IFwiRVJSX0lOVkFMSURfVVJMXCI7XG59XG5cbi8vIFVSTCBmaWVsZHMgdG8gcHJlc2VydmUgaW4gY29weSBvcGVyYXRpb25zXG52YXIgcHJlc2VydmVkVXJsRmllbGRzID0gW1xuICBcImF1dGhcIixcbiAgXCJob3N0XCIsXG4gIFwiaG9zdG5hbWVcIixcbiAgXCJocmVmXCIsXG4gIFwicGF0aFwiLFxuICBcInBhdGhuYW1lXCIsXG4gIFwicG9ydFwiLFxuICBcInByb3RvY29sXCIsXG4gIFwicXVlcnlcIixcbiAgXCJzZWFyY2hcIixcbiAgXCJoYXNoXCIsXG5dO1xuXG4vLyBDcmVhdGUgaGFuZGxlcnMgdGhhdCBwYXNzIGV2ZW50cyBmcm9tIG5hdGl2ZSByZXF1ZXN0c1xudmFyIGV2ZW50cyA9IFtcImFib3J0XCIsIFwiYWJvcnRlZFwiLCBcImNvbm5lY3RcIiwgXCJlcnJvclwiLCBcInNvY2tldFwiLCBcInRpbWVvdXRcIl07XG52YXIgZXZlbnRIYW5kbGVycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5ldmVudHMuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgZXZlbnRIYW5kbGVyc1tldmVudF0gPSBmdW5jdGlvbiAoYXJnMSwgYXJnMiwgYXJnMykge1xuICAgIHRoaXMuX3JlZGlyZWN0YWJsZS5lbWl0KGV2ZW50LCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfTtcbn0pO1xuXG4vLyBFcnJvciB0eXBlcyB3aXRoIGNvZGVzXG52YXIgSW52YWxpZFVybEVycm9yID0gY3JlYXRlRXJyb3JUeXBlKFxuICBcIkVSUl9JTlZBTElEX1VSTFwiLFxuICBcIkludmFsaWQgVVJMXCIsXG4gIFR5cGVFcnJvclxuKTtcbnZhciBSZWRpcmVjdGlvbkVycm9yID0gY3JlYXRlRXJyb3JUeXBlKFxuICBcIkVSUl9GUl9SRURJUkVDVElPTl9GQUlMVVJFXCIsXG4gIFwiUmVkaXJlY3RlZCByZXF1ZXN0IGZhaWxlZFwiXG4pO1xudmFyIFRvb01hbnlSZWRpcmVjdHNFcnJvciA9IGNyZWF0ZUVycm9yVHlwZShcbiAgXCJFUlJfRlJfVE9PX01BTllfUkVESVJFQ1RTXCIsXG4gIFwiTWF4aW11bSBudW1iZXIgb2YgcmVkaXJlY3RzIGV4Y2VlZGVkXCIsXG4gIFJlZGlyZWN0aW9uRXJyb3Jcbik7XG52YXIgTWF4Qm9keUxlbmd0aEV4Y2VlZGVkRXJyb3IgPSBjcmVhdGVFcnJvclR5cGUoXG4gIFwiRVJSX0ZSX01BWF9CT0RZX0xFTkdUSF9FWENFRURFRFwiLFxuICBcIlJlcXVlc3QgYm9keSBsYXJnZXIgdGhhbiBtYXhCb2R5TGVuZ3RoIGxpbWl0XCJcbik7XG52YXIgV3JpdGVBZnRlckVuZEVycm9yID0gY3JlYXRlRXJyb3JUeXBlKFxuICBcIkVSUl9TVFJFQU1fV1JJVEVfQUZURVJfRU5EXCIsXG4gIFwid3JpdGUgYWZ0ZXIgZW5kXCJcbik7XG5cbi8vIGlzdGFuYnVsIGlnbm9yZSBuZXh0XG52YXIgZGVzdHJveSA9IFdyaXRhYmxlLnByb3RvdHlwZS5kZXN0cm95IHx8IG5vb3A7XG5cbi8vIEFuIEhUVFAoUykgcmVxdWVzdCB0aGF0IGNhbiBiZSByZWRpcmVjdGVkXG5mdW5jdGlvbiBSZWRpcmVjdGFibGVSZXF1ZXN0KG9wdGlvbnMsIHJlc3BvbnNlQ2FsbGJhY2spIHtcbiAgLy8gSW5pdGlhbGl6ZSB0aGUgcmVxdWVzdFxuICBXcml0YWJsZS5jYWxsKHRoaXMpO1xuICB0aGlzLl9zYW5pdGl6ZU9wdGlvbnMob3B0aW9ucyk7XG4gIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zO1xuICB0aGlzLl9lbmRlZCA9IGZhbHNlO1xuICB0aGlzLl9lbmRpbmcgPSBmYWxzZTtcbiAgdGhpcy5fcmVkaXJlY3RDb3VudCA9IDA7XG4gIHRoaXMuX3JlZGlyZWN0cyA9IFtdO1xuICB0aGlzLl9yZXF1ZXN0Qm9keUxlbmd0aCA9IDA7XG4gIHRoaXMuX3JlcXVlc3RCb2R5QnVmZmVycyA9IFtdO1xuXG4gIC8vIEF0dGFjaCBhIGNhbGxiYWNrIGlmIHBhc3NlZFxuICBpZiAocmVzcG9uc2VDYWxsYmFjaykge1xuICAgIHRoaXMub24oXCJyZXNwb25zZVwiLCByZXNwb25zZUNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vIFJlYWN0IHRvIHJlc3BvbnNlcyBvZiBuYXRpdmUgcmVxdWVzdHNcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9vbk5hdGl2ZVJlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdHJ5IHtcbiAgICAgIHNlbGYuX3Byb2Nlc3NSZXNwb25zZShyZXNwb25zZSk7XG4gICAgfVxuICAgIGNhdGNoIChjYXVzZSkge1xuICAgICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgY2F1c2UgaW5zdGFuY2VvZiBSZWRpcmVjdGlvbkVycm9yID9cbiAgICAgICAgY2F1c2UgOiBuZXcgUmVkaXJlY3Rpb25FcnJvcih7IGNhdXNlOiBjYXVzZSB9KSk7XG4gICAgfVxuICB9O1xuXG4gIC8vIFBlcmZvcm0gdGhlIGZpcnN0IHJlcXVlc3RcbiAgdGhpcy5fcGVyZm9ybVJlcXVlc3QoKTtcbn1cblJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShXcml0YWJsZS5wcm90b3R5cGUpO1xuXG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5hYm9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgZGVzdHJveVJlcXVlc3QodGhpcy5fY3VycmVudFJlcXVlc3QpO1xuICB0aGlzLl9jdXJyZW50UmVxdWVzdC5hYm9ydCgpO1xuICB0aGlzLmVtaXQoXCJhYm9ydFwiKTtcbn07XG5cblJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgZGVzdHJveVJlcXVlc3QodGhpcy5fY3VycmVudFJlcXVlc3QsIGVycm9yKTtcbiAgZGVzdHJveS5jYWxsKHRoaXMsIGVycm9yKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBXcml0ZXMgYnVmZmVyZWQgZGF0YSB0byB0aGUgY3VycmVudCBuYXRpdmUgcmVxdWVzdFxuUmVkaXJlY3RhYmxlUmVxdWVzdC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gIC8vIFdyaXRpbmcgaXMgbm90IGFsbG93ZWQgaWYgZW5kIGhhcyBiZWVuIGNhbGxlZFxuICBpZiAodGhpcy5fZW5kaW5nKSB7XG4gICAgdGhyb3cgbmV3IFdyaXRlQWZ0ZXJFbmRFcnJvcigpO1xuICB9XG5cbiAgLy8gVmFsaWRhdGUgaW5wdXQgYW5kIHNoaWZ0IHBhcmFtZXRlcnMgaWYgbmVjZXNzYXJ5XG4gIGlmICghaXNTdHJpbmcoZGF0YSkgJiYgIWlzQnVmZmVyKGRhdGEpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImRhdGEgc2hvdWxkIGJlIGEgc3RyaW5nLCBCdWZmZXIgb3IgVWludDhBcnJheVwiKTtcbiAgfVxuICBpZiAoaXNGdW5jdGlvbihlbmNvZGluZykpIHtcbiAgICBjYWxsYmFjayA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIC8vIElnbm9yZSBlbXB0eSBidWZmZXJzLCBzaW5jZSB3cml0aW5nIHRoZW0gZG9lc24ndCBpbnZva2UgdGhlIGNhbGxiYWNrXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9pc3N1ZXMvMjIwNjZcbiAgaWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgICByZXR1cm47XG4gIH1cbiAgLy8gT25seSB3cml0ZSB3aGVuIHdlIGRvbid0IGV4Y2VlZCB0aGUgbWF4aW11bSBib2R5IGxlbmd0aFxuICBpZiAodGhpcy5fcmVxdWVzdEJvZHlMZW5ndGggKyBkYXRhLmxlbmd0aCA8PSB0aGlzLl9vcHRpb25zLm1heEJvZHlMZW5ndGgpIHtcbiAgICB0aGlzLl9yZXF1ZXN0Qm9keUxlbmd0aCArPSBkYXRhLmxlbmd0aDtcbiAgICB0aGlzLl9yZXF1ZXN0Qm9keUJ1ZmZlcnMucHVzaCh7IGRhdGE6IGRhdGEsIGVuY29kaW5nOiBlbmNvZGluZyB9KTtcbiAgICB0aGlzLl9jdXJyZW50UmVxdWVzdC53cml0ZShkYXRhLCBlbmNvZGluZywgY2FsbGJhY2spO1xuICB9XG4gIC8vIEVycm9yIHdoZW4gd2UgZXhjZWVkIHRoZSBtYXhpbXVtIGJvZHkgbGVuZ3RoXG4gIGVsc2Uge1xuICAgIHRoaXMuZW1pdChcImVycm9yXCIsIG5ldyBNYXhCb2R5TGVuZ3RoRXhjZWVkZWRFcnJvcigpKTtcbiAgICB0aGlzLmFib3J0KCk7XG4gIH1cbn07XG5cbi8vIEVuZHMgdGhlIGN1cnJlbnQgbmF0aXZlIHJlcXVlc3RcblJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIChkYXRhLCBlbmNvZGluZywgY2FsbGJhY2spIHtcbiAgLy8gU2hpZnQgcGFyYW1ldGVycyBpZiBuZWNlc3NhcnlcbiAgaWYgKGlzRnVuY3Rpb24oZGF0YSkpIHtcbiAgICBjYWxsYmFjayA9IGRhdGE7XG4gICAgZGF0YSA9IGVuY29kaW5nID0gbnVsbDtcbiAgfVxuICBlbHNlIGlmIChpc0Z1bmN0aW9uKGVuY29kaW5nKSkge1xuICAgIGNhbGxiYWNrID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgLy8gV3JpdGUgZGF0YSBpZiBuZWVkZWQgYW5kIGVuZFxuICBpZiAoIWRhdGEpIHtcbiAgICB0aGlzLl9lbmRlZCA9IHRoaXMuX2VuZGluZyA9IHRydWU7XG4gICAgdGhpcy5fY3VycmVudFJlcXVlc3QuZW5kKG51bGwsIG51bGwsIGNhbGxiYWNrKTtcbiAgfVxuICBlbHNlIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGN1cnJlbnRSZXF1ZXN0ID0gdGhpcy5fY3VycmVudFJlcXVlc3Q7XG4gICAgdGhpcy53cml0ZShkYXRhLCBlbmNvZGluZywgZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5fZW5kZWQgPSB0cnVlO1xuICAgICAgY3VycmVudFJlcXVlc3QuZW5kKG51bGwsIG51bGwsIGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgICB0aGlzLl9lbmRpbmcgPSB0cnVlO1xuICB9XG59O1xuXG4vLyBTZXRzIGEgaGVhZGVyIHZhbHVlIG9uIHRoZSBjdXJyZW50IG5hdGl2ZSByZXF1ZXN0XG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5zZXRIZWFkZXIgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgdGhpcy5fb3B0aW9ucy5oZWFkZXJzW25hbWVdID0gdmFsdWU7XG4gIHRoaXMuX2N1cnJlbnRSZXF1ZXN0LnNldEhlYWRlcihuYW1lLCB2YWx1ZSk7XG59O1xuXG4vLyBDbGVhcnMgYSBoZWFkZXIgdmFsdWUgb24gdGhlIGN1cnJlbnQgbmF0aXZlIHJlcXVlc3RcblJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlLnJlbW92ZUhlYWRlciA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlbGV0ZSB0aGlzLl9vcHRpb25zLmhlYWRlcnNbbmFtZV07XG4gIHRoaXMuX2N1cnJlbnRSZXF1ZXN0LnJlbW92ZUhlYWRlcihuYW1lKTtcbn07XG5cbi8vIEdsb2JhbCB0aW1lb3V0IGZvciBhbGwgdW5kZXJseWluZyByZXF1ZXN0c1xuUmVkaXJlY3RhYmxlUmVxdWVzdC5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uIChtc2VjcywgY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIERlc3Ryb3lzIHRoZSBzb2NrZXQgb24gdGltZW91dFxuICBmdW5jdGlvbiBkZXN0cm95T25UaW1lb3V0KHNvY2tldCkge1xuICAgIHNvY2tldC5zZXRUaW1lb3V0KG1zZWNzKTtcbiAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoXCJ0aW1lb3V0XCIsIHNvY2tldC5kZXN0cm95KTtcbiAgICBzb2NrZXQuYWRkTGlzdGVuZXIoXCJ0aW1lb3V0XCIsIHNvY2tldC5kZXN0cm95KTtcbiAgfVxuXG4gIC8vIFNldHMgdXAgYSB0aW1lciB0byB0cmlnZ2VyIGEgdGltZW91dCBldmVudFxuICBmdW5jdGlvbiBzdGFydFRpbWVyKHNvY2tldCkge1xuICAgIGlmIChzZWxmLl90aW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQoc2VsZi5fdGltZW91dCk7XG4gICAgfVxuICAgIHNlbGYuX3RpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYuZW1pdChcInRpbWVvdXRcIik7XG4gICAgICBjbGVhclRpbWVyKCk7XG4gICAgfSwgbXNlY3MpO1xuICAgIGRlc3Ryb3lPblRpbWVvdXQoc29ja2V0KTtcbiAgfVxuXG4gIC8vIFN0b3BzIGEgdGltZW91dCBmcm9tIHRyaWdnZXJpbmdcbiAgZnVuY3Rpb24gY2xlYXJUaW1lcigpIHtcbiAgICAvLyBDbGVhciB0aGUgdGltZW91dFxuICAgIGlmIChzZWxmLl90aW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQoc2VsZi5fdGltZW91dCk7XG4gICAgICBzZWxmLl90aW1lb3V0ID0gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBDbGVhbiB1cCBhbGwgYXR0YWNoZWQgbGlzdGVuZXJzXG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcihcImFib3J0XCIsIGNsZWFyVGltZXIpO1xuICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoXCJlcnJvclwiLCBjbGVhclRpbWVyKTtcbiAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKFwicmVzcG9uc2VcIiwgY2xlYXJUaW1lcik7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcihcImNsb3NlXCIsIGNsZWFyVGltZXIpO1xuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgc2VsZi5yZW1vdmVMaXN0ZW5lcihcInRpbWVvdXRcIiwgY2FsbGJhY2spO1xuICAgIH1cbiAgICBpZiAoIXNlbGYuc29ja2V0KSB7XG4gICAgICBzZWxmLl9jdXJyZW50UmVxdWVzdC5yZW1vdmVMaXN0ZW5lcihcInNvY2tldFwiLCBzdGFydFRpbWVyKTtcbiAgICB9XG4gIH1cblxuICAvLyBBdHRhY2ggY2FsbGJhY2sgaWYgcGFzc2VkXG4gIGlmIChjYWxsYmFjaykge1xuICAgIHRoaXMub24oXCJ0aW1lb3V0XCIsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vIFN0YXJ0IHRoZSB0aW1lciBpZiBvciB3aGVuIHRoZSBzb2NrZXQgaXMgb3BlbmVkXG4gIGlmICh0aGlzLnNvY2tldCkge1xuICAgIHN0YXJ0VGltZXIodGhpcy5zb2NrZXQpO1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMuX2N1cnJlbnRSZXF1ZXN0Lm9uY2UoXCJzb2NrZXRcIiwgc3RhcnRUaW1lcik7XG4gIH1cblxuICAvLyBDbGVhbiB1cCBvbiBldmVudHNcbiAgdGhpcy5vbihcInNvY2tldFwiLCBkZXN0cm95T25UaW1lb3V0KTtcbiAgdGhpcy5vbihcImFib3J0XCIsIGNsZWFyVGltZXIpO1xuICB0aGlzLm9uKFwiZXJyb3JcIiwgY2xlYXJUaW1lcik7XG4gIHRoaXMub24oXCJyZXNwb25zZVwiLCBjbGVhclRpbWVyKTtcbiAgdGhpcy5vbihcImNsb3NlXCIsIGNsZWFyVGltZXIpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gUHJveHkgYWxsIG90aGVyIHB1YmxpYyBDbGllbnRSZXF1ZXN0IG1ldGhvZHNcbltcbiAgXCJmbHVzaEhlYWRlcnNcIiwgXCJnZXRIZWFkZXJcIixcbiAgXCJzZXROb0RlbGF5XCIsIFwic2V0U29ja2V0S2VlcEFsaXZlXCIsXG5dLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xuICBSZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFJlcXVlc3RbbWV0aG9kXShhLCBiKTtcbiAgfTtcbn0pO1xuXG4vLyBQcm94eSBhbGwgcHVibGljIENsaWVudFJlcXVlc3QgcHJvcGVydGllc1xuW1wiYWJvcnRlZFwiLCBcImNvbm5lY3Rpb25cIiwgXCJzb2NrZXRcIl0uZm9yRWFjaChmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlZGlyZWN0YWJsZVJlcXVlc3QucHJvdG90eXBlLCBwcm9wZXJ0eSwge1xuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fY3VycmVudFJlcXVlc3RbcHJvcGVydHldOyB9LFxuICB9KTtcbn0pO1xuXG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5fc2FuaXRpemVPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgLy8gRW5zdXJlIGhlYWRlcnMgYXJlIGFsd2F5cyBwcmVzZW50XG4gIGlmICghb3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgb3B0aW9ucy5oZWFkZXJzID0ge307XG4gIH1cblxuICAvLyBTaW5jZSBodHRwLnJlcXVlc3QgdHJlYXRzIGhvc3QgYXMgYW4gYWxpYXMgb2YgaG9zdG5hbWUsXG4gIC8vIGJ1dCB0aGUgdXJsIG1vZHVsZSBpbnRlcnByZXRzIGhvc3QgYXMgaG9zdG5hbWUgcGx1cyBwb3J0LFxuICAvLyBlbGltaW5hdGUgdGhlIGhvc3QgcHJvcGVydHkgdG8gYXZvaWQgY29uZnVzaW9uLlxuICBpZiAob3B0aW9ucy5ob3N0KSB7XG4gICAgLy8gVXNlIGhvc3RuYW1lIGlmIHNldCwgYmVjYXVzZSBpdCBoYXMgcHJlY2VkZW5jZVxuICAgIGlmICghb3B0aW9ucy5ob3N0bmFtZSkge1xuICAgICAgb3B0aW9ucy5ob3N0bmFtZSA9IG9wdGlvbnMuaG9zdDtcbiAgICB9XG4gICAgZGVsZXRlIG9wdGlvbnMuaG9zdDtcbiAgfVxuXG4gIC8vIENvbXBsZXRlIHRoZSBVUkwgb2JqZWN0IHdoZW4gbmVjZXNzYXJ5XG4gIGlmICghb3B0aW9ucy5wYXRobmFtZSAmJiBvcHRpb25zLnBhdGgpIHtcbiAgICB2YXIgc2VhcmNoUG9zID0gb3B0aW9ucy5wYXRoLmluZGV4T2YoXCI/XCIpO1xuICAgIGlmIChzZWFyY2hQb3MgPCAwKSB7XG4gICAgICBvcHRpb25zLnBhdGhuYW1lID0gb3B0aW9ucy5wYXRoO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIG9wdGlvbnMucGF0aG5hbWUgPSBvcHRpb25zLnBhdGguc3Vic3RyaW5nKDAsIHNlYXJjaFBvcyk7XG4gICAgICBvcHRpb25zLnNlYXJjaCA9IG9wdGlvbnMucGF0aC5zdWJzdHJpbmcoc2VhcmNoUG9zKTtcbiAgICB9XG4gIH1cbn07XG5cblxuLy8gRXhlY3V0ZXMgdGhlIG5leHQgbmF0aXZlIHJlcXVlc3QgKGluaXRpYWwgb3IgcmVkaXJlY3QpXG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5fcGVyZm9ybVJlcXVlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIExvYWQgdGhlIG5hdGl2ZSBwcm90b2NvbFxuICB2YXIgcHJvdG9jb2wgPSB0aGlzLl9vcHRpb25zLnByb3RvY29sO1xuICB2YXIgbmF0aXZlUHJvdG9jb2wgPSB0aGlzLl9vcHRpb25zLm5hdGl2ZVByb3RvY29sc1twcm90b2NvbF07XG4gIGlmICghbmF0aXZlUHJvdG9jb2wpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5zdXBwb3J0ZWQgcHJvdG9jb2wgXCIgKyBwcm90b2NvbCk7XG4gIH1cblxuICAvLyBJZiBzcGVjaWZpZWQsIHVzZSB0aGUgYWdlbnQgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvdG9jb2xcbiAgLy8gKEhUVFAgYW5kIEhUVFBTIHVzZSBkaWZmZXJlbnQgdHlwZXMgb2YgYWdlbnRzKVxuICBpZiAodGhpcy5fb3B0aW9ucy5hZ2VudHMpIHtcbiAgICB2YXIgc2NoZW1lID0gcHJvdG9jb2wuc2xpY2UoMCwgLTEpO1xuICAgIHRoaXMuX29wdGlvbnMuYWdlbnQgPSB0aGlzLl9vcHRpb25zLmFnZW50c1tzY2hlbWVdO1xuICB9XG5cbiAgLy8gQ3JlYXRlIHRoZSBuYXRpdmUgcmVxdWVzdCBhbmQgc2V0IHVwIGl0cyBldmVudCBoYW5kbGVyc1xuICB2YXIgcmVxdWVzdCA9IHRoaXMuX2N1cnJlbnRSZXF1ZXN0ID1cbiAgICAgICAgbmF0aXZlUHJvdG9jb2wucmVxdWVzdCh0aGlzLl9vcHRpb25zLCB0aGlzLl9vbk5hdGl2ZVJlc3BvbnNlKTtcbiAgcmVxdWVzdC5fcmVkaXJlY3RhYmxlID0gdGhpcztcbiAgZm9yICh2YXIgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgcmVxdWVzdC5vbihldmVudCwgZXZlbnRIYW5kbGVyc1tldmVudF0pO1xuICB9XG5cbiAgLy8gUkZDNzIzMMKnNS4zLjE6IFdoZW4gbWFraW5nIGEgcmVxdWVzdCBkaXJlY3RseSB0byBhbiBvcmlnaW4gc2VydmVyLCBb4oCmXVxuICAvLyBhIGNsaWVudCBNVVNUIHNlbmQgb25seSB0aGUgYWJzb2x1dGUgcGF0aCBb4oCmXSBhcyB0aGUgcmVxdWVzdC10YXJnZXQuXG4gIHRoaXMuX2N1cnJlbnRVcmwgPSAvXlxcLy8udGVzdCh0aGlzLl9vcHRpb25zLnBhdGgpID9cbiAgICB1cmwuZm9ybWF0KHRoaXMuX29wdGlvbnMpIDpcbiAgICAvLyBXaGVuIG1ha2luZyBhIHJlcXVlc3QgdG8gYSBwcm94eSwgW+KApl1cbiAgICAvLyBhIGNsaWVudCBNVVNUIHNlbmQgdGhlIHRhcmdldCBVUkkgaW4gYWJzb2x1dGUtZm9ybSBb4oCmXS5cbiAgICB0aGlzLl9vcHRpb25zLnBhdGg7XG5cbiAgLy8gRW5kIGEgcmVkaXJlY3RlZCByZXF1ZXN0XG4gIC8vIChUaGUgZmlyc3QgcmVxdWVzdCBtdXN0IGJlIGVuZGVkIGV4cGxpY2l0bHkgd2l0aCBSZWRpcmVjdGFibGVSZXF1ZXN0I2VuZClcbiAgaWYgKHRoaXMuX2lzUmVkaXJlY3QpIHtcbiAgICAvLyBXcml0ZSB0aGUgcmVxdWVzdCBlbnRpdHkgYW5kIGVuZFxuICAgIHZhciBpID0gMDtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGJ1ZmZlcnMgPSB0aGlzLl9yZXF1ZXN0Qm9keUJ1ZmZlcnM7XG4gICAgKGZ1bmN0aW9uIHdyaXRlTmV4dChlcnJvcikge1xuICAgICAgLy8gT25seSB3cml0ZSBpZiB0aGlzIHJlcXVlc3QgaGFzIG5vdCBiZWVuIHJlZGlyZWN0ZWQgeWV0XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKHJlcXVlc3QgPT09IHNlbGYuX2N1cnJlbnRSZXF1ZXN0KSB7XG4gICAgICAgIC8vIFJlcG9ydCBhbnkgd3JpdGUgZXJyb3JzXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gV3JpdGUgdGhlIG5leHQgYnVmZmVyIGlmIHRoZXJlIGFyZSBzdGlsbCBsZWZ0XG4gICAgICAgIGVsc2UgaWYgKGkgPCBidWZmZXJzLmxlbmd0aCkge1xuICAgICAgICAgIHZhciBidWZmZXIgPSBidWZmZXJzW2krK107XG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgICBpZiAoIXJlcXVlc3QuZmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJlcXVlc3Qud3JpdGUoYnVmZmVyLmRhdGEsIGJ1ZmZlci5lbmNvZGluZywgd3JpdGVOZXh0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gRW5kIHRoZSByZXF1ZXN0IGlmIGBlbmRgIGhhcyBiZWVuIGNhbGxlZCBvbiB1c1xuICAgICAgICBlbHNlIGlmIChzZWxmLl9lbmRlZCkge1xuICAgICAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KCkpO1xuICB9XG59O1xuXG4vLyBQcm9jZXNzZXMgYSByZXNwb25zZSBmcm9tIHRoZSBjdXJyZW50IG5hdGl2ZSByZXF1ZXN0XG5SZWRpcmVjdGFibGVSZXF1ZXN0LnByb3RvdHlwZS5fcHJvY2Vzc1Jlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIC8vIFN0b3JlIHRoZSByZWRpcmVjdGVkIHJlc3BvbnNlXG4gIHZhciBzdGF0dXNDb2RlID0gcmVzcG9uc2Uuc3RhdHVzQ29kZTtcbiAgaWYgKHRoaXMuX29wdGlvbnMudHJhY2tSZWRpcmVjdHMpIHtcbiAgICB0aGlzLl9yZWRpcmVjdHMucHVzaCh7XG4gICAgICB1cmw6IHRoaXMuX2N1cnJlbnRVcmwsXG4gICAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgc3RhdHVzQ29kZTogc3RhdHVzQ29kZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJGQzcyMzHCpzYuNDogVGhlIDN4eCAoUmVkaXJlY3Rpb24pIGNsYXNzIG9mIHN0YXR1cyBjb2RlIGluZGljYXRlc1xuICAvLyB0aGF0IGZ1cnRoZXIgYWN0aW9uIG5lZWRzIHRvIGJlIHRha2VuIGJ5IHRoZSB1c2VyIGFnZW50IGluIG9yZGVyIHRvXG4gIC8vIGZ1bGZpbGwgdGhlIHJlcXVlc3QuIElmIGEgTG9jYXRpb24gaGVhZGVyIGZpZWxkIGlzIHByb3ZpZGVkLFxuICAvLyB0aGUgdXNlciBhZ2VudCBNQVkgYXV0b21hdGljYWxseSByZWRpcmVjdCBpdHMgcmVxdWVzdCB0byB0aGUgVVJJXG4gIC8vIHJlZmVyZW5jZWQgYnkgdGhlIExvY2F0aW9uIGZpZWxkIHZhbHVlLFxuICAvLyBldmVuIGlmIHRoZSBzcGVjaWZpYyBzdGF0dXMgY29kZSBpcyBub3QgdW5kZXJzdG9vZC5cblxuICAvLyBJZiB0aGUgcmVzcG9uc2UgaXMgbm90IGEgcmVkaXJlY3Q7IHJldHVybiBpdCBhcy1pc1xuICB2YXIgbG9jYXRpb24gPSByZXNwb25zZS5oZWFkZXJzLmxvY2F0aW9uO1xuICBpZiAoIWxvY2F0aW9uIHx8IHRoaXMuX29wdGlvbnMuZm9sbG93UmVkaXJlY3RzID09PSBmYWxzZSB8fFxuICAgICAgc3RhdHVzQ29kZSA8IDMwMCB8fCBzdGF0dXNDb2RlID49IDQwMCkge1xuICAgIHJlc3BvbnNlLnJlc3BvbnNlVXJsID0gdGhpcy5fY3VycmVudFVybDtcbiAgICByZXNwb25zZS5yZWRpcmVjdHMgPSB0aGlzLl9yZWRpcmVjdHM7XG4gICAgdGhpcy5lbWl0KFwicmVzcG9uc2VcIiwgcmVzcG9uc2UpO1xuXG4gICAgLy8gQ2xlYW4gdXBcbiAgICB0aGlzLl9yZXF1ZXN0Qm9keUJ1ZmZlcnMgPSBbXTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUaGUgcmVzcG9uc2UgaXMgYSByZWRpcmVjdCwgc28gYWJvcnQgdGhlIGN1cnJlbnQgcmVxdWVzdFxuICBkZXN0cm95UmVxdWVzdCh0aGlzLl9jdXJyZW50UmVxdWVzdCk7XG4gIC8vIERpc2NhcmQgdGhlIHJlbWFpbmRlciBvZiB0aGUgcmVzcG9uc2UgdG8gYXZvaWQgd2FpdGluZyBmb3IgZGF0YVxuICByZXNwb25zZS5kZXN0cm95KCk7XG5cbiAgLy8gUkZDNzIzMcKnNi40OiBBIGNsaWVudCBTSE9VTEQgZGV0ZWN0IGFuZCBpbnRlcnZlbmVcbiAgLy8gaW4gY3ljbGljYWwgcmVkaXJlY3Rpb25zIChpLmUuLCBcImluZmluaXRlXCIgcmVkaXJlY3Rpb24gbG9vcHMpLlxuICBpZiAoKyt0aGlzLl9yZWRpcmVjdENvdW50ID4gdGhpcy5fb3B0aW9ucy5tYXhSZWRpcmVjdHMpIHtcbiAgICB0aHJvdyBuZXcgVG9vTWFueVJlZGlyZWN0c0Vycm9yKCk7XG4gIH1cblxuICAvLyBTdG9yZSB0aGUgcmVxdWVzdCBoZWFkZXJzIGlmIGFwcGxpY2FibGVcbiAgdmFyIHJlcXVlc3RIZWFkZXJzO1xuICB2YXIgYmVmb3JlUmVkaXJlY3QgPSB0aGlzLl9vcHRpb25zLmJlZm9yZVJlZGlyZWN0O1xuICBpZiAoYmVmb3JlUmVkaXJlY3QpIHtcbiAgICByZXF1ZXN0SGVhZGVycyA9IE9iamVjdC5hc3NpZ24oe1xuICAgICAgLy8gVGhlIEhvc3QgaGVhZGVyIHdhcyBzZXQgYnkgbmF0aXZlUHJvdG9jb2wucmVxdWVzdFxuICAgICAgSG9zdDogcmVzcG9uc2UucmVxLmdldEhlYWRlcihcImhvc3RcIiksXG4gICAgfSwgdGhpcy5fb3B0aW9ucy5oZWFkZXJzKTtcbiAgfVxuXG4gIC8vIFJGQzcyMzHCpzYuNDogQXV0b21hdGljIHJlZGlyZWN0aW9uIG5lZWRzIHRvIGRvbmUgd2l0aFxuICAvLyBjYXJlIGZvciBtZXRob2RzIG5vdCBrbm93biB0byBiZSBzYWZlLCBb4oCmXVxuICAvLyBSRkM3MjMxwqc2LjQuMuKAkzM6IEZvciBoaXN0b3JpY2FsIHJlYXNvbnMsIGEgdXNlciBhZ2VudCBNQVkgY2hhbmdlXG4gIC8vIHRoZSByZXF1ZXN0IG1ldGhvZCBmcm9tIFBPU1QgdG8gR0VUIGZvciB0aGUgc3Vic2VxdWVudCByZXF1ZXN0LlxuICB2YXIgbWV0aG9kID0gdGhpcy5fb3B0aW9ucy5tZXRob2Q7XG4gIGlmICgoc3RhdHVzQ29kZSA9PT0gMzAxIHx8IHN0YXR1c0NvZGUgPT09IDMwMikgJiYgdGhpcy5fb3B0aW9ucy5tZXRob2QgPT09IFwiUE9TVFwiIHx8XG4gICAgICAvLyBSRkM3MjMxwqc2LjQuNDogVGhlIDMwMyAoU2VlIE90aGVyKSBzdGF0dXMgY29kZSBpbmRpY2F0ZXMgdGhhdFxuICAgICAgLy8gdGhlIHNlcnZlciBpcyByZWRpcmVjdGluZyB0aGUgdXNlciBhZ2VudCB0byBhIGRpZmZlcmVudCByZXNvdXJjZSBb4oCmXVxuICAgICAgLy8gQSB1c2VyIGFnZW50IGNhbiBwZXJmb3JtIGEgcmV0cmlldmFsIHJlcXVlc3QgdGFyZ2V0aW5nIHRoYXQgVVJJXG4gICAgICAvLyAoYSBHRVQgb3IgSEVBRCByZXF1ZXN0IGlmIHVzaW5nIEhUVFApIFvigKZdXG4gICAgICAoc3RhdHVzQ29kZSA9PT0gMzAzKSAmJiAhL14oPzpHRVR8SEVBRCkkLy50ZXN0KHRoaXMuX29wdGlvbnMubWV0aG9kKSkge1xuICAgIHRoaXMuX29wdGlvbnMubWV0aG9kID0gXCJHRVRcIjtcbiAgICAvLyBEcm9wIGEgcG9zc2libGUgZW50aXR5IGFuZCBoZWFkZXJzIHJlbGF0ZWQgdG8gaXRcbiAgICB0aGlzLl9yZXF1ZXN0Qm9keUJ1ZmZlcnMgPSBbXTtcbiAgICByZW1vdmVNYXRjaGluZ0hlYWRlcnMoL15jb250ZW50LS9pLCB0aGlzLl9vcHRpb25zLmhlYWRlcnMpO1xuICB9XG5cbiAgLy8gRHJvcCB0aGUgSG9zdCBoZWFkZXIsIGFzIHRoZSByZWRpcmVjdCBtaWdodCBsZWFkIHRvIGEgZGlmZmVyZW50IGhvc3RcbiAgdmFyIGN1cnJlbnRIb3N0SGVhZGVyID0gcmVtb3ZlTWF0Y2hpbmdIZWFkZXJzKC9eaG9zdCQvaSwgdGhpcy5fb3B0aW9ucy5oZWFkZXJzKTtcblxuICAvLyBJZiB0aGUgcmVkaXJlY3QgaXMgcmVsYXRpdmUsIGNhcnJ5IG92ZXIgdGhlIGhvc3Qgb2YgdGhlIGxhc3QgcmVxdWVzdFxuICB2YXIgY3VycmVudFVybFBhcnRzID0gcGFyc2VVcmwodGhpcy5fY3VycmVudFVybCk7XG4gIHZhciBjdXJyZW50SG9zdCA9IGN1cnJlbnRIb3N0SGVhZGVyIHx8IGN1cnJlbnRVcmxQYXJ0cy5ob3N0O1xuICB2YXIgY3VycmVudFVybCA9IC9eXFx3KzovLnRlc3QobG9jYXRpb24pID8gdGhpcy5fY3VycmVudFVybCA6XG4gICAgdXJsLmZvcm1hdChPYmplY3QuYXNzaWduKGN1cnJlbnRVcmxQYXJ0cywgeyBob3N0OiBjdXJyZW50SG9zdCB9KSk7XG5cbiAgLy8gQ3JlYXRlIHRoZSByZWRpcmVjdGVkIHJlcXVlc3RcbiAgdmFyIHJlZGlyZWN0VXJsID0gcmVzb2x2ZVVybChsb2NhdGlvbiwgY3VycmVudFVybCk7XG4gIGRlYnVnKFwicmVkaXJlY3RpbmcgdG9cIiwgcmVkaXJlY3RVcmwuaHJlZik7XG4gIHRoaXMuX2lzUmVkaXJlY3QgPSB0cnVlO1xuICBzcHJlYWRVcmxPYmplY3QocmVkaXJlY3RVcmwsIHRoaXMuX29wdGlvbnMpO1xuXG4gIC8vIERyb3AgY29uZmlkZW50aWFsIGhlYWRlcnMgd2hlbiByZWRpcmVjdGluZyB0byBhIGxlc3Mgc2VjdXJlIHByb3RvY29sXG4gIC8vIG9yIHRvIGEgZGlmZmVyZW50IGRvbWFpbiB0aGF0IGlzIG5vdCBhIHN1cGVyZG9tYWluXG4gIGlmIChyZWRpcmVjdFVybC5wcm90b2NvbCAhPT0gY3VycmVudFVybFBhcnRzLnByb3RvY29sICYmXG4gICAgIHJlZGlyZWN0VXJsLnByb3RvY29sICE9PSBcImh0dHBzOlwiIHx8XG4gICAgIHJlZGlyZWN0VXJsLmhvc3QgIT09IGN1cnJlbnRIb3N0ICYmXG4gICAgICFpc1N1YmRvbWFpbihyZWRpcmVjdFVybC5ob3N0LCBjdXJyZW50SG9zdCkpIHtcbiAgICByZW1vdmVNYXRjaGluZ0hlYWRlcnMoL14oPzphdXRob3JpemF0aW9ufGNvb2tpZSkkL2ksIHRoaXMuX29wdGlvbnMuaGVhZGVycyk7XG4gIH1cblxuICAvLyBFdmFsdWF0ZSB0aGUgYmVmb3JlUmVkaXJlY3QgY2FsbGJhY2tcbiAgaWYgKGlzRnVuY3Rpb24oYmVmb3JlUmVkaXJlY3QpKSB7XG4gICAgdmFyIHJlc3BvbnNlRGV0YWlscyA9IHtcbiAgICAgIGhlYWRlcnM6IHJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICBzdGF0dXNDb2RlOiBzdGF0dXNDb2RlLFxuICAgIH07XG4gICAgdmFyIHJlcXVlc3REZXRhaWxzID0ge1xuICAgICAgdXJsOiBjdXJyZW50VXJsLFxuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBoZWFkZXJzOiByZXF1ZXN0SGVhZGVycyxcbiAgICB9O1xuICAgIGJlZm9yZVJlZGlyZWN0KHRoaXMuX29wdGlvbnMsIHJlc3BvbnNlRGV0YWlscywgcmVxdWVzdERldGFpbHMpO1xuICAgIHRoaXMuX3Nhbml0aXplT3B0aW9ucyh0aGlzLl9vcHRpb25zKTtcbiAgfVxuXG4gIC8vIFBlcmZvcm0gdGhlIHJlZGlyZWN0ZWQgcmVxdWVzdFxuICB0aGlzLl9wZXJmb3JtUmVxdWVzdCgpO1xufTtcblxuLy8gV3JhcHMgdGhlIGtleS92YWx1ZSBvYmplY3Qgb2YgcHJvdG9jb2xzIHdpdGggcmVkaXJlY3QgZnVuY3Rpb25hbGl0eVxuZnVuY3Rpb24gd3JhcChwcm90b2NvbHMpIHtcbiAgLy8gRGVmYXVsdCBzZXR0aW5nc1xuICB2YXIgZXhwb3J0cyA9IHtcbiAgICBtYXhSZWRpcmVjdHM6IDIxLFxuICAgIG1heEJvZHlMZW5ndGg6IDEwICogMTAyNCAqIDEwMjQsXG4gIH07XG5cbiAgLy8gV3JhcCBlYWNoIHByb3RvY29sXG4gIHZhciBuYXRpdmVQcm90b2NvbHMgPSB7fTtcbiAgT2JqZWN0LmtleXMocHJvdG9jb2xzKS5mb3JFYWNoKGZ1bmN0aW9uIChzY2hlbWUpIHtcbiAgICB2YXIgcHJvdG9jb2wgPSBzY2hlbWUgKyBcIjpcIjtcbiAgICB2YXIgbmF0aXZlUHJvdG9jb2wgPSBuYXRpdmVQcm90b2NvbHNbcHJvdG9jb2xdID0gcHJvdG9jb2xzW3NjaGVtZV07XG4gICAgdmFyIHdyYXBwZWRQcm90b2NvbCA9IGV4cG9ydHNbc2NoZW1lXSA9IE9iamVjdC5jcmVhdGUobmF0aXZlUHJvdG9jb2wpO1xuXG4gICAgLy8gRXhlY3V0ZXMgYSByZXF1ZXN0LCBmb2xsb3dpbmcgcmVkaXJlY3RzXG4gICAgZnVuY3Rpb24gcmVxdWVzdChpbnB1dCwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICAgIC8vIFBhcnNlIHBhcmFtZXRlcnMsIGVuc3VyaW5nIHRoYXQgaW5wdXQgaXMgYW4gb2JqZWN0XG4gICAgICBpZiAoaXNVUkwoaW5wdXQpKSB7XG4gICAgICAgIGlucHV0ID0gc3ByZWFkVXJsT2JqZWN0KGlucHV0KTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKGlucHV0KSkge1xuICAgICAgICBpbnB1dCA9IHNwcmVhZFVybE9iamVjdChwYXJzZVVybChpbnB1dCkpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrID0gb3B0aW9ucztcbiAgICAgICAgb3B0aW9ucyA9IHZhbGlkYXRlVXJsKGlucHV0KTtcbiAgICAgICAgaW5wdXQgPSB7IHByb3RvY29sOiBwcm90b2NvbCB9O1xuICAgICAgfVxuICAgICAgaWYgKGlzRnVuY3Rpb24ob3B0aW9ucykpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBvcHRpb25zO1xuICAgICAgICBvcHRpb25zID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgLy8gU2V0IGRlZmF1bHRzXG4gICAgICBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7XG4gICAgICAgIG1heFJlZGlyZWN0czogZXhwb3J0cy5tYXhSZWRpcmVjdHMsXG4gICAgICAgIG1heEJvZHlMZW5ndGg6IGV4cG9ydHMubWF4Qm9keUxlbmd0aCxcbiAgICAgIH0sIGlucHV0LCBvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMubmF0aXZlUHJvdG9jb2xzID0gbmF0aXZlUHJvdG9jb2xzO1xuICAgICAgaWYgKCFpc1N0cmluZyhvcHRpb25zLmhvc3QpICYmICFpc1N0cmluZyhvcHRpb25zLmhvc3RuYW1lKSkge1xuICAgICAgICBvcHRpb25zLmhvc3RuYW1lID0gXCI6OjFcIjtcbiAgICAgIH1cblxuICAgICAgYXNzZXJ0LmVxdWFsKG9wdGlvbnMucHJvdG9jb2wsIHByb3RvY29sLCBcInByb3RvY29sIG1pc21hdGNoXCIpO1xuICAgICAgZGVidWcoXCJvcHRpb25zXCIsIG9wdGlvbnMpO1xuICAgICAgcmV0dXJuIG5ldyBSZWRpcmVjdGFibGVSZXF1ZXN0KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICAvLyBFeGVjdXRlcyBhIEdFVCByZXF1ZXN0LCBmb2xsb3dpbmcgcmVkaXJlY3RzXG4gICAgZnVuY3Rpb24gZ2V0KGlucHV0LCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgdmFyIHdyYXBwZWRSZXF1ZXN0ID0gd3JhcHBlZFByb3RvY29sLnJlcXVlc3QoaW5wdXQsIG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgIHdyYXBwZWRSZXF1ZXN0LmVuZCgpO1xuICAgICAgcmV0dXJuIHdyYXBwZWRSZXF1ZXN0O1xuICAgIH1cblxuICAgIC8vIEV4cG9zZSB0aGUgcHJvcGVydGllcyBvbiB0aGUgd3JhcHBlZCBwcm90b2NvbFxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdyYXBwZWRQcm90b2NvbCwge1xuICAgICAgcmVxdWVzdDogeyB2YWx1ZTogcmVxdWVzdCwgY29uZmlndXJhYmxlOiB0cnVlLCBlbnVtZXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSB9LFxuICAgICAgZ2V0OiB7IHZhbHVlOiBnZXQsIGNvbmZpZ3VyYWJsZTogdHJ1ZSwgZW51bWVyYWJsZTogdHJ1ZSwgd3JpdGFibGU6IHRydWUgfSxcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBleHBvcnRzO1xufVxuXG5mdW5jdGlvbiBub29wKCkgeyAvKiBlbXB0eSAqLyB9XG5cbmZ1bmN0aW9uIHBhcnNlVXJsKGlucHV0KSB7XG4gIHZhciBwYXJzZWQ7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmICh1c2VOYXRpdmVVUkwpIHtcbiAgICBwYXJzZWQgPSBuZXcgVVJMKGlucHV0KTtcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBFbnN1cmUgdGhlIFVSTCBpcyB2YWxpZCBhbmQgYWJzb2x1dGVcbiAgICBwYXJzZWQgPSB2YWxpZGF0ZVVybCh1cmwucGFyc2UoaW5wdXQpKTtcbiAgICBpZiAoIWlzU3RyaW5nKHBhcnNlZC5wcm90b2NvbCkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVXJsRXJyb3IoeyBpbnB1dCB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZVVybChyZWxhdGl2ZSwgYmFzZSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICByZXR1cm4gdXNlTmF0aXZlVVJMID8gbmV3IFVSTChyZWxhdGl2ZSwgYmFzZSkgOiBwYXJzZVVybCh1cmwucmVzb2x2ZShiYXNlLCByZWxhdGl2ZSkpO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVVybChpbnB1dCkge1xuICBpZiAoL15cXFsvLnRlc3QoaW5wdXQuaG9zdG5hbWUpICYmICEvXlxcW1s6MC05YS1mXStcXF0kL2kudGVzdChpbnB1dC5ob3N0bmFtZSkpIHtcbiAgICB0aHJvdyBuZXcgSW52YWxpZFVybEVycm9yKHsgaW5wdXQ6IGlucHV0LmhyZWYgfHwgaW5wdXQgfSk7XG4gIH1cbiAgaWYgKC9eXFxbLy50ZXN0KGlucHV0Lmhvc3QpICYmICEvXlxcW1s6MC05YS1mXStcXF0oOlxcZCspPyQvaS50ZXN0KGlucHV0Lmhvc3QpKSB7XG4gICAgdGhyb3cgbmV3IEludmFsaWRVcmxFcnJvcih7IGlucHV0OiBpbnB1dC5ocmVmIHx8IGlucHV0IH0pO1xuICB9XG4gIHJldHVybiBpbnB1dDtcbn1cblxuZnVuY3Rpb24gc3ByZWFkVXJsT2JqZWN0KHVybE9iamVjdCwgdGFyZ2V0KSB7XG4gIHZhciBzcHJlYWQgPSB0YXJnZXQgfHwge307XG4gIGZvciAodmFyIGtleSBvZiBwcmVzZXJ2ZWRVcmxGaWVsZHMpIHtcbiAgICBzcHJlYWRba2V5XSA9IHVybE9iamVjdFtrZXldO1xuICB9XG5cbiAgLy8gRml4IElQdjYgaG9zdG5hbWVcbiAgaWYgKHNwcmVhZC5ob3N0bmFtZS5zdGFydHNXaXRoKFwiW1wiKSkge1xuICAgIHNwcmVhZC5ob3N0bmFtZSA9IHNwcmVhZC5ob3N0bmFtZS5zbGljZSgxLCAtMSk7XG4gIH1cbiAgLy8gRW5zdXJlIHBvcnQgaXMgYSBudW1iZXJcbiAgaWYgKHNwcmVhZC5wb3J0ICE9PSBcIlwiKSB7XG4gICAgc3ByZWFkLnBvcnQgPSBOdW1iZXIoc3ByZWFkLnBvcnQpO1xuICB9XG4gIC8vIENvbmNhdGVuYXRlIHBhdGhcbiAgc3ByZWFkLnBhdGggPSBzcHJlYWQuc2VhcmNoID8gc3ByZWFkLnBhdGhuYW1lICsgc3ByZWFkLnNlYXJjaCA6IHNwcmVhZC5wYXRobmFtZTtcblxuICByZXR1cm4gc3ByZWFkO1xufVxuXG5mdW5jdGlvbiByZW1vdmVNYXRjaGluZ0hlYWRlcnMocmVnZXgsIGhlYWRlcnMpIHtcbiAgdmFyIGxhc3RWYWx1ZTtcbiAgZm9yICh2YXIgaGVhZGVyIGluIGhlYWRlcnMpIHtcbiAgICBpZiAocmVnZXgudGVzdChoZWFkZXIpKSB7XG4gICAgICBsYXN0VmFsdWUgPSBoZWFkZXJzW2hlYWRlcl07XG4gICAgICBkZWxldGUgaGVhZGVyc1toZWFkZXJdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gKGxhc3RWYWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgbGFzdFZhbHVlID09PSBcInVuZGVmaW5lZFwiKSA/XG4gICAgdW5kZWZpbmVkIDogU3RyaW5nKGxhc3RWYWx1ZSkudHJpbSgpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVFcnJvclR5cGUoY29kZSwgbWVzc2FnZSwgYmFzZUNsYXNzKSB7XG4gIC8vIENyZWF0ZSBjb25zdHJ1Y3RvclxuICBmdW5jdGlvbiBDdXN0b21FcnJvcihwcm9wZXJ0aWVzKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBwcm9wZXJ0aWVzIHx8IHt9KTtcbiAgICB0aGlzLmNvZGUgPSBjb2RlO1xuICAgIHRoaXMubWVzc2FnZSA9IHRoaXMuY2F1c2UgPyBtZXNzYWdlICsgXCI6IFwiICsgdGhpcy5jYXVzZS5tZXNzYWdlIDogbWVzc2FnZTtcbiAgfVxuXG4gIC8vIEF0dGFjaCBjb25zdHJ1Y3RvciBhbmQgc2V0IGRlZmF1bHQgcHJvcGVydGllc1xuICBDdXN0b21FcnJvci5wcm90b3R5cGUgPSBuZXcgKGJhc2VDbGFzcyB8fCBFcnJvcikoKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQ3VzdG9tRXJyb3IucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBDdXN0b21FcnJvcixcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIH0sXG4gICAgbmFtZToge1xuICAgICAgdmFsdWU6IFwiRXJyb3IgW1wiICsgY29kZSArIFwiXVwiLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgfSxcbiAgfSk7XG4gIHJldHVybiBDdXN0b21FcnJvcjtcbn1cblxuZnVuY3Rpb24gZGVzdHJveVJlcXVlc3QocmVxdWVzdCwgZXJyb3IpIHtcbiAgZm9yICh2YXIgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgcmVxdWVzdC5yZW1vdmVMaXN0ZW5lcihldmVudCwgZXZlbnRIYW5kbGVyc1tldmVudF0pO1xuICB9XG4gIHJlcXVlc3Qub24oXCJlcnJvclwiLCBub29wKTtcbiAgcmVxdWVzdC5kZXN0cm95KGVycm9yKTtcbn1cblxuZnVuY3Rpb24gaXNTdWJkb21haW4oc3ViZG9tYWluLCBkb21haW4pIHtcbiAgYXNzZXJ0KGlzU3RyaW5nKHN1YmRvbWFpbikgJiYgaXNTdHJpbmcoZG9tYWluKSk7XG4gIHZhciBkb3QgPSBzdWJkb21haW4ubGVuZ3RoIC0gZG9tYWluLmxlbmd0aCAtIDE7XG4gIHJldHVybiBkb3QgPiAwICYmIHN1YmRvbWFpbltkb3RdID09PSBcIi5cIiAmJiBzdWJkb21haW4uZW5kc1dpdGgoZG9tYWluKTtcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmcodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiB8fCB2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZztcbn1cblxuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbmZ1bmN0aW9uIGlzQnVmZmVyKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgKFwibGVuZ3RoXCIgaW4gdmFsdWUpO1xufVxuXG5mdW5jdGlvbiBpc1VSTCh2YWx1ZSkge1xuICByZXR1cm4gVVJMICYmIHZhbHVlIGluc3RhbmNlb2YgVVJMO1xufVxuXG4vLyBFeHBvcnRzXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXAoeyBodHRwOiBodHRwLCBodHRwczogaHR0cHMgfSk7XG5tb2R1bGUuZXhwb3J0cy53cmFwID0gd3JhcDtcbiIsIid1c2Ugc3RyaWN0Jztcbm1vZHVsZS5leHBvcnRzID0gKGZsYWcsIGFyZ3YpID0+IHtcblx0YXJndiA9IGFyZ3YgfHwgcHJvY2Vzcy5hcmd2O1xuXHRjb25zdCBwcmVmaXggPSBmbGFnLnN0YXJ0c1dpdGgoJy0nKSA/ICcnIDogKGZsYWcubGVuZ3RoID09PSAxID8gJy0nIDogJy0tJyk7XG5cdGNvbnN0IHBvcyA9IGFyZ3YuaW5kZXhPZihwcmVmaXggKyBmbGFnKTtcblx0Y29uc3QgdGVybWluYXRvclBvcyA9IGFyZ3YuaW5kZXhPZignLS0nKTtcblx0cmV0dXJuIHBvcyAhPT0gLTEgJiYgKHRlcm1pbmF0b3JQb3MgPT09IC0xID8gdHJ1ZSA6IHBvcyA8IHRlcm1pbmF0b3JQb3MpO1xufTtcbiIsIi8qIVxuICogbWltZS1kYlxuICogQ29weXJpZ2h0KGMpIDIwMTQgSm9uYXRoYW4gT25nXG4gKiBDb3B5cmlnaHQoYykgMjAxNS0yMDIyIERvdWdsYXMgQ2hyaXN0b3BoZXIgV2lsc29uXG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9kYi5qc29uJylcbiIsIi8qIVxuICogbWltZS10eXBlc1xuICogQ29weXJpZ2h0KGMpIDIwMTQgSm9uYXRoYW4gT25nXG4gKiBDb3B5cmlnaHQoYykgMjAxNSBEb3VnbGFzIENocmlzdG9waGVyIFdpbHNvblxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuJ3VzZSBzdHJpY3QnXG5cbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIGRiID0gcmVxdWlyZSgnbWltZS1kYicpXG52YXIgZXh0bmFtZSA9IHJlcXVpcmUoJ3BhdGgnKS5leHRuYW1lXG5cbi8qKlxuICogTW9kdWxlIHZhcmlhYmxlcy5cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIEVYVFJBQ1RfVFlQRV9SRUdFWFAgPSAvXlxccyooW147XFxzXSopKD86O3xcXHN8JCkvXG52YXIgVEVYVF9UWVBFX1JFR0VYUCA9IC9edGV4dFxcLy9pXG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKiBAcHVibGljXG4gKi9cblxuZXhwb3J0cy5jaGFyc2V0ID0gY2hhcnNldFxuZXhwb3J0cy5jaGFyc2V0cyA9IHsgbG9va3VwOiBjaGFyc2V0IH1cbmV4cG9ydHMuY29udGVudFR5cGUgPSBjb250ZW50VHlwZVxuZXhwb3J0cy5leHRlbnNpb24gPSBleHRlbnNpb25cbmV4cG9ydHMuZXh0ZW5zaW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbClcbmV4cG9ydHMubG9va3VwID0gbG9va3VwXG5leHBvcnRzLnR5cGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4vLyBQb3B1bGF0ZSB0aGUgZXh0ZW5zaW9ucy90eXBlcyBtYXBzXG5wb3B1bGF0ZU1hcHMoZXhwb3J0cy5leHRlbnNpb25zLCBleHBvcnRzLnR5cGVzKVxuXG4vKipcbiAqIEdldCB0aGUgZGVmYXVsdCBjaGFyc2V0IGZvciBhIE1JTUUgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZVxuICogQHJldHVybiB7Ym9vbGVhbnxzdHJpbmd9XG4gKi9cblxuZnVuY3Rpb24gY2hhcnNldCAodHlwZSkge1xuICBpZiAoIXR5cGUgfHwgdHlwZW9mIHR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBUT0RPOiB1c2UgbWVkaWEtdHlwZXJcbiAgdmFyIG1hdGNoID0gRVhUUkFDVF9UWVBFX1JFR0VYUC5leGVjKHR5cGUpXG4gIHZhciBtaW1lID0gbWF0Y2ggJiYgZGJbbWF0Y2hbMV0udG9Mb3dlckNhc2UoKV1cblxuICBpZiAobWltZSAmJiBtaW1lLmNoYXJzZXQpIHtcbiAgICByZXR1cm4gbWltZS5jaGFyc2V0XG4gIH1cblxuICAvLyBkZWZhdWx0IHRleHQvKiB0byB1dGYtOFxuICBpZiAobWF0Y2ggJiYgVEVYVF9UWVBFX1JFR0VYUC50ZXN0KG1hdGNoWzFdKSkge1xuICAgIHJldHVybiAnVVRGLTgnXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBmdWxsIENvbnRlbnQtVHlwZSBoZWFkZXIgZ2l2ZW4gYSBNSU1FIHR5cGUgb3IgZXh0ZW5zaW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge2Jvb2xlYW58c3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIGNvbnRlbnRUeXBlIChzdHIpIHtcbiAgLy8gVE9ETzogc2hvdWxkIHRoaXMgZXZlbiBiZSBpbiB0aGlzIG1vZHVsZT9cbiAgaWYgKCFzdHIgfHwgdHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHZhciBtaW1lID0gc3RyLmluZGV4T2YoJy8nKSA9PT0gLTFcbiAgICA/IGV4cG9ydHMubG9va3VwKHN0cilcbiAgICA6IHN0clxuXG4gIGlmICghbWltZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gVE9ETzogdXNlIGNvbnRlbnQtdHlwZSBvciBvdGhlciBtb2R1bGVcbiAgaWYgKG1pbWUuaW5kZXhPZignY2hhcnNldCcpID09PSAtMSkge1xuICAgIHZhciBjaGFyc2V0ID0gZXhwb3J0cy5jaGFyc2V0KG1pbWUpXG4gICAgaWYgKGNoYXJzZXQpIG1pbWUgKz0gJzsgY2hhcnNldD0nICsgY2hhcnNldC50b0xvd2VyQ2FzZSgpXG4gIH1cblxuICByZXR1cm4gbWltZVxufVxuXG4vKipcbiAqIEdldCB0aGUgZGVmYXVsdCBleHRlbnNpb24gZm9yIGEgTUlNRSB0eXBlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtib29sZWFufHN0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBleHRlbnNpb24gKHR5cGUpIHtcbiAgaWYgKCF0eXBlIHx8IHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gVE9ETzogdXNlIG1lZGlhLXR5cGVyXG4gIHZhciBtYXRjaCA9IEVYVFJBQ1RfVFlQRV9SRUdFWFAuZXhlYyh0eXBlKVxuXG4gIC8vIGdldCBleHRlbnNpb25zXG4gIHZhciBleHRzID0gbWF0Y2ggJiYgZXhwb3J0cy5leHRlbnNpb25zW21hdGNoWzFdLnRvTG93ZXJDYXNlKCldXG5cbiAgaWYgKCFleHRzIHx8ICFleHRzLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIGV4dHNbMF1cbn1cblxuLyoqXG4gKiBMb29rdXAgdGhlIE1JTUUgdHlwZSBmb3IgYSBmaWxlIHBhdGgvZXh0ZW5zaW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJuIHtib29sZWFufHN0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBsb29rdXAgKHBhdGgpIHtcbiAgaWYgKCFwYXRoIHx8IHR5cGVvZiBwYXRoICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gZ2V0IHRoZSBleHRlbnNpb24gKFwiZXh0XCIgb3IgXCIuZXh0XCIgb3IgZnVsbCBwYXRoKVxuICB2YXIgZXh0ZW5zaW9uID0gZXh0bmFtZSgneC4nICsgcGF0aClcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5zdWJzdHIoMSlcblxuICBpZiAoIWV4dGVuc2lvbikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIGV4cG9ydHMudHlwZXNbZXh0ZW5zaW9uXSB8fCBmYWxzZVxufVxuXG4vKipcbiAqIFBvcHVsYXRlIHRoZSBleHRlbnNpb25zIGFuZCB0eXBlcyBtYXBzLlxuICogQHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwb3B1bGF0ZU1hcHMgKGV4dGVuc2lvbnMsIHR5cGVzKSB7XG4gIC8vIHNvdXJjZSBwcmVmZXJlbmNlIChsZWFzdCAtPiBtb3N0KVxuICB2YXIgcHJlZmVyZW5jZSA9IFsnbmdpbngnLCAnYXBhY2hlJywgdW5kZWZpbmVkLCAnaWFuYSddXG5cbiAgT2JqZWN0LmtleXMoZGIpLmZvckVhY2goZnVuY3Rpb24gZm9yRWFjaE1pbWVUeXBlICh0eXBlKSB7XG4gICAgdmFyIG1pbWUgPSBkYlt0eXBlXVxuICAgIHZhciBleHRzID0gbWltZS5leHRlbnNpb25zXG5cbiAgICBpZiAoIWV4dHMgfHwgIWV4dHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBtaW1lIC0+IGV4dGVuc2lvbnNcbiAgICBleHRlbnNpb25zW3R5cGVdID0gZXh0c1xuXG4gICAgLy8gZXh0ZW5zaW9uIC0+IG1pbWVcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV4dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBleHRlbnNpb24gPSBleHRzW2ldXG5cbiAgICAgIGlmICh0eXBlc1tleHRlbnNpb25dKSB7XG4gICAgICAgIHZhciBmcm9tID0gcHJlZmVyZW5jZS5pbmRleE9mKGRiW3R5cGVzW2V4dGVuc2lvbl1dLnNvdXJjZSlcbiAgICAgICAgdmFyIHRvID0gcHJlZmVyZW5jZS5pbmRleE9mKG1pbWUuc291cmNlKVxuXG4gICAgICAgIGlmICh0eXBlc1tleHRlbnNpb25dICE9PSAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyAmJlxuICAgICAgICAgIChmcm9tID4gdG8gfHwgKGZyb20gPT09IHRvICYmIHR5cGVzW2V4dGVuc2lvbl0uc3Vic3RyKDAsIDEyKSA9PT0gJ2FwcGxpY2F0aW9uLycpKSkge1xuICAgICAgICAgIC8vIHNraXAgdGhlIHJlbWFwcGluZ1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gc2V0IHRoZSBleHRlbnNpb24gLT4gbWltZVxuICAgICAgdHlwZXNbZXh0ZW5zaW9uXSA9IHR5cGVcbiAgICB9XG4gIH0pXG59XG4iLCIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwO1xudmFyIG0gPSBzICogNjA7XG52YXIgaCA9IG0gKiA2MDtcbnZhciBkID0gaCAqIDI0O1xudmFyIHcgPSBkICogNztcbnZhciB5ID0gZCAqIDM2NS4yNTtcblxuLyoqXG4gKiBQYXJzZSBvciBmb3JtYXQgdGhlIGdpdmVuIGB2YWxgLlxuICpcbiAqIE9wdGlvbnM6XG4gKlxuICogIC0gYGxvbmdgIHZlcmJvc2UgZm9ybWF0dGluZyBbZmFsc2VdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cbiAqIEB0aHJvd3Mge0Vycm9yfSB0aHJvdyBhbiBlcnJvciBpZiB2YWwgaXMgbm90IGEgbm9uLWVtcHR5IHN0cmluZyBvciBhIG51bWJlclxuICogQHJldHVybiB7U3RyaW5nfE51bWJlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih2YWwsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbDtcbiAgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIHZhbC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHBhcnNlKHZhbCk7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgaXNGaW5pdGUodmFsKSkge1xuICAgIHJldHVybiBvcHRpb25zLmxvbmcgPyBmbXRMb25nKHZhbCkgOiBmbXRTaG9ydCh2YWwpO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihcbiAgICAndmFsIGlzIG5vdCBhIG5vbi1lbXB0eSBzdHJpbmcgb3IgYSB2YWxpZCBudW1iZXIuIHZhbD0nICtcbiAgICAgIEpTT04uc3RyaW5naWZ5KHZhbClcbiAgKTtcbn07XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICBzdHIgPSBTdHJpbmcoc3RyKTtcbiAgaWYgKHN0ci5sZW5ndGggPiAxMDApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIG1hdGNoID0gL14oLT8oPzpcXGQrKT9cXC4/XFxkKykgKihtaWxsaXNlY29uZHM/fG1zZWNzP3xtc3xzZWNvbmRzP3xzZWNzP3xzfG1pbnV0ZXM/fG1pbnM/fG18aG91cnM/fGhycz98aHxkYXlzP3xkfHdlZWtzP3x3fHllYXJzP3x5cnM/fHkpPyQvaS5leGVjKFxuICAgIHN0clxuICApO1xuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBuID0gcGFyc2VGbG9hdChtYXRjaFsxXSk7XG4gIHZhciB0eXBlID0gKG1hdGNoWzJdIHx8ICdtcycpLnRvTG93ZXJDYXNlKCk7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ3llYXJzJzpcbiAgICBjYXNlICd5ZWFyJzpcbiAgICBjYXNlICd5cnMnOlxuICAgIGNhc2UgJ3lyJzpcbiAgICBjYXNlICd5JzpcbiAgICAgIHJldHVybiBuICogeTtcbiAgICBjYXNlICd3ZWVrcyc6XG4gICAgY2FzZSAnd2Vlayc6XG4gICAgY2FzZSAndyc6XG4gICAgICByZXR1cm4gbiAqIHc7XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZDtcbiAgICBjYXNlICdob3Vycyc6XG4gICAgY2FzZSAnaG91cic6XG4gICAgY2FzZSAnaHJzJzpcbiAgICBjYXNlICdocic6XG4gICAgY2FzZSAnaCc6XG4gICAgICByZXR1cm4gbiAqIGg7XG4gICAgY2FzZSAnbWludXRlcyc6XG4gICAgY2FzZSAnbWludXRlJzpcbiAgICBjYXNlICdtaW5zJzpcbiAgICBjYXNlICdtaW4nOlxuICAgIGNhc2UgJ20nOlxuICAgICAgcmV0dXJuIG4gKiBtO1xuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogcztcbiAgICBjYXNlICdtaWxsaXNlY29uZHMnOlxuICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICBjYXNlICdtc2Vjcyc6XG4gICAgY2FzZSAnbXNlYyc6XG4gICAgY2FzZSAnbXMnOlxuICAgICAgcmV0dXJuIG47XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBmbXRTaG9ydChtcykge1xuICB2YXIgbXNBYnMgPSBNYXRoLmFicyhtcyk7XG4gIGlmIChtc0FicyA+PSBkKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgfVxuICBpZiAobXNBYnMgPj0gaCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCc7XG4gIH1cbiAgaWYgKG1zQWJzID49IG0pIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG0pICsgJ20nO1xuICB9XG4gIGlmIChtc0FicyA+PSBzKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgfVxuICByZXR1cm4gbXMgKyAnbXMnO1xufVxuXG4vKipcbiAqIExvbmcgZm9ybWF0IGZvciBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZm10TG9uZyhtcykge1xuICB2YXIgbXNBYnMgPSBNYXRoLmFicyhtcyk7XG4gIGlmIChtc0FicyA+PSBkKSB7XG4gICAgcmV0dXJuIHBsdXJhbChtcywgbXNBYnMsIGQsICdkYXknKTtcbiAgfVxuICBpZiAobXNBYnMgPj0gaCkge1xuICAgIHJldHVybiBwbHVyYWwobXMsIG1zQWJzLCBoLCAnaG91cicpO1xuICB9XG4gIGlmIChtc0FicyA+PSBtKSB7XG4gICAgcmV0dXJuIHBsdXJhbChtcywgbXNBYnMsIG0sICdtaW51dGUnKTtcbiAgfVxuICBpZiAobXNBYnMgPj0gcykge1xuICAgIHJldHVybiBwbHVyYWwobXMsIG1zQWJzLCBzLCAnc2Vjb25kJyk7XG4gIH1cbiAgcmV0dXJuIG1zICsgJyBtcyc7XG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBtc0FicywgbiwgbmFtZSkge1xuICB2YXIgaXNQbHVyYWwgPSBtc0FicyA+PSBuICogMS41O1xuICByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG4pICsgJyAnICsgbmFtZSArIChpc1BsdXJhbCA/ICdzJyA6ICcnKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHBhcnNlVXJsID0gcmVxdWlyZSgndXJsJykucGFyc2U7XG5cbnZhciBERUZBVUxUX1BPUlRTID0ge1xuICBmdHA6IDIxLFxuICBnb3BoZXI6IDcwLFxuICBodHRwOiA4MCxcbiAgaHR0cHM6IDQ0MyxcbiAgd3M6IDgwLFxuICB3c3M6IDQ0Myxcbn07XG5cbnZhciBzdHJpbmdFbmRzV2l0aCA9IFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggfHwgZnVuY3Rpb24ocykge1xuICByZXR1cm4gcy5sZW5ndGggPD0gdGhpcy5sZW5ndGggJiZcbiAgICB0aGlzLmluZGV4T2YocywgdGhpcy5sZW5ndGggLSBzLmxlbmd0aCkgIT09IC0xO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHVybCAtIFRoZSBVUkwsIG9yIHRoZSByZXN1bHQgZnJvbSB1cmwucGFyc2UuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBVUkwgb2YgdGhlIHByb3h5IHRoYXQgc2hvdWxkIGhhbmRsZSB0aGUgcmVxdWVzdCB0byB0aGVcbiAqICBnaXZlbiBVUkwuIElmIG5vIHByb3h5IGlzIHNldCwgdGhpcyB3aWxsIGJlIGFuIGVtcHR5IHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gZ2V0UHJveHlGb3JVcmwodXJsKSB7XG4gIHZhciBwYXJzZWRVcmwgPSB0eXBlb2YgdXJsID09PSAnc3RyaW5nJyA/IHBhcnNlVXJsKHVybCkgOiB1cmwgfHwge307XG4gIHZhciBwcm90byA9IHBhcnNlZFVybC5wcm90b2NvbDtcbiAgdmFyIGhvc3RuYW1lID0gcGFyc2VkVXJsLmhvc3Q7XG4gIHZhciBwb3J0ID0gcGFyc2VkVXJsLnBvcnQ7XG4gIGlmICh0eXBlb2YgaG9zdG5hbWUgIT09ICdzdHJpbmcnIHx8ICFob3N0bmFtZSB8fCB0eXBlb2YgcHJvdG8gIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuICcnOyAgLy8gRG9uJ3QgcHJveHkgVVJMcyB3aXRob3V0IGEgdmFsaWQgc2NoZW1lIG9yIGhvc3QuXG4gIH1cblxuICBwcm90byA9IHByb3RvLnNwbGl0KCc6JywgMSlbMF07XG4gIC8vIFN0cmlwcGluZyBwb3J0cyBpbiB0aGlzIHdheSBpbnN0ZWFkIG9mIHVzaW5nIHBhcnNlZFVybC5ob3N0bmFtZSB0byBtYWtlXG4gIC8vIHN1cmUgdGhhdCB0aGUgYnJhY2tldHMgYXJvdW5kIElQdjYgYWRkcmVzc2VzIGFyZSBrZXB0LlxuICBob3N0bmFtZSA9IGhvc3RuYW1lLnJlcGxhY2UoLzpcXGQqJC8sICcnKTtcbiAgcG9ydCA9IHBhcnNlSW50KHBvcnQpIHx8IERFRkFVTFRfUE9SVFNbcHJvdG9dIHx8IDA7XG4gIGlmICghc2hvdWxkUHJveHkoaG9zdG5hbWUsIHBvcnQpKSB7XG4gICAgcmV0dXJuICcnOyAgLy8gRG9uJ3QgcHJveHkgVVJMcyB0aGF0IG1hdGNoIE5PX1BST1hZLlxuICB9XG5cbiAgdmFyIHByb3h5ID1cbiAgICBnZXRFbnYoJ25wbV9jb25maWdfJyArIHByb3RvICsgJ19wcm94eScpIHx8XG4gICAgZ2V0RW52KHByb3RvICsgJ19wcm94eScpIHx8XG4gICAgZ2V0RW52KCducG1fY29uZmlnX3Byb3h5JykgfHxcbiAgICBnZXRFbnYoJ2FsbF9wcm94eScpO1xuICBpZiAocHJveHkgJiYgcHJveHkuaW5kZXhPZignOi8vJykgPT09IC0xKSB7XG4gICAgLy8gTWlzc2luZyBzY2hlbWUgaW4gcHJveHksIGRlZmF1bHQgdG8gdGhlIHJlcXVlc3RlZCBVUkwncyBzY2hlbWUuXG4gICAgcHJveHkgPSBwcm90byArICc6Ly8nICsgcHJveHk7XG4gIH1cbiAgcmV0dXJuIHByb3h5O1xufVxuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIGdpdmVuIFVSTCBzaG91bGQgYmUgcHJveGllZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaG9zdG5hbWUgLSBUaGUgaG9zdCBuYW1lIG9mIHRoZSBVUkwuXG4gKiBAcGFyYW0ge251bWJlcn0gcG9ydCAtIFRoZSBlZmZlY3RpdmUgcG9ydCBvZiB0aGUgVVJMLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIGdpdmVuIFVSTCBzaG91bGQgYmUgcHJveGllZC5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHNob3VsZFByb3h5KGhvc3RuYW1lLCBwb3J0KSB7XG4gIHZhciBOT19QUk9YWSA9XG4gICAgKGdldEVudignbnBtX2NvbmZpZ19ub19wcm94eScpIHx8IGdldEVudignbm9fcHJveHknKSkudG9Mb3dlckNhc2UoKTtcbiAgaWYgKCFOT19QUk9YWSkge1xuICAgIHJldHVybiB0cnVlOyAgLy8gQWx3YXlzIHByb3h5IGlmIE5PX1BST1hZIGlzIG5vdCBzZXQuXG4gIH1cbiAgaWYgKE5PX1BST1hZID09PSAnKicpIHtcbiAgICByZXR1cm4gZmFsc2U7ICAvLyBOZXZlciBwcm94eSBpZiB3aWxkY2FyZCBpcyBzZXQuXG4gIH1cblxuICByZXR1cm4gTk9fUFJPWFkuc3BsaXQoL1ssXFxzXS8pLmV2ZXJ5KGZ1bmN0aW9uKHByb3h5KSB7XG4gICAgaWYgKCFwcm94eSkge1xuICAgICAgcmV0dXJuIHRydWU7ICAvLyBTa2lwIHplcm8tbGVuZ3RoIGhvc3RzLlxuICAgIH1cbiAgICB2YXIgcGFyc2VkUHJveHkgPSBwcm94eS5tYXRjaCgvXiguKyk6KFxcZCspJC8pO1xuICAgIHZhciBwYXJzZWRQcm94eUhvc3RuYW1lID0gcGFyc2VkUHJveHkgPyBwYXJzZWRQcm94eVsxXSA6IHByb3h5O1xuICAgIHZhciBwYXJzZWRQcm94eVBvcnQgPSBwYXJzZWRQcm94eSA/IHBhcnNlSW50KHBhcnNlZFByb3h5WzJdKSA6IDA7XG4gICAgaWYgKHBhcnNlZFByb3h5UG9ydCAmJiBwYXJzZWRQcm94eVBvcnQgIT09IHBvcnQpIHtcbiAgICAgIHJldHVybiB0cnVlOyAgLy8gU2tpcCBpZiBwb3J0cyBkb24ndCBtYXRjaC5cbiAgICB9XG5cbiAgICBpZiAoIS9eWy4qXS8udGVzdChwYXJzZWRQcm94eUhvc3RuYW1lKSkge1xuICAgICAgLy8gTm8gd2lsZGNhcmRzLCBzbyBzdG9wIHByb3h5aW5nIGlmIHRoZXJlIGlzIGFuIGV4YWN0IG1hdGNoLlxuICAgICAgcmV0dXJuIGhvc3RuYW1lICE9PSBwYXJzZWRQcm94eUhvc3RuYW1lO1xuICAgIH1cblxuICAgIGlmIChwYXJzZWRQcm94eUhvc3RuYW1lLmNoYXJBdCgwKSA9PT0gJyonKSB7XG4gICAgICAvLyBSZW1vdmUgbGVhZGluZyB3aWxkY2FyZC5cbiAgICAgIHBhcnNlZFByb3h5SG9zdG5hbWUgPSBwYXJzZWRQcm94eUhvc3RuYW1lLnNsaWNlKDEpO1xuICAgIH1cbiAgICAvLyBTdG9wIHByb3h5aW5nIGlmIHRoZSBob3N0bmFtZSBlbmRzIHdpdGggdGhlIG5vX3Byb3h5IGhvc3QuXG4gICAgcmV0dXJuICFzdHJpbmdFbmRzV2l0aC5jYWxsKGhvc3RuYW1lLCBwYXJzZWRQcm94eUhvc3RuYW1lKTtcbiAgfSk7XG59XG5cbi8qKlxuICogR2V0IHRoZSB2YWx1ZSBmb3IgYW4gZW52aXJvbm1lbnQgdmFyaWFibGUuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBuYW1lIG9mIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZS5cbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHZhbHVlIG9mIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZS5cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGdldEVudihrZXkpIHtcbiAgcmV0dXJuIHByb2Nlc3MuZW52W2tleS50b0xvd2VyQ2FzZSgpXSB8fCBwcm9jZXNzLmVudltrZXkudG9VcHBlckNhc2UoKV0gfHwgJyc7XG59XG5cbmV4cG9ydHMuZ2V0UHJveHlGb3JVcmwgPSBnZXRQcm94eUZvclVybDtcbiIsIid1c2Ugc3RyaWN0JztcbmNvbnN0IG9zID0gcmVxdWlyZSgnb3MnKTtcbmNvbnN0IGhhc0ZsYWcgPSByZXF1aXJlKCdoYXMtZmxhZycpO1xuXG5jb25zdCBlbnYgPSBwcm9jZXNzLmVudjtcblxubGV0IGZvcmNlQ29sb3I7XG5pZiAoaGFzRmxhZygnbm8tY29sb3InKSB8fFxuXHRoYXNGbGFnKCduby1jb2xvcnMnKSB8fFxuXHRoYXNGbGFnKCdjb2xvcj1mYWxzZScpKSB7XG5cdGZvcmNlQ29sb3IgPSBmYWxzZTtcbn0gZWxzZSBpZiAoaGFzRmxhZygnY29sb3InKSB8fFxuXHRoYXNGbGFnKCdjb2xvcnMnKSB8fFxuXHRoYXNGbGFnKCdjb2xvcj10cnVlJykgfHxcblx0aGFzRmxhZygnY29sb3I9YWx3YXlzJykpIHtcblx0Zm9yY2VDb2xvciA9IHRydWU7XG59XG5pZiAoJ0ZPUkNFX0NPTE9SJyBpbiBlbnYpIHtcblx0Zm9yY2VDb2xvciA9IGVudi5GT1JDRV9DT0xPUi5sZW5ndGggPT09IDAgfHwgcGFyc2VJbnQoZW52LkZPUkNFX0NPTE9SLCAxMCkgIT09IDA7XG59XG5cbmZ1bmN0aW9uIHRyYW5zbGF0ZUxldmVsKGxldmVsKSB7XG5cdGlmIChsZXZlbCA9PT0gMCkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0bGV2ZWwsXG5cdFx0aGFzQmFzaWM6IHRydWUsXG5cdFx0aGFzMjU2OiBsZXZlbCA+PSAyLFxuXHRcdGhhczE2bTogbGV2ZWwgPj0gM1xuXHR9O1xufVxuXG5mdW5jdGlvbiBzdXBwb3J0c0NvbG9yKHN0cmVhbSkge1xuXHRpZiAoZm9yY2VDb2xvciA9PT0gZmFsc2UpIHtcblx0XHRyZXR1cm4gMDtcblx0fVxuXG5cdGlmIChoYXNGbGFnKCdjb2xvcj0xNm0nKSB8fFxuXHRcdGhhc0ZsYWcoJ2NvbG9yPWZ1bGwnKSB8fFxuXHRcdGhhc0ZsYWcoJ2NvbG9yPXRydWVjb2xvcicpKSB7XG5cdFx0cmV0dXJuIDM7XG5cdH1cblxuXHRpZiAoaGFzRmxhZygnY29sb3I9MjU2JykpIHtcblx0XHRyZXR1cm4gMjtcblx0fVxuXG5cdGlmIChzdHJlYW0gJiYgIXN0cmVhbS5pc1RUWSAmJiBmb3JjZUNvbG9yICE9PSB0cnVlKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHRjb25zdCBtaW4gPSBmb3JjZUNvbG9yID8gMSA6IDA7XG5cblx0aWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICd3aW4zMicpIHtcblx0XHQvLyBOb2RlLmpzIDcuNS4wIGlzIHRoZSBmaXJzdCB2ZXJzaW9uIG9mIE5vZGUuanMgdG8gaW5jbHVkZSBhIHBhdGNoIHRvXG5cdFx0Ly8gbGlidXYgdGhhdCBlbmFibGVzIDI1NiBjb2xvciBvdXRwdXQgb24gV2luZG93cy4gQW55dGhpbmcgZWFybGllciBhbmQgaXRcblx0XHQvLyB3b24ndCB3b3JrLiBIb3dldmVyLCBoZXJlIHdlIHRhcmdldCBOb2RlLmpzIDggYXQgbWluaW11bSBhcyBpdCBpcyBhbiBMVFNcblx0XHQvLyByZWxlYXNlLCBhbmQgTm9kZS5qcyA3IGlzIG5vdC4gV2luZG93cyAxMCBidWlsZCAxMDU4NiBpcyB0aGUgZmlyc3QgV2luZG93c1xuXHRcdC8vIHJlbGVhc2UgdGhhdCBzdXBwb3J0cyAyNTYgY29sb3JzLiBXaW5kb3dzIDEwIGJ1aWxkIDE0OTMxIGlzIHRoZSBmaXJzdCByZWxlYXNlXG5cdFx0Ly8gdGhhdCBzdXBwb3J0cyAxNm0vVHJ1ZUNvbG9yLlxuXHRcdGNvbnN0IG9zUmVsZWFzZSA9IG9zLnJlbGVhc2UoKS5zcGxpdCgnLicpO1xuXHRcdGlmIChcblx0XHRcdE51bWJlcihwcm9jZXNzLnZlcnNpb25zLm5vZGUuc3BsaXQoJy4nKVswXSkgPj0gOCAmJlxuXHRcdFx0TnVtYmVyKG9zUmVsZWFzZVswXSkgPj0gMTAgJiZcblx0XHRcdE51bWJlcihvc1JlbGVhc2VbMl0pID49IDEwNTg2XG5cdFx0KSB7XG5cdFx0XHRyZXR1cm4gTnVtYmVyKG9zUmVsZWFzZVsyXSkgPj0gMTQ5MzEgPyAzIDogMjtcblx0XHR9XG5cblx0XHRyZXR1cm4gMTtcblx0fVxuXG5cdGlmICgnQ0knIGluIGVudikge1xuXHRcdGlmIChbJ1RSQVZJUycsICdDSVJDTEVDSScsICdBUFBWRVlPUicsICdHSVRMQUJfQ0knXS5zb21lKHNpZ24gPT4gc2lnbiBpbiBlbnYpIHx8IGVudi5DSV9OQU1FID09PSAnY29kZXNoaXAnKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbWluO1xuXHR9XG5cblx0aWYgKCdURUFNQ0lUWV9WRVJTSU9OJyBpbiBlbnYpIHtcblx0XHRyZXR1cm4gL14oOVxcLigwKlsxLTldXFxkKilcXC58XFxkezIsfVxcLikvLnRlc3QoZW52LlRFQU1DSVRZX1ZFUlNJT04pID8gMSA6IDA7XG5cdH1cblxuXHRpZiAoZW52LkNPTE9SVEVSTSA9PT0gJ3RydWVjb2xvcicpIHtcblx0XHRyZXR1cm4gMztcblx0fVxuXG5cdGlmICgnVEVSTV9QUk9HUkFNJyBpbiBlbnYpIHtcblx0XHRjb25zdCB2ZXJzaW9uID0gcGFyc2VJbnQoKGVudi5URVJNX1BST0dSQU1fVkVSU0lPTiB8fCAnJykuc3BsaXQoJy4nKVswXSwgMTApO1xuXG5cdFx0c3dpdGNoIChlbnYuVEVSTV9QUk9HUkFNKSB7XG5cdFx0XHRjYXNlICdpVGVybS5hcHAnOlxuXHRcdFx0XHRyZXR1cm4gdmVyc2lvbiA+PSAzID8gMyA6IDI7XG5cdFx0XHRjYXNlICdBcHBsZV9UZXJtaW5hbCc6XG5cdFx0XHRcdHJldHVybiAyO1xuXHRcdFx0Ly8gTm8gZGVmYXVsdFxuXHRcdH1cblx0fVxuXG5cdGlmICgvLTI1Nihjb2xvcik/JC9pLnRlc3QoZW52LlRFUk0pKSB7XG5cdFx0cmV0dXJuIDI7XG5cdH1cblxuXHRpZiAoL15zY3JlZW58Xnh0ZXJtfF52dDEwMHxednQyMjB8XnJ4dnR8Y29sb3J8YW5zaXxjeWd3aW58bGludXgvaS50ZXN0KGVudi5URVJNKSkge1xuXHRcdHJldHVybiAxO1xuXHR9XG5cblx0aWYgKCdDT0xPUlRFUk0nIGluIGVudikge1xuXHRcdHJldHVybiAxO1xuXHR9XG5cblx0aWYgKGVudi5URVJNID09PSAnZHVtYicpIHtcblx0XHRyZXR1cm4gbWluO1xuXHR9XG5cblx0cmV0dXJuIG1pbjtcbn1cblxuZnVuY3Rpb24gZ2V0U3VwcG9ydExldmVsKHN0cmVhbSkge1xuXHRjb25zdCBsZXZlbCA9IHN1cHBvcnRzQ29sb3Ioc3RyZWFtKTtcblx0cmV0dXJuIHRyYW5zbGF0ZUxldmVsKGxldmVsKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHN1cHBvcnRzQ29sb3I6IGdldFN1cHBvcnRMZXZlbCxcblx0c3Rkb3V0OiBnZXRTdXBwb3J0TGV2ZWwocHJvY2Vzcy5zdGRvdXQpLFxuXHRzdGRlcnI6IGdldFN1cHBvcnRMZXZlbChwcm9jZXNzLnN0ZGVycilcbn07XG4iLCIoZnVuY3Rpb24gKG5hbWUsIGNvbnRleHQsIGRlZmluaXRpb24pIHtcbiAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSBkZWZpbmUoZGVmaW5pdGlvbik7XG4gIGVsc2UgY29udGV4dFtuYW1lXSA9IGRlZmluaXRpb24oKTtcbn0pKCd1cmxqb2luJywgdGhpcywgZnVuY3Rpb24gKCkge1xuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZSAoc3RyQXJyYXkpIHtcbiAgICB2YXIgcmVzdWx0QXJyYXkgPSBbXTtcbiAgICBpZiAoc3RyQXJyYXkubGVuZ3RoID09PSAwKSB7IHJldHVybiAnJzsgfVxuXG4gICAgaWYgKHR5cGVvZiBzdHJBcnJheVswXSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1VybCBtdXN0IGJlIGEgc3RyaW5nLiBSZWNlaXZlZCAnICsgc3RyQXJyYXlbMF0pO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSBmaXJzdCBwYXJ0IGlzIGEgcGxhaW4gcHJvdG9jb2wsIHdlIGNvbWJpbmUgaXQgd2l0aCB0aGUgbmV4dCBwYXJ0LlxuICAgIGlmIChzdHJBcnJheVswXS5tYXRjaCgvXlteLzpdKzpcXC8qJC8pICYmIHN0ckFycmF5Lmxlbmd0aCA+IDEpIHtcbiAgICAgIHZhciBmaXJzdCA9IHN0ckFycmF5LnNoaWZ0KCk7XG4gICAgICBzdHJBcnJheVswXSA9IGZpcnN0ICsgc3RyQXJyYXlbMF07XG4gICAgfVxuXG4gICAgLy8gVGhlcmUgbXVzdCBiZSB0d28gb3IgdGhyZWUgc2xhc2hlcyBpbiB0aGUgZmlsZSBwcm90b2NvbCwgdHdvIHNsYXNoZXMgaW4gYW55dGhpbmcgZWxzZS5cbiAgICBpZiAoc3RyQXJyYXlbMF0ubWF0Y2goL15maWxlOlxcL1xcL1xcLy8pKSB7XG4gICAgICBzdHJBcnJheVswXSA9IHN0ckFycmF5WzBdLnJlcGxhY2UoL14oW14vOl0rKTpcXC8qLywgJyQxOi8vLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHJBcnJheVswXSA9IHN0ckFycmF5WzBdLnJlcGxhY2UoL14oW14vOl0rKTpcXC8qLywgJyQxOi8vJyk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGNvbXBvbmVudCA9IHN0ckFycmF5W2ldO1xuXG4gICAgICBpZiAodHlwZW9mIGNvbXBvbmVudCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVXJsIG11c3QgYmUgYSBzdHJpbmcuIFJlY2VpdmVkICcgKyBjb21wb25lbnQpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29tcG9uZW50ID09PSAnJykgeyBjb250aW51ZTsgfVxuXG4gICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgLy8gUmVtb3ZpbmcgdGhlIHN0YXJ0aW5nIHNsYXNoZXMgZm9yIGVhY2ggY29tcG9uZW50IGJ1dCB0aGUgZmlyc3QuXG4gICAgICAgIGNvbXBvbmVudCA9IGNvbXBvbmVudC5yZXBsYWNlKC9eW1xcL10rLywgJycpO1xuICAgICAgfVxuICAgICAgaWYgKGkgPCBzdHJBcnJheS5sZW5ndGggLSAxKSB7XG4gICAgICAgIC8vIFJlbW92aW5nIHRoZSBlbmRpbmcgc2xhc2hlcyBmb3IgZWFjaCBjb21wb25lbnQgYnV0IHRoZSBsYXN0LlxuICAgICAgICBjb21wb25lbnQgPSBjb21wb25lbnQucmVwbGFjZSgvW1xcL10rJC8sICcnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEZvciB0aGUgbGFzdCBjb21wb25lbnQgd2Ugd2lsbCBjb21iaW5lIG11bHRpcGxlIHNsYXNoZXMgdG8gYSBzaW5nbGUgb25lLlxuICAgICAgICBjb21wb25lbnQgPSBjb21wb25lbnQucmVwbGFjZSgvW1xcL10rJC8sICcvJyk7XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdEFycmF5LnB1c2goY29tcG9uZW50KTtcblxuICAgIH1cblxuICAgIHZhciBzdHIgPSByZXN1bHRBcnJheS5qb2luKCcvJyk7XG4gICAgLy8gRWFjaCBpbnB1dCBjb21wb25lbnQgaXMgbm93IHNlcGFyYXRlZCBieSBhIHNpbmdsZSBzbGFzaCBleGNlcHQgdGhlIHBvc3NpYmxlIGZpcnN0IHBsYWluIHByb3RvY29sIHBhcnQuXG5cbiAgICAvLyByZW1vdmUgdHJhaWxpbmcgc2xhc2ggYmVmb3JlIHBhcmFtZXRlcnMgb3IgaGFzaFxuICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cXC8oXFw/fCZ8I1teIV0pL2csICckMScpO1xuXG4gICAgLy8gcmVwbGFjZSA/IGluIHBhcmFtZXRlcnMgd2l0aCAmXG4gICAgdmFyIHBhcnRzID0gc3RyLnNwbGl0KCc/Jyk7XG4gICAgc3RyID0gcGFydHMuc2hpZnQoKSArIChwYXJ0cy5sZW5ndGggPiAwID8gJz8nOiAnJykgKyBwYXJ0cy5qb2luKCcmJyk7XG5cbiAgICByZXR1cm4gc3RyO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaW5wdXQ7XG5cbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlucHV0ID0gYXJndW1lbnRzWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbnB1dCA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplKGlucHV0KTtcbiAgfTtcblxufSk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJhc3NlcnRcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXZlbnRzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImZzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImh0dHBcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaHR0cHNcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwib3NcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicGF0aFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJzdHJlYW1cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidHR5XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInVybFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1dGlsXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInpsaWJcIik7IiwiLy8gQXhpb3MgdjEuNi4wIENvcHlyaWdodCAoYykgMjAyMyBNYXR0IFphYnJpc2tpZSBhbmQgY29udHJpYnV0b3JzXG4ndXNlIHN0cmljdCc7XG5cbmNvbnN0IEZvcm1EYXRhJDEgPSByZXF1aXJlKCdmb3JtLWRhdGEnKTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcHJveHlGcm9tRW52ID0gcmVxdWlyZSgncHJveHktZnJvbS1lbnYnKTtcbmNvbnN0IGh0dHAgPSByZXF1aXJlKCdodHRwJyk7XG5jb25zdCBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyk7XG5jb25zdCB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuY29uc3QgZm9sbG93UmVkaXJlY3RzID0gcmVxdWlyZSgnZm9sbG93LXJlZGlyZWN0cycpO1xuY29uc3QgemxpYiA9IHJlcXVpcmUoJ3psaWInKTtcbmNvbnN0IHN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xuY29uc3QgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wRGVmYXVsdExlZ2FjeSAoZSkgeyByZXR1cm4gZSAmJiB0eXBlb2YgZSA9PT0gJ29iamVjdCcgJiYgJ2RlZmF1bHQnIGluIGUgPyBlIDogeyAnZGVmYXVsdCc6IGUgfTsgfVxuXG5jb25zdCBGb3JtRGF0YV9fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koRm9ybURhdGEkMSk7XG5jb25zdCB1cmxfX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX2ludGVyb3BEZWZhdWx0TGVnYWN5KHVybCk7XG5jb25zdCBodHRwX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShodHRwKTtcbmNvbnN0IGh0dHBzX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShodHRwcyk7XG5jb25zdCB1dGlsX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeSh1dGlsKTtcbmNvbnN0IGZvbGxvd1JlZGlyZWN0c19fZGVmYXVsdCA9IC8qI19fUFVSRV9fKi9faW50ZXJvcERlZmF1bHRMZWdhY3koZm9sbG93UmVkaXJlY3RzKTtcbmNvbnN0IHpsaWJfX2RlZmF1bHQgPSAvKiNfX1BVUkVfXyovX2ludGVyb3BEZWZhdWx0TGVnYWN5KHpsaWIpO1xuY29uc3Qgc3RyZWFtX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShzdHJlYW0pO1xuY29uc3QgRXZlbnRFbWl0dGVyX19kZWZhdWx0ID0gLyojX19QVVJFX18qL19pbnRlcm9wRGVmYXVsdExlZ2FjeShFdmVudEVtaXR0ZXIpO1xuXG5mdW5jdGlvbiBiaW5kKGZuLCB0aGlzQXJnKSB7XG4gIHJldHVybiBmdW5jdGlvbiB3cmFwKCkge1xuICAgIHJldHVybiBmbi5hcHBseSh0aGlzQXJnLCBhcmd1bWVudHMpO1xuICB9O1xufVxuXG4vLyB1dGlscyBpcyBhIGxpYnJhcnkgb2YgZ2VuZXJpYyBoZWxwZXIgZnVuY3Rpb25zIG5vbi1zcGVjaWZpYyB0byBheGlvc1xuXG5jb25zdCB7dG9TdHJpbmd9ID0gT2JqZWN0LnByb3RvdHlwZTtcbmNvbnN0IHtnZXRQcm90b3R5cGVPZn0gPSBPYmplY3Q7XG5cbmNvbnN0IGtpbmRPZiA9IChjYWNoZSA9PiB0aGluZyA9PiB7XG4gICAgY29uc3Qgc3RyID0gdG9TdHJpbmcuY2FsbCh0aGluZyk7XG4gICAgcmV0dXJuIGNhY2hlW3N0cl0gfHwgKGNhY2hlW3N0cl0gPSBzdHIuc2xpY2UoOCwgLTEpLnRvTG93ZXJDYXNlKCkpO1xufSkoT2JqZWN0LmNyZWF0ZShudWxsKSk7XG5cbmNvbnN0IGtpbmRPZlRlc3QgPSAodHlwZSkgPT4ge1xuICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKHRoaW5nKSA9PiBraW5kT2YodGhpbmcpID09PSB0eXBlXG59O1xuXG5jb25zdCB0eXBlT2ZUZXN0ID0gdHlwZSA9PiB0aGluZyA9PiB0eXBlb2YgdGhpbmcgPT09IHR5cGU7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYW4gQXJyYXlcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXksIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCB7aXNBcnJheX0gPSBBcnJheTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyB1bmRlZmluZWRcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyB1bmRlZmluZWQsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1VuZGVmaW5lZCA9IHR5cGVPZlRlc3QoJ3VuZGVmaW5lZCcpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgQnVmZmVyXG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEJ1ZmZlciwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQnVmZmVyKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSBudWxsICYmICFpc1VuZGVmaW5lZCh2YWwpICYmIHZhbC5jb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiAhaXNVbmRlZmluZWQodmFsLmNvbnN0cnVjdG9yKVxuICAgICYmIGlzRnVuY3Rpb24odmFsLmNvbnN0cnVjdG9yLmlzQnVmZmVyKSAmJiB2YWwuY29uc3RydWN0b3IuaXNCdWZmZXIodmFsKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhbiBBcnJheUJ1ZmZlclxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXlCdWZmZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc0FycmF5QnVmZmVyID0ga2luZE9mVGVzdCgnQXJyYXlCdWZmZXInKTtcblxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgdmlldyBvbiBhbiBBcnJheUJ1ZmZlclxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSB2aWV3IG9uIGFuIEFycmF5QnVmZmVyLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheUJ1ZmZlclZpZXcodmFsKSB7XG4gIGxldCByZXN1bHQ7XG4gIGlmICgodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJykgJiYgKEFycmF5QnVmZmVyLmlzVmlldykpIHtcbiAgICByZXN1bHQgPSBBcnJheUJ1ZmZlci5pc1ZpZXcodmFsKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSAodmFsKSAmJiAodmFsLmJ1ZmZlcikgJiYgKGlzQXJyYXlCdWZmZXIodmFsLmJ1ZmZlcikpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBTdHJpbmdcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgU3RyaW5nLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNTdHJpbmcgPSB0eXBlT2ZUZXN0KCdzdHJpbmcnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZ1bmN0aW9uXG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRnVuY3Rpb24sIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc0Z1bmN0aW9uID0gdHlwZU9mVGVzdCgnZnVuY3Rpb24nKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIE51bWJlclxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBOdW1iZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc051bWJlciA9IHR5cGVPZlRlc3QoJ251bWJlcicpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIE9iamVjdFxuICpcbiAqIEBwYXJhbSB7Kn0gdGhpbmcgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBPYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc09iamVjdCA9ICh0aGluZykgPT4gdGhpbmcgIT09IG51bGwgJiYgdHlwZW9mIHRoaW5nID09PSAnb2JqZWN0JztcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEJvb2xlYW5cbiAqXG4gKiBAcGFyYW0geyp9IHRoaW5nIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEJvb2xlYW4sIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc0Jvb2xlYW4gPSB0aGluZyA9PiB0aGluZyA9PT0gdHJ1ZSB8fCB0aGluZyA9PT0gZmFsc2U7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBwbGFpbiBPYmplY3RcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgcGxhaW4gT2JqZWN0LCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNQbGFpbk9iamVjdCA9ICh2YWwpID0+IHtcbiAgaWYgKGtpbmRPZih2YWwpICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IHByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKHZhbCk7XG4gIHJldHVybiAocHJvdG90eXBlID09PSBudWxsIHx8IHByb3RvdHlwZSA9PT0gT2JqZWN0LnByb3RvdHlwZSB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKSA9PT0gbnVsbCkgJiYgIShTeW1ib2wudG9TdHJpbmdUYWcgaW4gdmFsKSAmJiAhKFN5bWJvbC5pdGVyYXRvciBpbiB2YWwpO1xufTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIERhdGVcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRGF0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzRGF0ZSA9IGtpbmRPZlRlc3QoJ0RhdGUnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZpbGVcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRmlsZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzRmlsZSA9IGtpbmRPZlRlc3QoJ0ZpbGUnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEJsb2JcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgQmxvYiwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzQmxvYiA9IGtpbmRPZlRlc3QoJ0Jsb2InKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZpbGVMaXN0XG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEZpbGUsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc0ZpbGVMaXN0ID0ga2luZE9mVGVzdCgnRmlsZUxpc3QnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIFN0cmVhbVxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBTdHJlYW0sIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1N0cmVhbSA9ICh2YWwpID0+IGlzT2JqZWN0KHZhbCkgJiYgaXNGdW5jdGlvbih2YWwucGlwZSk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBGb3JtRGF0YVxuICpcbiAqIEBwYXJhbSB7Kn0gdGhpbmcgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBGb3JtRGF0YSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzRm9ybURhdGEgPSAodGhpbmcpID0+IHtcbiAgbGV0IGtpbmQ7XG4gIHJldHVybiB0aGluZyAmJiAoXG4gICAgKHR5cGVvZiBGb3JtRGF0YSA9PT0gJ2Z1bmN0aW9uJyAmJiB0aGluZyBpbnN0YW5jZW9mIEZvcm1EYXRhKSB8fCAoXG4gICAgICBpc0Z1bmN0aW9uKHRoaW5nLmFwcGVuZCkgJiYgKFxuICAgICAgICAoa2luZCA9IGtpbmRPZih0aGluZykpID09PSAnZm9ybWRhdGEnIHx8XG4gICAgICAgIC8vIGRldGVjdCBmb3JtLWRhdGEgaW5zdGFuY2VcbiAgICAgICAgKGtpbmQgPT09ICdvYmplY3QnICYmIGlzRnVuY3Rpb24odGhpbmcudG9TdHJpbmcpICYmIHRoaW5nLnRvU3RyaW5nKCkgPT09ICdbb2JqZWN0IEZvcm1EYXRhXScpXG4gICAgICApXG4gICAgKVxuICApXG59O1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBVUkxTZWFyY2hQYXJhbXMgb2JqZWN0LCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNVUkxTZWFyY2hQYXJhbXMgPSBraW5kT2ZUZXN0KCdVUkxTZWFyY2hQYXJhbXMnKTtcblxuLyoqXG4gKiBUcmltIGV4Y2VzcyB3aGl0ZXNwYWNlIG9mZiB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgb2YgYSBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBTdHJpbmcgdG8gdHJpbVxuICpcbiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBTdHJpbmcgZnJlZWQgb2YgZXhjZXNzIHdoaXRlc3BhY2VcbiAqL1xuY29uc3QgdHJpbSA9IChzdHIpID0+IHN0ci50cmltID9cbiAgc3RyLnRyaW0oKSA6IHN0ci5yZXBsYWNlKC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZywgJycpO1xuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBhbiBBcnJheSBvciBhbiBPYmplY3QgaW52b2tpbmcgYSBmdW5jdGlvbiBmb3IgZWFjaCBpdGVtLlxuICpcbiAqIElmIGBvYmpgIGlzIGFuIEFycmF5IGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHBhc3NpbmdcbiAqIHRoZSB2YWx1ZSwgaW5kZXgsIGFuZCBjb21wbGV0ZSBhcnJheSBmb3IgZWFjaCBpdGVtLlxuICpcbiAqIElmICdvYmonIGlzIGFuIE9iamVjdCBjYWxsYmFjayB3aWxsIGJlIGNhbGxlZCBwYXNzaW5nXG4gKiB0aGUgdmFsdWUsIGtleSwgYW5kIGNvbXBsZXRlIG9iamVjdCBmb3IgZWFjaCBwcm9wZXJ0eS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gb2JqIFRoZSBvYmplY3QgdG8gaXRlcmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGNhbGxiYWNrIHRvIGludm9rZSBmb3IgZWFjaCBpdGVtXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBbYWxsT3duS2V5cyA9IGZhbHNlXVxuICogQHJldHVybnMge2FueX1cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaChvYmosIGZuLCB7YWxsT3duS2V5cyA9IGZhbHNlfSA9IHt9KSB7XG4gIC8vIERvbid0IGJvdGhlciBpZiBubyB2YWx1ZSBwcm92aWRlZFxuICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IGk7XG4gIGxldCBsO1xuXG4gIC8vIEZvcmNlIGFuIGFycmF5IGlmIG5vdCBhbHJlYWR5IHNvbWV0aGluZyBpdGVyYWJsZVxuICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHtcbiAgICAvKmVzbGludCBuby1wYXJhbS1yZWFzc2lnbjowKi9cbiAgICBvYmogPSBbb2JqXTtcbiAgfVxuXG4gIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAvLyBJdGVyYXRlIG92ZXIgYXJyYXkgdmFsdWVzXG4gICAgZm9yIChpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgb2JqW2ldLCBpLCBvYmopO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBJdGVyYXRlIG92ZXIgb2JqZWN0IGtleXNcbiAgICBjb25zdCBrZXlzID0gYWxsT3duS2V5cyA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG9iaikgOiBPYmplY3Qua2V5cyhvYmopO1xuICAgIGNvbnN0IGxlbiA9IGtleXMubGVuZ3RoO1xuICAgIGxldCBrZXk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICBmbi5jYWxsKG51bGwsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmRLZXkob2JqLCBrZXkpIHtcbiAga2V5ID0ga2V5LnRvTG93ZXJDYXNlKCk7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICBsZXQgaSA9IGtleXMubGVuZ3RoO1xuICBsZXQgX2tleTtcbiAgd2hpbGUgKGktLSA+IDApIHtcbiAgICBfa2V5ID0ga2V5c1tpXTtcbiAgICBpZiAoa2V5ID09PSBfa2V5LnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIHJldHVybiBfa2V5O1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuY29uc3QgX2dsb2JhbCA9ICgoKSA9PiB7XG4gIC8qZXNsaW50IG5vLXVuZGVmOjAqL1xuICBpZiAodHlwZW9mIGdsb2JhbFRoaXMgIT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBnbG9iYWxUaGlzO1xuICByZXR1cm4gdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogZ2xvYmFsKVxufSkoKTtcblxuY29uc3QgaXNDb250ZXh0RGVmaW5lZCA9IChjb250ZXh0KSA9PiAhaXNVbmRlZmluZWQoY29udGV4dCkgJiYgY29udGV4dCAhPT0gX2dsb2JhbDtcblxuLyoqXG4gKiBBY2NlcHRzIHZhcmFyZ3MgZXhwZWN0aW5nIGVhY2ggYXJndW1lbnQgdG8gYmUgYW4gb2JqZWN0LCB0aGVuXG4gKiBpbW11dGFibHkgbWVyZ2VzIHRoZSBwcm9wZXJ0aWVzIG9mIGVhY2ggb2JqZWN0IGFuZCByZXR1cm5zIHJlc3VsdC5cbiAqXG4gKiBXaGVuIG11bHRpcGxlIG9iamVjdHMgY29udGFpbiB0aGUgc2FtZSBrZXkgdGhlIGxhdGVyIG9iamVjdCBpblxuICogdGhlIGFyZ3VtZW50cyBsaXN0IHdpbGwgdGFrZSBwcmVjZWRlbmNlLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogYGBganNcbiAqIHZhciByZXN1bHQgPSBtZXJnZSh7Zm9vOiAxMjN9LCB7Zm9vOiA0NTZ9KTtcbiAqIGNvbnNvbGUubG9nKHJlc3VsdC5mb28pOyAvLyBvdXRwdXRzIDQ1NlxuICogYGBgXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iajEgT2JqZWN0IHRvIG1lcmdlXG4gKlxuICogQHJldHVybnMge09iamVjdH0gUmVzdWx0IG9mIGFsbCBtZXJnZSBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIG1lcmdlKC8qIG9iajEsIG9iajIsIG9iajMsIC4uLiAqLykge1xuICBjb25zdCB7Y2FzZWxlc3N9ID0gaXNDb250ZXh0RGVmaW5lZCh0aGlzKSAmJiB0aGlzIHx8IHt9O1xuICBjb25zdCByZXN1bHQgPSB7fTtcbiAgY29uc3QgYXNzaWduVmFsdWUgPSAodmFsLCBrZXkpID0+IHtcbiAgICBjb25zdCB0YXJnZXRLZXkgPSBjYXNlbGVzcyAmJiBmaW5kS2V5KHJlc3VsdCwga2V5KSB8fCBrZXk7XG4gICAgaWYgKGlzUGxhaW5PYmplY3QocmVzdWx0W3RhcmdldEtleV0pICYmIGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgICAgcmVzdWx0W3RhcmdldEtleV0gPSBtZXJnZShyZXN1bHRbdGFyZ2V0S2V5XSwgdmFsKTtcbiAgICB9IGVsc2UgaWYgKGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgICAgcmVzdWx0W3RhcmdldEtleV0gPSBtZXJnZSh7fSwgdmFsKTtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsKSkge1xuICAgICAgcmVzdWx0W3RhcmdldEtleV0gPSB2YWwuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0W3RhcmdldEtleV0gPSB2YWw7XG4gICAgfVxuICB9O1xuXG4gIGZvciAobGV0IGkgPSAwLCBsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGFyZ3VtZW50c1tpXSAmJiBmb3JFYWNoKGFyZ3VtZW50c1tpXSwgYXNzaWduVmFsdWUpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRXh0ZW5kcyBvYmplY3QgYSBieSBtdXRhYmx5IGFkZGluZyB0byBpdCB0aGUgcHJvcGVydGllcyBvZiBvYmplY3QgYi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYSBUaGUgb2JqZWN0IHRvIGJlIGV4dGVuZGVkXG4gKiBAcGFyYW0ge09iamVjdH0gYiBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyBmcm9tXG4gKiBAcGFyYW0ge09iamVjdH0gdGhpc0FyZyBUaGUgb2JqZWN0IHRvIGJpbmQgZnVuY3Rpb24gdG9cbiAqXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFthbGxPd25LZXlzXVxuICogQHJldHVybnMge09iamVjdH0gVGhlIHJlc3VsdGluZyB2YWx1ZSBvZiBvYmplY3QgYVxuICovXG5jb25zdCBleHRlbmQgPSAoYSwgYiwgdGhpc0FyZywge2FsbE93bktleXN9PSB7fSkgPT4ge1xuICBmb3JFYWNoKGIsICh2YWwsIGtleSkgPT4ge1xuICAgIGlmICh0aGlzQXJnICYmIGlzRnVuY3Rpb24odmFsKSkge1xuICAgICAgYVtrZXldID0gYmluZCh2YWwsIHRoaXNBcmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhW2tleV0gPSB2YWw7XG4gICAgfVxuICB9LCB7YWxsT3duS2V5c30pO1xuICByZXR1cm4gYTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGJ5dGUgb3JkZXIgbWFya2VyLiBUaGlzIGNhdGNoZXMgRUYgQkIgQkYgKHRoZSBVVEYtOCBCT00pXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnQgd2l0aCBCT01cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBjb250ZW50IHZhbHVlIHdpdGhvdXQgQk9NXG4gKi9cbmNvbnN0IHN0cmlwQk9NID0gKGNvbnRlbnQpID0+IHtcbiAgaWYgKGNvbnRlbnQuY2hhckNvZGVBdCgwKSA9PT0gMHhGRUZGKSB7XG4gICAgY29udGVudCA9IGNvbnRlbnQuc2xpY2UoMSk7XG4gIH1cbiAgcmV0dXJuIGNvbnRlbnQ7XG59O1xuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlclxuICogQHBhcmFtIHtmdW5jdGlvbn0gY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBbcHJvcHNdXG4gKiBAcGFyYW0ge29iamVjdH0gW2Rlc2NyaXB0b3JzXVxuICpcbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5jb25zdCBpbmhlcml0cyA9IChjb25zdHJ1Y3Rvciwgc3VwZXJDb25zdHJ1Y3RvciwgcHJvcHMsIGRlc2NyaXB0b3JzKSA9PiB7XG4gIGNvbnN0cnVjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIGRlc2NyaXB0b3JzKTtcbiAgY29uc3RydWN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY29uc3RydWN0b3I7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb25zdHJ1Y3RvciwgJ3N1cGVyJywge1xuICAgIHZhbHVlOiBzdXBlckNvbnN0cnVjdG9yLnByb3RvdHlwZVxuICB9KTtcbiAgcHJvcHMgJiYgT2JqZWN0LmFzc2lnbihjb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3BzKTtcbn07XG5cbi8qKlxuICogUmVzb2x2ZSBvYmplY3Qgd2l0aCBkZWVwIHByb3RvdHlwZSBjaGFpbiB0byBhIGZsYXQgb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlT2JqIHNvdXJjZSBvYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBbZGVzdE9ial1cbiAqIEBwYXJhbSB7RnVuY3Rpb258Qm9vbGVhbn0gW2ZpbHRlcl1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcm9wRmlsdGVyXVxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9XG4gKi9cbmNvbnN0IHRvRmxhdE9iamVjdCA9IChzb3VyY2VPYmosIGRlc3RPYmosIGZpbHRlciwgcHJvcEZpbHRlcikgPT4ge1xuICBsZXQgcHJvcHM7XG4gIGxldCBpO1xuICBsZXQgcHJvcDtcbiAgY29uc3QgbWVyZ2VkID0ge307XG5cbiAgZGVzdE9iaiA9IGRlc3RPYmogfHwge307XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lcS1udWxsLGVxZXFlcVxuICBpZiAoc291cmNlT2JqID09IG51bGwpIHJldHVybiBkZXN0T2JqO1xuXG4gIGRvIHtcbiAgICBwcm9wcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHNvdXJjZU9iaik7XG4gICAgaSA9IHByb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tID4gMCkge1xuICAgICAgcHJvcCA9IHByb3BzW2ldO1xuICAgICAgaWYgKCghcHJvcEZpbHRlciB8fCBwcm9wRmlsdGVyKHByb3AsIHNvdXJjZU9iaiwgZGVzdE9iaikpICYmICFtZXJnZWRbcHJvcF0pIHtcbiAgICAgICAgZGVzdE9ialtwcm9wXSA9IHNvdXJjZU9ialtwcm9wXTtcbiAgICAgICAgbWVyZ2VkW3Byb3BdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgc291cmNlT2JqID0gZmlsdGVyICE9PSBmYWxzZSAmJiBnZXRQcm90b3R5cGVPZihzb3VyY2VPYmopO1xuICB9IHdoaWxlIChzb3VyY2VPYmogJiYgKCFmaWx0ZXIgfHwgZmlsdGVyKHNvdXJjZU9iaiwgZGVzdE9iaikpICYmIHNvdXJjZU9iaiAhPT0gT2JqZWN0LnByb3RvdHlwZSk7XG5cbiAgcmV0dXJuIGRlc3RPYmo7XG59O1xuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciBhIHN0cmluZyBlbmRzIHdpdGggdGhlIGNoYXJhY3RlcnMgb2YgYSBzcGVjaWZpZWQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHBhcmFtIHtTdHJpbmd9IHNlYXJjaFN0cmluZ1xuICogQHBhcmFtIHtOdW1iZXJ9IFtwb3NpdGlvbj0gMF1cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuY29uc3QgZW5kc1dpdGggPSAoc3RyLCBzZWFyY2hTdHJpbmcsIHBvc2l0aW9uKSA9PiB7XG4gIHN0ciA9IFN0cmluZyhzdHIpO1xuICBpZiAocG9zaXRpb24gPT09IHVuZGVmaW5lZCB8fCBwb3NpdGlvbiA+IHN0ci5sZW5ndGgpIHtcbiAgICBwb3NpdGlvbiA9IHN0ci5sZW5ndGg7XG4gIH1cbiAgcG9zaXRpb24gLT0gc2VhcmNoU3RyaW5nLmxlbmd0aDtcbiAgY29uc3QgbGFzdEluZGV4ID0gc3RyLmluZGV4T2Yoc2VhcmNoU3RyaW5nLCBwb3NpdGlvbik7XG4gIHJldHVybiBsYXN0SW5kZXggIT09IC0xICYmIGxhc3RJbmRleCA9PT0gcG9zaXRpb247XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyBuZXcgYXJyYXkgZnJvbSBhcnJheSBsaWtlIG9iamVjdCBvciBudWxsIGlmIGZhaWxlZFxuICpcbiAqIEBwYXJhbSB7Kn0gW3RoaW5nXVxuICpcbiAqIEByZXR1cm5zIHs/QXJyYXl9XG4gKi9cbmNvbnN0IHRvQXJyYXkgPSAodGhpbmcpID0+IHtcbiAgaWYgKCF0aGluZykgcmV0dXJuIG51bGw7XG4gIGlmIChpc0FycmF5KHRoaW5nKSkgcmV0dXJuIHRoaW5nO1xuICBsZXQgaSA9IHRoaW5nLmxlbmd0aDtcbiAgaWYgKCFpc051bWJlcihpKSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IGFyciA9IG5ldyBBcnJheShpKTtcbiAgd2hpbGUgKGktLSA+IDApIHtcbiAgICBhcnJbaV0gPSB0aGluZ1tpXTtcbiAgfVxuICByZXR1cm4gYXJyO1xufTtcblxuLyoqXG4gKiBDaGVja2luZyBpZiB0aGUgVWludDhBcnJheSBleGlzdHMgYW5kIGlmIGl0IGRvZXMsIGl0IHJldHVybnMgYSBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiB0aGVcbiAqIHRoaW5nIHBhc3NlZCBpbiBpcyBhbiBpbnN0YW5jZSBvZiBVaW50OEFycmF5XG4gKlxuICogQHBhcmFtIHtUeXBlZEFycmF5fVxuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbmNvbnN0IGlzVHlwZWRBcnJheSA9IChUeXBlZEFycmF5ID0+IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbiAgcmV0dXJuIHRoaW5nID0+IHtcbiAgICByZXR1cm4gVHlwZWRBcnJheSAmJiB0aGluZyBpbnN0YW5jZW9mIFR5cGVkQXJyYXk7XG4gIH07XG59KSh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgJiYgZ2V0UHJvdG90eXBlT2YoVWludDhBcnJheSkpO1xuXG4vKipcbiAqIEZvciBlYWNoIGVudHJ5IGluIHRoZSBvYmplY3QsIGNhbGwgdGhlIGZ1bmN0aW9uIHdpdGggdGhlIGtleSBhbmQgdmFsdWUuXG4gKlxuICogQHBhcmFtIHtPYmplY3Q8YW55LCBhbnk+fSBvYmogLSBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gVGhlIGZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggZW50cnkuXG4gKlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmNvbnN0IGZvckVhY2hFbnRyeSA9IChvYmosIGZuKSA9PiB7XG4gIGNvbnN0IGdlbmVyYXRvciA9IG9iaiAmJiBvYmpbU3ltYm9sLml0ZXJhdG9yXTtcblxuICBjb25zdCBpdGVyYXRvciA9IGdlbmVyYXRvci5jYWxsKG9iaik7XG5cbiAgbGV0IHJlc3VsdDtcblxuICB3aGlsZSAoKHJlc3VsdCA9IGl0ZXJhdG9yLm5leHQoKSkgJiYgIXJlc3VsdC5kb25lKSB7XG4gICAgY29uc3QgcGFpciA9IHJlc3VsdC52YWx1ZTtcbiAgICBmbi5jYWxsKG9iaiwgcGFpclswXSwgcGFpclsxXSk7XG4gIH1cbn07XG5cbi8qKlxuICogSXQgdGFrZXMgYSByZWd1bGFyIGV4cHJlc3Npb24gYW5kIGEgc3RyaW5nLCBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBhbGwgdGhlIG1hdGNoZXNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVnRXhwIC0gVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCBhZ2FpbnN0LlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFRoZSBzdHJpbmcgdG8gc2VhcmNoLlxuICpcbiAqIEByZXR1cm5zIHtBcnJheTxib29sZWFuPn1cbiAqL1xuY29uc3QgbWF0Y2hBbGwgPSAocmVnRXhwLCBzdHIpID0+IHtcbiAgbGV0IG1hdGNoZXM7XG4gIGNvbnN0IGFyciA9IFtdO1xuXG4gIHdoaWxlICgobWF0Y2hlcyA9IHJlZ0V4cC5leGVjKHN0cikpICE9PSBudWxsKSB7XG4gICAgYXJyLnB1c2gobWF0Y2hlcyk7XG4gIH1cblxuICByZXR1cm4gYXJyO1xufTtcblxuLyogQ2hlY2tpbmcgaWYgdGhlIGtpbmRPZlRlc3QgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHdoZW4gcGFzc2VkIGFuIEhUTUxGb3JtRWxlbWVudC4gKi9cbmNvbnN0IGlzSFRNTEZvcm0gPSBraW5kT2ZUZXN0KCdIVE1MRm9ybUVsZW1lbnQnKTtcblxuY29uc3QgdG9DYW1lbENhc2UgPSBzdHIgPT4ge1xuICByZXR1cm4gc3RyLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXFxzXShbYS16XFxkXSkoXFx3KikvZyxcbiAgICBmdW5jdGlvbiByZXBsYWNlcihtLCBwMSwgcDIpIHtcbiAgICAgIHJldHVybiBwMS50b1VwcGVyQ2FzZSgpICsgcDI7XG4gICAgfVxuICApO1xufTtcblxuLyogQ3JlYXRpbmcgYSBmdW5jdGlvbiB0aGF0IHdpbGwgY2hlY2sgaWYgYW4gb2JqZWN0IGhhcyBhIHByb3BlcnR5LiAqL1xuY29uc3QgaGFzT3duUHJvcGVydHkgPSAoKHtoYXNPd25Qcm9wZXJ0eX0pID0+IChvYmosIHByb3ApID0+IGhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKSkoT2JqZWN0LnByb3RvdHlwZSk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0XG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIFJlZ0V4cCBvYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1JlZ0V4cCA9IGtpbmRPZlRlc3QoJ1JlZ0V4cCcpO1xuXG5jb25zdCByZWR1Y2VEZXNjcmlwdG9ycyA9IChvYmosIHJlZHVjZXIpID0+IHtcbiAgY29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhvYmopO1xuICBjb25zdCByZWR1Y2VkRGVzY3JpcHRvcnMgPSB7fTtcblxuICBmb3JFYWNoKGRlc2NyaXB0b3JzLCAoZGVzY3JpcHRvciwgbmFtZSkgPT4ge1xuICAgIGxldCByZXQ7XG4gICAgaWYgKChyZXQgPSByZWR1Y2VyKGRlc2NyaXB0b3IsIG5hbWUsIG9iaikpICE9PSBmYWxzZSkge1xuICAgICAgcmVkdWNlZERlc2NyaXB0b3JzW25hbWVdID0gcmV0IHx8IGRlc2NyaXB0b3I7XG4gICAgfVxuICB9KTtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhvYmosIHJlZHVjZWREZXNjcmlwdG9ycyk7XG59O1xuXG4vKipcbiAqIE1ha2VzIGFsbCBtZXRob2RzIHJlYWQtb25seVxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICovXG5cbmNvbnN0IGZyZWV6ZU1ldGhvZHMgPSAob2JqKSA9PiB7XG4gIHJlZHVjZURlc2NyaXB0b3JzKG9iaiwgKGRlc2NyaXB0b3IsIG5hbWUpID0+IHtcbiAgICAvLyBza2lwIHJlc3RyaWN0ZWQgcHJvcHMgaW4gc3RyaWN0IG1vZGVcbiAgICBpZiAoaXNGdW5jdGlvbihvYmopICYmIFsnYXJndW1lbnRzJywgJ2NhbGxlcicsICdjYWxsZWUnXS5pbmRleE9mKG5hbWUpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gb2JqW25hbWVdO1xuXG4gICAgaWYgKCFpc0Z1bmN0aW9uKHZhbHVlKSkgcmV0dXJuO1xuXG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZmFsc2U7XG5cbiAgICBpZiAoJ3dyaXRhYmxlJyBpbiBkZXNjcmlwdG9yKSB7XG4gICAgICBkZXNjcmlwdG9yLndyaXRhYmxlID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFkZXNjcmlwdG9yLnNldCkge1xuICAgICAgZGVzY3JpcHRvci5zZXQgPSAoKSA9PiB7XG4gICAgICAgIHRocm93IEVycm9yKCdDYW4gbm90IHJld3JpdGUgcmVhZC1vbmx5IG1ldGhvZCBcXCcnICsgbmFtZSArICdcXCcnKTtcbiAgICAgIH07XG4gICAgfVxuICB9KTtcbn07XG5cbmNvbnN0IHRvT2JqZWN0U2V0ID0gKGFycmF5T3JTdHJpbmcsIGRlbGltaXRlcikgPT4ge1xuICBjb25zdCBvYmogPSB7fTtcblxuICBjb25zdCBkZWZpbmUgPSAoYXJyKSA9PiB7XG4gICAgYXJyLmZvckVhY2godmFsdWUgPT4ge1xuICAgICAgb2JqW3ZhbHVlXSA9IHRydWU7XG4gICAgfSk7XG4gIH07XG5cbiAgaXNBcnJheShhcnJheU9yU3RyaW5nKSA/IGRlZmluZShhcnJheU9yU3RyaW5nKSA6IGRlZmluZShTdHJpbmcoYXJyYXlPclN0cmluZykuc3BsaXQoZGVsaW1pdGVyKSk7XG5cbiAgcmV0dXJuIG9iajtcbn07XG5cbmNvbnN0IG5vb3AgPSAoKSA9PiB7fTtcblxuY29uc3QgdG9GaW5pdGVOdW1iZXIgPSAodmFsdWUsIGRlZmF1bHRWYWx1ZSkgPT4ge1xuICB2YWx1ZSA9ICt2YWx1ZTtcbiAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgPyB2YWx1ZSA6IGRlZmF1bHRWYWx1ZTtcbn07XG5cbmNvbnN0IEFMUEhBID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6JztcblxuY29uc3QgRElHSVQgPSAnMDEyMzQ1Njc4OSc7XG5cbmNvbnN0IEFMUEhBQkVUID0ge1xuICBESUdJVCxcbiAgQUxQSEEsXG4gIEFMUEhBX0RJR0lUOiBBTFBIQSArIEFMUEhBLnRvVXBwZXJDYXNlKCkgKyBESUdJVFxufTtcblxuY29uc3QgZ2VuZXJhdGVTdHJpbmcgPSAoc2l6ZSA9IDE2LCBhbHBoYWJldCA9IEFMUEhBQkVULkFMUEhBX0RJR0lUKSA9PiB7XG4gIGxldCBzdHIgPSAnJztcbiAgY29uc3Qge2xlbmd0aH0gPSBhbHBoYWJldDtcbiAgd2hpbGUgKHNpemUtLSkge1xuICAgIHN0ciArPSBhbHBoYWJldFtNYXRoLnJhbmRvbSgpICogbGVuZ3RofDBdO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn07XG5cbi8qKlxuICogSWYgdGhlIHRoaW5nIGlzIGEgRm9ybURhdGEgb2JqZWN0LCByZXR1cm4gdHJ1ZSwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS5cbiAqXG4gKiBAcGFyYW0ge3Vua25vd259IHRoaW5nIC0gVGhlIHRoaW5nIHRvIGNoZWNrLlxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc1NwZWNDb21wbGlhbnRGb3JtKHRoaW5nKSB7XG4gIHJldHVybiAhISh0aGluZyAmJiBpc0Z1bmN0aW9uKHRoaW5nLmFwcGVuZCkgJiYgdGhpbmdbU3ltYm9sLnRvU3RyaW5nVGFnXSA9PT0gJ0Zvcm1EYXRhJyAmJiB0aGluZ1tTeW1ib2wuaXRlcmF0b3JdKTtcbn1cblxuY29uc3QgdG9KU09OT2JqZWN0ID0gKG9iaikgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBBcnJheSgxMCk7XG5cbiAgY29uc3QgdmlzaXQgPSAoc291cmNlLCBpKSA9PiB7XG5cbiAgICBpZiAoaXNPYmplY3Qoc291cmNlKSkge1xuICAgICAgaWYgKHN0YWNrLmluZGV4T2Yoc291cmNlKSA+PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYoISgndG9KU09OJyBpbiBzb3VyY2UpKSB7XG4gICAgICAgIHN0YWNrW2ldID0gc291cmNlO1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBpc0FycmF5KHNvdXJjZSkgPyBbXSA6IHt9O1xuXG4gICAgICAgIGZvckVhY2goc291cmNlLCAodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlZHVjZWRWYWx1ZSA9IHZpc2l0KHZhbHVlLCBpICsgMSk7XG4gICAgICAgICAgIWlzVW5kZWZpbmVkKHJlZHVjZWRWYWx1ZSkgJiYgKHRhcmdldFtrZXldID0gcmVkdWNlZFZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3RhY2tbaV0gPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc291cmNlO1xuICB9O1xuXG4gIHJldHVybiB2aXNpdChvYmosIDApO1xufTtcblxuY29uc3QgaXNBc3luY0ZuID0ga2luZE9mVGVzdCgnQXN5bmNGdW5jdGlvbicpO1xuXG5jb25zdCBpc1RoZW5hYmxlID0gKHRoaW5nKSA9PlxuICB0aGluZyAmJiAoaXNPYmplY3QodGhpbmcpIHx8IGlzRnVuY3Rpb24odGhpbmcpKSAmJiBpc0Z1bmN0aW9uKHRoaW5nLnRoZW4pICYmIGlzRnVuY3Rpb24odGhpbmcuY2F0Y2gpO1xuXG5jb25zdCB1dGlscyA9IHtcbiAgaXNBcnJheSxcbiAgaXNBcnJheUJ1ZmZlcixcbiAgaXNCdWZmZXIsXG4gIGlzRm9ybURhdGEsXG4gIGlzQXJyYXlCdWZmZXJWaWV3LFxuICBpc1N0cmluZyxcbiAgaXNOdW1iZXIsXG4gIGlzQm9vbGVhbixcbiAgaXNPYmplY3QsXG4gIGlzUGxhaW5PYmplY3QsXG4gIGlzVW5kZWZpbmVkLFxuICBpc0RhdGUsXG4gIGlzRmlsZSxcbiAgaXNCbG9iLFxuICBpc1JlZ0V4cCxcbiAgaXNGdW5jdGlvbixcbiAgaXNTdHJlYW0sXG4gIGlzVVJMU2VhcmNoUGFyYW1zLFxuICBpc1R5cGVkQXJyYXksXG4gIGlzRmlsZUxpc3QsXG4gIGZvckVhY2gsXG4gIG1lcmdlLFxuICBleHRlbmQsXG4gIHRyaW0sXG4gIHN0cmlwQk9NLFxuICBpbmhlcml0cyxcbiAgdG9GbGF0T2JqZWN0LFxuICBraW5kT2YsXG4gIGtpbmRPZlRlc3QsXG4gIGVuZHNXaXRoLFxuICB0b0FycmF5LFxuICBmb3JFYWNoRW50cnksXG4gIG1hdGNoQWxsLFxuICBpc0hUTUxGb3JtLFxuICBoYXNPd25Qcm9wZXJ0eSxcbiAgaGFzT3duUHJvcDogaGFzT3duUHJvcGVydHksIC8vIGFuIGFsaWFzIHRvIGF2b2lkIEVTTGludCBuby1wcm90b3R5cGUtYnVpbHRpbnMgZGV0ZWN0aW9uXG4gIHJlZHVjZURlc2NyaXB0b3JzLFxuICBmcmVlemVNZXRob2RzLFxuICB0b09iamVjdFNldCxcbiAgdG9DYW1lbENhc2UsXG4gIG5vb3AsXG4gIHRvRmluaXRlTnVtYmVyLFxuICBmaW5kS2V5LFxuICBnbG9iYWw6IF9nbG9iYWwsXG4gIGlzQ29udGV4dERlZmluZWQsXG4gIEFMUEhBQkVULFxuICBnZW5lcmF0ZVN0cmluZyxcbiAgaXNTcGVjQ29tcGxpYW50Rm9ybSxcbiAgdG9KU09OT2JqZWN0LFxuICBpc0FzeW5jRm4sXG4gIGlzVGhlbmFibGVcbn07XG5cbi8qKlxuICogQ3JlYXRlIGFuIEVycm9yIHdpdGggdGhlIHNwZWNpZmllZCBtZXNzYWdlLCBjb25maWcsIGVycm9yIGNvZGUsIHJlcXVlc3QgYW5kIHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBlcnJvciBtZXNzYWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtjb2RlXSBUaGUgZXJyb3IgY29kZSAoZm9yIGV4YW1wbGUsICdFQ09OTkFCT1JURUQnKS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbY29uZmlnXSBUaGUgY29uZmlnLlxuICogQHBhcmFtIHtPYmplY3R9IFtyZXF1ZXN0XSBUaGUgcmVxdWVzdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVzcG9uc2VdIFRoZSByZXNwb25zZS5cbiAqXG4gKiBAcmV0dXJucyB7RXJyb3J9IFRoZSBjcmVhdGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBBeGlvc0Vycm9yKG1lc3NhZ2UsIGNvZGUsIGNvbmZpZywgcmVxdWVzdCwgcmVzcG9uc2UpIHtcbiAgRXJyb3IuY2FsbCh0aGlzKTtcblxuICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIHtcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnN0YWNrID0gKG5ldyBFcnJvcigpKS5zdGFjaztcbiAgfVxuXG4gIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gIHRoaXMubmFtZSA9ICdBeGlvc0Vycm9yJztcbiAgY29kZSAmJiAodGhpcy5jb2RlID0gY29kZSk7XG4gIGNvbmZpZyAmJiAodGhpcy5jb25maWcgPSBjb25maWcpO1xuICByZXF1ZXN0ICYmICh0aGlzLnJlcXVlc3QgPSByZXF1ZXN0KTtcbiAgcmVzcG9uc2UgJiYgKHRoaXMucmVzcG9uc2UgPSByZXNwb25zZSk7XG59XG5cbnV0aWxzLmluaGVyaXRzKEF4aW9zRXJyb3IsIEVycm9yLCB7XG4gIHRvSlNPTjogZnVuY3Rpb24gdG9KU09OKCkge1xuICAgIHJldHVybiB7XG4gICAgICAvLyBTdGFuZGFyZFxuICAgICAgbWVzc2FnZTogdGhpcy5tZXNzYWdlLFxuICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgLy8gTWljcm9zb2Z0XG4gICAgICBkZXNjcmlwdGlvbjogdGhpcy5kZXNjcmlwdGlvbixcbiAgICAgIG51bWJlcjogdGhpcy5udW1iZXIsXG4gICAgICAvLyBNb3ppbGxhXG4gICAgICBmaWxlTmFtZTogdGhpcy5maWxlTmFtZSxcbiAgICAgIGxpbmVOdW1iZXI6IHRoaXMubGluZU51bWJlcixcbiAgICAgIGNvbHVtbk51bWJlcjogdGhpcy5jb2x1bW5OdW1iZXIsXG4gICAgICBzdGFjazogdGhpcy5zdGFjayxcbiAgICAgIC8vIEF4aW9zXG4gICAgICBjb25maWc6IHV0aWxzLnRvSlNPTk9iamVjdCh0aGlzLmNvbmZpZyksXG4gICAgICBjb2RlOiB0aGlzLmNvZGUsXG4gICAgICBzdGF0dXM6IHRoaXMucmVzcG9uc2UgJiYgdGhpcy5yZXNwb25zZS5zdGF0dXMgPyB0aGlzLnJlc3BvbnNlLnN0YXR1cyA6IG51bGxcbiAgICB9O1xuICB9XG59KTtcblxuY29uc3QgcHJvdG90eXBlJDEgPSBBeGlvc0Vycm9yLnByb3RvdHlwZTtcbmNvbnN0IGRlc2NyaXB0b3JzID0ge307XG5cbltcbiAgJ0VSUl9CQURfT1BUSU9OX1ZBTFVFJyxcbiAgJ0VSUl9CQURfT1BUSU9OJyxcbiAgJ0VDT05OQUJPUlRFRCcsXG4gICdFVElNRURPVVQnLFxuICAnRVJSX05FVFdPUksnLFxuICAnRVJSX0ZSX1RPT19NQU5ZX1JFRElSRUNUUycsXG4gICdFUlJfREVQUkVDQVRFRCcsXG4gICdFUlJfQkFEX1JFU1BPTlNFJyxcbiAgJ0VSUl9CQURfUkVRVUVTVCcsXG4gICdFUlJfQ0FOQ0VMRUQnLFxuICAnRVJSX05PVF9TVVBQT1JUJyxcbiAgJ0VSUl9JTlZBTElEX1VSTCdcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG5dLmZvckVhY2goY29kZSA9PiB7XG4gIGRlc2NyaXB0b3JzW2NvZGVdID0ge3ZhbHVlOiBjb2RlfTtcbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydGllcyhBeGlvc0Vycm9yLCBkZXNjcmlwdG9ycyk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG90eXBlJDEsICdpc0F4aW9zRXJyb3InLCB7dmFsdWU6IHRydWV9KTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbkF4aW9zRXJyb3IuZnJvbSA9IChlcnJvciwgY29kZSwgY29uZmlnLCByZXF1ZXN0LCByZXNwb25zZSwgY3VzdG9tUHJvcHMpID0+IHtcbiAgY29uc3QgYXhpb3NFcnJvciA9IE9iamVjdC5jcmVhdGUocHJvdG90eXBlJDEpO1xuXG4gIHV0aWxzLnRvRmxhdE9iamVjdChlcnJvciwgYXhpb3NFcnJvciwgZnVuY3Rpb24gZmlsdGVyKG9iaikge1xuICAgIHJldHVybiBvYmogIT09IEVycm9yLnByb3RvdHlwZTtcbiAgfSwgcHJvcCA9PiB7XG4gICAgcmV0dXJuIHByb3AgIT09ICdpc0F4aW9zRXJyb3InO1xuICB9KTtcblxuICBBeGlvc0Vycm9yLmNhbGwoYXhpb3NFcnJvciwgZXJyb3IubWVzc2FnZSwgY29kZSwgY29uZmlnLCByZXF1ZXN0LCByZXNwb25zZSk7XG5cbiAgYXhpb3NFcnJvci5jYXVzZSA9IGVycm9yO1xuXG4gIGF4aW9zRXJyb3IubmFtZSA9IGVycm9yLm5hbWU7XG5cbiAgY3VzdG9tUHJvcHMgJiYgT2JqZWN0LmFzc2lnbihheGlvc0Vycm9yLCBjdXN0b21Qcm9wcyk7XG5cbiAgcmV0dXJuIGF4aW9zRXJyb3I7XG59O1xuXG4vKipcbiAqIERldGVybWluZXMgaWYgdGhlIGdpdmVuIHRoaW5nIGlzIGEgYXJyYXkgb3IganMgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0aGluZyAtIFRoZSBvYmplY3Qgb3IgYXJyYXkgdG8gYmUgdmlzaXRlZC5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNWaXNpdGFibGUodGhpbmcpIHtcbiAgcmV0dXJuIHV0aWxzLmlzUGxhaW5PYmplY3QodGhpbmcpIHx8IHV0aWxzLmlzQXJyYXkodGhpbmcpO1xufVxuXG4vKipcbiAqIEl0IHJlbW92ZXMgdGhlIGJyYWNrZXRzIGZyb20gdGhlIGVuZCBvZiBhIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUga2V5IG9mIHRoZSBwYXJhbWV0ZXIuXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gdGhlIGtleSB3aXRob3V0IHRoZSBicmFja2V0cy5cbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQnJhY2tldHMoa2V5KSB7XG4gIHJldHVybiB1dGlscy5lbmRzV2l0aChrZXksICdbXScpID8ga2V5LnNsaWNlKDAsIC0yKSA6IGtleTtcbn1cblxuLyoqXG4gKiBJdCB0YWtlcyBhIHBhdGgsIGEga2V5LCBhbmQgYSBib29sZWFuLCBhbmQgcmV0dXJucyBhIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIGN1cnJlbnQga2V5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBrZXkgb2YgdGhlIGN1cnJlbnQgb2JqZWN0IGJlaW5nIGl0ZXJhdGVkIG92ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gZG90cyAtIElmIHRydWUsIHRoZSBrZXkgd2lsbCBiZSByZW5kZXJlZCB3aXRoIGRvdHMgaW5zdGVhZCBvZiBicmFja2V0cy5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgcGF0aCB0byB0aGUgY3VycmVudCBrZXkuXG4gKi9cbmZ1bmN0aW9uIHJlbmRlcktleShwYXRoLCBrZXksIGRvdHMpIHtcbiAgaWYgKCFwYXRoKSByZXR1cm4ga2V5O1xuICByZXR1cm4gcGF0aC5jb25jYXQoa2V5KS5tYXAoZnVuY3Rpb24gZWFjaCh0b2tlbiwgaSkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgIHRva2VuID0gcmVtb3ZlQnJhY2tldHModG9rZW4pO1xuICAgIHJldHVybiAhZG90cyAmJiBpID8gJ1snICsgdG9rZW4gKyAnXScgOiB0b2tlbjtcbiAgfSkuam9pbihkb3RzID8gJy4nIDogJycpO1xufVxuXG4vKipcbiAqIElmIHRoZSBhcnJheSBpcyBhbiBhcnJheSBhbmQgbm9uZSBvZiBpdHMgZWxlbWVudHMgYXJlIHZpc2l0YWJsZSwgdGhlbiBpdCdzIGEgZmxhdCBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGFueT59IGFyciAtIFRoZSBhcnJheSB0byBjaGVja1xuICpcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc0ZsYXRBcnJheShhcnIpIHtcbiAgcmV0dXJuIHV0aWxzLmlzQXJyYXkoYXJyKSAmJiAhYXJyLnNvbWUoaXNWaXNpdGFibGUpO1xufVxuXG5jb25zdCBwcmVkaWNhdGVzID0gdXRpbHMudG9GbGF0T2JqZWN0KHV0aWxzLCB7fSwgbnVsbCwgZnVuY3Rpb24gZmlsdGVyKHByb3ApIHtcbiAgcmV0dXJuIC9eaXNbQS1aXS8udGVzdChwcm9wKTtcbn0pO1xuXG4vKipcbiAqIENvbnZlcnQgYSBkYXRhIG9iamVjdCB0byBGb3JtRGF0YVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7P09iamVjdH0gW2Zvcm1EYXRhXVxuICogQHBhcmFtIHs/T2JqZWN0fSBbb3B0aW9uc11cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLnZpc2l0b3JdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLm1ldGFUb2tlbnMgPSB0cnVlXVxuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5kb3RzID0gZmFsc2VdXG4gKiBAcGFyYW0gez9Cb29sZWFufSBbb3B0aW9ucy5pbmRleGVzID0gZmFsc2VdXG4gKlxuICogQHJldHVybnMge09iamVjdH1cbiAqKi9cblxuLyoqXG4gKiBJdCBjb252ZXJ0cyBhbiBvYmplY3QgaW50byBhIEZvcm1EYXRhIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PGFueSwgYW55Pn0gb2JqIC0gVGhlIG9iamVjdCB0byBjb252ZXJ0IHRvIGZvcm0gZGF0YS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtRGF0YSAtIFRoZSBGb3JtRGF0YSBvYmplY3QgdG8gYXBwZW5kIHRvLlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCBhbnk+fSBvcHRpb25zXG4gKlxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gdG9Gb3JtRGF0YShvYmosIGZvcm1EYXRhLCBvcHRpb25zKSB7XG4gIGlmICghdXRpbHMuaXNPYmplY3Qob2JqKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RhcmdldCBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gIGZvcm1EYXRhID0gZm9ybURhdGEgfHwgbmV3IChGb3JtRGF0YV9fZGVmYXVsdFtcImRlZmF1bHRcIl0gfHwgRm9ybURhdGEpKCk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gIG9wdGlvbnMgPSB1dGlscy50b0ZsYXRPYmplY3Qob3B0aW9ucywge1xuICAgIG1ldGFUb2tlbnM6IHRydWUsXG4gICAgZG90czogZmFsc2UsXG4gICAgaW5kZXhlczogZmFsc2VcbiAgfSwgZmFsc2UsIGZ1bmN0aW9uIGRlZmluZWQob3B0aW9uLCBzb3VyY2UpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXEtbnVsbCxlcWVxZXFcbiAgICByZXR1cm4gIXV0aWxzLmlzVW5kZWZpbmVkKHNvdXJjZVtvcHRpb25dKTtcbiAgfSk7XG5cbiAgY29uc3QgbWV0YVRva2VucyA9IG9wdGlvbnMubWV0YVRva2VucztcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gIGNvbnN0IHZpc2l0b3IgPSBvcHRpb25zLnZpc2l0b3IgfHwgZGVmYXVsdFZpc2l0b3I7XG4gIGNvbnN0IGRvdHMgPSBvcHRpb25zLmRvdHM7XG4gIGNvbnN0IGluZGV4ZXMgPSBvcHRpb25zLmluZGV4ZXM7XG4gIGNvbnN0IF9CbG9iID0gb3B0aW9ucy5CbG9iIHx8IHR5cGVvZiBCbG9iICE9PSAndW5kZWZpbmVkJyAmJiBCbG9iO1xuICBjb25zdCB1c2VCbG9iID0gX0Jsb2IgJiYgdXRpbHMuaXNTcGVjQ29tcGxpYW50Rm9ybShmb3JtRGF0YSk7XG5cbiAgaWYgKCF1dGlscy5pc0Z1bmN0aW9uKHZpc2l0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmlzaXRvciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnZlcnRWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuICcnO1xuXG4gICAgaWYgKHV0aWxzLmlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICAgIH1cblxuICAgIGlmICghdXNlQmxvYiAmJiB1dGlscy5pc0Jsb2IodmFsdWUpKSB7XG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignQmxvYiBpcyBub3Qgc3VwcG9ydGVkLiBVc2UgYSBCdWZmZXIgaW5zdGVhZC4nKTtcbiAgICB9XG5cbiAgICBpZiAodXRpbHMuaXNBcnJheUJ1ZmZlcih2YWx1ZSkgfHwgdXRpbHMuaXNUeXBlZEFycmF5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHVzZUJsb2IgJiYgdHlwZW9mIEJsb2IgPT09ICdmdW5jdGlvbicgPyBuZXcgQmxvYihbdmFsdWVdKSA6IEJ1ZmZlci5mcm9tKHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogRGVmYXVsdCB2aXNpdG9yLlxuICAgKlxuICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfE51bWJlcn0ga2V5XG4gICAqIEBwYXJhbSB7QXJyYXk8U3RyaW5nfE51bWJlcj59IHBhdGhcbiAgICogQHRoaXMge0Zvcm1EYXRhfVxuICAgKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gcmV0dXJuIHRydWUgdG8gdmlzaXQgdGhlIGVhY2ggcHJvcCBvZiB0aGUgdmFsdWUgcmVjdXJzaXZlbHlcbiAgICovXG4gIGZ1bmN0aW9uIGRlZmF1bHRWaXNpdG9yKHZhbHVlLCBrZXksIHBhdGgpIHtcbiAgICBsZXQgYXJyID0gdmFsdWU7XG5cbiAgICBpZiAodmFsdWUgJiYgIXBhdGggJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHV0aWxzLmVuZHNXaXRoKGtleSwgJ3t9JykpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgIGtleSA9IG1ldGFUb2tlbnMgPyBrZXkgOiBrZXkuc2xpY2UoMCwgLTIpO1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAgdmFsdWUgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAodXRpbHMuaXNBcnJheSh2YWx1ZSkgJiYgaXNGbGF0QXJyYXkodmFsdWUpKSB8fFxuICAgICAgICAoKHV0aWxzLmlzRmlsZUxpc3QodmFsdWUpIHx8IHV0aWxzLmVuZHNXaXRoKGtleSwgJ1tdJykpICYmIChhcnIgPSB1dGlscy50b0FycmF5KHZhbHVlKSlcbiAgICAgICAgKSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAga2V5ID0gcmVtb3ZlQnJhY2tldHMoa2V5KTtcblxuICAgICAgICBhcnIuZm9yRWFjaChmdW5jdGlvbiBlYWNoKGVsLCBpbmRleCkge1xuICAgICAgICAgICEodXRpbHMuaXNVbmRlZmluZWQoZWwpIHx8IGVsID09PSBudWxsKSAmJiBmb3JtRGF0YS5hcHBlbmQoXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmVzdGVkLXRlcm5hcnlcbiAgICAgICAgICAgIGluZGV4ZXMgPT09IHRydWUgPyByZW5kZXJLZXkoW2tleV0sIGluZGV4LCBkb3RzKSA6IChpbmRleGVzID09PSBudWxsID8ga2V5IDoga2V5ICsgJ1tdJyksXG4gICAgICAgICAgICBjb252ZXJ0VmFsdWUoZWwpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNWaXNpdGFibGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmb3JtRGF0YS5hcHBlbmQocmVuZGVyS2V5KHBhdGgsIGtleSwgZG90cyksIGNvbnZlcnRWYWx1ZSh2YWx1ZSkpO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3Qgc3RhY2sgPSBbXTtcblxuICBjb25zdCBleHBvc2VkSGVscGVycyA9IE9iamVjdC5hc3NpZ24ocHJlZGljYXRlcywge1xuICAgIGRlZmF1bHRWaXNpdG9yLFxuICAgIGNvbnZlcnRWYWx1ZSxcbiAgICBpc1Zpc2l0YWJsZVxuICB9KTtcblxuICBmdW5jdGlvbiBidWlsZCh2YWx1ZSwgcGF0aCkge1xuICAgIGlmICh1dGlscy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHJldHVybjtcblxuICAgIGlmIChzdGFjay5pbmRleE9mKHZhbHVlKSAhPT0gLTEpIHtcbiAgICAgIHRocm93IEVycm9yKCdDaXJjdWxhciByZWZlcmVuY2UgZGV0ZWN0ZWQgaW4gJyArIHBhdGguam9pbignLicpKTtcbiAgICB9XG5cbiAgICBzdGFjay5wdXNoKHZhbHVlKTtcblxuICAgIHV0aWxzLmZvckVhY2godmFsdWUsIGZ1bmN0aW9uIGVhY2goZWwsIGtleSkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gISh1dGlscy5pc1VuZGVmaW5lZChlbCkgfHwgZWwgPT09IG51bGwpICYmIHZpc2l0b3IuY2FsbChcbiAgICAgICAgZm9ybURhdGEsIGVsLCB1dGlscy5pc1N0cmluZyhrZXkpID8ga2V5LnRyaW0oKSA6IGtleSwgcGF0aCwgZXhwb3NlZEhlbHBlcnNcbiAgICAgICk7XG5cbiAgICAgIGlmIChyZXN1bHQgPT09IHRydWUpIHtcbiAgICAgICAgYnVpbGQoZWwsIHBhdGggPyBwYXRoLmNvbmNhdChrZXkpIDogW2tleV0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgc3RhY2sucG9wKCk7XG4gIH1cblxuICBpZiAoIXV0aWxzLmlzT2JqZWN0KG9iaikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gIH1cblxuICBidWlsZChvYmopO1xuXG4gIHJldHVybiBmb3JtRGF0YTtcbn1cblxuLyoqXG4gKiBJdCBlbmNvZGVzIGEgc3RyaW5nIGJ5IHJlcGxhY2luZyBhbGwgY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgaW4gdGhlIHVucmVzZXJ2ZWQgc2V0IHdpdGhcbiAqIHRoZWlyIHBlcmNlbnQtZW5jb2RlZCBlcXVpdmFsZW50c1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgc3RyaW5nIHRvIGVuY29kZS5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZW5jb2RlZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGVuY29kZSQxKHN0cikge1xuICBjb25zdCBjaGFyTWFwID0ge1xuICAgICchJzogJyUyMScsXG4gICAgXCInXCI6ICclMjcnLFxuICAgICcoJzogJyUyOCcsXG4gICAgJyknOiAnJTI5JyxcbiAgICAnfic6ICclN0UnLFxuICAgICclMjAnOiAnKycsXG4gICAgJyUwMCc6ICdcXHgwMCdcbiAgfTtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpLnJlcGxhY2UoL1shJygpfl18JTIwfCUwMC9nLCBmdW5jdGlvbiByZXBsYWNlcihtYXRjaCkge1xuICAgIHJldHVybiBjaGFyTWFwW21hdGNoXTtcbiAgfSk7XG59XG5cbi8qKlxuICogSXQgdGFrZXMgYSBwYXJhbXMgb2JqZWN0IGFuZCBjb252ZXJ0cyBpdCB0byBhIEZvcm1EYXRhIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgYW55Pn0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgdG8gYmUgY29udmVydGVkIHRvIGEgRm9ybURhdGEgb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCBhbnk+fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IHBhc3NlZCB0byB0aGUgQXhpb3MgY29uc3RydWN0b3IuXG4gKlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIEF4aW9zVVJMU2VhcmNoUGFyYW1zKHBhcmFtcywgb3B0aW9ucykge1xuICB0aGlzLl9wYWlycyA9IFtdO1xuXG4gIHBhcmFtcyAmJiB0b0Zvcm1EYXRhKHBhcmFtcywgdGhpcywgb3B0aW9ucyk7XG59XG5cbmNvbnN0IHByb3RvdHlwZSA9IEF4aW9zVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZTtcblxucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIGFwcGVuZChuYW1lLCB2YWx1ZSkge1xuICB0aGlzLl9wYWlycy5wdXNoKFtuYW1lLCB2YWx1ZV0pO1xufTtcblxucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoZW5jb2Rlcikge1xuICBjb25zdCBfZW5jb2RlID0gZW5jb2RlciA/IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGVuY29kZXIuY2FsbCh0aGlzLCB2YWx1ZSwgZW5jb2RlJDEpO1xuICB9IDogZW5jb2RlJDE7XG5cbiAgcmV0dXJuIHRoaXMuX3BhaXJzLm1hcChmdW5jdGlvbiBlYWNoKHBhaXIpIHtcbiAgICByZXR1cm4gX2VuY29kZShwYWlyWzBdKSArICc9JyArIF9lbmNvZGUocGFpclsxXSk7XG4gIH0sICcnKS5qb2luKCcmJyk7XG59O1xuXG4vKipcbiAqIEl0IHJlcGxhY2VzIGFsbCBpbnN0YW5jZXMgb2YgdGhlIGNoYXJhY3RlcnMgYDpgLCBgJGAsIGAsYCwgYCtgLCBgW2AsIGFuZCBgXWAgd2l0aCB0aGVpclxuICogVVJJIGVuY29kZWQgY291bnRlcnBhcnRzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbCBUaGUgdmFsdWUgdG8gYmUgZW5jb2RlZC5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZW5jb2RlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gZW5jb2RlKHZhbCkge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHZhbCkuXG4gICAgcmVwbGFjZSgvJTNBL2dpLCAnOicpLlxuICAgIHJlcGxhY2UoLyUyNC9nLCAnJCcpLlxuICAgIHJlcGxhY2UoLyUyQy9naSwgJywnKS5cbiAgICByZXBsYWNlKC8lMjAvZywgJysnKS5cbiAgICByZXBsYWNlKC8lNUIvZ2ksICdbJykuXG4gICAgcmVwbGFjZSgvJTVEL2dpLCAnXScpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgVVJMIGJ5IGFwcGVuZGluZyBwYXJhbXMgdG8gdGhlIGVuZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIGJhc2Ugb2YgdGhlIHVybCAoZS5nLiwgaHR0cDovL3d3dy5nb29nbGUuY29tKVxuICogQHBhcmFtIHtvYmplY3R9IFtwYXJhbXNdIFRoZSBwYXJhbXMgdG8gYmUgYXBwZW5kZWRcbiAqIEBwYXJhbSB7P29iamVjdH0gb3B0aW9uc1xuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtYXR0ZWQgdXJsXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkVVJMKHVybCwgcGFyYW1zLCBvcHRpb25zKSB7XG4gIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICBpZiAoIXBhcmFtcykge1xuICAgIHJldHVybiB1cmw7XG4gIH1cbiAgXG4gIGNvbnN0IF9lbmNvZGUgPSBvcHRpb25zICYmIG9wdGlvbnMuZW5jb2RlIHx8IGVuY29kZTtcblxuICBjb25zdCBzZXJpYWxpemVGbiA9IG9wdGlvbnMgJiYgb3B0aW9ucy5zZXJpYWxpemU7XG5cbiAgbGV0IHNlcmlhbGl6ZWRQYXJhbXM7XG5cbiAgaWYgKHNlcmlhbGl6ZUZuKSB7XG4gICAgc2VyaWFsaXplZFBhcmFtcyA9IHNlcmlhbGl6ZUZuKHBhcmFtcywgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgc2VyaWFsaXplZFBhcmFtcyA9IHV0aWxzLmlzVVJMU2VhcmNoUGFyYW1zKHBhcmFtcykgP1xuICAgICAgcGFyYW1zLnRvU3RyaW5nKCkgOlxuICAgICAgbmV3IEF4aW9zVVJMU2VhcmNoUGFyYW1zKHBhcmFtcywgb3B0aW9ucykudG9TdHJpbmcoX2VuY29kZSk7XG4gIH1cblxuICBpZiAoc2VyaWFsaXplZFBhcmFtcykge1xuICAgIGNvbnN0IGhhc2htYXJrSW5kZXggPSB1cmwuaW5kZXhPZihcIiNcIik7XG5cbiAgICBpZiAoaGFzaG1hcmtJbmRleCAhPT0gLTEpIHtcbiAgICAgIHVybCA9IHVybC5zbGljZSgwLCBoYXNobWFya0luZGV4KTtcbiAgICB9XG4gICAgdXJsICs9ICh1cmwuaW5kZXhPZignPycpID09PSAtMSA/ICc/JyA6ICcmJykgKyBzZXJpYWxpemVkUGFyYW1zO1xuICB9XG5cbiAgcmV0dXJuIHVybDtcbn1cblxuY2xhc3MgSW50ZXJjZXB0b3JNYW5hZ2VyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5oYW5kbGVycyA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIG5ldyBpbnRlcmNlcHRvciB0byB0aGUgc3RhY2tcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVsZmlsbGVkIFRoZSBmdW5jdGlvbiB0byBoYW5kbGUgYHRoZW5gIGZvciBhIGBQcm9taXNlYFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3RlZCBUaGUgZnVuY3Rpb24gdG8gaGFuZGxlIGByZWplY3RgIGZvciBhIGBQcm9taXNlYFxuICAgKlxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IEFuIElEIHVzZWQgdG8gcmVtb3ZlIGludGVyY2VwdG9yIGxhdGVyXG4gICAqL1xuICB1c2UoZnVsZmlsbGVkLCByZWplY3RlZCwgb3B0aW9ucykge1xuICAgIHRoaXMuaGFuZGxlcnMucHVzaCh7XG4gICAgICBmdWxmaWxsZWQsXG4gICAgICByZWplY3RlZCxcbiAgICAgIHN5bmNocm9ub3VzOiBvcHRpb25zID8gb3B0aW9ucy5zeW5jaHJvbm91cyA6IGZhbHNlLFxuICAgICAgcnVuV2hlbjogb3B0aW9ucyA/IG9wdGlvbnMucnVuV2hlbiA6IG51bGxcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVycy5sZW5ndGggLSAxO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBpbnRlcmNlcHRvciBmcm9tIHRoZSBzdGFja1xuICAgKlxuICAgKiBAcGFyYW0ge051bWJlcn0gaWQgVGhlIElEIHRoYXQgd2FzIHJldHVybmVkIGJ5IGB1c2VgXG4gICAqXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBgdHJ1ZWAgaWYgdGhlIGludGVyY2VwdG9yIHdhcyByZW1vdmVkLCBgZmFsc2VgIG90aGVyd2lzZVxuICAgKi9cbiAgZWplY3QoaWQpIHtcbiAgICBpZiAodGhpcy5oYW5kbGVyc1tpZF0pIHtcbiAgICAgIHRoaXMuaGFuZGxlcnNbaWRdID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgYWxsIGludGVyY2VwdG9ycyBmcm9tIHRoZSBzdGFja1xuICAgKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNsZWFyKCkge1xuICAgIGlmICh0aGlzLmhhbmRsZXJzKSB7XG4gICAgICB0aGlzLmhhbmRsZXJzID0gW107XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBhbGwgdGhlIHJlZ2lzdGVyZWQgaW50ZXJjZXB0b3JzXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgZm9yIHNraXBwaW5nIG92ZXIgYW55XG4gICAqIGludGVyY2VwdG9ycyB0aGF0IG1heSBoYXZlIGJlY29tZSBgbnVsbGAgY2FsbGluZyBgZWplY3RgLlxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZWFjaCBpbnRlcmNlcHRvclxuICAgKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGZvckVhY2goZm4pIHtcbiAgICB1dGlscy5mb3JFYWNoKHRoaXMuaGFuZGxlcnMsIGZ1bmN0aW9uIGZvckVhY2hIYW5kbGVyKGgpIHtcbiAgICAgIGlmIChoICE9PSBudWxsKSB7XG4gICAgICAgIGZuKGgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbmNvbnN0IEludGVyY2VwdG9yTWFuYWdlciQxID0gSW50ZXJjZXB0b3JNYW5hZ2VyO1xuXG5jb25zdCB0cmFuc2l0aW9uYWxEZWZhdWx0cyA9IHtcbiAgc2lsZW50SlNPTlBhcnNpbmc6IHRydWUsXG4gIGZvcmNlZEpTT05QYXJzaW5nOiB0cnVlLFxuICBjbGFyaWZ5VGltZW91dEVycm9yOiBmYWxzZVxufTtcblxuY29uc3QgVVJMU2VhcmNoUGFyYW1zID0gdXJsX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5VUkxTZWFyY2hQYXJhbXM7XG5cbmNvbnN0IHBsYXRmb3JtID0ge1xuICBpc05vZGU6IHRydWUsXG4gIGNsYXNzZXM6IHtcbiAgICBVUkxTZWFyY2hQYXJhbXMsXG4gICAgRm9ybURhdGE6IEZvcm1EYXRhX19kZWZhdWx0W1wiZGVmYXVsdFwiXSxcbiAgICBCbG9iOiB0eXBlb2YgQmxvYiAhPT0gJ3VuZGVmaW5lZCcgJiYgQmxvYiB8fCBudWxsXG4gIH0sXG4gIHByb3RvY29sczogWyAnaHR0cCcsICdodHRwcycsICdmaWxlJywgJ2RhdGEnIF1cbn07XG5cbmZ1bmN0aW9uIHRvVVJMRW5jb2RlZEZvcm0oZGF0YSwgb3B0aW9ucykge1xuICByZXR1cm4gdG9Gb3JtRGF0YShkYXRhLCBuZXcgcGxhdGZvcm0uY2xhc3Nlcy5VUkxTZWFyY2hQYXJhbXMoKSwgT2JqZWN0LmFzc2lnbih7XG4gICAgdmlzaXRvcjogZnVuY3Rpb24odmFsdWUsIGtleSwgcGF0aCwgaGVscGVycykge1xuICAgICAgaWYgKHV0aWxzLmlzQnVmZmVyKHZhbHVlKSkge1xuICAgICAgICB0aGlzLmFwcGVuZChrZXksIHZhbHVlLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGhlbHBlcnMuZGVmYXVsdFZpc2l0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH0sIG9wdGlvbnMpKTtcbn1cblxuLyoqXG4gKiBJdCB0YWtlcyBhIHN0cmluZyBsaWtlIGBmb29beF1beV1bel1gIGFuZCByZXR1cm5zIGFuIGFycmF5IGxpa2UgYFsnZm9vJywgJ3gnLCAneScsICd6J11cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKlxuICogQHJldHVybnMgQW4gYXJyYXkgb2Ygc3RyaW5ncy5cbiAqL1xuZnVuY3Rpb24gcGFyc2VQcm9wUGF0aChuYW1lKSB7XG4gIC8vIGZvb1t4XVt5XVt6XVxuICAvLyBmb28ueC55LnpcbiAgLy8gZm9vLXgteS16XG4gIC8vIGZvbyB4IHkgelxuICByZXR1cm4gdXRpbHMubWF0Y2hBbGwoL1xcdyt8XFxbKFxcdyopXS9nLCBuYW1lKS5tYXAobWF0Y2ggPT4ge1xuICAgIHJldHVybiBtYXRjaFswXSA9PT0gJ1tdJyA/ICcnIDogbWF0Y2hbMV0gfHwgbWF0Y2hbMF07XG4gIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnQgYW4gYXJyYXkgdG8gYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8YW55Pn0gYXJyIC0gVGhlIGFycmF5IHRvIGNvbnZlcnQgdG8gYW4gb2JqZWN0LlxuICpcbiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleXMgYW5kIHZhbHVlcyBhcyB0aGUgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5VG9PYmplY3QoYXJyKSB7XG4gIGNvbnN0IG9iaiA9IHt9O1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoYXJyKTtcbiAgbGV0IGk7XG4gIGNvbnN0IGxlbiA9IGtleXMubGVuZ3RoO1xuICBsZXQga2V5O1xuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBrZXkgPSBrZXlzW2ldO1xuICAgIG9ialtrZXldID0gYXJyW2tleV07XG4gIH1cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBJdCB0YWtlcyBhIEZvcm1EYXRhIG9iamVjdCBhbmQgcmV0dXJucyBhIEphdmFTY3JpcHQgb2JqZWN0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1EYXRhIFRoZSBGb3JtRGF0YSBvYmplY3QgdG8gY29udmVydCB0byBKU09OLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3Q8c3RyaW5nLCBhbnk+IHwgbnVsbH0gVGhlIGNvbnZlcnRlZCBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGZvcm1EYXRhVG9KU09OKGZvcm1EYXRhKSB7XG4gIGZ1bmN0aW9uIGJ1aWxkUGF0aChwYXRoLCB2YWx1ZSwgdGFyZ2V0LCBpbmRleCkge1xuICAgIGxldCBuYW1lID0gcGF0aFtpbmRleCsrXTtcbiAgICBjb25zdCBpc051bWVyaWNLZXkgPSBOdW1iZXIuaXNGaW5pdGUoK25hbWUpO1xuICAgIGNvbnN0IGlzTGFzdCA9IGluZGV4ID49IHBhdGgubGVuZ3RoO1xuICAgIG5hbWUgPSAhbmFtZSAmJiB1dGlscy5pc0FycmF5KHRhcmdldCkgPyB0YXJnZXQubGVuZ3RoIDogbmFtZTtcblxuICAgIGlmIChpc0xhc3QpIHtcbiAgICAgIGlmICh1dGlscy5oYXNPd25Qcm9wKHRhcmdldCwgbmFtZSkpIHtcbiAgICAgICAgdGFyZ2V0W25hbWVdID0gW3RhcmdldFtuYW1lXSwgdmFsdWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0W25hbWVdID0gdmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAhaXNOdW1lcmljS2V5O1xuICAgIH1cblxuICAgIGlmICghdGFyZ2V0W25hbWVdIHx8ICF1dGlscy5pc09iamVjdCh0YXJnZXRbbmFtZV0pKSB7XG4gICAgICB0YXJnZXRbbmFtZV0gPSBbXTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBidWlsZFBhdGgocGF0aCwgdmFsdWUsIHRhcmdldFtuYW1lXSwgaW5kZXgpO1xuXG4gICAgaWYgKHJlc3VsdCAmJiB1dGlscy5pc0FycmF5KHRhcmdldFtuYW1lXSkpIHtcbiAgICAgIHRhcmdldFtuYW1lXSA9IGFycmF5VG9PYmplY3QodGFyZ2V0W25hbWVdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gIWlzTnVtZXJpY0tleTtcbiAgfVxuXG4gIGlmICh1dGlscy5pc0Zvcm1EYXRhKGZvcm1EYXRhKSAmJiB1dGlscy5pc0Z1bmN0aW9uKGZvcm1EYXRhLmVudHJpZXMpKSB7XG4gICAgY29uc3Qgb2JqID0ge307XG5cbiAgICB1dGlscy5mb3JFYWNoRW50cnkoZm9ybURhdGEsIChuYW1lLCB2YWx1ZSkgPT4ge1xuICAgICAgYnVpbGRQYXRoKHBhcnNlUHJvcFBhdGgobmFtZSksIHZhbHVlLCBvYmosIDApO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIEl0IHRha2VzIGEgc3RyaW5nLCB0cmllcyB0byBwYXJzZSBpdCwgYW5kIGlmIGl0IGZhaWxzLCBpdCByZXR1cm5zIHRoZSBzdHJpbmdpZmllZCB2ZXJzaW9uXG4gKiBvZiB0aGUgaW5wdXRcbiAqXG4gKiBAcGFyYW0ge2FueX0gcmF3VmFsdWUgLSBUaGUgdmFsdWUgdG8gYmUgc3RyaW5naWZpZWQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwYXJzZXIgLSBBIGZ1bmN0aW9uIHRoYXQgcGFyc2VzIGEgc3RyaW5nIGludG8gYSBKYXZhU2NyaXB0IG9iamVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVuY29kZXIgLSBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYSB2YWx1ZSBhbmQgcmV0dXJucyBhIHN0cmluZy5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBBIHN0cmluZ2lmaWVkIHZlcnNpb24gb2YgdGhlIHJhd1ZhbHVlLlxuICovXG5mdW5jdGlvbiBzdHJpbmdpZnlTYWZlbHkocmF3VmFsdWUsIHBhcnNlciwgZW5jb2Rlcikge1xuICBpZiAodXRpbHMuaXNTdHJpbmcocmF3VmFsdWUpKSB7XG4gICAgdHJ5IHtcbiAgICAgIChwYXJzZXIgfHwgSlNPTi5wYXJzZSkocmF3VmFsdWUpO1xuICAgICAgcmV0dXJuIHV0aWxzLnRyaW0ocmF3VmFsdWUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlLm5hbWUgIT09ICdTeW50YXhFcnJvcicpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gKGVuY29kZXIgfHwgSlNPTi5zdHJpbmdpZnkpKHJhd1ZhbHVlKTtcbn1cblxuY29uc3QgZGVmYXVsdHMgPSB7XG5cbiAgdHJhbnNpdGlvbmFsOiB0cmFuc2l0aW9uYWxEZWZhdWx0cyxcblxuICBhZGFwdGVyOiBbJ3hocicsICdodHRwJ10sXG5cbiAgdHJhbnNmb3JtUmVxdWVzdDogW2Z1bmN0aW9uIHRyYW5zZm9ybVJlcXVlc3QoZGF0YSwgaGVhZGVycykge1xuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gaGVhZGVycy5nZXRDb250ZW50VHlwZSgpIHx8ICcnO1xuICAgIGNvbnN0IGhhc0pTT05Db250ZW50VHlwZSA9IGNvbnRlbnRUeXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA+IC0xO1xuICAgIGNvbnN0IGlzT2JqZWN0UGF5bG9hZCA9IHV0aWxzLmlzT2JqZWN0KGRhdGEpO1xuXG4gICAgaWYgKGlzT2JqZWN0UGF5bG9hZCAmJiB1dGlscy5pc0hUTUxGb3JtKGRhdGEpKSB7XG4gICAgICBkYXRhID0gbmV3IEZvcm1EYXRhKGRhdGEpO1xuICAgIH1cblxuICAgIGNvbnN0IGlzRm9ybURhdGEgPSB1dGlscy5pc0Zvcm1EYXRhKGRhdGEpO1xuXG4gICAgaWYgKGlzRm9ybURhdGEpIHtcbiAgICAgIGlmICghaGFzSlNPTkNvbnRlbnRUeXBlKSB7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0pTT05Db250ZW50VHlwZSA/IEpTT04uc3RyaW5naWZ5KGZvcm1EYXRhVG9KU09OKGRhdGEpKSA6IGRhdGE7XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzLmlzQXJyYXlCdWZmZXIoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzQnVmZmVyKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc1N0cmVhbShkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNGaWxlKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc0Jsb2IoZGF0YSlcbiAgICApIHtcbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICBpZiAodXRpbHMuaXNBcnJheUJ1ZmZlclZpZXcoZGF0YSkpIHtcbiAgICAgIHJldHVybiBkYXRhLmJ1ZmZlcjtcbiAgICB9XG4gICAgaWYgKHV0aWxzLmlzVVJMU2VhcmNoUGFyYW1zKGRhdGEpKSB7XG4gICAgICBoZWFkZXJzLnNldENvbnRlbnRUeXBlKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7Y2hhcnNldD11dGYtOCcsIGZhbHNlKTtcbiAgICAgIHJldHVybiBkYXRhLnRvU3RyaW5nKCk7XG4gICAgfVxuXG4gICAgbGV0IGlzRmlsZUxpc3Q7XG5cbiAgICBpZiAoaXNPYmplY3RQYXlsb2FkKSB7XG4gICAgICBpZiAoY29udGVudFR5cGUuaW5kZXhPZignYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykgPiAtMSkge1xuICAgICAgICByZXR1cm4gdG9VUkxFbmNvZGVkRm9ybShkYXRhLCB0aGlzLmZvcm1TZXJpYWxpemVyKS50b1N0cmluZygpO1xuICAgICAgfVxuXG4gICAgICBpZiAoKGlzRmlsZUxpc3QgPSB1dGlscy5pc0ZpbGVMaXN0KGRhdGEpKSB8fCBjb250ZW50VHlwZS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPiAtMSkge1xuICAgICAgICBjb25zdCBfRm9ybURhdGEgPSB0aGlzLmVudiAmJiB0aGlzLmVudi5Gb3JtRGF0YTtcblxuICAgICAgICByZXR1cm4gdG9Gb3JtRGF0YShcbiAgICAgICAgICBpc0ZpbGVMaXN0ID8geydmaWxlc1tdJzogZGF0YX0gOiBkYXRhLFxuICAgICAgICAgIF9Gb3JtRGF0YSAmJiBuZXcgX0Zvcm1EYXRhKCksXG4gICAgICAgICAgdGhpcy5mb3JtU2VyaWFsaXplclxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc09iamVjdFBheWxvYWQgfHwgaGFzSlNPTkNvbnRlbnRUeXBlICkge1xuICAgICAgaGVhZGVycy5zZXRDb250ZW50VHlwZSgnYXBwbGljYXRpb24vanNvbicsIGZhbHNlKTtcbiAgICAgIHJldHVybiBzdHJpbmdpZnlTYWZlbHkoZGF0YSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1dLFxuXG4gIHRyYW5zZm9ybVJlc3BvbnNlOiBbZnVuY3Rpb24gdHJhbnNmb3JtUmVzcG9uc2UoZGF0YSkge1xuICAgIGNvbnN0IHRyYW5zaXRpb25hbCA9IHRoaXMudHJhbnNpdGlvbmFsIHx8IGRlZmF1bHRzLnRyYW5zaXRpb25hbDtcbiAgICBjb25zdCBmb3JjZWRKU09OUGFyc2luZyA9IHRyYW5zaXRpb25hbCAmJiB0cmFuc2l0aW9uYWwuZm9yY2VkSlNPTlBhcnNpbmc7XG4gICAgY29uc3QgSlNPTlJlcXVlc3RlZCA9IHRoaXMucmVzcG9uc2VUeXBlID09PSAnanNvbic7XG5cbiAgICBpZiAoZGF0YSAmJiB1dGlscy5pc1N0cmluZyhkYXRhKSAmJiAoKGZvcmNlZEpTT05QYXJzaW5nICYmICF0aGlzLnJlc3BvbnNlVHlwZSkgfHwgSlNPTlJlcXVlc3RlZCkpIHtcbiAgICAgIGNvbnN0IHNpbGVudEpTT05QYXJzaW5nID0gdHJhbnNpdGlvbmFsICYmIHRyYW5zaXRpb25hbC5zaWxlbnRKU09OUGFyc2luZztcbiAgICAgIGNvbnN0IHN0cmljdEpTT05QYXJzaW5nID0gIXNpbGVudEpTT05QYXJzaW5nICYmIEpTT05SZXF1ZXN0ZWQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoc3RyaWN0SlNPTlBhcnNpbmcpIHtcbiAgICAgICAgICBpZiAoZS5uYW1lID09PSAnU3ludGF4RXJyb3InKSB7XG4gICAgICAgICAgICB0aHJvdyBBeGlvc0Vycm9yLmZyb20oZSwgQXhpb3NFcnJvci5FUlJfQkFEX1JFU1BPTlNFLCB0aGlzLCBudWxsLCB0aGlzLnJlc3BvbnNlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkYXRhO1xuICB9XSxcblxuICAvKipcbiAgICogQSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyB0byBhYm9ydCBhIHJlcXVlc3QuIElmIHNldCB0byAwIChkZWZhdWx0KSBhXG4gICAqIHRpbWVvdXQgaXMgbm90IGNyZWF0ZWQuXG4gICAqL1xuICB0aW1lb3V0OiAwLFxuXG4gIHhzcmZDb29raWVOYW1lOiAnWFNSRi1UT0tFTicsXG4gIHhzcmZIZWFkZXJOYW1lOiAnWC1YU1JGLVRPS0VOJyxcblxuICBtYXhDb250ZW50TGVuZ3RoOiAtMSxcbiAgbWF4Qm9keUxlbmd0aDogLTEsXG5cbiAgZW52OiB7XG4gICAgRm9ybURhdGE6IHBsYXRmb3JtLmNsYXNzZXMuRm9ybURhdGEsXG4gICAgQmxvYjogcGxhdGZvcm0uY2xhc3Nlcy5CbG9iXG4gIH0sXG5cbiAgdmFsaWRhdGVTdGF0dXM6IGZ1bmN0aW9uIHZhbGlkYXRlU3RhdHVzKHN0YXR1cykge1xuICAgIHJldHVybiBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMDtcbiAgfSxcblxuICBoZWFkZXJzOiB7XG4gICAgY29tbW9uOiB7XG4gICAgICAnQWNjZXB0JzogJ2FwcGxpY2F0aW9uL2pzb24sIHRleHQvcGxhaW4sICovKicsXG4gICAgICAnQ29udGVudC1UeXBlJzogdW5kZWZpbmVkXG4gICAgfVxuICB9XG59O1xuXG51dGlscy5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJ10sIChtZXRob2QpID0+IHtcbiAgZGVmYXVsdHMuaGVhZGVyc1ttZXRob2RdID0ge307XG59KTtcblxuY29uc3QgZGVmYXVsdHMkMSA9IGRlZmF1bHRzO1xuXG4vLyBSYXdBeGlvc0hlYWRlcnMgd2hvc2UgZHVwbGljYXRlcyBhcmUgaWdub3JlZCBieSBub2RlXG4vLyBjLmYuIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvaHR0cC5odG1sI2h0dHBfbWVzc2FnZV9oZWFkZXJzXG5jb25zdCBpZ25vcmVEdXBsaWNhdGVPZiA9IHV0aWxzLnRvT2JqZWN0U2V0KFtcbiAgJ2FnZScsICdhdXRob3JpemF0aW9uJywgJ2NvbnRlbnQtbGVuZ3RoJywgJ2NvbnRlbnQtdHlwZScsICdldGFnJyxcbiAgJ2V4cGlyZXMnLCAnZnJvbScsICdob3N0JywgJ2lmLW1vZGlmaWVkLXNpbmNlJywgJ2lmLXVubW9kaWZpZWQtc2luY2UnLFxuICAnbGFzdC1tb2RpZmllZCcsICdsb2NhdGlvbicsICdtYXgtZm9yd2FyZHMnLCAncHJveHktYXV0aG9yaXphdGlvbicsXG4gICdyZWZlcmVyJywgJ3JldHJ5LWFmdGVyJywgJ3VzZXItYWdlbnQnXG5dKTtcblxuLyoqXG4gKiBQYXJzZSBoZWFkZXJzIGludG8gYW4gb2JqZWN0XG4gKlxuICogYGBgXG4gKiBEYXRlOiBXZWQsIDI3IEF1ZyAyMDE0IDA4OjU4OjQ5IEdNVFxuICogQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uXG4gKiBDb25uZWN0aW9uOiBrZWVwLWFsaXZlXG4gKiBUcmFuc2Zlci1FbmNvZGluZzogY2h1bmtlZFxuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJhd0hlYWRlcnMgSGVhZGVycyBuZWVkaW5nIHRvIGJlIHBhcnNlZFxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IEhlYWRlcnMgcGFyc2VkIGludG8gYW4gb2JqZWN0XG4gKi9cbmNvbnN0IHBhcnNlSGVhZGVycyA9IHJhd0hlYWRlcnMgPT4ge1xuICBjb25zdCBwYXJzZWQgPSB7fTtcbiAgbGV0IGtleTtcbiAgbGV0IHZhbDtcbiAgbGV0IGk7XG5cbiAgcmF3SGVhZGVycyAmJiByYXdIZWFkZXJzLnNwbGl0KCdcXG4nKS5mb3JFYWNoKGZ1bmN0aW9uIHBhcnNlcihsaW5lKSB7XG4gICAgaSA9IGxpbmUuaW5kZXhPZignOicpO1xuICAgIGtleSA9IGxpbmUuc3Vic3RyaW5nKDAsIGkpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhbCA9IGxpbmUuc3Vic3RyaW5nKGkgKyAxKS50cmltKCk7XG5cbiAgICBpZiAoIWtleSB8fCAocGFyc2VkW2tleV0gJiYgaWdub3JlRHVwbGljYXRlT2Zba2V5XSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoa2V5ID09PSAnc2V0LWNvb2tpZScpIHtcbiAgICAgIGlmIChwYXJzZWRba2V5XSkge1xuICAgICAgICBwYXJzZWRba2V5XS5wdXNoKHZhbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJzZWRba2V5XSA9IFt2YWxdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYXJzZWRba2V5XSA9IHBhcnNlZFtrZXldID8gcGFyc2VkW2tleV0gKyAnLCAnICsgdmFsIDogdmFsO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHBhcnNlZDtcbn07XG5cbmNvbnN0ICRpbnRlcm5hbHMgPSBTeW1ib2woJ2ludGVybmFscycpO1xuXG5mdW5jdGlvbiBub3JtYWxpemVIZWFkZXIoaGVhZGVyKSB7XG4gIHJldHVybiBoZWFkZXIgJiYgU3RyaW5nKGhlYWRlcikudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVZhbHVlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PT0gZmFsc2UgfHwgdmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiB1dGlscy5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLm1hcChub3JtYWxpemVWYWx1ZSkgOiBTdHJpbmcodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBwYXJzZVRva2VucyhzdHIpIHtcbiAgY29uc3QgdG9rZW5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgY29uc3QgdG9rZW5zUkUgPSAvKFteXFxzLDs9XSspXFxzKig/Oj1cXHMqKFteLDtdKykpPy9nO1xuICBsZXQgbWF0Y2g7XG5cbiAgd2hpbGUgKChtYXRjaCA9IHRva2Vuc1JFLmV4ZWMoc3RyKSkpIHtcbiAgICB0b2tlbnNbbWF0Y2hbMV1dID0gbWF0Y2hbMl07XG4gIH1cblxuICByZXR1cm4gdG9rZW5zO1xufVxuXG5jb25zdCBpc1ZhbGlkSGVhZGVyTmFtZSA9IChzdHIpID0+IC9eWy1fYS16QS1aMC05XmB8fiwhIyQlJicqKy5dKyQvLnRlc3Qoc3RyLnRyaW0oKSk7XG5cbmZ1bmN0aW9uIG1hdGNoSGVhZGVyVmFsdWUoY29udGV4dCwgdmFsdWUsIGhlYWRlciwgZmlsdGVyLCBpc0hlYWRlck5hbWVGaWx0ZXIpIHtcbiAgaWYgKHV0aWxzLmlzRnVuY3Rpb24oZmlsdGVyKSkge1xuICAgIHJldHVybiBmaWx0ZXIuY2FsbCh0aGlzLCB2YWx1ZSwgaGVhZGVyKTtcbiAgfVxuXG4gIGlmIChpc0hlYWRlck5hbWVGaWx0ZXIpIHtcbiAgICB2YWx1ZSA9IGhlYWRlcjtcbiAgfVxuXG4gIGlmICghdXRpbHMuaXNTdHJpbmcodmFsdWUpKSByZXR1cm47XG5cbiAgaWYgKHV0aWxzLmlzU3RyaW5nKGZpbHRlcikpIHtcbiAgICByZXR1cm4gdmFsdWUuaW5kZXhPZihmaWx0ZXIpICE9PSAtMTtcbiAgfVxuXG4gIGlmICh1dGlscy5pc1JlZ0V4cChmaWx0ZXIpKSB7XG4gICAgcmV0dXJuIGZpbHRlci50ZXN0KHZhbHVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JtYXRIZWFkZXIoaGVhZGVyKSB7XG4gIHJldHVybiBoZWFkZXIudHJpbSgpXG4gICAgLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvKFthLXpcXGRdKShcXHcqKS9nLCAodywgY2hhciwgc3RyKSA9PiB7XG4gICAgICByZXR1cm4gY2hhci50b1VwcGVyQ2FzZSgpICsgc3RyO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBidWlsZEFjY2Vzc29ycyhvYmosIGhlYWRlcikge1xuICBjb25zdCBhY2Nlc3Nvck5hbWUgPSB1dGlscy50b0NhbWVsQ2FzZSgnICcgKyBoZWFkZXIpO1xuXG4gIFsnZ2V0JywgJ3NldCcsICdoYXMnXS5mb3JFYWNoKG1ldGhvZE5hbWUgPT4ge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIG1ldGhvZE5hbWUgKyBhY2Nlc3Nvck5hbWUsIHtcbiAgICAgIHZhbHVlOiBmdW5jdGlvbihhcmcxLCBhcmcyLCBhcmczKSB7XG4gICAgICAgIHJldHVybiB0aGlzW21ldGhvZE5hbWVdLmNhbGwodGhpcywgaGVhZGVyLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgICAgIH0sXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgfSk7XG59XG5cbmNsYXNzIEF4aW9zSGVhZGVycyB7XG4gIGNvbnN0cnVjdG9yKGhlYWRlcnMpIHtcbiAgICBoZWFkZXJzICYmIHRoaXMuc2V0KGhlYWRlcnMpO1xuICB9XG5cbiAgc2V0KGhlYWRlciwgdmFsdWVPclJld3JpdGUsIHJld3JpdGUpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGZ1bmN0aW9uIHNldEhlYWRlcihfdmFsdWUsIF9oZWFkZXIsIF9yZXdyaXRlKSB7XG4gICAgICBjb25zdCBsSGVhZGVyID0gbm9ybWFsaXplSGVhZGVyKF9oZWFkZXIpO1xuXG4gICAgICBpZiAoIWxIZWFkZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdoZWFkZXIgbmFtZSBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBrZXkgPSB1dGlscy5maW5kS2V5KHNlbGYsIGxIZWFkZXIpO1xuXG4gICAgICBpZigha2V5IHx8IHNlbGZba2V5XSA9PT0gdW5kZWZpbmVkIHx8IF9yZXdyaXRlID09PSB0cnVlIHx8IChfcmV3cml0ZSA9PT0gdW5kZWZpbmVkICYmIHNlbGZba2V5XSAhPT0gZmFsc2UpKSB7XG4gICAgICAgIHNlbGZba2V5IHx8IF9oZWFkZXJdID0gbm9ybWFsaXplVmFsdWUoX3ZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzZXRIZWFkZXJzID0gKGhlYWRlcnMsIF9yZXdyaXRlKSA9PlxuICAgICAgdXRpbHMuZm9yRWFjaChoZWFkZXJzLCAoX3ZhbHVlLCBfaGVhZGVyKSA9PiBzZXRIZWFkZXIoX3ZhbHVlLCBfaGVhZGVyLCBfcmV3cml0ZSkpO1xuXG4gICAgaWYgKHV0aWxzLmlzUGxhaW5PYmplY3QoaGVhZGVyKSB8fCBoZWFkZXIgaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yKSB7XG4gICAgICBzZXRIZWFkZXJzKGhlYWRlciwgdmFsdWVPclJld3JpdGUpO1xuICAgIH0gZWxzZSBpZih1dGlscy5pc1N0cmluZyhoZWFkZXIpICYmIChoZWFkZXIgPSBoZWFkZXIudHJpbSgpKSAmJiAhaXNWYWxpZEhlYWRlck5hbWUoaGVhZGVyKSkge1xuICAgICAgc2V0SGVhZGVycyhwYXJzZUhlYWRlcnMoaGVhZGVyKSwgdmFsdWVPclJld3JpdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBoZWFkZXIgIT0gbnVsbCAmJiBzZXRIZWFkZXIodmFsdWVPclJld3JpdGUsIGhlYWRlciwgcmV3cml0ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBnZXQoaGVhZGVyLCBwYXJzZXIpIHtcbiAgICBoZWFkZXIgPSBub3JtYWxpemVIZWFkZXIoaGVhZGVyKTtcblxuICAgIGlmIChoZWFkZXIpIHtcbiAgICAgIGNvbnN0IGtleSA9IHV0aWxzLmZpbmRLZXkodGhpcywgaGVhZGVyKTtcblxuICAgICAgaWYgKGtleSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXNba2V5XTtcblxuICAgICAgICBpZiAoIXBhcnNlcikge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJzZXIgPT09IHRydWUpIHtcbiAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlbnModmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzRnVuY3Rpb24ocGFyc2VyKSkge1xuICAgICAgICAgIHJldHVybiBwYXJzZXIuY2FsbCh0aGlzLCB2YWx1ZSwga2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1dGlscy5pc1JlZ0V4cChwYXJzZXIpKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlci5leGVjKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3BhcnNlciBtdXN0IGJlIGJvb2xlYW58cmVnZXhwfGZ1bmN0aW9uJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFzKGhlYWRlciwgbWF0Y2hlcikge1xuICAgIGhlYWRlciA9IG5vcm1hbGl6ZUhlYWRlcihoZWFkZXIpO1xuXG4gICAgaWYgKGhlYWRlcikge1xuICAgICAgY29uc3Qga2V5ID0gdXRpbHMuZmluZEtleSh0aGlzLCBoZWFkZXIpO1xuXG4gICAgICByZXR1cm4gISEoa2V5ICYmIHRoaXNba2V5XSAhPT0gdW5kZWZpbmVkICYmICghbWF0Y2hlciB8fCBtYXRjaEhlYWRlclZhbHVlKHRoaXMsIHRoaXNba2V5XSwga2V5LCBtYXRjaGVyKSkpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGRlbGV0ZShoZWFkZXIsIG1hdGNoZXIpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBsZXQgZGVsZXRlZCA9IGZhbHNlO1xuXG4gICAgZnVuY3Rpb24gZGVsZXRlSGVhZGVyKF9oZWFkZXIpIHtcbiAgICAgIF9oZWFkZXIgPSBub3JtYWxpemVIZWFkZXIoX2hlYWRlcik7XG5cbiAgICAgIGlmIChfaGVhZGVyKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHV0aWxzLmZpbmRLZXkoc2VsZiwgX2hlYWRlcik7XG5cbiAgICAgICAgaWYgKGtleSAmJiAoIW1hdGNoZXIgfHwgbWF0Y2hIZWFkZXJWYWx1ZShzZWxmLCBzZWxmW2tleV0sIGtleSwgbWF0Y2hlcikpKSB7XG4gICAgICAgICAgZGVsZXRlIHNlbGZba2V5XTtcblxuICAgICAgICAgIGRlbGV0ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzLmlzQXJyYXkoaGVhZGVyKSkge1xuICAgICAgaGVhZGVyLmZvckVhY2goZGVsZXRlSGVhZGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlSGVhZGVyKGhlYWRlcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRlbGV0ZWQ7XG4gIH1cblxuICBjbGVhcihtYXRjaGVyKSB7XG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpO1xuICAgIGxldCBpID0ga2V5cy5sZW5ndGg7XG4gICAgbGV0IGRlbGV0ZWQgPSBmYWxzZTtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07XG4gICAgICBpZighbWF0Y2hlciB8fCBtYXRjaEhlYWRlclZhbHVlKHRoaXMsIHRoaXNba2V5XSwga2V5LCBtYXRjaGVyLCB0cnVlKSkge1xuICAgICAgICBkZWxldGUgdGhpc1trZXldO1xuICAgICAgICBkZWxldGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGVsZXRlZDtcbiAgfVxuXG4gIG5vcm1hbGl6ZShmb3JtYXQpIHtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCBoZWFkZXJzID0ge307XG5cbiAgICB1dGlscy5mb3JFYWNoKHRoaXMsICh2YWx1ZSwgaGVhZGVyKSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSB1dGlscy5maW5kS2V5KGhlYWRlcnMsIGhlYWRlcik7XG5cbiAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgc2VsZltrZXldID0gbm9ybWFsaXplVmFsdWUodmFsdWUpO1xuICAgICAgICBkZWxldGUgc2VsZltoZWFkZXJdO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBmb3JtYXQgPyBmb3JtYXRIZWFkZXIoaGVhZGVyKSA6IFN0cmluZyhoZWFkZXIpLnRyaW0oKTtcblxuICAgICAgaWYgKG5vcm1hbGl6ZWQgIT09IGhlYWRlcikge1xuICAgICAgICBkZWxldGUgc2VsZltoZWFkZXJdO1xuICAgICAgfVxuXG4gICAgICBzZWxmW25vcm1hbGl6ZWRdID0gbm9ybWFsaXplVmFsdWUodmFsdWUpO1xuXG4gICAgICBoZWFkZXJzW25vcm1hbGl6ZWRdID0gdHJ1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgY29uY2F0KC4uLnRhcmdldHMpIHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5jb25jYXQodGhpcywgLi4udGFyZ2V0cyk7XG4gIH1cblxuICB0b0pTT04oYXNTdHJpbmdzKSB7XG4gICAgY29uc3Qgb2JqID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgIHV0aWxzLmZvckVhY2godGhpcywgKHZhbHVlLCBoZWFkZXIpID0+IHtcbiAgICAgIHZhbHVlICE9IG51bGwgJiYgdmFsdWUgIT09IGZhbHNlICYmIChvYmpbaGVhZGVyXSA9IGFzU3RyaW5ncyAmJiB1dGlscy5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLmpvaW4oJywgJykgOiB2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgW1N5bWJvbC5pdGVyYXRvcl0oKSB7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHRoaXMudG9KU09OKCkpW1N5bWJvbC5pdGVyYXRvcl0oKTtcbiAgfVxuXG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyh0aGlzLnRvSlNPTigpKS5tYXAoKFtoZWFkZXIsIHZhbHVlXSkgPT4gaGVhZGVyICsgJzogJyArIHZhbHVlKS5qb2luKCdcXG4nKTtcbiAgfVxuXG4gIGdldCBbU3ltYm9sLnRvU3RyaW5nVGFnXSgpIHtcbiAgICByZXR1cm4gJ0F4aW9zSGVhZGVycyc7XG4gIH1cblxuICBzdGF0aWMgZnJvbSh0aGluZykge1xuICAgIHJldHVybiB0aGluZyBpbnN0YW5jZW9mIHRoaXMgPyB0aGluZyA6IG5ldyB0aGlzKHRoaW5nKTtcbiAgfVxuXG4gIHN0YXRpYyBjb25jYXQoZmlyc3QsIC4uLnRhcmdldHMpIHtcbiAgICBjb25zdCBjb21wdXRlZCA9IG5ldyB0aGlzKGZpcnN0KTtcblxuICAgIHRhcmdldHMuZm9yRWFjaCgodGFyZ2V0KSA9PiBjb21wdXRlZC5zZXQodGFyZ2V0KSk7XG5cbiAgICByZXR1cm4gY29tcHV0ZWQ7XG4gIH1cblxuICBzdGF0aWMgYWNjZXNzb3IoaGVhZGVyKSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gdGhpc1skaW50ZXJuYWxzXSA9ICh0aGlzWyRpbnRlcm5hbHNdID0ge1xuICAgICAgYWNjZXNzb3JzOiB7fVxuICAgIH0pO1xuXG4gICAgY29uc3QgYWNjZXNzb3JzID0gaW50ZXJuYWxzLmFjY2Vzc29ycztcbiAgICBjb25zdCBwcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcblxuICAgIGZ1bmN0aW9uIGRlZmluZUFjY2Vzc29yKF9oZWFkZXIpIHtcbiAgICAgIGNvbnN0IGxIZWFkZXIgPSBub3JtYWxpemVIZWFkZXIoX2hlYWRlcik7XG5cbiAgICAgIGlmICghYWNjZXNzb3JzW2xIZWFkZXJdKSB7XG4gICAgICAgIGJ1aWxkQWNjZXNzb3JzKHByb3RvdHlwZSwgX2hlYWRlcik7XG4gICAgICAgIGFjY2Vzc29yc1tsSGVhZGVyXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdXRpbHMuaXNBcnJheShoZWFkZXIpID8gaGVhZGVyLmZvckVhY2goZGVmaW5lQWNjZXNzb3IpIDogZGVmaW5lQWNjZXNzb3IoaGVhZGVyKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbkF4aW9zSGVhZGVycy5hY2Nlc3NvcihbJ0NvbnRlbnQtVHlwZScsICdDb250ZW50LUxlbmd0aCcsICdBY2NlcHQnLCAnQWNjZXB0LUVuY29kaW5nJywgJ1VzZXItQWdlbnQnLCAnQXV0aG9yaXphdGlvbiddKTtcblxuLy8gcmVzZXJ2ZWQgbmFtZXMgaG90Zml4XG51dGlscy5yZWR1Y2VEZXNjcmlwdG9ycyhBeGlvc0hlYWRlcnMucHJvdG90eXBlLCAoe3ZhbHVlfSwga2V5KSA9PiB7XG4gIGxldCBtYXBwZWQgPSBrZXlbMF0udG9VcHBlckNhc2UoKSArIGtleS5zbGljZSgxKTsgLy8gbWFwIGBzZXRgID0+IGBTZXRgXG4gIHJldHVybiB7XG4gICAgZ2V0OiAoKSA9PiB2YWx1ZSxcbiAgICBzZXQoaGVhZGVyVmFsdWUpIHtcbiAgICAgIHRoaXNbbWFwcGVkXSA9IGhlYWRlclZhbHVlO1xuICAgIH1cbiAgfVxufSk7XG5cbnV0aWxzLmZyZWV6ZU1ldGhvZHMoQXhpb3NIZWFkZXJzKTtcblxuY29uc3QgQXhpb3NIZWFkZXJzJDEgPSBBeGlvc0hlYWRlcnM7XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBkYXRhIGZvciBhIHJlcXVlc3Qgb3IgYSByZXNwb25zZVxuICpcbiAqIEBwYXJhbSB7QXJyYXl8RnVuY3Rpb259IGZucyBBIHNpbmdsZSBmdW5jdGlvbiBvciBBcnJheSBvZiBmdW5jdGlvbnNcbiAqIEBwYXJhbSB7P09iamVjdH0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlIG9iamVjdFxuICpcbiAqIEByZXR1cm5zIHsqfSBUaGUgcmVzdWx0aW5nIHRyYW5zZm9ybWVkIGRhdGFcbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtRGF0YShmbnMsIHJlc3BvbnNlKSB7XG4gIGNvbnN0IGNvbmZpZyA9IHRoaXMgfHwgZGVmYXVsdHMkMTtcbiAgY29uc3QgY29udGV4dCA9IHJlc3BvbnNlIHx8IGNvbmZpZztcbiAgY29uc3QgaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmZyb20oY29udGV4dC5oZWFkZXJzKTtcbiAgbGV0IGRhdGEgPSBjb250ZXh0LmRhdGE7XG5cbiAgdXRpbHMuZm9yRWFjaChmbnMsIGZ1bmN0aW9uIHRyYW5zZm9ybShmbikge1xuICAgIGRhdGEgPSBmbi5jYWxsKGNvbmZpZywgZGF0YSwgaGVhZGVycy5ub3JtYWxpemUoKSwgcmVzcG9uc2UgPyByZXNwb25zZS5zdGF0dXMgOiB1bmRlZmluZWQpO1xuICB9KTtcblxuICBoZWFkZXJzLm5vcm1hbGl6ZSgpO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG5mdW5jdGlvbiBpc0NhbmNlbCh2YWx1ZSkge1xuICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWUuX19DQU5DRUxfXyk7XG59XG5cbi8qKlxuICogQSBgQ2FuY2VsZWRFcnJvcmAgaXMgYW4gb2JqZWN0IHRoYXQgaXMgdGhyb3duIHdoZW4gYW4gb3BlcmF0aW9uIGlzIGNhbmNlbGVkLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nPX0gbWVzc2FnZSBUaGUgbWVzc2FnZS5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gY29uZmlnIFRoZSBjb25maWcuXG4gKiBAcGFyYW0ge09iamVjdD19IHJlcXVlc3QgVGhlIHJlcXVlc3QuXG4gKlxuICogQHJldHVybnMge0NhbmNlbGVkRXJyb3J9IFRoZSBjcmVhdGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBDYW5jZWxlZEVycm9yKG1lc3NhZ2UsIGNvbmZpZywgcmVxdWVzdCkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXEtbnVsbCxlcWVxZXFcbiAgQXhpb3NFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UgPT0gbnVsbCA/ICdjYW5jZWxlZCcgOiBtZXNzYWdlLCBBeGlvc0Vycm9yLkVSUl9DQU5DRUxFRCwgY29uZmlnLCByZXF1ZXN0KTtcbiAgdGhpcy5uYW1lID0gJ0NhbmNlbGVkRXJyb3InO1xufVxuXG51dGlscy5pbmhlcml0cyhDYW5jZWxlZEVycm9yLCBBeGlvc0Vycm9yLCB7XG4gIF9fQ0FOQ0VMX186IHRydWVcbn0pO1xuXG4vKipcbiAqIFJlc29sdmUgb3IgcmVqZWN0IGEgUHJvbWlzZSBiYXNlZCBvbiByZXNwb25zZSBzdGF0dXMuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZSBBIGZ1bmN0aW9uIHRoYXQgcmVzb2x2ZXMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3QgQSBmdW5jdGlvbiB0aGF0IHJlamVjdHMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge29iamVjdH0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlLlxuICpcbiAqIEByZXR1cm5zIHtvYmplY3R9IFRoZSByZXNwb25zZS5cbiAqL1xuZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgcmVzcG9uc2UpIHtcbiAgY29uc3QgdmFsaWRhdGVTdGF0dXMgPSByZXNwb25zZS5jb25maWcudmFsaWRhdGVTdGF0dXM7XG4gIGlmICghcmVzcG9uc2Uuc3RhdHVzIHx8ICF2YWxpZGF0ZVN0YXR1cyB8fCB2YWxpZGF0ZVN0YXR1cyhyZXNwb25zZS5zdGF0dXMpKSB7XG4gICAgcmVzb2x2ZShyZXNwb25zZSk7XG4gIH0gZWxzZSB7XG4gICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgJ1JlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJyArIHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIFtBeGlvc0Vycm9yLkVSUl9CQURfUkVRVUVTVCwgQXhpb3NFcnJvci5FUlJfQkFEX1JFU1BPTlNFXVtNYXRoLmZsb29yKHJlc3BvbnNlLnN0YXR1cyAvIDEwMCkgLSA0XSxcbiAgICAgIHJlc3BvbnNlLmNvbmZpZyxcbiAgICAgIHJlc3BvbnNlLnJlcXVlc3QsXG4gICAgICByZXNwb25zZVxuICAgICkpO1xuICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgVVJMIGlzIGFic29sdXRlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgVVJMIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIFVSTCBpcyBhYnNvbHV0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQWJzb2x1dGVVUkwodXJsKSB7XG4gIC8vIEEgVVJMIGlzIGNvbnNpZGVyZWQgYWJzb2x1dGUgaWYgaXQgYmVnaW5zIHdpdGggXCI8c2NoZW1lPjovL1wiIG9yIFwiLy9cIiAocHJvdG9jb2wtcmVsYXRpdmUgVVJMKS5cbiAgLy8gUkZDIDM5ODYgZGVmaW5lcyBzY2hlbWUgbmFtZSBhcyBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYmVnaW5uaW5nIHdpdGggYSBsZXR0ZXIgYW5kIGZvbGxvd2VkXG4gIC8vIGJ5IGFueSBjb21iaW5hdGlvbiBvZiBsZXR0ZXJzLCBkaWdpdHMsIHBsdXMsIHBlcmlvZCwgb3IgaHlwaGVuLlxuICByZXR1cm4gL14oW2Etel1bYS16XFxkK1xcLS5dKjopP1xcL1xcLy9pLnRlc3QodXJsKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IFVSTCBieSBjb21iaW5pbmcgdGhlIHNwZWNpZmllZCBVUkxzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVUkwgVGhlIGJhc2UgVVJMXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVsYXRpdmVVUkwgVGhlIHJlbGF0aXZlIFVSTFxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb21iaW5lZCBVUkxcbiAqL1xuZnVuY3Rpb24gY29tYmluZVVSTHMoYmFzZVVSTCwgcmVsYXRpdmVVUkwpIHtcbiAgcmV0dXJuIHJlbGF0aXZlVVJMXG4gICAgPyBiYXNlVVJMLnJlcGxhY2UoL1xcLyskLywgJycpICsgJy8nICsgcmVsYXRpdmVVUkwucmVwbGFjZSgvXlxcLysvLCAnJylcbiAgICA6IGJhc2VVUkw7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBVUkwgYnkgY29tYmluaW5nIHRoZSBiYXNlVVJMIHdpdGggdGhlIHJlcXVlc3RlZFVSTCxcbiAqIG9ubHkgd2hlbiB0aGUgcmVxdWVzdGVkVVJMIGlzIG5vdCBhbHJlYWR5IGFuIGFic29sdXRlIFVSTC5cbiAqIElmIHRoZSByZXF1ZXN0VVJMIGlzIGFic29sdXRlLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIHJlcXVlc3RlZFVSTCB1bnRvdWNoZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVUkwgVGhlIGJhc2UgVVJMXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVxdWVzdGVkVVJMIEFic29sdXRlIG9yIHJlbGF0aXZlIFVSTCB0byBjb21iaW5lXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbWJpbmVkIGZ1bGwgcGF0aFxuICovXG5mdW5jdGlvbiBidWlsZEZ1bGxQYXRoKGJhc2VVUkwsIHJlcXVlc3RlZFVSTCkge1xuICBpZiAoYmFzZVVSTCAmJiAhaXNBYnNvbHV0ZVVSTChyZXF1ZXN0ZWRVUkwpKSB7XG4gICAgcmV0dXJuIGNvbWJpbmVVUkxzKGJhc2VVUkwsIHJlcXVlc3RlZFVSTCk7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3RlZFVSTDtcbn1cblxuY29uc3QgVkVSU0lPTiA9IFwiMS42LjBcIjtcblxuZnVuY3Rpb24gcGFyc2VQcm90b2NvbCh1cmwpIHtcbiAgY29uc3QgbWF0Y2ggPSAvXihbLStcXHddezEsMjV9KSg6P1xcL1xcL3w6KS8uZXhlYyh1cmwpO1xuICByZXR1cm4gbWF0Y2ggJiYgbWF0Y2hbMV0gfHwgJyc7XG59XG5cbmNvbnN0IERBVEFfVVJMX1BBVFRFUk4gPSAvXig/OihbXjtdKyk7KT8oPzpbXjtdKzspPyhiYXNlNjR8KSwoW1xcc1xcU10qKSQvO1xuXG4vKipcbiAqIFBhcnNlIGRhdGEgdXJpIHRvIGEgQnVmZmVyIG9yIEJsb2JcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJpXG4gKiBAcGFyYW0gez9Cb29sZWFufSBhc0Jsb2JcbiAqIEBwYXJhbSB7P09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHs/RnVuY3Rpb259IG9wdGlvbnMuQmxvYlxuICpcbiAqIEByZXR1cm5zIHtCdWZmZXJ8QmxvYn1cbiAqL1xuZnVuY3Rpb24gZnJvbURhdGFVUkkodXJpLCBhc0Jsb2IsIG9wdGlvbnMpIHtcbiAgY29uc3QgX0Jsb2IgPSBvcHRpb25zICYmIG9wdGlvbnMuQmxvYiB8fCBwbGF0Zm9ybS5jbGFzc2VzLkJsb2I7XG4gIGNvbnN0IHByb3RvY29sID0gcGFyc2VQcm90b2NvbCh1cmkpO1xuXG4gIGlmIChhc0Jsb2IgPT09IHVuZGVmaW5lZCAmJiBfQmxvYikge1xuICAgIGFzQmxvYiA9IHRydWU7XG4gIH1cblxuICBpZiAocHJvdG9jb2wgPT09ICdkYXRhJykge1xuICAgIHVyaSA9IHByb3RvY29sLmxlbmd0aCA/IHVyaS5zbGljZShwcm90b2NvbC5sZW5ndGggKyAxKSA6IHVyaTtcblxuICAgIGNvbnN0IG1hdGNoID0gREFUQV9VUkxfUEFUVEVSTi5leGVjKHVyaSk7XG5cbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignSW52YWxpZCBVUkwnLCBBeGlvc0Vycm9yLkVSUl9JTlZBTElEX1VSTCk7XG4gICAgfVxuXG4gICAgY29uc3QgbWltZSA9IG1hdGNoWzFdO1xuICAgIGNvbnN0IGlzQmFzZTY0ID0gbWF0Y2hbMl07XG4gICAgY29uc3QgYm9keSA9IG1hdGNoWzNdO1xuICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGRlY29kZVVSSUNvbXBvbmVudChib2R5KSwgaXNCYXNlNjQgPyAnYmFzZTY0JyA6ICd1dGY4Jyk7XG5cbiAgICBpZiAoYXNCbG9iKSB7XG4gICAgICBpZiAoIV9CbG9iKSB7XG4gICAgICAgIHRocm93IG5ldyBBeGlvc0Vycm9yKCdCbG9iIGlzIG5vdCBzdXBwb3J0ZWQnLCBBeGlvc0Vycm9yLkVSUl9OT1RfU1VQUE9SVCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgX0Jsb2IoW2J1ZmZlcl0sIHt0eXBlOiBtaW1lfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxuXG4gIHRocm93IG5ldyBBeGlvc0Vycm9yKCdVbnN1cHBvcnRlZCBwcm90b2NvbCAnICsgcHJvdG9jb2wsIEF4aW9zRXJyb3IuRVJSX05PVF9TVVBQT1JUKTtcbn1cblxuLyoqXG4gKiBUaHJvdHRsZSBkZWNvcmF0b3JcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge051bWJlcn0gZnJlcVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIHRocm90dGxlKGZuLCBmcmVxKSB7XG4gIGxldCB0aW1lc3RhbXAgPSAwO1xuICBjb25zdCB0aHJlc2hvbGQgPSAxMDAwIC8gZnJlcTtcbiAgbGV0IHRpbWVyID0gbnVsbDtcbiAgcmV0dXJuIGZ1bmN0aW9uIHRocm90dGxlZChmb3JjZSwgYXJncykge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgaWYgKGZvcmNlIHx8IG5vdyAtIHRpbWVzdGFtcCA+IHRocmVzaG9sZCkge1xuICAgICAgaWYgKHRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgIHRpbWVyID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRpbWVzdGFtcCA9IG5vdztcbiAgICAgIHJldHVybiBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICB9XG4gICAgaWYgKCF0aW1lcikge1xuICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgICB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICB9LCB0aHJlc2hvbGQgLSAobm93IC0gdGltZXN0YW1wKSk7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBkYXRhIG1heFJhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc2FtcGxlc0NvdW50PSAxMF1cbiAqIEBwYXJhbSB7TnVtYmVyfSBbbWluPSAxMDAwXVxuICogQHJldHVybnMge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBzcGVlZG9tZXRlcihzYW1wbGVzQ291bnQsIG1pbikge1xuICBzYW1wbGVzQ291bnQgPSBzYW1wbGVzQ291bnQgfHwgMTA7XG4gIGNvbnN0IGJ5dGVzID0gbmV3IEFycmF5KHNhbXBsZXNDb3VudCk7XG4gIGNvbnN0IHRpbWVzdGFtcHMgPSBuZXcgQXJyYXkoc2FtcGxlc0NvdW50KTtcbiAgbGV0IGhlYWQgPSAwO1xuICBsZXQgdGFpbCA9IDA7XG4gIGxldCBmaXJzdFNhbXBsZVRTO1xuXG4gIG1pbiA9IG1pbiAhPT0gdW5kZWZpbmVkID8gbWluIDogMTAwMDtcblxuICByZXR1cm4gZnVuY3Rpb24gcHVzaChjaHVua0xlbmd0aCkge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cbiAgICBjb25zdCBzdGFydGVkQXQgPSB0aW1lc3RhbXBzW3RhaWxdO1xuXG4gICAgaWYgKCFmaXJzdFNhbXBsZVRTKSB7XG4gICAgICBmaXJzdFNhbXBsZVRTID0gbm93O1xuICAgIH1cblxuICAgIGJ5dGVzW2hlYWRdID0gY2h1bmtMZW5ndGg7XG4gICAgdGltZXN0YW1wc1toZWFkXSA9IG5vdztcblxuICAgIGxldCBpID0gdGFpbDtcbiAgICBsZXQgYnl0ZXNDb3VudCA9IDA7XG5cbiAgICB3aGlsZSAoaSAhPT0gaGVhZCkge1xuICAgICAgYnl0ZXNDb3VudCArPSBieXRlc1tpKytdO1xuICAgICAgaSA9IGkgJSBzYW1wbGVzQ291bnQ7XG4gICAgfVxuXG4gICAgaGVhZCA9IChoZWFkICsgMSkgJSBzYW1wbGVzQ291bnQ7XG5cbiAgICBpZiAoaGVhZCA9PT0gdGFpbCkge1xuICAgICAgdGFpbCA9ICh0YWlsICsgMSkgJSBzYW1wbGVzQ291bnQ7XG4gICAgfVxuXG4gICAgaWYgKG5vdyAtIGZpcnN0U2FtcGxlVFMgPCBtaW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXNzZWQgPSBzdGFydGVkQXQgJiYgbm93IC0gc3RhcnRlZEF0O1xuXG4gICAgcmV0dXJuIHBhc3NlZCA/IE1hdGgucm91bmQoYnl0ZXNDb3VudCAqIDEwMDAgLyBwYXNzZWQpIDogdW5kZWZpbmVkO1xuICB9O1xufVxuXG5jb25zdCBrSW50ZXJuYWxzID0gU3ltYm9sKCdpbnRlcm5hbHMnKTtcblxuY2xhc3MgQXhpb3NUcmFuc2Zvcm1TdHJlYW0gZXh0ZW5kcyBzdHJlYW1fX2RlZmF1bHRbXCJkZWZhdWx0XCJdLlRyYW5zZm9ybXtcbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSB1dGlscy50b0ZsYXRPYmplY3Qob3B0aW9ucywge1xuICAgICAgbWF4UmF0ZTogMCxcbiAgICAgIGNodW5rU2l6ZTogNjQgKiAxMDI0LFxuICAgICAgbWluQ2h1bmtTaXplOiAxMDAsXG4gICAgICB0aW1lV2luZG93OiA1MDAsXG4gICAgICB0aWNrc1JhdGU6IDIsXG4gICAgICBzYW1wbGVzQ291bnQ6IDE1XG4gICAgfSwgbnVsbCwgKHByb3AsIHNvdXJjZSkgPT4ge1xuICAgICAgcmV0dXJuICF1dGlscy5pc1VuZGVmaW5lZChzb3VyY2VbcHJvcF0pO1xuICAgIH0pO1xuXG4gICAgc3VwZXIoe1xuICAgICAgcmVhZGFibGVIaWdoV2F0ZXJNYXJrOiBvcHRpb25zLmNodW5rU2l6ZVxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBjb25zdCBpbnRlcm5hbHMgPSB0aGlzW2tJbnRlcm5hbHNdID0ge1xuICAgICAgbGVuZ3RoOiBvcHRpb25zLmxlbmd0aCxcbiAgICAgIHRpbWVXaW5kb3c6IG9wdGlvbnMudGltZVdpbmRvdyxcbiAgICAgIHRpY2tzUmF0ZTogb3B0aW9ucy50aWNrc1JhdGUsXG4gICAgICBjaHVua1NpemU6IG9wdGlvbnMuY2h1bmtTaXplLFxuICAgICAgbWF4UmF0ZTogb3B0aW9ucy5tYXhSYXRlLFxuICAgICAgbWluQ2h1bmtTaXplOiBvcHRpb25zLm1pbkNodW5rU2l6ZSxcbiAgICAgIGJ5dGVzU2VlbjogMCxcbiAgICAgIGlzQ2FwdHVyZWQ6IGZhbHNlLFxuICAgICAgbm90aWZpZWRCeXRlc0xvYWRlZDogMCxcbiAgICAgIHRzOiBEYXRlLm5vdygpLFxuICAgICAgYnl0ZXM6IDAsXG4gICAgICBvblJlYWRDYWxsYmFjazogbnVsbFxuICAgIH07XG5cbiAgICBjb25zdCBfc3BlZWRvbWV0ZXIgPSBzcGVlZG9tZXRlcihpbnRlcm5hbHMudGlja3NSYXRlICogb3B0aW9ucy5zYW1wbGVzQ291bnQsIGludGVybmFscy50aW1lV2luZG93KTtcblxuICAgIHRoaXMub24oJ25ld0xpc3RlbmVyJywgZXZlbnQgPT4ge1xuICAgICAgaWYgKGV2ZW50ID09PSAncHJvZ3Jlc3MnKSB7XG4gICAgICAgIGlmICghaW50ZXJuYWxzLmlzQ2FwdHVyZWQpIHtcbiAgICAgICAgICBpbnRlcm5hbHMuaXNDYXB0dXJlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGxldCBieXRlc05vdGlmaWVkID0gMDtcblxuICAgIGludGVybmFscy51cGRhdGVQcm9ncmVzcyA9IHRocm90dGxlKGZ1bmN0aW9uIHRocm90dGxlZEhhbmRsZXIoKSB7XG4gICAgICBjb25zdCB0b3RhbEJ5dGVzID0gaW50ZXJuYWxzLmxlbmd0aDtcbiAgICAgIGNvbnN0IGJ5dGVzVHJhbnNmZXJyZWQgPSBpbnRlcm5hbHMuYnl0ZXNTZWVuO1xuICAgICAgY29uc3QgcHJvZ3Jlc3NCeXRlcyA9IGJ5dGVzVHJhbnNmZXJyZWQgLSBieXRlc05vdGlmaWVkO1xuICAgICAgaWYgKCFwcm9ncmVzc0J5dGVzIHx8IHNlbGYuZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IHJhdGUgPSBfc3BlZWRvbWV0ZXIocHJvZ3Jlc3NCeXRlcyk7XG5cbiAgICAgIGJ5dGVzTm90aWZpZWQgPSBieXRlc1RyYW5zZmVycmVkO1xuXG4gICAgICBwcm9jZXNzLm5leHRUaWNrKCgpID0+IHtcbiAgICAgICAgc2VsZi5lbWl0KCdwcm9ncmVzcycsIHtcbiAgICAgICAgICAnbG9hZGVkJzogYnl0ZXNUcmFuc2ZlcnJlZCxcbiAgICAgICAgICAndG90YWwnOiB0b3RhbEJ5dGVzLFxuICAgICAgICAgICdwcm9ncmVzcyc6IHRvdGFsQnl0ZXMgPyAoYnl0ZXNUcmFuc2ZlcnJlZCAvIHRvdGFsQnl0ZXMpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICdieXRlcyc6IHByb2dyZXNzQnl0ZXMsXG4gICAgICAgICAgJ3JhdGUnOiByYXRlID8gcmF0ZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAnZXN0aW1hdGVkJzogcmF0ZSAmJiB0b3RhbEJ5dGVzICYmIGJ5dGVzVHJhbnNmZXJyZWQgPD0gdG90YWxCeXRlcyA/XG4gICAgICAgICAgICAodG90YWxCeXRlcyAtIGJ5dGVzVHJhbnNmZXJyZWQpIC8gcmF0ZSA6IHVuZGVmaW5lZFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0sIGludGVybmFscy50aWNrc1JhdGUpO1xuXG4gICAgY29uc3Qgb25GaW5pc2ggPSAoKSA9PiB7XG4gICAgICBpbnRlcm5hbHMudXBkYXRlUHJvZ3Jlc3ModHJ1ZSk7XG4gICAgfTtcblxuICAgIHRoaXMub25jZSgnZW5kJywgb25GaW5pc2gpO1xuICAgIHRoaXMub25jZSgnZXJyb3InLCBvbkZpbmlzaCk7XG4gIH1cblxuICBfcmVhZChzaXplKSB7XG4gICAgY29uc3QgaW50ZXJuYWxzID0gdGhpc1trSW50ZXJuYWxzXTtcblxuICAgIGlmIChpbnRlcm5hbHMub25SZWFkQ2FsbGJhY2spIHtcbiAgICAgIGludGVybmFscy5vblJlYWRDYWxsYmFjaygpO1xuICAgIH1cblxuICAgIHJldHVybiBzdXBlci5fcmVhZChzaXplKTtcbiAgfVxuXG4gIF90cmFuc2Zvcm0oY2h1bmssIGVuY29kaW5nLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IGludGVybmFscyA9IHRoaXNba0ludGVybmFsc107XG4gICAgY29uc3QgbWF4UmF0ZSA9IGludGVybmFscy5tYXhSYXRlO1xuXG4gICAgY29uc3QgcmVhZGFibGVIaWdoV2F0ZXJNYXJrID0gdGhpcy5yZWFkYWJsZUhpZ2hXYXRlck1hcms7XG5cbiAgICBjb25zdCB0aW1lV2luZG93ID0gaW50ZXJuYWxzLnRpbWVXaW5kb3c7XG5cbiAgICBjb25zdCBkaXZpZGVyID0gMTAwMCAvIHRpbWVXaW5kb3c7XG4gICAgY29uc3QgYnl0ZXNUaHJlc2hvbGQgPSAobWF4UmF0ZSAvIGRpdmlkZXIpO1xuICAgIGNvbnN0IG1pbkNodW5rU2l6ZSA9IGludGVybmFscy5taW5DaHVua1NpemUgIT09IGZhbHNlID8gTWF0aC5tYXgoaW50ZXJuYWxzLm1pbkNodW5rU2l6ZSwgYnl0ZXNUaHJlc2hvbGQgKiAwLjAxKSA6IDA7XG5cbiAgICBmdW5jdGlvbiBwdXNoQ2h1bmsoX2NodW5rLCBfY2FsbGJhY2spIHtcbiAgICAgIGNvbnN0IGJ5dGVzID0gQnVmZmVyLmJ5dGVMZW5ndGgoX2NodW5rKTtcbiAgICAgIGludGVybmFscy5ieXRlc1NlZW4gKz0gYnl0ZXM7XG4gICAgICBpbnRlcm5hbHMuYnl0ZXMgKz0gYnl0ZXM7XG5cbiAgICAgIGlmIChpbnRlcm5hbHMuaXNDYXB0dXJlZCkge1xuICAgICAgICBpbnRlcm5hbHMudXBkYXRlUHJvZ3Jlc3MoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNlbGYucHVzaChfY2h1bmspKSB7XG4gICAgICAgIHByb2Nlc3MubmV4dFRpY2soX2NhbGxiYWNrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGludGVybmFscy5vblJlYWRDYWxsYmFjayA9ICgpID0+IHtcbiAgICAgICAgICBpbnRlcm5hbHMub25SZWFkQ2FsbGJhY2sgPSBudWxsO1xuICAgICAgICAgIHByb2Nlc3MubmV4dFRpY2soX2NhbGxiYWNrKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc2Zvcm1DaHVuayA9IChfY2h1bmssIF9jYWxsYmFjaykgPT4ge1xuICAgICAgY29uc3QgY2h1bmtTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgoX2NodW5rKTtcbiAgICAgIGxldCBjaHVua1JlbWFpbmRlciA9IG51bGw7XG4gICAgICBsZXQgbWF4Q2h1bmtTaXplID0gcmVhZGFibGVIaWdoV2F0ZXJNYXJrO1xuICAgICAgbGV0IGJ5dGVzTGVmdDtcbiAgICAgIGxldCBwYXNzZWQgPSAwO1xuXG4gICAgICBpZiAobWF4UmF0ZSkge1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgIGlmICghaW50ZXJuYWxzLnRzIHx8IChwYXNzZWQgPSAobm93IC0gaW50ZXJuYWxzLnRzKSkgPj0gdGltZVdpbmRvdykge1xuICAgICAgICAgIGludGVybmFscy50cyA9IG5vdztcbiAgICAgICAgICBieXRlc0xlZnQgPSBieXRlc1RocmVzaG9sZCAtIGludGVybmFscy5ieXRlcztcbiAgICAgICAgICBpbnRlcm5hbHMuYnl0ZXMgPSBieXRlc0xlZnQgPCAwID8gLWJ5dGVzTGVmdCA6IDA7XG4gICAgICAgICAgcGFzc2VkID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGJ5dGVzTGVmdCA9IGJ5dGVzVGhyZXNob2xkIC0gaW50ZXJuYWxzLmJ5dGVzO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF4UmF0ZSkge1xuICAgICAgICBpZiAoYnl0ZXNMZWZ0IDw9IDApIHtcbiAgICAgICAgICAvLyBuZXh0IHRpbWUgd2luZG93XG4gICAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgX2NhbGxiYWNrKG51bGwsIF9jaHVuayk7XG4gICAgICAgICAgfSwgdGltZVdpbmRvdyAtIHBhc3NlZCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYnl0ZXNMZWZ0IDwgbWF4Q2h1bmtTaXplKSB7XG4gICAgICAgICAgbWF4Q2h1bmtTaXplID0gYnl0ZXNMZWZ0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChtYXhDaHVua1NpemUgJiYgY2h1bmtTaXplID4gbWF4Q2h1bmtTaXplICYmIChjaHVua1NpemUgLSBtYXhDaHVua1NpemUpID4gbWluQ2h1bmtTaXplKSB7XG4gICAgICAgIGNodW5rUmVtYWluZGVyID0gX2NodW5rLnN1YmFycmF5KG1heENodW5rU2l6ZSk7XG4gICAgICAgIF9jaHVuayA9IF9jaHVuay5zdWJhcnJheSgwLCBtYXhDaHVua1NpemUpO1xuICAgICAgfVxuXG4gICAgICBwdXNoQ2h1bmsoX2NodW5rLCBjaHVua1JlbWFpbmRlciA/ICgpID0+IHtcbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhfY2FsbGJhY2ssIG51bGwsIGNodW5rUmVtYWluZGVyKTtcbiAgICAgIH0gOiBfY2FsbGJhY2spO1xuICAgIH07XG5cbiAgICB0cmFuc2Zvcm1DaHVuayhjaHVuaywgZnVuY3Rpb24gdHJhbnNmb3JtTmV4dENodW5rKGVyciwgX2NodW5rKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoX2NodW5rKSB7XG4gICAgICAgIHRyYW5zZm9ybUNodW5rKF9jaHVuaywgdHJhbnNmb3JtTmV4dENodW5rKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2V0TGVuZ3RoKGxlbmd0aCkge1xuICAgIHRoaXNba0ludGVybmFsc10ubGVuZ3RoID0gK2xlbmd0aDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG5jb25zdCBBeGlvc1RyYW5zZm9ybVN0cmVhbSQxID0gQXhpb3NUcmFuc2Zvcm1TdHJlYW07XG5cbmNvbnN0IHthc3luY0l0ZXJhdG9yfSA9IFN5bWJvbDtcblxuY29uc3QgcmVhZEJsb2IgPSBhc3luYyBmdW5jdGlvbiogKGJsb2IpIHtcbiAgaWYgKGJsb2Iuc3RyZWFtKSB7XG4gICAgeWllbGQqIGJsb2Iuc3RyZWFtKCk7XG4gIH0gZWxzZSBpZiAoYmxvYi5hcnJheUJ1ZmZlcikge1xuICAgIHlpZWxkIGF3YWl0IGJsb2IuYXJyYXlCdWZmZXIoKTtcbiAgfSBlbHNlIGlmIChibG9iW2FzeW5jSXRlcmF0b3JdKSB7XG4gICAgeWllbGQqIGJsb2JbYXN5bmNJdGVyYXRvcl0oKTtcbiAgfSBlbHNlIHtcbiAgICB5aWVsZCBibG9iO1xuICB9XG59O1xuXG5jb25zdCByZWFkQmxvYiQxID0gcmVhZEJsb2I7XG5cbmNvbnN0IEJPVU5EQVJZX0FMUEhBQkVUID0gdXRpbHMuQUxQSEFCRVQuQUxQSEFfRElHSVQgKyAnLV8nO1xuXG5jb25zdCB0ZXh0RW5jb2RlciA9IG5ldyB1dGlsLlRleHRFbmNvZGVyKCk7XG5cbmNvbnN0IENSTEYgPSAnXFxyXFxuJztcbmNvbnN0IENSTEZfQllURVMgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoQ1JMRik7XG5jb25zdCBDUkxGX0JZVEVTX0NPVU5UID0gMjtcblxuY2xhc3MgRm9ybURhdGFQYXJ0IHtcbiAgY29uc3RydWN0b3IobmFtZSwgdmFsdWUpIHtcbiAgICBjb25zdCB7ZXNjYXBlTmFtZX0gPSB0aGlzLmNvbnN0cnVjdG9yO1xuICAgIGNvbnN0IGlzU3RyaW5nVmFsdWUgPSB1dGlscy5pc1N0cmluZyh2YWx1ZSk7XG5cbiAgICBsZXQgaGVhZGVycyA9IGBDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9XCIke2VzY2FwZU5hbWUobmFtZSl9XCIke1xuICAgICAgIWlzU3RyaW5nVmFsdWUgJiYgdmFsdWUubmFtZSA/IGA7IGZpbGVuYW1lPVwiJHtlc2NhcGVOYW1lKHZhbHVlLm5hbWUpfVwiYCA6ICcnXG4gICAgfSR7Q1JMRn1gO1xuXG4gICAgaWYgKGlzU3RyaW5nVmFsdWUpIHtcbiAgICAgIHZhbHVlID0gdGV4dEVuY29kZXIuZW5jb2RlKFN0cmluZyh2YWx1ZSkucmVwbGFjZSgvXFxyP1xcbnxcXHJcXG4/L2csIENSTEYpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGVhZGVycyArPSBgQ29udGVudC1UeXBlOiAke3ZhbHVlLnR5cGUgfHwgXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIn0ke0NSTEZ9YDtcbiAgICB9XG5cbiAgICB0aGlzLmhlYWRlcnMgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoaGVhZGVycyArIENSTEYpO1xuXG4gICAgdGhpcy5jb250ZW50TGVuZ3RoID0gaXNTdHJpbmdWYWx1ZSA/IHZhbHVlLmJ5dGVMZW5ndGggOiB2YWx1ZS5zaXplO1xuXG4gICAgdGhpcy5zaXplID0gdGhpcy5oZWFkZXJzLmJ5dGVMZW5ndGggKyB0aGlzLmNvbnRlbnRMZW5ndGggKyBDUkxGX0JZVEVTX0NPVU5UO1xuXG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIH1cblxuICBhc3luYyAqZW5jb2RlKCl7XG4gICAgeWllbGQgdGhpcy5oZWFkZXJzO1xuXG4gICAgY29uc3Qge3ZhbHVlfSA9IHRoaXM7XG5cbiAgICBpZih1dGlscy5pc1R5cGVkQXJyYXkodmFsdWUpKSB7XG4gICAgICB5aWVsZCB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgeWllbGQqIHJlYWRCbG9iJDEodmFsdWUpO1xuICAgIH1cblxuICAgIHlpZWxkIENSTEZfQllURVM7XG4gIH1cblxuICBzdGF0aWMgZXNjYXBlTmFtZShuYW1lKSB7XG4gICAgICByZXR1cm4gU3RyaW5nKG5hbWUpLnJlcGxhY2UoL1tcXHJcXG5cIl0vZywgKG1hdGNoKSA9PiAoe1xuICAgICAgICAnXFxyJyA6ICclMEQnLFxuICAgICAgICAnXFxuJyA6ICclMEEnLFxuICAgICAgICAnXCInIDogJyUyMicsXG4gICAgICB9W21hdGNoXSkpO1xuICB9XG59XG5cbmNvbnN0IGZvcm1EYXRhVG9TdHJlYW0gPSAoZm9ybSwgaGVhZGVyc0hhbmRsZXIsIG9wdGlvbnMpID0+IHtcbiAgY29uc3Qge1xuICAgIHRhZyA9ICdmb3JtLWRhdGEtYm91bmRhcnknLFxuICAgIHNpemUgPSAyNSxcbiAgICBib3VuZGFyeSA9IHRhZyArICctJyArIHV0aWxzLmdlbmVyYXRlU3RyaW5nKHNpemUsIEJPVU5EQVJZX0FMUEhBQkVUKVxuICB9ID0gb3B0aW9ucyB8fCB7fTtcblxuICBpZighdXRpbHMuaXNGb3JtRGF0YShmb3JtKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignRm9ybURhdGEgaW5zdGFuY2UgcmVxdWlyZWQnKTtcbiAgfVxuXG4gIGlmIChib3VuZGFyeS5sZW5ndGggPCAxIHx8IGJvdW5kYXJ5Lmxlbmd0aCA+IDcwKSB7XG4gICAgdGhyb3cgRXJyb3IoJ2JvdW5kYXJ5IG11c3QgYmUgMTAtNzAgY2hhcmFjdGVycyBsb25nJylcbiAgfVxuXG4gIGNvbnN0IGJvdW5kYXJ5Qnl0ZXMgPSB0ZXh0RW5jb2Rlci5lbmNvZGUoJy0tJyArIGJvdW5kYXJ5ICsgQ1JMRik7XG4gIGNvbnN0IGZvb3RlckJ5dGVzID0gdGV4dEVuY29kZXIuZW5jb2RlKCctLScgKyBib3VuZGFyeSArICctLScgKyBDUkxGICsgQ1JMRik7XG4gIGxldCBjb250ZW50TGVuZ3RoID0gZm9vdGVyQnl0ZXMuYnl0ZUxlbmd0aDtcblxuICBjb25zdCBwYXJ0cyA9IEFycmF5LmZyb20oZm9ybS5lbnRyaWVzKCkpLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4ge1xuICAgIGNvbnN0IHBhcnQgPSBuZXcgRm9ybURhdGFQYXJ0KG5hbWUsIHZhbHVlKTtcbiAgICBjb250ZW50TGVuZ3RoICs9IHBhcnQuc2l6ZTtcbiAgICByZXR1cm4gcGFydDtcbiAgfSk7XG5cbiAgY29udGVudExlbmd0aCArPSBib3VuZGFyeUJ5dGVzLmJ5dGVMZW5ndGggKiBwYXJ0cy5sZW5ndGg7XG5cbiAgY29udGVudExlbmd0aCA9IHV0aWxzLnRvRmluaXRlTnVtYmVyKGNvbnRlbnRMZW5ndGgpO1xuXG4gIGNvbnN0IGNvbXB1dGVkSGVhZGVycyA9IHtcbiAgICAnQ29udGVudC1UeXBlJzogYG11bHRpcGFydC9mb3JtLWRhdGE7IGJvdW5kYXJ5PSR7Ym91bmRhcnl9YFxuICB9O1xuXG4gIGlmIChOdW1iZXIuaXNGaW5pdGUoY29udGVudExlbmd0aCkpIHtcbiAgICBjb21wdXRlZEhlYWRlcnNbJ0NvbnRlbnQtTGVuZ3RoJ10gPSBjb250ZW50TGVuZ3RoO1xuICB9XG5cbiAgaGVhZGVyc0hhbmRsZXIgJiYgaGVhZGVyc0hhbmRsZXIoY29tcHV0ZWRIZWFkZXJzKTtcblxuICByZXR1cm4gc3RyZWFtLlJlYWRhYmxlLmZyb20oKGFzeW5jIGZ1bmN0aW9uICooKSB7XG4gICAgZm9yKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgIHlpZWxkIGJvdW5kYXJ5Qnl0ZXM7XG4gICAgICB5aWVsZCogcGFydC5lbmNvZGUoKTtcbiAgICB9XG5cbiAgICB5aWVsZCBmb290ZXJCeXRlcztcbiAgfSkoKSk7XG59O1xuXG5jb25zdCBmb3JtRGF0YVRvU3RyZWFtJDEgPSBmb3JtRGF0YVRvU3RyZWFtO1xuXG5jbGFzcyBabGliSGVhZGVyVHJhbnNmb3JtU3RyZWFtIGV4dGVuZHMgc3RyZWFtX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5UcmFuc2Zvcm0ge1xuICBfX3RyYW5zZm9ybShjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gICAgdGhpcy5wdXNoKGNodW5rKTtcbiAgICBjYWxsYmFjaygpO1xuICB9XG5cbiAgX3RyYW5zZm9ybShjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGNodW5rLmxlbmd0aCAhPT0gMCkge1xuICAgICAgdGhpcy5fdHJhbnNmb3JtID0gdGhpcy5fX3RyYW5zZm9ybTtcblxuICAgICAgLy8gQWRkIERlZmF1bHQgQ29tcHJlc3Npb24gaGVhZGVycyBpZiBubyB6bGliIGhlYWRlcnMgYXJlIHByZXNlbnRcbiAgICAgIGlmIChjaHVua1swXSAhPT0gMTIwKSB7IC8vIEhleDogNzhcbiAgICAgICAgY29uc3QgaGVhZGVyID0gQnVmZmVyLmFsbG9jKDIpO1xuICAgICAgICBoZWFkZXJbMF0gPSAxMjA7IC8vIEhleDogNzhcbiAgICAgICAgaGVhZGVyWzFdID0gMTU2OyAvLyBIZXg6IDlDIFxuICAgICAgICB0aGlzLnB1c2goaGVhZGVyLCBlbmNvZGluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fX3RyYW5zZm9ybShjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKTtcbiAgfVxufVxuXG5jb25zdCBabGliSGVhZGVyVHJhbnNmb3JtU3RyZWFtJDEgPSBabGliSGVhZGVyVHJhbnNmb3JtU3RyZWFtO1xuXG5jb25zdCBjYWxsYmFja2lmeSA9IChmbiwgcmVkdWNlcikgPT4ge1xuICByZXR1cm4gdXRpbHMuaXNBc3luY0ZuKGZuKSA/IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgY29uc3QgY2IgPSBhcmdzLnBvcCgpO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3MpLnRoZW4oKHZhbHVlKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICByZWR1Y2VyID8gY2IobnVsbCwgLi4ucmVkdWNlcih2YWx1ZSkpIDogY2IobnVsbCwgdmFsdWUpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNiKGVycik7XG4gICAgICB9XG4gICAgfSwgY2IpO1xuICB9IDogZm47XG59O1xuXG5jb25zdCBjYWxsYmFja2lmeSQxID0gY2FsbGJhY2tpZnk7XG5cbmNvbnN0IHpsaWJPcHRpb25zID0ge1xuICBmbHVzaDogemxpYl9fZGVmYXVsdFtcImRlZmF1bHRcIl0uY29uc3RhbnRzLlpfU1lOQ19GTFVTSCxcbiAgZmluaXNoRmx1c2g6IHpsaWJfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLmNvbnN0YW50cy5aX1NZTkNfRkxVU0hcbn07XG5cbmNvbnN0IGJyb3RsaU9wdGlvbnMgPSB7XG4gIGZsdXNoOiB6bGliX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5jb25zdGFudHMuQlJPVExJX09QRVJBVElPTl9GTFVTSCxcbiAgZmluaXNoRmx1c2g6IHpsaWJfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLmNvbnN0YW50cy5CUk9UTElfT1BFUkFUSU9OX0ZMVVNIXG59O1xuXG5jb25zdCBpc0Jyb3RsaVN1cHBvcnRlZCA9IHV0aWxzLmlzRnVuY3Rpb24oemxpYl9fZGVmYXVsdFtcImRlZmF1bHRcIl0uY3JlYXRlQnJvdGxpRGVjb21wcmVzcyk7XG5cbmNvbnN0IHtodHRwOiBodHRwRm9sbG93LCBodHRwczogaHR0cHNGb2xsb3d9ID0gZm9sbG93UmVkaXJlY3RzX19kZWZhdWx0W1wiZGVmYXVsdFwiXTtcblxuY29uc3QgaXNIdHRwcyA9IC9odHRwczo/LztcblxuY29uc3Qgc3VwcG9ydGVkUHJvdG9jb2xzID0gcGxhdGZvcm0ucHJvdG9jb2xzLm1hcChwcm90b2NvbCA9PiB7XG4gIHJldHVybiBwcm90b2NvbCArICc6Jztcbn0pO1xuXG4vKipcbiAqIElmIHRoZSBwcm94eSBvciBjb25maWcgYmVmb3JlUmVkaXJlY3RzIGZ1bmN0aW9ucyBhcmUgZGVmaW5lZCwgY2FsbCB0aGVtIHdpdGggdGhlIG9wdGlvbnNcbiAqIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsIGFueT59IG9wdGlvbnMgLSBUaGUgb3B0aW9ucyBvYmplY3QgdGhhdCB3YXMgcGFzc2VkIHRvIHRoZSByZXF1ZXN0LlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3Q8c3RyaW5nLCBhbnk+fVxuICovXG5mdW5jdGlvbiBkaXNwYXRjaEJlZm9yZVJlZGlyZWN0KG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMuYmVmb3JlUmVkaXJlY3RzLnByb3h5KSB7XG4gICAgb3B0aW9ucy5iZWZvcmVSZWRpcmVjdHMucHJveHkob3B0aW9ucyk7XG4gIH1cbiAgaWYgKG9wdGlvbnMuYmVmb3JlUmVkaXJlY3RzLmNvbmZpZykge1xuICAgIG9wdGlvbnMuYmVmb3JlUmVkaXJlY3RzLmNvbmZpZyhvcHRpb25zKTtcbiAgfVxufVxuXG4vKipcbiAqIElmIHRoZSBwcm94eSBvciBjb25maWcgYWZ0ZXJSZWRpcmVjdHMgZnVuY3Rpb25zIGFyZSBkZWZpbmVkLCBjYWxsIHRoZW0gd2l0aCB0aGUgb3B0aW9uc1xuICpcbiAqIEBwYXJhbSB7aHR0cC5DbGllbnRSZXF1ZXN0QXJnc30gb3B0aW9uc1xuICogQHBhcmFtIHtBeGlvc1Byb3h5Q29uZmlnfSBjb25maWdQcm94eSBjb25maWd1cmF0aW9uIGZyb20gQXhpb3Mgb3B0aW9ucyBvYmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhdGlvblxuICpcbiAqIEByZXR1cm5zIHtodHRwLkNsaWVudFJlcXVlc3RBcmdzfVxuICovXG5mdW5jdGlvbiBzZXRQcm94eShvcHRpb25zLCBjb25maWdQcm94eSwgbG9jYXRpb24pIHtcbiAgbGV0IHByb3h5ID0gY29uZmlnUHJveHk7XG4gIGlmICghcHJveHkgJiYgcHJveHkgIT09IGZhbHNlKSB7XG4gICAgY29uc3QgcHJveHlVcmwgPSBwcm94eUZyb21FbnYuZ2V0UHJveHlGb3JVcmwobG9jYXRpb24pO1xuICAgIGlmIChwcm94eVVybCkge1xuICAgICAgcHJveHkgPSBuZXcgVVJMKHByb3h5VXJsKTtcbiAgICB9XG4gIH1cbiAgaWYgKHByb3h5KSB7XG4gICAgLy8gQmFzaWMgcHJveHkgYXV0aG9yaXphdGlvblxuICAgIGlmIChwcm94eS51c2VybmFtZSkge1xuICAgICAgcHJveHkuYXV0aCA9IChwcm94eS51c2VybmFtZSB8fCAnJykgKyAnOicgKyAocHJveHkucGFzc3dvcmQgfHwgJycpO1xuICAgIH1cblxuICAgIGlmIChwcm94eS5hdXRoKSB7XG4gICAgICAvLyBTdXBwb3J0IHByb3h5IGF1dGggb2JqZWN0IGZvcm1cbiAgICAgIGlmIChwcm94eS5hdXRoLnVzZXJuYW1lIHx8IHByb3h5LmF1dGgucGFzc3dvcmQpIHtcbiAgICAgICAgcHJveHkuYXV0aCA9IChwcm94eS5hdXRoLnVzZXJuYW1lIHx8ICcnKSArICc6JyArIChwcm94eS5hdXRoLnBhc3N3b3JkIHx8ICcnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJhc2U2NCA9IEJ1ZmZlclxuICAgICAgICAuZnJvbShwcm94eS5hdXRoLCAndXRmOCcpXG4gICAgICAgIC50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICBvcHRpb25zLmhlYWRlcnNbJ1Byb3h5LUF1dGhvcml6YXRpb24nXSA9ICdCYXNpYyAnICsgYmFzZTY0O1xuICAgIH1cblxuICAgIG9wdGlvbnMuaGVhZGVycy5ob3N0ID0gb3B0aW9ucy5ob3N0bmFtZSArIChvcHRpb25zLnBvcnQgPyAnOicgKyBvcHRpb25zLnBvcnQgOiAnJyk7XG4gICAgY29uc3QgcHJveHlIb3N0ID0gcHJveHkuaG9zdG5hbWUgfHwgcHJveHkuaG9zdDtcbiAgICBvcHRpb25zLmhvc3RuYW1lID0gcHJveHlIb3N0O1xuICAgIC8vIFJlcGxhY2UgJ2hvc3QnIHNpbmNlIG9wdGlvbnMgaXMgbm90IGEgVVJMIG9iamVjdFxuICAgIG9wdGlvbnMuaG9zdCA9IHByb3h5SG9zdDtcbiAgICBvcHRpb25zLnBvcnQgPSBwcm94eS5wb3J0O1xuICAgIG9wdGlvbnMucGF0aCA9IGxvY2F0aW9uO1xuICAgIGlmIChwcm94eS5wcm90b2NvbCkge1xuICAgICAgb3B0aW9ucy5wcm90b2NvbCA9IHByb3h5LnByb3RvY29sLmluY2x1ZGVzKCc6JykgPyBwcm94eS5wcm90b2NvbCA6IGAke3Byb3h5LnByb3RvY29sfTpgO1xuICAgIH1cbiAgfVxuXG4gIG9wdGlvbnMuYmVmb3JlUmVkaXJlY3RzLnByb3h5ID0gZnVuY3Rpb24gYmVmb3JlUmVkaXJlY3QocmVkaXJlY3RPcHRpb25zKSB7XG4gICAgLy8gQ29uZmlndXJlIHByb3h5IGZvciByZWRpcmVjdGVkIHJlcXVlc3QsIHBhc3NpbmcgdGhlIG9yaWdpbmFsIGNvbmZpZyBwcm94eSB0byBhcHBseVxuICAgIC8vIHRoZSBleGFjdCBzYW1lIGxvZ2ljIGFzIGlmIHRoZSByZWRpcmVjdGVkIHJlcXVlc3Qgd2FzIHBlcmZvcm1lZCBieSBheGlvcyBkaXJlY3RseS5cbiAgICBzZXRQcm94eShyZWRpcmVjdE9wdGlvbnMsIGNvbmZpZ1Byb3h5LCByZWRpcmVjdE9wdGlvbnMuaHJlZik7XG4gIH07XG59XG5cbmNvbnN0IGlzSHR0cEFkYXB0ZXJTdXBwb3J0ZWQgPSB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgdXRpbHMua2luZE9mKHByb2Nlc3MpID09PSAncHJvY2Vzcyc7XG5cbi8vIHRlbXBvcmFyeSBob3RmaXhcblxuY29uc3Qgd3JhcEFzeW5jID0gKGFzeW5jRXhlY3V0b3IpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBsZXQgb25Eb25lO1xuICAgIGxldCBpc0RvbmU7XG5cbiAgICBjb25zdCBkb25lID0gKHZhbHVlLCBpc1JlamVjdGVkKSA9PiB7XG4gICAgICBpZiAoaXNEb25lKSByZXR1cm47XG4gICAgICBpc0RvbmUgPSB0cnVlO1xuICAgICAgb25Eb25lICYmIG9uRG9uZSh2YWx1ZSwgaXNSZWplY3RlZCk7XG4gICAgfTtcblxuICAgIGNvbnN0IF9yZXNvbHZlID0gKHZhbHVlKSA9PiB7XG4gICAgICBkb25lKHZhbHVlKTtcbiAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgIH07XG5cbiAgICBjb25zdCBfcmVqZWN0ID0gKHJlYXNvbikgPT4ge1xuICAgICAgZG9uZShyZWFzb24sIHRydWUpO1xuICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgfTtcblxuICAgIGFzeW5jRXhlY3V0b3IoX3Jlc29sdmUsIF9yZWplY3QsIChvbkRvbmVIYW5kbGVyKSA9PiAob25Eb25lID0gb25Eb25lSGFuZGxlcikpLmNhdGNoKF9yZWplY3QpO1xuICB9KVxufTtcblxuY29uc3QgcmVzb2x2ZUZhbWlseSA9ICh7YWRkcmVzcywgZmFtaWx5fSkgPT4ge1xuICBpZiAoIXV0aWxzLmlzU3RyaW5nKGFkZHJlc3MpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKCdhZGRyZXNzIG11c3QgYmUgYSBzdHJpbmcnKTtcbiAgfVxuICByZXR1cm4gKHtcbiAgICBhZGRyZXNzLFxuICAgIGZhbWlseTogZmFtaWx5IHx8IChhZGRyZXNzLmluZGV4T2YoJy4nKSA8IDAgPyA2IDogNClcbiAgfSk7XG59O1xuXG5jb25zdCBidWlsZEFkZHJlc3NFbnRyeSA9IChhZGRyZXNzLCBmYW1pbHkpID0+IHJlc29sdmVGYW1pbHkodXRpbHMuaXNPYmplY3QoYWRkcmVzcykgPyBhZGRyZXNzIDoge2FkZHJlc3MsIGZhbWlseX0pO1xuXG4vKmVzbGludCBjb25zaXN0ZW50LXJldHVybjowKi9cbmNvbnN0IGh0dHBBZGFwdGVyID0gaXNIdHRwQWRhcHRlclN1cHBvcnRlZCAmJiBmdW5jdGlvbiBodHRwQWRhcHRlcihjb25maWcpIHtcbiAgcmV0dXJuIHdyYXBBc3luYyhhc3luYyBmdW5jdGlvbiBkaXNwYXRjaEh0dHBSZXF1ZXN0KHJlc29sdmUsIHJlamVjdCwgb25Eb25lKSB7XG4gICAgbGV0IHtkYXRhLCBsb29rdXAsIGZhbWlseX0gPSBjb25maWc7XG4gICAgY29uc3Qge3Jlc3BvbnNlVHlwZSwgcmVzcG9uc2VFbmNvZGluZ30gPSBjb25maWc7XG4gICAgY29uc3QgbWV0aG9kID0gY29uZmlnLm1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgIGxldCBpc0RvbmU7XG4gICAgbGV0IHJlamVjdGVkID0gZmFsc2U7XG4gICAgbGV0IHJlcTtcblxuICAgIGlmIChsb29rdXApIHtcbiAgICAgIGNvbnN0IF9sb29rdXAgPSBjYWxsYmFja2lmeSQxKGxvb2t1cCwgKHZhbHVlKSA9PiB1dGlscy5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXSk7XG4gICAgICAvLyBob3RmaXggdG8gc3VwcG9ydCBvcHQuYWxsIG9wdGlvbiB3aGljaCBpcyByZXF1aXJlZCBmb3Igbm9kZSAyMC54XG4gICAgICBsb29rdXAgPSAoaG9zdG5hbWUsIG9wdCwgY2IpID0+IHtcbiAgICAgICAgX2xvb2t1cChob3N0bmFtZSwgb3B0LCAoZXJyLCBhcmcwLCBhcmcxKSA9PiB7XG4gICAgICAgICAgY29uc3QgYWRkcmVzc2VzID0gdXRpbHMuaXNBcnJheShhcmcwKSA/IGFyZzAubWFwKGFkZHIgPT4gYnVpbGRBZGRyZXNzRW50cnkoYWRkcikpIDogW2J1aWxkQWRkcmVzc0VudHJ5KGFyZzAsIGFyZzEpXTtcblxuICAgICAgICAgIG9wdC5hbGwgPyBjYihlcnIsIGFkZHJlc3NlcykgOiBjYihlcnIsIGFkZHJlc3Nlc1swXS5hZGRyZXNzLCBhZGRyZXNzZXNbMF0uZmFtaWx5KTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIHRlbXBvcmFyeSBpbnRlcm5hbCBlbWl0dGVyIHVudGlsIHRoZSBBeGlvc1JlcXVlc3QgY2xhc3Mgd2lsbCBiZSBpbXBsZW1lbnRlZFxuICAgIGNvbnN0IGVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyX19kZWZhdWx0W1wiZGVmYXVsdFwiXSgpO1xuXG4gICAgY29uc3Qgb25GaW5pc2hlZCA9ICgpID0+IHtcbiAgICAgIGlmIChjb25maWcuY2FuY2VsVG9rZW4pIHtcbiAgICAgICAgY29uZmlnLmNhbmNlbFRva2VuLnVuc3Vic2NyaWJlKGFib3J0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbmZpZy5zaWduYWwpIHtcbiAgICAgICAgY29uZmlnLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKCdhYm9ydCcsIGFib3J0KTtcbiAgICAgIH1cblxuICAgICAgZW1pdHRlci5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICB9O1xuXG4gICAgb25Eb25lKCh2YWx1ZSwgaXNSZWplY3RlZCkgPT4ge1xuICAgICAgaXNEb25lID0gdHJ1ZTtcbiAgICAgIGlmIChpc1JlamVjdGVkKSB7XG4gICAgICAgIHJlamVjdGVkID0gdHJ1ZTtcbiAgICAgICAgb25GaW5pc2hlZCgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWJvcnQocmVhc29uKSB7XG4gICAgICBlbWl0dGVyLmVtaXQoJ2Fib3J0JywgIXJlYXNvbiB8fCByZWFzb24udHlwZSA/IG5ldyBDYW5jZWxlZEVycm9yKG51bGwsIGNvbmZpZywgcmVxKSA6IHJlYXNvbik7XG4gICAgfVxuXG4gICAgZW1pdHRlci5vbmNlKCdhYm9ydCcsIHJlamVjdCk7XG5cbiAgICBpZiAoY29uZmlnLmNhbmNlbFRva2VuIHx8IGNvbmZpZy5zaWduYWwpIHtcbiAgICAgIGNvbmZpZy5jYW5jZWxUb2tlbiAmJiBjb25maWcuY2FuY2VsVG9rZW4uc3Vic2NyaWJlKGFib3J0KTtcbiAgICAgIGlmIChjb25maWcuc2lnbmFsKSB7XG4gICAgICAgIGNvbmZpZy5zaWduYWwuYWJvcnRlZCA/IGFib3J0KCkgOiBjb25maWcuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0JywgYWJvcnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFBhcnNlIHVybFxuICAgIGNvbnN0IGZ1bGxQYXRoID0gYnVpbGRGdWxsUGF0aChjb25maWcuYmFzZVVSTCwgY29uZmlnLnVybCk7XG4gICAgY29uc3QgcGFyc2VkID0gbmV3IFVSTChmdWxsUGF0aCwgJ2h0dHA6Ly9sb2NhbGhvc3QnKTtcbiAgICBjb25zdCBwcm90b2NvbCA9IHBhcnNlZC5wcm90b2NvbCB8fCBzdXBwb3J0ZWRQcm90b2NvbHNbMF07XG5cbiAgICBpZiAocHJvdG9jb2wgPT09ICdkYXRhOicpIHtcbiAgICAgIGxldCBjb252ZXJ0ZWREYXRhO1xuXG4gICAgICBpZiAobWV0aG9kICE9PSAnR0VUJykge1xuICAgICAgICByZXR1cm4gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwge1xuICAgICAgICAgIHN0YXR1czogNDA1LFxuICAgICAgICAgIHN0YXR1c1RleHQ6ICdtZXRob2Qgbm90IGFsbG93ZWQnLFxuICAgICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICAgIGNvbmZpZ1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29udmVydGVkRGF0YSA9IGZyb21EYXRhVVJJKGNvbmZpZy51cmwsIHJlc3BvbnNlVHlwZSA9PT0gJ2Jsb2InLCB7XG4gICAgICAgICAgQmxvYjogY29uZmlnLmVudiAmJiBjb25maWcuZW52LkJsb2JcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhyb3cgQXhpb3NFcnJvci5mcm9tKGVyciwgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsIGNvbmZpZyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZVR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICBjb252ZXJ0ZWREYXRhID0gY29udmVydGVkRGF0YS50b1N0cmluZyhyZXNwb25zZUVuY29kaW5nKTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlRW5jb2RpbmcgfHwgcmVzcG9uc2VFbmNvZGluZyA9PT0gJ3V0ZjgnKSB7XG4gICAgICAgICAgY29udmVydGVkRGF0YSA9IHV0aWxzLnN0cmlwQk9NKGNvbnZlcnRlZERhdGEpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlVHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICAgICAgY29udmVydGVkRGF0YSA9IHN0cmVhbV9fZGVmYXVsdFtcImRlZmF1bHRcIl0uUmVhZGFibGUuZnJvbShjb252ZXJ0ZWREYXRhKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHtcbiAgICAgICAgZGF0YTogY29udmVydGVkRGF0YSxcbiAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgIHN0YXR1c1RleHQ6ICdPSycsXG4gICAgICAgIGhlYWRlcnM6IG5ldyBBeGlvc0hlYWRlcnMkMSgpLFxuICAgICAgICBjb25maWdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChzdXBwb3J0ZWRQcm90b2NvbHMuaW5kZXhPZihwcm90b2NvbCkgPT09IC0xKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICAnVW5zdXBwb3J0ZWQgcHJvdG9jb2wgJyArIHByb3RvY29sLFxuICAgICAgICBBeGlvc0Vycm9yLkVSUl9CQURfUkVRVUVTVCxcbiAgICAgICAgY29uZmlnXG4gICAgICApKTtcbiAgICB9XG5cbiAgICBjb25zdCBoZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShjb25maWcuaGVhZGVycykubm9ybWFsaXplKCk7XG5cbiAgICAvLyBTZXQgVXNlci1BZ2VudCAocmVxdWlyZWQgYnkgc29tZSBzZXJ2ZXJzKVxuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYXhpb3MvYXhpb3MvaXNzdWVzLzY5XG4gICAgLy8gVXNlci1BZ2VudCBpcyBzcGVjaWZpZWQ7IGhhbmRsZSBjYXNlIHdoZXJlIG5vIFVBIGhlYWRlciBpcyBkZXNpcmVkXG4gICAgLy8gT25seSBzZXQgaGVhZGVyIGlmIGl0IGhhc24ndCBiZWVuIHNldCBpbiBjb25maWdcbiAgICBoZWFkZXJzLnNldCgnVXNlci1BZ2VudCcsICdheGlvcy8nICsgVkVSU0lPTiwgZmFsc2UpO1xuXG4gICAgY29uc3Qgb25Eb3dubG9hZFByb2dyZXNzID0gY29uZmlnLm9uRG93bmxvYWRQcm9ncmVzcztcbiAgICBjb25zdCBvblVwbG9hZFByb2dyZXNzID0gY29uZmlnLm9uVXBsb2FkUHJvZ3Jlc3M7XG4gICAgY29uc3QgbWF4UmF0ZSA9IGNvbmZpZy5tYXhSYXRlO1xuICAgIGxldCBtYXhVcGxvYWRSYXRlID0gdW5kZWZpbmVkO1xuICAgIGxldCBtYXhEb3dubG9hZFJhdGUgPSB1bmRlZmluZWQ7XG5cbiAgICAvLyBzdXBwb3J0IGZvciBzcGVjIGNvbXBsaWFudCBGb3JtRGF0YSBvYmplY3RzXG4gICAgaWYgKHV0aWxzLmlzU3BlY0NvbXBsaWFudEZvcm0oZGF0YSkpIHtcbiAgICAgIGNvbnN0IHVzZXJCb3VuZGFyeSA9IGhlYWRlcnMuZ2V0Q29udGVudFR5cGUoL2JvdW5kYXJ5PShbLV9cXHdcXGRdezEwLDcwfSkvaSk7XG5cbiAgICAgIGRhdGEgPSBmb3JtRGF0YVRvU3RyZWFtJDEoZGF0YSwgKGZvcm1IZWFkZXJzKSA9PiB7XG4gICAgICAgIGhlYWRlcnMuc2V0KGZvcm1IZWFkZXJzKTtcbiAgICAgIH0sIHtcbiAgICAgICAgdGFnOiBgYXhpb3MtJHtWRVJTSU9OfS1ib3VuZGFyeWAsXG4gICAgICAgIGJvdW5kYXJ5OiB1c2VyQm91bmRhcnkgJiYgdXNlckJvdW5kYXJ5WzFdIHx8IHVuZGVmaW5lZFxuICAgICAgfSk7XG4gICAgICAvLyBzdXBwb3J0IGZvciBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9mb3JtLWRhdGEgYXBpXG4gICAgfSBlbHNlIGlmICh1dGlscy5pc0Zvcm1EYXRhKGRhdGEpICYmIHV0aWxzLmlzRnVuY3Rpb24oZGF0YS5nZXRIZWFkZXJzKSkge1xuICAgICAgaGVhZGVycy5zZXQoZGF0YS5nZXRIZWFkZXJzKCkpO1xuXG4gICAgICBpZiAoIWhlYWRlcnMuaGFzQ29udGVudExlbmd0aCgpKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qga25vd25MZW5ndGggPSBhd2FpdCB1dGlsX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5wcm9taXNpZnkoZGF0YS5nZXRMZW5ndGgpLmNhbGwoZGF0YSk7XG4gICAgICAgICAgTnVtYmVyLmlzRmluaXRlKGtub3duTGVuZ3RoKSAmJiBrbm93bkxlbmd0aCA+PSAwICYmIGhlYWRlcnMuc2V0Q29udGVudExlbmd0aChrbm93bkxlbmd0aCk7XG4gICAgICAgICAgLyplc2xpbnQgbm8tZW1wdHk6MCovXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodXRpbHMuaXNCbG9iKGRhdGEpKSB7XG4gICAgICBkYXRhLnNpemUgJiYgaGVhZGVycy5zZXRDb250ZW50VHlwZShkYXRhLnR5cGUgfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpO1xuICAgICAgaGVhZGVycy5zZXRDb250ZW50TGVuZ3RoKGRhdGEuc2l6ZSB8fCAwKTtcbiAgICAgIGRhdGEgPSBzdHJlYW1fX2RlZmF1bHRbXCJkZWZhdWx0XCJdLlJlYWRhYmxlLmZyb20ocmVhZEJsb2IkMShkYXRhKSk7XG4gICAgfSBlbHNlIGlmIChkYXRhICYmICF1dGlscy5pc1N0cmVhbShkYXRhKSkge1xuICAgICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgOyBlbHNlIGlmICh1dGlscy5pc0FycmF5QnVmZmVyKGRhdGEpKSB7XG4gICAgICAgIGRhdGEgPSBCdWZmZXIuZnJvbShuZXcgVWludDhBcnJheShkYXRhKSk7XG4gICAgICB9IGVsc2UgaWYgKHV0aWxzLmlzU3RyaW5nKGRhdGEpKSB7XG4gICAgICAgIGRhdGEgPSBCdWZmZXIuZnJvbShkYXRhLCAndXRmLTgnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZWplY3QobmV3IEF4aW9zRXJyb3IoXG4gICAgICAgICAgJ0RhdGEgYWZ0ZXIgdHJhbnNmb3JtYXRpb24gbXVzdCBiZSBhIHN0cmluZywgYW4gQXJyYXlCdWZmZXIsIGEgQnVmZmVyLCBvciBhIFN0cmVhbScsXG4gICAgICAgICAgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsXG4gICAgICAgICAgY29uZmlnXG4gICAgICAgICkpO1xuICAgICAgfVxuXG4gICAgICAvLyBBZGQgQ29udGVudC1MZW5ndGggaGVhZGVyIGlmIGRhdGEgZXhpc3RzXG4gICAgICBoZWFkZXJzLnNldENvbnRlbnRMZW5ndGgoZGF0YS5sZW5ndGgsIGZhbHNlKTtcblxuICAgICAgaWYgKGNvbmZpZy5tYXhCb2R5TGVuZ3RoID4gLTEgJiYgZGF0YS5sZW5ndGggPiBjb25maWcubWF4Qm9keUxlbmd0aCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICAgICdSZXF1ZXN0IGJvZHkgbGFyZ2VyIHRoYW4gbWF4Qm9keUxlbmd0aCBsaW1pdCcsXG4gICAgICAgICAgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsXG4gICAgICAgICAgY29uZmlnXG4gICAgICAgICkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNvbnRlbnRMZW5ndGggPSB1dGlscy50b0Zpbml0ZU51bWJlcihoZWFkZXJzLmdldENvbnRlbnRMZW5ndGgoKSk7XG5cbiAgICBpZiAodXRpbHMuaXNBcnJheShtYXhSYXRlKSkge1xuICAgICAgbWF4VXBsb2FkUmF0ZSA9IG1heFJhdGVbMF07XG4gICAgICBtYXhEb3dubG9hZFJhdGUgPSBtYXhSYXRlWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYXhVcGxvYWRSYXRlID0gbWF4RG93bmxvYWRSYXRlID0gbWF4UmF0ZTtcbiAgICB9XG5cbiAgICBpZiAoZGF0YSAmJiAob25VcGxvYWRQcm9ncmVzcyB8fCBtYXhVcGxvYWRSYXRlKSkge1xuICAgICAgaWYgKCF1dGlscy5pc1N0cmVhbShkYXRhKSkge1xuICAgICAgICBkYXRhID0gc3RyZWFtX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5SZWFkYWJsZS5mcm9tKGRhdGEsIHtvYmplY3RNb2RlOiBmYWxzZX0pO1xuICAgICAgfVxuXG4gICAgICBkYXRhID0gc3RyZWFtX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5waXBlbGluZShbZGF0YSwgbmV3IEF4aW9zVHJhbnNmb3JtU3RyZWFtJDEoe1xuICAgICAgICBsZW5ndGg6IGNvbnRlbnRMZW5ndGgsXG4gICAgICAgIG1heFJhdGU6IHV0aWxzLnRvRmluaXRlTnVtYmVyKG1heFVwbG9hZFJhdGUpXG4gICAgICB9KV0sIHV0aWxzLm5vb3ApO1xuXG4gICAgICBvblVwbG9hZFByb2dyZXNzICYmIGRhdGEub24oJ3Byb2dyZXNzJywgcHJvZ3Jlc3MgPT4ge1xuICAgICAgICBvblVwbG9hZFByb2dyZXNzKE9iamVjdC5hc3NpZ24ocHJvZ3Jlc3MsIHtcbiAgICAgICAgICB1cGxvYWQ6IHRydWVcbiAgICAgICAgfSkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSFRUUCBiYXNpYyBhdXRoZW50aWNhdGlvblxuICAgIGxldCBhdXRoID0gdW5kZWZpbmVkO1xuICAgIGlmIChjb25maWcuYXV0aCkge1xuICAgICAgY29uc3QgdXNlcm5hbWUgPSBjb25maWcuYXV0aC51c2VybmFtZSB8fCAnJztcbiAgICAgIGNvbnN0IHBhc3N3b3JkID0gY29uZmlnLmF1dGgucGFzc3dvcmQgfHwgJyc7XG4gICAgICBhdXRoID0gdXNlcm5hbWUgKyAnOicgKyBwYXNzd29yZDtcbiAgICB9XG5cbiAgICBpZiAoIWF1dGggJiYgcGFyc2VkLnVzZXJuYW1lKSB7XG4gICAgICBjb25zdCB1cmxVc2VybmFtZSA9IHBhcnNlZC51c2VybmFtZTtcbiAgICAgIGNvbnN0IHVybFBhc3N3b3JkID0gcGFyc2VkLnBhc3N3b3JkO1xuICAgICAgYXV0aCA9IHVybFVzZXJuYW1lICsgJzonICsgdXJsUGFzc3dvcmQ7XG4gICAgfVxuXG4gICAgYXV0aCAmJiBoZWFkZXJzLmRlbGV0ZSgnYXV0aG9yaXphdGlvbicpO1xuXG4gICAgbGV0IHBhdGg7XG5cbiAgICB0cnkge1xuICAgICAgcGF0aCA9IGJ1aWxkVVJMKFxuICAgICAgICBwYXJzZWQucGF0aG5hbWUgKyBwYXJzZWQuc2VhcmNoLFxuICAgICAgICBjb25maWcucGFyYW1zLFxuICAgICAgICBjb25maWcucGFyYW1zU2VyaWFsaXplclxuICAgICAgKS5yZXBsYWNlKC9eXFw/LywgJycpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc3QgY3VzdG9tRXJyID0gbmV3IEVycm9yKGVyci5tZXNzYWdlKTtcbiAgICAgIGN1c3RvbUVyci5jb25maWcgPSBjb25maWc7XG4gICAgICBjdXN0b21FcnIudXJsID0gY29uZmlnLnVybDtcbiAgICAgIGN1c3RvbUVyci5leGlzdHMgPSB0cnVlO1xuICAgICAgcmV0dXJuIHJlamVjdChjdXN0b21FcnIpO1xuICAgIH1cblxuICAgIGhlYWRlcnMuc2V0KFxuICAgICAgJ0FjY2VwdC1FbmNvZGluZycsXG4gICAgICAnZ3ppcCwgY29tcHJlc3MsIGRlZmxhdGUnICsgKGlzQnJvdGxpU3VwcG9ydGVkID8gJywgYnInIDogJycpLCBmYWxzZVxuICAgICAgKTtcblxuICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICBwYXRoLFxuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzLnRvSlNPTigpLFxuICAgICAgYWdlbnRzOiB7IGh0dHA6IGNvbmZpZy5odHRwQWdlbnQsIGh0dHBzOiBjb25maWcuaHR0cHNBZ2VudCB9LFxuICAgICAgYXV0aCxcbiAgICAgIHByb3RvY29sLFxuICAgICAgZmFtaWx5LFxuICAgICAgYmVmb3JlUmVkaXJlY3Q6IGRpc3BhdGNoQmVmb3JlUmVkaXJlY3QsXG4gICAgICBiZWZvcmVSZWRpcmVjdHM6IHt9XG4gICAgfTtcblxuICAgIC8vIGNhY2hlYWJsZS1sb29rdXAgaW50ZWdyYXRpb24gaG90Zml4XG4gICAgIXV0aWxzLmlzVW5kZWZpbmVkKGxvb2t1cCkgJiYgKG9wdGlvbnMubG9va3VwID0gbG9va3VwKTtcblxuICAgIGlmIChjb25maWcuc29ja2V0UGF0aCkge1xuICAgICAgb3B0aW9ucy5zb2NrZXRQYXRoID0gY29uZmlnLnNvY2tldFBhdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMuaG9zdG5hbWUgPSBwYXJzZWQuaG9zdG5hbWU7XG4gICAgICBvcHRpb25zLnBvcnQgPSBwYXJzZWQucG9ydDtcbiAgICAgIHNldFByb3h5KG9wdGlvbnMsIGNvbmZpZy5wcm94eSwgcHJvdG9jb2wgKyAnLy8nICsgcGFyc2VkLmhvc3RuYW1lICsgKHBhcnNlZC5wb3J0ID8gJzonICsgcGFyc2VkLnBvcnQgOiAnJykgKyBvcHRpb25zLnBhdGgpO1xuICAgIH1cblxuICAgIGxldCB0cmFuc3BvcnQ7XG4gICAgY29uc3QgaXNIdHRwc1JlcXVlc3QgPSBpc0h0dHBzLnRlc3Qob3B0aW9ucy5wcm90b2NvbCk7XG4gICAgb3B0aW9ucy5hZ2VudCA9IGlzSHR0cHNSZXF1ZXN0ID8gY29uZmlnLmh0dHBzQWdlbnQgOiBjb25maWcuaHR0cEFnZW50O1xuICAgIGlmIChjb25maWcudHJhbnNwb3J0KSB7XG4gICAgICB0cmFuc3BvcnQgPSBjb25maWcudHJhbnNwb3J0O1xuICAgIH0gZWxzZSBpZiAoY29uZmlnLm1heFJlZGlyZWN0cyA9PT0gMCkge1xuICAgICAgdHJhbnNwb3J0ID0gaXNIdHRwc1JlcXVlc3QgPyBodHRwc19fZGVmYXVsdFtcImRlZmF1bHRcIl0gOiBodHRwX19kZWZhdWx0W1wiZGVmYXVsdFwiXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNvbmZpZy5tYXhSZWRpcmVjdHMpIHtcbiAgICAgICAgb3B0aW9ucy5tYXhSZWRpcmVjdHMgPSBjb25maWcubWF4UmVkaXJlY3RzO1xuICAgICAgfVxuICAgICAgaWYgKGNvbmZpZy5iZWZvcmVSZWRpcmVjdCkge1xuICAgICAgICBvcHRpb25zLmJlZm9yZVJlZGlyZWN0cy5jb25maWcgPSBjb25maWcuYmVmb3JlUmVkaXJlY3Q7XG4gICAgICB9XG4gICAgICB0cmFuc3BvcnQgPSBpc0h0dHBzUmVxdWVzdCA/IGh0dHBzRm9sbG93IDogaHR0cEZvbGxvdztcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLm1heEJvZHlMZW5ndGggPiAtMSkge1xuICAgICAgb3B0aW9ucy5tYXhCb2R5TGVuZ3RoID0gY29uZmlnLm1heEJvZHlMZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGZvbGxvdy1yZWRpcmVjdHMgZG9lcyBub3Qgc2tpcCBjb21wYXJpc29uLCBzbyBpdCBzaG91bGQgYWx3YXlzIHN1Y2NlZWQgZm9yIGF4aW9zIC0xIHVubGltaXRlZFxuICAgICAgb3B0aW9ucy5tYXhCb2R5TGVuZ3RoID0gSW5maW5pdHk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5pbnNlY3VyZUhUVFBQYXJzZXIpIHtcbiAgICAgIG9wdGlvbnMuaW5zZWN1cmVIVFRQUGFyc2VyID0gY29uZmlnLmluc2VjdXJlSFRUUFBhcnNlcjtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgdGhlIHJlcXVlc3RcbiAgICByZXEgPSB0cmFuc3BvcnQucmVxdWVzdChvcHRpb25zLCBmdW5jdGlvbiBoYW5kbGVSZXNwb25zZShyZXMpIHtcbiAgICAgIGlmIChyZXEuZGVzdHJveWVkKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IHN0cmVhbXMgPSBbcmVzXTtcblxuICAgICAgY29uc3QgcmVzcG9uc2VMZW5ndGggPSArcmVzLmhlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ107XG5cbiAgICAgIGlmIChvbkRvd25sb2FkUHJvZ3Jlc3MpIHtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtU3RyZWFtID0gbmV3IEF4aW9zVHJhbnNmb3JtU3RyZWFtJDEoe1xuICAgICAgICAgIGxlbmd0aDogdXRpbHMudG9GaW5pdGVOdW1iZXIocmVzcG9uc2VMZW5ndGgpLFxuICAgICAgICAgIG1heFJhdGU6IHV0aWxzLnRvRmluaXRlTnVtYmVyKG1heERvd25sb2FkUmF0ZSlcbiAgICAgICAgfSk7XG5cbiAgICAgICAgb25Eb3dubG9hZFByb2dyZXNzICYmIHRyYW5zZm9ybVN0cmVhbS5vbigncHJvZ3Jlc3MnLCBwcm9ncmVzcyA9PiB7XG4gICAgICAgICAgb25Eb3dubG9hZFByb2dyZXNzKE9iamVjdC5hc3NpZ24ocHJvZ3Jlc3MsIHtcbiAgICAgICAgICAgIGRvd25sb2FkOiB0cnVlXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9KTtcblxuICAgICAgICBzdHJlYW1zLnB1c2godHJhbnNmb3JtU3RyZWFtKTtcbiAgICAgIH1cblxuICAgICAgLy8gZGVjb21wcmVzcyB0aGUgcmVzcG9uc2UgYm9keSB0cmFuc3BhcmVudGx5IGlmIHJlcXVpcmVkXG4gICAgICBsZXQgcmVzcG9uc2VTdHJlYW0gPSByZXM7XG5cbiAgICAgIC8vIHJldHVybiB0aGUgbGFzdCByZXF1ZXN0IGluIGNhc2Ugb2YgcmVkaXJlY3RzXG4gICAgICBjb25zdCBsYXN0UmVxdWVzdCA9IHJlcy5yZXEgfHwgcmVxO1xuXG4gICAgICAvLyBpZiBkZWNvbXByZXNzIGRpc2FibGVkIHdlIHNob3VsZCBub3QgZGVjb21wcmVzc1xuICAgICAgaWYgKGNvbmZpZy5kZWNvbXByZXNzICE9PSBmYWxzZSAmJiByZXMuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddKSB7XG4gICAgICAgIC8vIGlmIG5vIGNvbnRlbnQsIGJ1dCBoZWFkZXJzIHN0aWxsIHNheSB0aGF0IGl0IGlzIGVuY29kZWQsXG4gICAgICAgIC8vIHJlbW92ZSB0aGUgaGVhZGVyIG5vdCBjb25mdXNlIGRvd25zdHJlYW0gb3BlcmF0aW9uc1xuICAgICAgICBpZiAobWV0aG9kID09PSAnSEVBRCcgfHwgcmVzLnN0YXR1c0NvZGUgPT09IDIwNCkge1xuICAgICAgICAgIGRlbGV0ZSByZXMuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoICgocmVzLmhlYWRlcnNbJ2NvbnRlbnQtZW5jb2RpbmcnXSB8fCAnJykudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAvKmVzbGludCBkZWZhdWx0LWNhc2U6MCovXG4gICAgICAgIGNhc2UgJ2d6aXAnOlxuICAgICAgICBjYXNlICd4LWd6aXAnOlxuICAgICAgICBjYXNlICdjb21wcmVzcyc6XG4gICAgICAgIGNhc2UgJ3gtY29tcHJlc3MnOlxuICAgICAgICAgIC8vIGFkZCB0aGUgdW56aXBwZXIgdG8gdGhlIGJvZHkgc3RyZWFtIHByb2Nlc3NpbmcgcGlwZWxpbmVcbiAgICAgICAgICBzdHJlYW1zLnB1c2goemxpYl9fZGVmYXVsdFtcImRlZmF1bHRcIl0uY3JlYXRlVW56aXAoemxpYk9wdGlvbnMpKTtcblxuICAgICAgICAgIC8vIHJlbW92ZSB0aGUgY29udGVudC1lbmNvZGluZyBpbiBvcmRlciB0byBub3QgY29uZnVzZSBkb3duc3RyZWFtIG9wZXJhdGlvbnNcbiAgICAgICAgICBkZWxldGUgcmVzLmhlYWRlcnNbJ2NvbnRlbnQtZW5jb2RpbmcnXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZGVmbGF0ZSc6XG4gICAgICAgICAgc3RyZWFtcy5wdXNoKG5ldyBabGliSGVhZGVyVHJhbnNmb3JtU3RyZWFtJDEoKSk7XG5cbiAgICAgICAgICAvLyBhZGQgdGhlIHVuemlwcGVyIHRvIHRoZSBib2R5IHN0cmVhbSBwcm9jZXNzaW5nIHBpcGVsaW5lXG4gICAgICAgICAgc3RyZWFtcy5wdXNoKHpsaWJfX2RlZmF1bHRbXCJkZWZhdWx0XCJdLmNyZWF0ZVVuemlwKHpsaWJPcHRpb25zKSk7XG5cbiAgICAgICAgICAvLyByZW1vdmUgdGhlIGNvbnRlbnQtZW5jb2RpbmcgaW4gb3JkZXIgdG8gbm90IGNvbmZ1c2UgZG93bnN0cmVhbSBvcGVyYXRpb25zXG4gICAgICAgICAgZGVsZXRlIHJlcy5oZWFkZXJzWydjb250ZW50LWVuY29kaW5nJ107XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2JyJzpcbiAgICAgICAgICBpZiAoaXNCcm90bGlTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgIHN0cmVhbXMucHVzaCh6bGliX19kZWZhdWx0W1wiZGVmYXVsdFwiXS5jcmVhdGVCcm90bGlEZWNvbXByZXNzKGJyb3RsaU9wdGlvbnMpKTtcbiAgICAgICAgICAgIGRlbGV0ZSByZXMuaGVhZGVyc1snY29udGVudC1lbmNvZGluZyddO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXNwb25zZVN0cmVhbSA9IHN0cmVhbXMubGVuZ3RoID4gMSA/IHN0cmVhbV9fZGVmYXVsdFtcImRlZmF1bHRcIl0ucGlwZWxpbmUoc3RyZWFtcywgdXRpbHMubm9vcCkgOiBzdHJlYW1zWzBdO1xuXG4gICAgICBjb25zdCBvZmZMaXN0ZW5lcnMgPSBzdHJlYW1fX2RlZmF1bHRbXCJkZWZhdWx0XCJdLmZpbmlzaGVkKHJlc3BvbnNlU3RyZWFtLCAoKSA9PiB7XG4gICAgICAgIG9mZkxpc3RlbmVycygpO1xuICAgICAgICBvbkZpbmlzaGVkKCk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSB7XG4gICAgICAgIHN0YXR1czogcmVzLnN0YXR1c0NvZGUsXG4gICAgICAgIHN0YXR1c1RleHQ6IHJlcy5zdGF0dXNNZXNzYWdlLFxuICAgICAgICBoZWFkZXJzOiBuZXcgQXhpb3NIZWFkZXJzJDEocmVzLmhlYWRlcnMpLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcXVlc3Q6IGxhc3RSZXF1ZXN0XG4gICAgICB9O1xuXG4gICAgICBpZiAocmVzcG9uc2VUeXBlID09PSAnc3RyZWFtJykge1xuICAgICAgICByZXNwb25zZS5kYXRhID0gcmVzcG9uc2VTdHJlYW07XG4gICAgICAgIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlQnVmZmVyID0gW107XG4gICAgICAgIGxldCB0b3RhbFJlc3BvbnNlQnl0ZXMgPSAwO1xuXG4gICAgICAgIHJlc3BvbnNlU3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24gaGFuZGxlU3RyZWFtRGF0YShjaHVuaykge1xuICAgICAgICAgIHJlc3BvbnNlQnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgICAgIHRvdGFsUmVzcG9uc2VCeXRlcyArPSBjaHVuay5sZW5ndGg7XG5cbiAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGNvbnRlbnQgbGVuZ3RoIGlzIG5vdCBvdmVyIHRoZSBtYXhDb250ZW50TGVuZ3RoIGlmIHNwZWNpZmllZFxuICAgICAgICAgIGlmIChjb25maWcubWF4Q29udGVudExlbmd0aCA+IC0xICYmIHRvdGFsUmVzcG9uc2VCeXRlcyA+IGNvbmZpZy5tYXhDb250ZW50TGVuZ3RoKSB7XG4gICAgICAgICAgICAvLyBzdHJlYW0uZGVzdHJveSgpIGVtaXQgYWJvcnRlZCBldmVudCBiZWZvcmUgY2FsbGluZyByZWplY3QoKSBvbiBOb2RlLmpzIHYxNlxuICAgICAgICAgICAgcmVqZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzcG9uc2VTdHJlYW0uZGVzdHJveSgpO1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKCdtYXhDb250ZW50TGVuZ3RoIHNpemUgb2YgJyArIGNvbmZpZy5tYXhDb250ZW50TGVuZ3RoICsgJyBleGNlZWRlZCcsXG4gICAgICAgICAgICAgIEF4aW9zRXJyb3IuRVJSX0JBRF9SRVNQT05TRSwgY29uZmlnLCBsYXN0UmVxdWVzdCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVzcG9uc2VTdHJlYW0ub24oJ2Fib3J0ZWQnLCBmdW5jdGlvbiBoYW5kbGVyU3RyZWFtQWJvcnRlZCgpIHtcbiAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgICAgICdtYXhDb250ZW50TGVuZ3RoIHNpemUgb2YgJyArIGNvbmZpZy5tYXhDb250ZW50TGVuZ3RoICsgJyBleGNlZWRlZCcsXG4gICAgICAgICAgICBBeGlvc0Vycm9yLkVSUl9CQURfUkVTUE9OU0UsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBsYXN0UmVxdWVzdFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmVzcG9uc2VTdHJlYW0uZGVzdHJveShlcnIpO1xuICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXNwb25zZVN0cmVhbS5vbignZXJyb3InLCBmdW5jdGlvbiBoYW5kbGVTdHJlYW1FcnJvcihlcnIpIHtcbiAgICAgICAgICBpZiAocmVxLmRlc3Ryb3llZCkgcmV0dXJuO1xuICAgICAgICAgIHJlamVjdChBeGlvc0Vycm9yLmZyb20oZXJyLCBudWxsLCBjb25maWcsIGxhc3RSZXF1ZXN0KSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3BvbnNlU3RyZWFtLm9uKCdlbmQnLCBmdW5jdGlvbiBoYW5kbGVTdHJlYW1FbmQoKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCByZXNwb25zZURhdGEgPSByZXNwb25zZUJ1ZmZlci5sZW5ndGggPT09IDEgPyByZXNwb25zZUJ1ZmZlclswXSA6IEJ1ZmZlci5jb25jYXQocmVzcG9uc2VCdWZmZXIpO1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlVHlwZSAhPT0gJ2FycmF5YnVmZmVyJykge1xuICAgICAgICAgICAgICByZXNwb25zZURhdGEgPSByZXNwb25zZURhdGEudG9TdHJpbmcocmVzcG9uc2VFbmNvZGluZyk7XG4gICAgICAgICAgICAgIGlmICghcmVzcG9uc2VFbmNvZGluZyB8fCByZXNwb25zZUVuY29kaW5nID09PSAndXRmOCcpIHtcbiAgICAgICAgICAgICAgICByZXNwb25zZURhdGEgPSB1dGlscy5zdHJpcEJPTShyZXNwb25zZURhdGEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNwb25zZS5kYXRhID0gcmVzcG9uc2VEYXRhO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgcmV0dXJuIHJlamVjdChBeGlvc0Vycm9yLmZyb20oZXJyLCBudWxsLCBjb25maWcsIHJlc3BvbnNlLnJlcXVlc3QsIHJlc3BvbnNlKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHJlc3BvbnNlKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGVtaXR0ZXIub25jZSgnYWJvcnQnLCBlcnIgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlU3RyZWFtLmRlc3Ryb3llZCkge1xuICAgICAgICAgIHJlc3BvbnNlU3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICByZXNwb25zZVN0cmVhbS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZW1pdHRlci5vbmNlKCdhYm9ydCcsIGVyciA9PiB7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICAgIHJlcS5kZXN0cm95KGVycik7XG4gICAgfSk7XG5cbiAgICAvLyBIYW5kbGUgZXJyb3JzXG4gICAgcmVxLm9uKCdlcnJvcicsIGZ1bmN0aW9uIGhhbmRsZVJlcXVlc3RFcnJvcihlcnIpIHtcbiAgICAgIC8vIEB0b2RvIHJlbW92ZVxuICAgICAgLy8gaWYgKHJlcS5hYm9ydGVkICYmIGVyci5jb2RlICE9PSBBeGlvc0Vycm9yLkVSUl9GUl9UT09fTUFOWV9SRURJUkVDVFMpIHJldHVybjtcbiAgICAgIHJlamVjdChBeGlvc0Vycm9yLmZyb20oZXJyLCBudWxsLCBjb25maWcsIHJlcSkpO1xuICAgIH0pO1xuXG4gICAgLy8gc2V0IHRjcCBrZWVwIGFsaXZlIHRvIHByZXZlbnQgZHJvcCBjb25uZWN0aW9uIGJ5IHBlZXJcbiAgICByZXEub24oJ3NvY2tldCcsIGZ1bmN0aW9uIGhhbmRsZVJlcXVlc3RTb2NrZXQoc29ja2V0KSB7XG4gICAgICAvLyBkZWZhdWx0IGludGVydmFsIG9mIHNlbmRpbmcgYWNrIHBhY2tldCBpcyAxIG1pbnV0ZVxuICAgICAgc29ja2V0LnNldEtlZXBBbGl2ZSh0cnVlLCAxMDAwICogNjApO1xuICAgIH0pO1xuXG4gICAgLy8gSGFuZGxlIHJlcXVlc3QgdGltZW91dFxuICAgIGlmIChjb25maWcudGltZW91dCkge1xuICAgICAgLy8gVGhpcyBpcyBmb3JjaW5nIGEgaW50IHRpbWVvdXQgdG8gYXZvaWQgcHJvYmxlbXMgaWYgdGhlIGByZXFgIGludGVyZmFjZSBkb2Vzbid0IGhhbmRsZSBvdGhlciB0eXBlcy5cbiAgICAgIGNvbnN0IHRpbWVvdXQgPSBwYXJzZUludChjb25maWcudGltZW91dCwgMTApO1xuXG4gICAgICBpZiAoTnVtYmVyLmlzTmFOKHRpbWVvdXQpKSB7XG4gICAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgICAnZXJyb3IgdHJ5aW5nIHRvIHBhcnNlIGBjb25maWcudGltZW91dGAgdG8gaW50JyxcbiAgICAgICAgICBBeGlvc0Vycm9yLkVSUl9CQURfT1BUSU9OX1ZBTFVFLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICByZXFcbiAgICAgICAgKSk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTb21ldGltZSwgdGhlIHJlc3BvbnNlIHdpbGwgYmUgdmVyeSBzbG93LCBhbmQgZG9lcyBub3QgcmVzcG9uZCwgdGhlIGNvbm5lY3QgZXZlbnQgd2lsbCBiZSBibG9jayBieSBldmVudCBsb29wIHN5c3RlbS5cbiAgICAgIC8vIEFuZCB0aW1lciBjYWxsYmFjayB3aWxsIGJlIGZpcmVkLCBhbmQgYWJvcnQoKSB3aWxsIGJlIGludm9rZWQgYmVmb3JlIGNvbm5lY3Rpb24sIHRoZW4gZ2V0IFwic29ja2V0IGhhbmcgdXBcIiBhbmQgY29kZSBFQ09OTlJFU0VULlxuICAgICAgLy8gQXQgdGhpcyB0aW1lLCBpZiB3ZSBoYXZlIGEgbGFyZ2UgbnVtYmVyIG9mIHJlcXVlc3QsIG5vZGVqcyB3aWxsIGhhbmcgdXAgc29tZSBzb2NrZXQgb24gYmFja2dyb3VuZC4gYW5kIHRoZSBudW1iZXIgd2lsbCB1cCBhbmQgdXAuXG4gICAgICAvLyBBbmQgdGhlbiB0aGVzZSBzb2NrZXQgd2hpY2ggYmUgaGFuZyB1cCB3aWxsIGRldm91cmluZyBDUFUgbGl0dGxlIGJ5IGxpdHRsZS5cbiAgICAgIC8vIENsaWVudFJlcXVlc3Quc2V0VGltZW91dCB3aWxsIGJlIGZpcmVkIG9uIHRoZSBzcGVjaWZ5IG1pbGxpc2Vjb25kcywgYW5kIGNhbiBtYWtlIHN1cmUgdGhhdCBhYm9ydCgpIHdpbGwgYmUgZmlyZWQgYWZ0ZXIgY29ubmVjdC5cbiAgICAgIHJlcS5zZXRUaW1lb3V0KHRpbWVvdXQsIGZ1bmN0aW9uIGhhbmRsZVJlcXVlc3RUaW1lb3V0KCkge1xuICAgICAgICBpZiAoaXNEb25lKSByZXR1cm47XG4gICAgICAgIGxldCB0aW1lb3V0RXJyb3JNZXNzYWdlID0gY29uZmlnLnRpbWVvdXQgPyAndGltZW91dCBvZiAnICsgY29uZmlnLnRpbWVvdXQgKyAnbXMgZXhjZWVkZWQnIDogJ3RpbWVvdXQgZXhjZWVkZWQnO1xuICAgICAgICBjb25zdCB0cmFuc2l0aW9uYWwgPSBjb25maWcudHJhbnNpdGlvbmFsIHx8IHRyYW5zaXRpb25hbERlZmF1bHRzO1xuICAgICAgICBpZiAoY29uZmlnLnRpbWVvdXRFcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgICB0aW1lb3V0RXJyb3JNZXNzYWdlID0gY29uZmlnLnRpbWVvdXRFcnJvck1lc3NhZ2U7XG4gICAgICAgIH1cbiAgICAgICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICAgIHRpbWVvdXRFcnJvck1lc3NhZ2UsXG4gICAgICAgICAgdHJhbnNpdGlvbmFsLmNsYXJpZnlUaW1lb3V0RXJyb3IgPyBBeGlvc0Vycm9yLkVUSU1FRE9VVCA6IEF4aW9zRXJyb3IuRUNPTk5BQk9SVEVELFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICByZXFcbiAgICAgICAgKSk7XG4gICAgICAgIGFib3J0KCk7XG4gICAgICB9KTtcbiAgICB9XG5cblxuICAgIC8vIFNlbmQgdGhlIHJlcXVlc3RcbiAgICBpZiAodXRpbHMuaXNTdHJlYW0oZGF0YSkpIHtcbiAgICAgIGxldCBlbmRlZCA9IGZhbHNlO1xuICAgICAgbGV0IGVycm9yZWQgPSBmYWxzZTtcblxuICAgICAgZGF0YS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICBlbmRlZCA9IHRydWU7XG4gICAgICB9KTtcblxuICAgICAgZGF0YS5vbmNlKCdlcnJvcicsIGVyciA9PiB7XG4gICAgICAgIGVycm9yZWQgPSB0cnVlO1xuICAgICAgICByZXEuZGVzdHJveShlcnIpO1xuICAgICAgfSk7XG5cbiAgICAgIGRhdGEub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgICBpZiAoIWVuZGVkICYmICFlcnJvcmVkKSB7XG4gICAgICAgICAgYWJvcnQobmV3IENhbmNlbGVkRXJyb3IoJ1JlcXVlc3Qgc3RyZWFtIGhhcyBiZWVuIGFib3J0ZWQnLCBjb25maWcsIHJlcSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZGF0YS5waXBlKHJlcSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcS5lbmQoZGF0YSk7XG4gICAgfVxuICB9KTtcbn07XG5cbmNvbnN0IGNvb2tpZXMgPSBwbGF0Zm9ybS5pc1N0YW5kYXJkQnJvd3NlckVudiA/XG5cbi8vIFN0YW5kYXJkIGJyb3dzZXIgZW52cyBzdXBwb3J0IGRvY3VtZW50LmNvb2tpZVxuICAoZnVuY3Rpb24gc3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgIHJldHVybiB7XG4gICAgICB3cml0ZTogZnVuY3Rpb24gd3JpdGUobmFtZSwgdmFsdWUsIGV4cGlyZXMsIHBhdGgsIGRvbWFpbiwgc2VjdXJlKSB7XG4gICAgICAgIGNvbnN0IGNvb2tpZSA9IFtdO1xuICAgICAgICBjb29raWUucHVzaChuYW1lICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKSk7XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzTnVtYmVyKGV4cGlyZXMpKSB7XG4gICAgICAgICAgY29va2llLnB1c2goJ2V4cGlyZXM9JyArIG5ldyBEYXRlKGV4cGlyZXMpLnRvR01UU3RyaW5nKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzU3RyaW5nKHBhdGgpKSB7XG4gICAgICAgICAgY29va2llLnB1c2goJ3BhdGg9JyArIHBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHV0aWxzLmlzU3RyaW5nKGRvbWFpbikpIHtcbiAgICAgICAgICBjb29raWUucHVzaCgnZG9tYWluPScgKyBkb21haW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNlY3VyZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgIGNvb2tpZS5wdXNoKCdzZWN1cmUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IGNvb2tpZS5qb2luKCc7ICcpO1xuICAgICAgfSxcblxuICAgICAgcmVhZDogZnVuY3Rpb24gcmVhZChuYW1lKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gZG9jdW1lbnQuY29va2llLm1hdGNoKG5ldyBSZWdFeHAoJyhefDtcXFxccyopKCcgKyBuYW1lICsgJyk9KFteO10qKScpKTtcbiAgICAgICAgcmV0dXJuIChtYXRjaCA/IGRlY29kZVVSSUNvbXBvbmVudChtYXRjaFszXSkgOiBudWxsKTtcbiAgICAgIH0sXG5cbiAgICAgIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlKG5hbWUpIHtcbiAgICAgICAgdGhpcy53cml0ZShuYW1lLCAnJywgRGF0ZS5ub3coKSAtIDg2NDAwMDAwKTtcbiAgICAgIH1cbiAgICB9O1xuICB9KSgpIDpcblxuLy8gTm9uIHN0YW5kYXJkIGJyb3dzZXIgZW52ICh3ZWIgd29ya2VycywgcmVhY3QtbmF0aXZlKSBsYWNrIG5lZWRlZCBzdXBwb3J0LlxuICAoZnVuY3Rpb24gbm9uU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgIHJldHVybiB7XG4gICAgICB3cml0ZTogZnVuY3Rpb24gd3JpdGUoKSB7fSxcbiAgICAgIHJlYWQ6IGZ1bmN0aW9uIHJlYWQoKSB7IHJldHVybiBudWxsOyB9LFxuICAgICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7fVxuICAgIH07XG4gIH0pKCk7XG5cbmNvbnN0IGlzVVJMU2FtZU9yaWdpbiA9IHBsYXRmb3JtLmlzU3RhbmRhcmRCcm93c2VyRW52ID9cblxuLy8gU3RhbmRhcmQgYnJvd3NlciBlbnZzIGhhdmUgZnVsbCBzdXBwb3J0IG9mIHRoZSBBUElzIG5lZWRlZCB0byB0ZXN0XG4vLyB3aGV0aGVyIHRoZSByZXF1ZXN0IFVSTCBpcyBvZiB0aGUgc2FtZSBvcmlnaW4gYXMgY3VycmVudCBsb2NhdGlvbi5cbiAgKGZ1bmN0aW9uIHN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICBjb25zdCBtc2llID0gLyhtc2llfHRyaWRlbnQpL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICBjb25zdCB1cmxQYXJzaW5nTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBsZXQgb3JpZ2luVVJMO1xuXG4gICAgLyoqXG4gICAgKiBQYXJzZSBhIFVSTCB0byBkaXNjb3ZlciBpdCdzIGNvbXBvbmVudHNcbiAgICAqXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gdXJsIFRoZSBVUkwgdG8gYmUgcGFyc2VkXG4gICAgKiBAcmV0dXJucyB7T2JqZWN0fVxuICAgICovXG4gICAgZnVuY3Rpb24gcmVzb2x2ZVVSTCh1cmwpIHtcbiAgICAgIGxldCBocmVmID0gdXJsO1xuXG4gICAgICBpZiAobXNpZSkge1xuICAgICAgICAvLyBJRSBuZWVkcyBhdHRyaWJ1dGUgc2V0IHR3aWNlIHRvIG5vcm1hbGl6ZSBwcm9wZXJ0aWVzXG4gICAgICAgIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZSgnaHJlZicsIGhyZWYpO1xuICAgICAgICBocmVmID0gdXJsUGFyc2luZ05vZGUuaHJlZjtcbiAgICAgIH1cblxuICAgICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG5cbiAgICAgIC8vIHVybFBhcnNpbmdOb2RlIHByb3ZpZGVzIHRoZSBVcmxVdGlscyBpbnRlcmZhY2UgLSBodHRwOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsdXRpbHNcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGhyZWY6IHVybFBhcnNpbmdOb2RlLmhyZWYsXG4gICAgICAgIHByb3RvY29sOiB1cmxQYXJzaW5nTm9kZS5wcm90b2NvbCA/IHVybFBhcnNpbmdOb2RlLnByb3RvY29sLnJlcGxhY2UoLzokLywgJycpIDogJycsXG4gICAgICAgIGhvc3Q6IHVybFBhcnNpbmdOb2RlLmhvc3QsXG4gICAgICAgIHNlYXJjaDogdXJsUGFyc2luZ05vZGUuc2VhcmNoID8gdXJsUGFyc2luZ05vZGUuc2VhcmNoLnJlcGxhY2UoL15cXD8vLCAnJykgOiAnJyxcbiAgICAgICAgaGFzaDogdXJsUGFyc2luZ05vZGUuaGFzaCA/IHVybFBhcnNpbmdOb2RlLmhhc2gucmVwbGFjZSgvXiMvLCAnJykgOiAnJyxcbiAgICAgICAgaG9zdG5hbWU6IHVybFBhcnNpbmdOb2RlLmhvc3RuYW1lLFxuICAgICAgICBwb3J0OiB1cmxQYXJzaW5nTm9kZS5wb3J0LFxuICAgICAgICBwYXRobmFtZTogKHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nKSA/XG4gICAgICAgICAgdXJsUGFyc2luZ05vZGUucGF0aG5hbWUgOlxuICAgICAgICAgICcvJyArIHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lXG4gICAgICB9O1xuICAgIH1cblxuICAgIG9yaWdpblVSTCA9IHJlc29sdmVVUkwod2luZG93LmxvY2F0aW9uLmhyZWYpO1xuXG4gICAgLyoqXG4gICAgKiBEZXRlcm1pbmUgaWYgYSBVUkwgc2hhcmVzIHRoZSBzYW1lIG9yaWdpbiBhcyB0aGUgY3VycmVudCBsb2NhdGlvblxuICAgICpcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSByZXF1ZXN0VVJMIFRoZSBVUkwgdG8gdGVzdFxuICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgVVJMIHNoYXJlcyB0aGUgc2FtZSBvcmlnaW4sIG90aGVyd2lzZSBmYWxzZVxuICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGlzVVJMU2FtZU9yaWdpbihyZXF1ZXN0VVJMKSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSAodXRpbHMuaXNTdHJpbmcocmVxdWVzdFVSTCkpID8gcmVzb2x2ZVVSTChyZXF1ZXN0VVJMKSA6IHJlcXVlc3RVUkw7XG4gICAgICByZXR1cm4gKHBhcnNlZC5wcm90b2NvbCA9PT0gb3JpZ2luVVJMLnByb3RvY29sICYmXG4gICAgICAgICAgcGFyc2VkLmhvc3QgPT09IG9yaWdpblVSTC5ob3N0KTtcbiAgICB9O1xuICB9KSgpIDpcblxuICAvLyBOb24gc3RhbmRhcmQgYnJvd3NlciBlbnZzICh3ZWIgd29ya2VycywgcmVhY3QtbmF0aXZlKSBsYWNrIG5lZWRlZCBzdXBwb3J0LlxuICAoZnVuY3Rpb24gbm9uU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBpc1VSTFNhbWVPcmlnaW4oKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuICB9KSgpO1xuXG5mdW5jdGlvbiBwcm9ncmVzc0V2ZW50UmVkdWNlcihsaXN0ZW5lciwgaXNEb3dubG9hZFN0cmVhbSkge1xuICBsZXQgYnl0ZXNOb3RpZmllZCA9IDA7XG4gIGNvbnN0IF9zcGVlZG9tZXRlciA9IHNwZWVkb21ldGVyKDUwLCAyNTApO1xuXG4gIHJldHVybiBlID0+IHtcbiAgICBjb25zdCBsb2FkZWQgPSBlLmxvYWRlZDtcbiAgICBjb25zdCB0b3RhbCA9IGUubGVuZ3RoQ29tcHV0YWJsZSA/IGUudG90YWwgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcHJvZ3Jlc3NCeXRlcyA9IGxvYWRlZCAtIGJ5dGVzTm90aWZpZWQ7XG4gICAgY29uc3QgcmF0ZSA9IF9zcGVlZG9tZXRlcihwcm9ncmVzc0J5dGVzKTtcbiAgICBjb25zdCBpblJhbmdlID0gbG9hZGVkIDw9IHRvdGFsO1xuXG4gICAgYnl0ZXNOb3RpZmllZCA9IGxvYWRlZDtcblxuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICBsb2FkZWQsXG4gICAgICB0b3RhbCxcbiAgICAgIHByb2dyZXNzOiB0b3RhbCA/IChsb2FkZWQgLyB0b3RhbCkgOiB1bmRlZmluZWQsXG4gICAgICBieXRlczogcHJvZ3Jlc3NCeXRlcyxcbiAgICAgIHJhdGU6IHJhdGUgPyByYXRlIDogdW5kZWZpbmVkLFxuICAgICAgZXN0aW1hdGVkOiByYXRlICYmIHRvdGFsICYmIGluUmFuZ2UgPyAodG90YWwgLSBsb2FkZWQpIC8gcmF0ZSA6IHVuZGVmaW5lZCxcbiAgICAgIGV2ZW50OiBlXG4gICAgfTtcblxuICAgIGRhdGFbaXNEb3dubG9hZFN0cmVhbSA/ICdkb3dubG9hZCcgOiAndXBsb2FkJ10gPSB0cnVlO1xuXG4gICAgbGlzdGVuZXIoZGF0YSk7XG4gIH07XG59XG5cbmNvbnN0IGlzWEhSQWRhcHRlclN1cHBvcnRlZCA9IHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCc7XG5cbmNvbnN0IHhockFkYXB0ZXIgPSBpc1hIUkFkYXB0ZXJTdXBwb3J0ZWQgJiYgZnVuY3Rpb24gKGNvbmZpZykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gZGlzcGF0Y2hYaHJSZXF1ZXN0KHJlc29sdmUsIHJlamVjdCkge1xuICAgIGxldCByZXF1ZXN0RGF0YSA9IGNvbmZpZy5kYXRhO1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShjb25maWcuaGVhZGVycykubm9ybWFsaXplKCk7XG4gICAgY29uc3QgcmVzcG9uc2VUeXBlID0gY29uZmlnLnJlc3BvbnNlVHlwZTtcbiAgICBsZXQgb25DYW5jZWxlZDtcbiAgICBmdW5jdGlvbiBkb25lKCkge1xuICAgICAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbikge1xuICAgICAgICBjb25maWcuY2FuY2VsVG9rZW4udW5zdWJzY3JpYmUob25DYW5jZWxlZCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcuc2lnbmFsKSB7XG4gICAgICAgIGNvbmZpZy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkNhbmNlbGVkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgY29udGVudFR5cGU7XG5cbiAgICBpZiAodXRpbHMuaXNGb3JtRGF0YShyZXF1ZXN0RGF0YSkpIHtcbiAgICAgIGlmIChwbGF0Zm9ybS5pc1N0YW5kYXJkQnJvd3NlckVudiB8fCBwbGF0Zm9ybS5pc1N0YW5kYXJkQnJvd3NlcldlYldvcmtlckVudikge1xuICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRDb250ZW50VHlwZShmYWxzZSk7IC8vIExldCB0aGUgYnJvd3NlciBzZXQgaXRcbiAgICAgIH0gZWxzZSBpZighcmVxdWVzdEhlYWRlcnMuZ2V0Q29udGVudFR5cGUoL15cXHMqbXVsdGlwYXJ0XFwvZm9ybS1kYXRhLykpe1xuICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRDb250ZW50VHlwZSgnbXVsdGlwYXJ0L2Zvcm0tZGF0YScpOyAvLyBtb2JpbGUvZGVza3RvcCBhcHAgZnJhbWV3b3Jrc1xuICAgICAgfSBlbHNlIGlmKHV0aWxzLmlzU3RyaW5nKGNvbnRlbnRUeXBlID0gcmVxdWVzdEhlYWRlcnMuZ2V0Q29udGVudFR5cGUoKSkpe1xuICAgICAgICAvLyBmaXggc2VtaWNvbG9uIGR1cGxpY2F0aW9uIGlzc3VlIGZvciBSZWFjdE5hdGl2ZSBGb3JtRGF0YSBpbXBsZW1lbnRhdGlvblxuICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXRDb250ZW50VHlwZShjb250ZW50VHlwZS5yZXBsYWNlKC9eXFxzKihtdWx0aXBhcnRcXC9mb3JtLWRhdGEpOysvLCAnJDEnKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblxuICAgIC8vIEhUVFAgYmFzaWMgYXV0aGVudGljYXRpb25cbiAgICBpZiAoY29uZmlnLmF1dGgpIHtcbiAgICAgIGNvbnN0IHVzZXJuYW1lID0gY29uZmlnLmF1dGgudXNlcm5hbWUgfHwgJyc7XG4gICAgICBjb25zdCBwYXNzd29yZCA9IGNvbmZpZy5hdXRoLnBhc3N3b3JkID8gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGNvbmZpZy5hdXRoLnBhc3N3b3JkKSkgOiAnJztcbiAgICAgIHJlcXVlc3RIZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgYnRvYSh1c2VybmFtZSArICc6JyArIHBhc3N3b3JkKSk7XG4gICAgfVxuXG4gICAgY29uc3QgZnVsbFBhdGggPSBidWlsZEZ1bGxQYXRoKGNvbmZpZy5iYXNlVVJMLCBjb25maWcudXJsKTtcblxuICAgIHJlcXVlc3Qub3Blbihjb25maWcubWV0aG9kLnRvVXBwZXJDYXNlKCksIGJ1aWxkVVJMKGZ1bGxQYXRoLCBjb25maWcucGFyYW1zLCBjb25maWcucGFyYW1zU2VyaWFsaXplciksIHRydWUpO1xuXG4gICAgLy8gU2V0IHRoZSByZXF1ZXN0IHRpbWVvdXQgaW4gTVNcbiAgICByZXF1ZXN0LnRpbWVvdXQgPSBjb25maWcudGltZW91dDtcblxuICAgIGZ1bmN0aW9uIG9ubG9hZGVuZCgpIHtcbiAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBQcmVwYXJlIHRoZSByZXNwb25zZVxuICAgICAgY29uc3QgcmVzcG9uc2VIZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShcbiAgICAgICAgJ2dldEFsbFJlc3BvbnNlSGVhZGVycycgaW4gcmVxdWVzdCAmJiByZXF1ZXN0LmdldEFsbFJlc3BvbnNlSGVhZGVycygpXG4gICAgICApO1xuICAgICAgY29uc3QgcmVzcG9uc2VEYXRhID0gIXJlc3BvbnNlVHlwZSB8fCByZXNwb25zZVR5cGUgPT09ICd0ZXh0JyB8fCByZXNwb25zZVR5cGUgPT09ICdqc29uJyA/XG4gICAgICAgIHJlcXVlc3QucmVzcG9uc2VUZXh0IDogcmVxdWVzdC5yZXNwb25zZTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgICAgICBkYXRhOiByZXNwb25zZURhdGEsXG4gICAgICAgIHN0YXR1czogcmVxdWVzdC5zdGF0dXMsXG4gICAgICAgIHN0YXR1c1RleHQ6IHJlcXVlc3Quc3RhdHVzVGV4dCxcbiAgICAgICAgaGVhZGVyczogcmVzcG9uc2VIZWFkZXJzLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcXVlc3RcbiAgICAgIH07XG5cbiAgICAgIHNldHRsZShmdW5jdGlvbiBfcmVzb2x2ZSh2YWx1ZSkge1xuICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSwgZnVuY3Rpb24gX3JlamVjdChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0sIHJlc3BvbnNlKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCdvbmxvYWRlbmQnIGluIHJlcXVlc3QpIHtcbiAgICAgIC8vIFVzZSBvbmxvYWRlbmQgaWYgYXZhaWxhYmxlXG4gICAgICByZXF1ZXN0Lm9ubG9hZGVuZCA9IG9ubG9hZGVuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTGlzdGVuIGZvciByZWFkeSBzdGF0ZSB0byBlbXVsYXRlIG9ubG9hZGVuZFxuICAgICAgcmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiBoYW5kbGVMb2FkKCkge1xuICAgICAgICBpZiAoIXJlcXVlc3QgfHwgcmVxdWVzdC5yZWFkeVN0YXRlICE9PSA0KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlIHJlcXVlc3QgZXJyb3JlZCBvdXQgYW5kIHdlIGRpZG4ndCBnZXQgYSByZXNwb25zZSwgdGhpcyB3aWxsIGJlXG4gICAgICAgIC8vIGhhbmRsZWQgYnkgb25lcnJvciBpbnN0ZWFkXG4gICAgICAgIC8vIFdpdGggb25lIGV4Y2VwdGlvbjogcmVxdWVzdCB0aGF0IHVzaW5nIGZpbGU6IHByb3RvY29sLCBtb3N0IGJyb3dzZXJzXG4gICAgICAgIC8vIHdpbGwgcmV0dXJuIHN0YXR1cyBhcyAwIGV2ZW4gdGhvdWdoIGl0J3MgYSBzdWNjZXNzZnVsIHJlcXVlc3RcbiAgICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09PSAwICYmICEocmVxdWVzdC5yZXNwb25zZVVSTCAmJiByZXF1ZXN0LnJlc3BvbnNlVVJMLmluZGV4T2YoJ2ZpbGU6JykgPT09IDApKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlYWR5c3RhdGUgaGFuZGxlciBpcyBjYWxsaW5nIGJlZm9yZSBvbmVycm9yIG9yIG9udGltZW91dCBoYW5kbGVycyxcbiAgICAgICAgLy8gc28gd2Ugc2hvdWxkIGNhbGwgb25sb2FkZW5kIG9uIHRoZSBuZXh0ICd0aWNrJ1xuICAgICAgICBzZXRUaW1lb3V0KG9ubG9hZGVuZCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBicm93c2VyIHJlcXVlc3QgY2FuY2VsbGF0aW9uIChhcyBvcHBvc2VkIHRvIGEgbWFudWFsIGNhbmNlbGxhdGlvbilcbiAgICByZXF1ZXN0Lm9uYWJvcnQgPSBmdW5jdGlvbiBoYW5kbGVBYm9ydCgpIHtcbiAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcignUmVxdWVzdCBhYm9ydGVkJywgQXhpb3NFcnJvci5FQ09OTkFCT1JURUQsIGNvbmZpZywgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIGxvdyBsZXZlbCBuZXR3b3JrIGVycm9yc1xuICAgIHJlcXVlc3Qub25lcnJvciA9IGZ1bmN0aW9uIGhhbmRsZUVycm9yKCkge1xuICAgICAgLy8gUmVhbCBlcnJvcnMgYXJlIGhpZGRlbiBmcm9tIHVzIGJ5IHRoZSBicm93c2VyXG4gICAgICAvLyBvbmVycm9yIHNob3VsZCBvbmx5IGZpcmUgaWYgaXQncyBhIG5ldHdvcmsgZXJyb3JcbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcignTmV0d29yayBFcnJvcicsIEF4aW9zRXJyb3IuRVJSX05FVFdPUkssIGNvbmZpZywgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIHRpbWVvdXRcbiAgICByZXF1ZXN0Lm9udGltZW91dCA9IGZ1bmN0aW9uIGhhbmRsZVRpbWVvdXQoKSB7XG4gICAgICBsZXQgdGltZW91dEVycm9yTWVzc2FnZSA9IGNvbmZpZy50aW1lb3V0ID8gJ3RpbWVvdXQgb2YgJyArIGNvbmZpZy50aW1lb3V0ICsgJ21zIGV4Y2VlZGVkJyA6ICd0aW1lb3V0IGV4Y2VlZGVkJztcbiAgICAgIGNvbnN0IHRyYW5zaXRpb25hbCA9IGNvbmZpZy50cmFuc2l0aW9uYWwgfHwgdHJhbnNpdGlvbmFsRGVmYXVsdHM7XG4gICAgICBpZiAoY29uZmlnLnRpbWVvdXRFcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgdGltZW91dEVycm9yTWVzc2FnZSA9IGNvbmZpZy50aW1lb3V0RXJyb3JNZXNzYWdlO1xuICAgICAgfVxuICAgICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICB0aW1lb3V0RXJyb3JNZXNzYWdlLFxuICAgICAgICB0cmFuc2l0aW9uYWwuY2xhcmlmeVRpbWVvdXRFcnJvciA/IEF4aW9zRXJyb3IuRVRJTUVET1VUIDogQXhpb3NFcnJvci5FQ09OTkFCT1JURUQsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gQWRkIHhzcmYgaGVhZGVyXG4gICAgLy8gVGhpcyBpcyBvbmx5IGRvbmUgaWYgcnVubmluZyBpbiBhIHN0YW5kYXJkIGJyb3dzZXIgZW52aXJvbm1lbnQuXG4gICAgLy8gU3BlY2lmaWNhbGx5IG5vdCBpZiB3ZSdyZSBpbiBhIHdlYiB3b3JrZXIsIG9yIHJlYWN0LW5hdGl2ZS5cbiAgICBpZiAocGxhdGZvcm0uaXNTdGFuZGFyZEJyb3dzZXJFbnYpIHtcbiAgICAgIC8vIEFkZCB4c3JmIGhlYWRlclxuICAgICAgLy8gcmVnYXJkaW5nIENWRS0yMDIzLTQ1ODU3IGNvbmZpZy53aXRoQ3JlZGVudGlhbHMgY29uZGl0aW9uIHdhcyByZW1vdmVkIHRlbXBvcmFyaWx5XG4gICAgICBjb25zdCB4c3JmVmFsdWUgPSBpc1VSTFNhbWVPcmlnaW4oZnVsbFBhdGgpICYmIGNvbmZpZy54c3JmQ29va2llTmFtZSAmJiBjb29raWVzLnJlYWQoY29uZmlnLnhzcmZDb29raWVOYW1lKTtcblxuICAgICAgaWYgKHhzcmZWYWx1ZSkge1xuICAgICAgICByZXF1ZXN0SGVhZGVycy5zZXQoY29uZmlnLnhzcmZIZWFkZXJOYW1lLCB4c3JmVmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlbW92ZSBDb250ZW50LVR5cGUgaWYgZGF0YSBpcyB1bmRlZmluZWRcbiAgICByZXF1ZXN0RGF0YSA9PT0gdW5kZWZpbmVkICYmIHJlcXVlc3RIZWFkZXJzLnNldENvbnRlbnRUeXBlKG51bGwpO1xuXG4gICAgLy8gQWRkIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3RcbiAgICBpZiAoJ3NldFJlcXVlc3RIZWFkZXInIGluIHJlcXVlc3QpIHtcbiAgICAgIHV0aWxzLmZvckVhY2gocmVxdWVzdEhlYWRlcnMudG9KU09OKCksIGZ1bmN0aW9uIHNldFJlcXVlc3RIZWFkZXIodmFsLCBrZXkpIHtcbiAgICAgICAgcmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEFkZCB3aXRoQ3JlZGVudGlhbHMgdG8gcmVxdWVzdCBpZiBuZWVkZWRcbiAgICBpZiAoIXV0aWxzLmlzVW5kZWZpbmVkKGNvbmZpZy53aXRoQ3JlZGVudGlhbHMpKSB7XG4gICAgICByZXF1ZXN0LndpdGhDcmVkZW50aWFscyA9ICEhY29uZmlnLndpdGhDcmVkZW50aWFscztcbiAgICB9XG5cbiAgICAvLyBBZGQgcmVzcG9uc2VUeXBlIHRvIHJlcXVlc3QgaWYgbmVlZGVkXG4gICAgaWYgKHJlc3BvbnNlVHlwZSAmJiByZXNwb25zZVR5cGUgIT09ICdqc29uJykge1xuICAgICAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSBjb25maWcucmVzcG9uc2VUeXBlO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBwcm9ncmVzcyBpZiBuZWVkZWRcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5vbkRvd25sb2FkUHJvZ3Jlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCBwcm9ncmVzc0V2ZW50UmVkdWNlcihjb25maWcub25Eb3dubG9hZFByb2dyZXNzLCB0cnVlKSk7XG4gICAgfVxuXG4gICAgLy8gTm90IGFsbCBicm93c2VycyBzdXBwb3J0IHVwbG9hZCBldmVudHNcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5vblVwbG9hZFByb2dyZXNzID09PSAnZnVuY3Rpb24nICYmIHJlcXVlc3QudXBsb2FkKSB7XG4gICAgICByZXF1ZXN0LnVwbG9hZC5hZGRFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIHByb2dyZXNzRXZlbnRSZWR1Y2VyKGNvbmZpZy5vblVwbG9hZFByb2dyZXNzKSk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbiB8fCBjb25maWcuc2lnbmFsKSB7XG4gICAgICAvLyBIYW5kbGUgY2FuY2VsbGF0aW9uXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuICAgICAgb25DYW5jZWxlZCA9IGNhbmNlbCA9PiB7XG4gICAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QoIWNhbmNlbCB8fCBjYW5jZWwudHlwZSA/IG5ldyBDYW5jZWxlZEVycm9yKG51bGwsIGNvbmZpZywgcmVxdWVzdCkgOiBjYW5jZWwpO1xuICAgICAgICByZXF1ZXN0LmFib3J0KCk7XG4gICAgICAgIHJlcXVlc3QgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgY29uZmlnLmNhbmNlbFRva2VuICYmIGNvbmZpZy5jYW5jZWxUb2tlbi5zdWJzY3JpYmUob25DYW5jZWxlZCk7XG4gICAgICBpZiAoY29uZmlnLnNpZ25hbCkge1xuICAgICAgICBjb25maWcuc2lnbmFsLmFib3J0ZWQgPyBvbkNhbmNlbGVkKCkgOiBjb25maWcuc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25DYW5jZWxlZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcHJvdG9jb2wgPSBwYXJzZVByb3RvY29sKGZ1bGxQYXRoKTtcblxuICAgIGlmIChwcm90b2NvbCAmJiBwbGF0Zm9ybS5wcm90b2NvbHMuaW5kZXhPZihwcm90b2NvbCkgPT09IC0xKSB7XG4gICAgICByZWplY3QobmV3IEF4aW9zRXJyb3IoJ1Vuc3VwcG9ydGVkIHByb3RvY29sICcgKyBwcm90b2NvbCArICc6JywgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsIGNvbmZpZykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuXG4gICAgLy8gU2VuZCB0aGUgcmVxdWVzdFxuICAgIHJlcXVlc3Quc2VuZChyZXF1ZXN0RGF0YSB8fCBudWxsKTtcbiAgfSk7XG59O1xuXG5jb25zdCBrbm93bkFkYXB0ZXJzID0ge1xuICBodHRwOiBodHRwQWRhcHRlcixcbiAgeGhyOiB4aHJBZGFwdGVyXG59O1xuXG51dGlscy5mb3JFYWNoKGtub3duQWRhcHRlcnMsIChmbiwgdmFsdWUpID0+IHtcbiAgaWYgKGZuKSB7XG4gICAgdHJ5IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmbiwgJ25hbWUnLCB7dmFsdWV9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHlcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGZuLCAnYWRhcHRlck5hbWUnLCB7dmFsdWV9KTtcbiAgfVxufSk7XG5cbmNvbnN0IHJlbmRlclJlYXNvbiA9IChyZWFzb24pID0+IGAtICR7cmVhc29ufWA7XG5cbmNvbnN0IGlzUmVzb2x2ZWRIYW5kbGUgPSAoYWRhcHRlcikgPT4gdXRpbHMuaXNGdW5jdGlvbihhZGFwdGVyKSB8fCBhZGFwdGVyID09PSBudWxsIHx8IGFkYXB0ZXIgPT09IGZhbHNlO1xuXG5jb25zdCBhZGFwdGVycyA9IHtcbiAgZ2V0QWRhcHRlcjogKGFkYXB0ZXJzKSA9PiB7XG4gICAgYWRhcHRlcnMgPSB1dGlscy5pc0FycmF5KGFkYXB0ZXJzKSA/IGFkYXB0ZXJzIDogW2FkYXB0ZXJzXTtcblxuICAgIGNvbnN0IHtsZW5ndGh9ID0gYWRhcHRlcnM7XG4gICAgbGV0IG5hbWVPckFkYXB0ZXI7XG4gICAgbGV0IGFkYXB0ZXI7XG5cbiAgICBjb25zdCByZWplY3RlZFJlYXNvbnMgPSB7fTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIG5hbWVPckFkYXB0ZXIgPSBhZGFwdGVyc1tpXTtcbiAgICAgIGxldCBpZDtcblxuICAgICAgYWRhcHRlciA9IG5hbWVPckFkYXB0ZXI7XG5cbiAgICAgIGlmICghaXNSZXNvbHZlZEhhbmRsZShuYW1lT3JBZGFwdGVyKSkge1xuICAgICAgICBhZGFwdGVyID0ga25vd25BZGFwdGVyc1soaWQgPSBTdHJpbmcobmFtZU9yQWRhcHRlcikpLnRvTG93ZXJDYXNlKCldO1xuXG4gICAgICAgIGlmIChhZGFwdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihgVW5rbm93biBhZGFwdGVyICcke2lkfSdgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYWRhcHRlcikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgcmVqZWN0ZWRSZWFzb25zW2lkIHx8ICcjJyArIGldID0gYWRhcHRlcjtcbiAgICB9XG5cbiAgICBpZiAoIWFkYXB0ZXIpIHtcblxuICAgICAgY29uc3QgcmVhc29ucyA9IE9iamVjdC5lbnRyaWVzKHJlamVjdGVkUmVhc29ucylcbiAgICAgICAgLm1hcCgoW2lkLCBzdGF0ZV0pID0+IGBhZGFwdGVyICR7aWR9IGAgK1xuICAgICAgICAgIChzdGF0ZSA9PT0gZmFsc2UgPyAnaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgZW52aXJvbm1lbnQnIDogJ2lzIG5vdCBhdmFpbGFibGUgaW4gdGhlIGJ1aWxkJylcbiAgICAgICAgKTtcblxuICAgICAgbGV0IHMgPSBsZW5ndGggP1xuICAgICAgICAocmVhc29ucy5sZW5ndGggPiAxID8gJ3NpbmNlIDpcXG4nICsgcmVhc29ucy5tYXAocmVuZGVyUmVhc29uKS5qb2luKCdcXG4nKSA6ICcgJyArIHJlbmRlclJlYXNvbihyZWFzb25zWzBdKSkgOlxuICAgICAgICAnYXMgbm8gYWRhcHRlciBzcGVjaWZpZWQnO1xuXG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgYFRoZXJlIGlzIG5vIHN1aXRhYmxlIGFkYXB0ZXIgdG8gZGlzcGF0Y2ggdGhlIHJlcXVlc3QgYCArIHMsXG4gICAgICAgICdFUlJfTk9UX1NVUFBPUlQnXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhZGFwdGVyO1xuICB9LFxuICBhZGFwdGVyczoga25vd25BZGFwdGVyc1xufTtcblxuLyoqXG4gKiBUaHJvd3MgYSBgQ2FuY2VsZWRFcnJvcmAgaWYgY2FuY2VsbGF0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIFRoZSBjb25maWcgdGhhdCBpcyB0byBiZSB1c2VkIGZvciB0aGUgcmVxdWVzdFxuICpcbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkKGNvbmZpZykge1xuICBpZiAoY29uZmlnLmNhbmNlbFRva2VuKSB7XG4gICAgY29uZmlnLmNhbmNlbFRva2VuLnRocm93SWZSZXF1ZXN0ZWQoKTtcbiAgfVxuXG4gIGlmIChjb25maWcuc2lnbmFsICYmIGNvbmZpZy5zaWduYWwuYWJvcnRlZCkge1xuICAgIHRocm93IG5ldyBDYW5jZWxlZEVycm9yKG51bGwsIGNvbmZpZyk7XG4gIH1cbn1cblxuLyoqXG4gKiBEaXNwYXRjaCBhIHJlcXVlc3QgdG8gdGhlIHNlcnZlciB1c2luZyB0aGUgY29uZmlndXJlZCBhZGFwdGVyLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgVGhlIGNvbmZpZyB0aGF0IGlzIHRvIGJlIHVzZWQgZm9yIHRoZSByZXF1ZXN0XG4gKlxuICogQHJldHVybnMge1Byb21pc2V9IFRoZSBQcm9taXNlIHRvIGJlIGZ1bGZpbGxlZFxuICovXG5mdW5jdGlvbiBkaXNwYXRjaFJlcXVlc3QoY29uZmlnKSB7XG4gIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICBjb25maWcuaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmZyb20oY29uZmlnLmhlYWRlcnMpO1xuXG4gIC8vIFRyYW5zZm9ybSByZXF1ZXN0IGRhdGFcbiAgY29uZmlnLmRhdGEgPSB0cmFuc2Zvcm1EYXRhLmNhbGwoXG4gICAgY29uZmlnLFxuICAgIGNvbmZpZy50cmFuc2Zvcm1SZXF1ZXN0XG4gICk7XG5cbiAgaWYgKFsncG9zdCcsICdwdXQnLCAncGF0Y2gnXS5pbmRleE9mKGNvbmZpZy5tZXRob2QpICE9PSAtMSkge1xuICAgIGNvbmZpZy5oZWFkZXJzLnNldENvbnRlbnRUeXBlKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLCBmYWxzZSk7XG4gIH1cblxuICBjb25zdCBhZGFwdGVyID0gYWRhcHRlcnMuZ2V0QWRhcHRlcihjb25maWcuYWRhcHRlciB8fCBkZWZhdWx0cyQxLmFkYXB0ZXIpO1xuXG4gIHJldHVybiBhZGFwdGVyKGNvbmZpZykudGhlbihmdW5jdGlvbiBvbkFkYXB0ZXJSZXNvbHV0aW9uKHJlc3BvbnNlKSB7XG4gICAgdGhyb3dJZkNhbmNlbGxhdGlvblJlcXVlc3RlZChjb25maWcpO1xuXG4gICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICByZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YS5jYWxsKFxuICAgICAgY29uZmlnLFxuICAgICAgY29uZmlnLnRyYW5zZm9ybVJlc3BvbnNlLFxuICAgICAgcmVzcG9uc2VcbiAgICApO1xuXG4gICAgcmVzcG9uc2UuaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmZyb20ocmVzcG9uc2UuaGVhZGVycyk7XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH0sIGZ1bmN0aW9uIG9uQWRhcHRlclJlamVjdGlvbihyZWFzb24pIHtcbiAgICBpZiAoIWlzQ2FuY2VsKHJlYXNvbikpIHtcbiAgICAgIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICAgICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICAgIGlmIChyZWFzb24gJiYgcmVhc29uLnJlc3BvbnNlKSB7XG4gICAgICAgIHJlYXNvbi5yZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YS5jYWxsKFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBjb25maWcudHJhbnNmb3JtUmVzcG9uc2UsXG4gICAgICAgICAgcmVhc29uLnJlc3BvbnNlXG4gICAgICAgICk7XG4gICAgICAgIHJlYXNvbi5yZXNwb25zZS5oZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShyZWFzb24ucmVzcG9uc2UuaGVhZGVycyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlYXNvbik7XG4gIH0pO1xufVxuXG5jb25zdCBoZWFkZXJzVG9PYmplY3QgPSAodGhpbmcpID0+IHRoaW5nIGluc3RhbmNlb2YgQXhpb3NIZWFkZXJzJDEgPyB0aGluZy50b0pTT04oKSA6IHRoaW5nO1xuXG4vKipcbiAqIENvbmZpZy1zcGVjaWZpYyBtZXJnZS1mdW5jdGlvbiB3aGljaCBjcmVhdGVzIGEgbmV3IGNvbmZpZy1vYmplY3RcbiAqIGJ5IG1lcmdpbmcgdHdvIGNvbmZpZ3VyYXRpb24gb2JqZWN0cyB0b2dldGhlci5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnMVxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZzJcbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBOZXcgb2JqZWN0IHJlc3VsdGluZyBmcm9tIG1lcmdpbmcgY29uZmlnMiB0byBjb25maWcxXG4gKi9cbmZ1bmN0aW9uIG1lcmdlQ29uZmlnKGNvbmZpZzEsIGNvbmZpZzIpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gIGNvbmZpZzIgPSBjb25maWcyIHx8IHt9O1xuICBjb25zdCBjb25maWcgPSB7fTtcblxuICBmdW5jdGlvbiBnZXRNZXJnZWRWYWx1ZSh0YXJnZXQsIHNvdXJjZSwgY2FzZWxlc3MpIHtcbiAgICBpZiAodXRpbHMuaXNQbGFpbk9iamVjdCh0YXJnZXQpICYmIHV0aWxzLmlzUGxhaW5PYmplY3Qoc291cmNlKSkge1xuICAgICAgcmV0dXJuIHV0aWxzLm1lcmdlLmNhbGwoe2Nhc2VsZXNzfSwgdGFyZ2V0LCBzb3VyY2UpO1xuICAgIH0gZWxzZSBpZiAodXRpbHMuaXNQbGFpbk9iamVjdChzb3VyY2UpKSB7XG4gICAgICByZXR1cm4gdXRpbHMubWVyZ2Uoe30sIHNvdXJjZSk7XG4gICAgfSBlbHNlIGlmICh1dGlscy5pc0FycmF5KHNvdXJjZSkpIHtcbiAgICAgIHJldHVybiBzb3VyY2Uuc2xpY2UoKTtcbiAgICB9XG4gICAgcmV0dXJuIHNvdXJjZTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICBmdW5jdGlvbiBtZXJnZURlZXBQcm9wZXJ0aWVzKGEsIGIsIGNhc2VsZXNzKSB7XG4gICAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChiKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKGEsIGIsIGNhc2VsZXNzKTtcbiAgICB9IGVsc2UgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChhKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYSwgY2FzZWxlc3MpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICBmdW5jdGlvbiB2YWx1ZUZyb21Db25maWcyKGEsIGIpIHtcbiAgICBpZiAoIXV0aWxzLmlzVW5kZWZpbmVkKGIpKSB7XG4gICAgICByZXR1cm4gZ2V0TWVyZ2VkVmFsdWUodW5kZWZpbmVkLCBiKTtcbiAgICB9XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgZnVuY3Rpb24gZGVmYXVsdFRvQ29uZmlnMihhLCBiKSB7XG4gICAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChiKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYik7XG4gICAgfSBlbHNlIGlmICghdXRpbHMuaXNVbmRlZmluZWQoYSkpIHtcbiAgICAgIHJldHVybiBnZXRNZXJnZWRWYWx1ZSh1bmRlZmluZWQsIGEpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICBmdW5jdGlvbiBtZXJnZURpcmVjdEtleXMoYSwgYiwgcHJvcCkge1xuICAgIGlmIChwcm9wIGluIGNvbmZpZzIpIHtcbiAgICAgIHJldHVybiBnZXRNZXJnZWRWYWx1ZShhLCBiKTtcbiAgICB9IGVsc2UgaWYgKHByb3AgaW4gY29uZmlnMSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgbWVyZ2VNYXAgPSB7XG4gICAgdXJsOiB2YWx1ZUZyb21Db25maWcyLFxuICAgIG1ldGhvZDogdmFsdWVGcm9tQ29uZmlnMixcbiAgICBkYXRhOiB2YWx1ZUZyb21Db25maWcyLFxuICAgIGJhc2VVUkw6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgdHJhbnNmb3JtUmVxdWVzdDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICB0cmFuc2Zvcm1SZXNwb25zZTogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBwYXJhbXNTZXJpYWxpemVyOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHRpbWVvdXQ6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgdGltZW91dE1lc3NhZ2U6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgd2l0aENyZWRlbnRpYWxzOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIGFkYXB0ZXI6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgcmVzcG9uc2VUeXBlOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHhzcmZDb29raWVOYW1lOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHhzcmZIZWFkZXJOYW1lOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIG9uVXBsb2FkUHJvZ3Jlc3M6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgb25Eb3dubG9hZFByb2dyZXNzOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIGRlY29tcHJlc3M6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgbWF4Q29udGVudExlbmd0aDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBtYXhCb2R5TGVuZ3RoOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIGJlZm9yZVJlZGlyZWN0OiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHRyYW5zcG9ydDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBodHRwQWdlbnQ6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgaHR0cHNBZ2VudDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBjYW5jZWxUb2tlbjogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBzb2NrZXRQYXRoOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHJlc3BvbnNlRW5jb2Rpbmc6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgdmFsaWRhdGVTdGF0dXM6IG1lcmdlRGlyZWN0S2V5cyxcbiAgICBoZWFkZXJzOiAoYSwgYikgPT4gbWVyZ2VEZWVwUHJvcGVydGllcyhoZWFkZXJzVG9PYmplY3QoYSksIGhlYWRlcnNUb09iamVjdChiKSwgdHJ1ZSlcbiAgfTtcblxuICB1dGlscy5mb3JFYWNoKE9iamVjdC5rZXlzKE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZzEsIGNvbmZpZzIpKSwgZnVuY3Rpb24gY29tcHV0ZUNvbmZpZ1ZhbHVlKHByb3ApIHtcbiAgICBjb25zdCBtZXJnZSA9IG1lcmdlTWFwW3Byb3BdIHx8IG1lcmdlRGVlcFByb3BlcnRpZXM7XG4gICAgY29uc3QgY29uZmlnVmFsdWUgPSBtZXJnZShjb25maWcxW3Byb3BdLCBjb25maWcyW3Byb3BdLCBwcm9wKTtcbiAgICAodXRpbHMuaXNVbmRlZmluZWQoY29uZmlnVmFsdWUpICYmIG1lcmdlICE9PSBtZXJnZURpcmVjdEtleXMpIHx8IChjb25maWdbcHJvcF0gPSBjb25maWdWYWx1ZSk7XG4gIH0pO1xuXG4gIHJldHVybiBjb25maWc7XG59XG5cbmNvbnN0IHZhbGlkYXRvcnMkMSA9IHt9O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuWydvYmplY3QnLCAnYm9vbGVhbicsICdudW1iZXInLCAnZnVuY3Rpb24nLCAnc3RyaW5nJywgJ3N5bWJvbCddLmZvckVhY2goKHR5cGUsIGkpID0+IHtcbiAgdmFsaWRhdG9ycyQxW3R5cGVdID0gZnVuY3Rpb24gdmFsaWRhdG9yKHRoaW5nKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gdHlwZSB8fCAnYScgKyAoaSA8IDEgPyAnbiAnIDogJyAnKSArIHR5cGU7XG4gIH07XG59KTtcblxuY29uc3QgZGVwcmVjYXRlZFdhcm5pbmdzID0ge307XG5cbi8qKlxuICogVHJhbnNpdGlvbmFsIG9wdGlvbiB2YWxpZGF0b3JcbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufGJvb2xlYW4/fSB2YWxpZGF0b3IgLSBzZXQgdG8gZmFsc2UgaWYgdGhlIHRyYW5zaXRpb25hbCBvcHRpb24gaGFzIGJlZW4gcmVtb3ZlZFxuICogQHBhcmFtIHtzdHJpbmc/fSB2ZXJzaW9uIC0gZGVwcmVjYXRlZCB2ZXJzaW9uIC8gcmVtb3ZlZCBzaW5jZSB2ZXJzaW9uXG4gKiBAcGFyYW0ge3N0cmluZz99IG1lc3NhZ2UgLSBzb21lIG1lc3NhZ2Ugd2l0aCBhZGRpdGlvbmFsIGluZm9cbiAqXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259XG4gKi9cbnZhbGlkYXRvcnMkMS50cmFuc2l0aW9uYWwgPSBmdW5jdGlvbiB0cmFuc2l0aW9uYWwodmFsaWRhdG9yLCB2ZXJzaW9uLCBtZXNzYWdlKSB7XG4gIGZ1bmN0aW9uIGZvcm1hdE1lc3NhZ2Uob3B0LCBkZXNjKSB7XG4gICAgcmV0dXJuICdbQXhpb3MgdicgKyBWRVJTSU9OICsgJ10gVHJhbnNpdGlvbmFsIG9wdGlvbiBcXCcnICsgb3B0ICsgJ1xcJycgKyBkZXNjICsgKG1lc3NhZ2UgPyAnLiAnICsgbWVzc2FnZSA6ICcnKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gIHJldHVybiAodmFsdWUsIG9wdCwgb3B0cykgPT4ge1xuICAgIGlmICh2YWxpZGF0b3IgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgZm9ybWF0TWVzc2FnZShvcHQsICcgaGFzIGJlZW4gcmVtb3ZlZCcgKyAodmVyc2lvbiA/ICcgaW4gJyArIHZlcnNpb24gOiAnJykpLFxuICAgICAgICBBeGlvc0Vycm9yLkVSUl9ERVBSRUNBVEVEXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh2ZXJzaW9uICYmICFkZXByZWNhdGVkV2FybmluZ3Nbb3B0XSkge1xuICAgICAgZGVwcmVjYXRlZFdhcm5pbmdzW29wdF0gPSB0cnVlO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgZm9ybWF0TWVzc2FnZShcbiAgICAgICAgICBvcHQsXG4gICAgICAgICAgJyBoYXMgYmVlbiBkZXByZWNhdGVkIHNpbmNlIHYnICsgdmVyc2lvbiArICcgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiB0aGUgbmVhciBmdXR1cmUnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRvciA/IHZhbGlkYXRvcih2YWx1ZSwgb3B0LCBvcHRzKSA6IHRydWU7XG4gIH07XG59O1xuXG4vKipcbiAqIEFzc2VydCBvYmplY3QncyBwcm9wZXJ0aWVzIHR5cGVcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtvYmplY3R9IHNjaGVtYVxuICogQHBhcmFtIHtib29sZWFuP30gYWxsb3dVbmtub3duXG4gKlxuICogQHJldHVybnMge29iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBhc3NlcnRPcHRpb25zKG9wdGlvbnMsIHNjaGVtYSwgYWxsb3dVbmtub3duKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignb3B0aW9ucyBtdXN0IGJlIGFuIG9iamVjdCcsIEF4aW9zRXJyb3IuRVJSX0JBRF9PUFRJT05fVkFMVUUpO1xuICB9XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvcHRpb25zKTtcbiAgbGV0IGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSA+IDApIHtcbiAgICBjb25zdCBvcHQgPSBrZXlzW2ldO1xuICAgIGNvbnN0IHZhbGlkYXRvciA9IHNjaGVtYVtvcHRdO1xuICAgIGlmICh2YWxpZGF0b3IpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gb3B0aW9uc1tvcHRdO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWxpZGF0b3IodmFsdWUsIG9wdCwgb3B0aW9ucyk7XG4gICAgICBpZiAocmVzdWx0ICE9PSB0cnVlKSB7XG4gICAgICAgIHRocm93IG5ldyBBeGlvc0Vycm9yKCdvcHRpb24gJyArIG9wdCArICcgbXVzdCBiZSAnICsgcmVzdWx0LCBBeGlvc0Vycm9yLkVSUl9CQURfT1BUSU9OX1ZBTFVFKTtcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAoYWxsb3dVbmtub3duICE9PSB0cnVlKSB7XG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignVW5rbm93biBvcHRpb24gJyArIG9wdCwgQXhpb3NFcnJvci5FUlJfQkFEX09QVElPTik7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IHZhbGlkYXRvciA9IHtcbiAgYXNzZXJ0T3B0aW9ucyxcbiAgdmFsaWRhdG9yczogdmFsaWRhdG9ycyQxXG59O1xuXG5jb25zdCB2YWxpZGF0b3JzID0gdmFsaWRhdG9yLnZhbGlkYXRvcnM7XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIEF4aW9zXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGluc3RhbmNlQ29uZmlnIFRoZSBkZWZhdWx0IGNvbmZpZyBmb3IgdGhlIGluc3RhbmNlXG4gKlxuICogQHJldHVybiB7QXhpb3N9IEEgbmV3IGluc3RhbmNlIG9mIEF4aW9zXG4gKi9cbmNsYXNzIEF4aW9zIHtcbiAgY29uc3RydWN0b3IoaW5zdGFuY2VDb25maWcpIHtcbiAgICB0aGlzLmRlZmF1bHRzID0gaW5zdGFuY2VDb25maWc7XG4gICAgdGhpcy5pbnRlcmNlcHRvcnMgPSB7XG4gICAgICByZXF1ZXN0OiBuZXcgSW50ZXJjZXB0b3JNYW5hZ2VyJDEoKSxcbiAgICAgIHJlc3BvbnNlOiBuZXcgSW50ZXJjZXB0b3JNYW5hZ2VyJDEoKVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2ggYSByZXF1ZXN0XG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gY29uZmlnT3JVcmwgVGhlIGNvbmZpZyBzcGVjaWZpYyBmb3IgdGhpcyByZXF1ZXN0IChtZXJnZWQgd2l0aCB0aGlzLmRlZmF1bHRzKVxuICAgKiBAcGFyYW0gez9PYmplY3R9IGNvbmZpZ1xuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gVGhlIFByb21pc2UgdG8gYmUgZnVsZmlsbGVkXG4gICAqL1xuICByZXF1ZXN0KGNvbmZpZ09yVXJsLCBjb25maWcpIHtcbiAgICAvKmVzbGludCBuby1wYXJhbS1yZWFzc2lnbjowKi9cbiAgICAvLyBBbGxvdyBmb3IgYXhpb3MoJ2V4YW1wbGUvdXJsJ1ssIGNvbmZpZ10pIGEgbGEgZmV0Y2ggQVBJXG4gICAgaWYgKHR5cGVvZiBjb25maWdPclVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgICAgIGNvbmZpZy51cmwgPSBjb25maWdPclVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlnID0gY29uZmlnT3JVcmwgfHwge307XG4gICAgfVxuXG4gICAgY29uZmlnID0gbWVyZ2VDb25maWcodGhpcy5kZWZhdWx0cywgY29uZmlnKTtcblxuICAgIGNvbnN0IHt0cmFuc2l0aW9uYWwsIHBhcmFtc1NlcmlhbGl6ZXIsIGhlYWRlcnN9ID0gY29uZmlnO1xuXG4gICAgaWYgKHRyYW5zaXRpb25hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YWxpZGF0b3IuYXNzZXJ0T3B0aW9ucyh0cmFuc2l0aW9uYWwsIHtcbiAgICAgICAgc2lsZW50SlNPTlBhcnNpbmc6IHZhbGlkYXRvcnMudHJhbnNpdGlvbmFsKHZhbGlkYXRvcnMuYm9vbGVhbiksXG4gICAgICAgIGZvcmNlZEpTT05QYXJzaW5nOiB2YWxpZGF0b3JzLnRyYW5zaXRpb25hbCh2YWxpZGF0b3JzLmJvb2xlYW4pLFxuICAgICAgICBjbGFyaWZ5VGltZW91dEVycm9yOiB2YWxpZGF0b3JzLnRyYW5zaXRpb25hbCh2YWxpZGF0b3JzLmJvb2xlYW4pXG4gICAgICB9LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtc1NlcmlhbGl6ZXIgIT0gbnVsbCkge1xuICAgICAgaWYgKHV0aWxzLmlzRnVuY3Rpb24ocGFyYW1zU2VyaWFsaXplcikpIHtcbiAgICAgICAgY29uZmlnLnBhcmFtc1NlcmlhbGl6ZXIgPSB7XG4gICAgICAgICAgc2VyaWFsaXplOiBwYXJhbXNTZXJpYWxpemVyXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWxpZGF0b3IuYXNzZXJ0T3B0aW9ucyhwYXJhbXNTZXJpYWxpemVyLCB7XG4gICAgICAgICAgZW5jb2RlOiB2YWxpZGF0b3JzLmZ1bmN0aW9uLFxuICAgICAgICAgIHNlcmlhbGl6ZTogdmFsaWRhdG9ycy5mdW5jdGlvblxuICAgICAgICB9LCB0cnVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZXQgY29uZmlnLm1ldGhvZFxuICAgIGNvbmZpZy5tZXRob2QgPSAoY29uZmlnLm1ldGhvZCB8fCB0aGlzLmRlZmF1bHRzLm1ldGhvZCB8fCAnZ2V0JykudG9Mb3dlckNhc2UoKTtcblxuICAgIC8vIEZsYXR0ZW4gaGVhZGVyc1xuICAgIGxldCBjb250ZXh0SGVhZGVycyA9IGhlYWRlcnMgJiYgdXRpbHMubWVyZ2UoXG4gICAgICBoZWFkZXJzLmNvbW1vbixcbiAgICAgIGhlYWRlcnNbY29uZmlnLm1ldGhvZF1cbiAgICApO1xuXG4gICAgaGVhZGVycyAmJiB1dGlscy5mb3JFYWNoKFxuICAgICAgWydkZWxldGUnLCAnZ2V0JywgJ2hlYWQnLCAncG9zdCcsICdwdXQnLCAncGF0Y2gnLCAnY29tbW9uJ10sXG4gICAgICAobWV0aG9kKSA9PiB7XG4gICAgICAgIGRlbGV0ZSBoZWFkZXJzW21ldGhvZF07XG4gICAgICB9XG4gICAgKTtcblxuICAgIGNvbmZpZy5oZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuY29uY2F0KGNvbnRleHRIZWFkZXJzLCBoZWFkZXJzKTtcblxuICAgIC8vIGZpbHRlciBvdXQgc2tpcHBlZCBpbnRlcmNlcHRvcnNcbiAgICBjb25zdCByZXF1ZXN0SW50ZXJjZXB0b3JDaGFpbiA9IFtdO1xuICAgIGxldCBzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMgPSB0cnVlO1xuICAgIHRoaXMuaW50ZXJjZXB0b3JzLnJlcXVlc3QuZm9yRWFjaChmdW5jdGlvbiB1bnNoaWZ0UmVxdWVzdEludGVyY2VwdG9ycyhpbnRlcmNlcHRvcikge1xuICAgICAgaWYgKHR5cGVvZiBpbnRlcmNlcHRvci5ydW5XaGVuID09PSAnZnVuY3Rpb24nICYmIGludGVyY2VwdG9yLnJ1bldoZW4oY29uZmlnKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMgPSBzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMgJiYgaW50ZXJjZXB0b3Iuc3luY2hyb25vdXM7XG5cbiAgICAgIHJlcXVlc3RJbnRlcmNlcHRvckNoYWluLnVuc2hpZnQoaW50ZXJjZXB0b3IuZnVsZmlsbGVkLCBpbnRlcmNlcHRvci5yZWplY3RlZCk7XG4gICAgfSk7XG5cbiAgICBjb25zdCByZXNwb25zZUludGVyY2VwdG9yQ2hhaW4gPSBbXTtcbiAgICB0aGlzLmludGVyY2VwdG9ycy5yZXNwb25zZS5mb3JFYWNoKGZ1bmN0aW9uIHB1c2hSZXNwb25zZUludGVyY2VwdG9ycyhpbnRlcmNlcHRvcikge1xuICAgICAgcmVzcG9uc2VJbnRlcmNlcHRvckNoYWluLnB1c2goaW50ZXJjZXB0b3IuZnVsZmlsbGVkLCBpbnRlcmNlcHRvci5yZWplY3RlZCk7XG4gICAgfSk7XG5cbiAgICBsZXQgcHJvbWlzZTtcbiAgICBsZXQgaSA9IDA7XG4gICAgbGV0IGxlbjtcblxuICAgIGlmICghc3luY2hyb25vdXNSZXF1ZXN0SW50ZXJjZXB0b3JzKSB7XG4gICAgICBjb25zdCBjaGFpbiA9IFtkaXNwYXRjaFJlcXVlc3QuYmluZCh0aGlzKSwgdW5kZWZpbmVkXTtcbiAgICAgIGNoYWluLnVuc2hpZnQuYXBwbHkoY2hhaW4sIHJlcXVlc3RJbnRlcmNlcHRvckNoYWluKTtcbiAgICAgIGNoYWluLnB1c2guYXBwbHkoY2hhaW4sIHJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbik7XG4gICAgICBsZW4gPSBjaGFpbi5sZW5ndGg7XG5cbiAgICAgIHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoY29uZmlnKTtcblxuICAgICAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICAgICAgcHJvbWlzZSA9IHByb21pc2UudGhlbihjaGFpbltpKytdLCBjaGFpbltpKytdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfVxuXG4gICAgbGVuID0gcmVxdWVzdEludGVyY2VwdG9yQ2hhaW4ubGVuZ3RoO1xuXG4gICAgbGV0IG5ld0NvbmZpZyA9IGNvbmZpZztcblxuICAgIGkgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICAgIGNvbnN0IG9uRnVsZmlsbGVkID0gcmVxdWVzdEludGVyY2VwdG9yQ2hhaW5baSsrXTtcbiAgICAgIGNvbnN0IG9uUmVqZWN0ZWQgPSByZXF1ZXN0SW50ZXJjZXB0b3JDaGFpbltpKytdO1xuICAgICAgdHJ5IHtcbiAgICAgICAgbmV3Q29uZmlnID0gb25GdWxmaWxsZWQobmV3Q29uZmlnKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIG9uUmVqZWN0ZWQuY2FsbCh0aGlzLCBlcnJvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBwcm9taXNlID0gZGlzcGF0Y2hSZXF1ZXN0LmNhbGwodGhpcywgbmV3Q29uZmlnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKTtcbiAgICB9XG5cbiAgICBpID0gMDtcbiAgICBsZW4gPSByZXNwb25zZUludGVyY2VwdG9yQ2hhaW4ubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICAgIHByb21pc2UgPSBwcm9taXNlLnRoZW4ocmVzcG9uc2VJbnRlcmNlcHRvckNoYWluW2krK10sIHJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbltpKytdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuXG4gIGdldFVyaShjb25maWcpIHtcbiAgICBjb25maWcgPSBtZXJnZUNvbmZpZyh0aGlzLmRlZmF1bHRzLCBjb25maWcpO1xuICAgIGNvbnN0IGZ1bGxQYXRoID0gYnVpbGRGdWxsUGF0aChjb25maWcuYmFzZVVSTCwgY29uZmlnLnVybCk7XG4gICAgcmV0dXJuIGJ1aWxkVVJMKGZ1bGxQYXRoLCBjb25maWcucGFyYW1zLCBjb25maWcucGFyYW1zU2VyaWFsaXplcik7XG4gIH1cbn1cblxuLy8gUHJvdmlkZSBhbGlhc2VzIGZvciBzdXBwb3J0ZWQgcmVxdWVzdCBtZXRob2RzXG51dGlscy5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ29wdGlvbnMnXSwgZnVuY3Rpb24gZm9yRWFjaE1ldGhvZE5vRGF0YShtZXRob2QpIHtcbiAgLyplc2xpbnQgZnVuYy1uYW1lczowKi9cbiAgQXhpb3MucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbih1cmwsIGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QobWVyZ2VDb25maWcoY29uZmlnIHx8IHt9LCB7XG4gICAgICBtZXRob2QsXG4gICAgICB1cmwsXG4gICAgICBkYXRhOiAoY29uZmlnIHx8IHt9KS5kYXRhXG4gICAgfSkpO1xuICB9O1xufSk7XG5cbnV0aWxzLmZvckVhY2goWydwb3N0JywgJ3B1dCcsICdwYXRjaCddLCBmdW5jdGlvbiBmb3JFYWNoTWV0aG9kV2l0aERhdGEobWV0aG9kKSB7XG4gIC8qZXNsaW50IGZ1bmMtbmFtZXM6MCovXG5cbiAgZnVuY3Rpb24gZ2VuZXJhdGVIVFRQTWV0aG9kKGlzRm9ybSkge1xuICAgIHJldHVybiBmdW5jdGlvbiBodHRwTWV0aG9kKHVybCwgZGF0YSwgY29uZmlnKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KG1lcmdlQ29uZmlnKGNvbmZpZyB8fCB7fSwge1xuICAgICAgICBtZXRob2QsXG4gICAgICAgIGhlYWRlcnM6IGlzRm9ybSA/IHtcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ211bHRpcGFydC9mb3JtLWRhdGEnXG4gICAgICAgIH0gOiB7fSxcbiAgICAgICAgdXJsLFxuICAgICAgICBkYXRhXG4gICAgICB9KSk7XG4gICAgfTtcbiAgfVxuXG4gIEF4aW9zLnByb3RvdHlwZVttZXRob2RdID0gZ2VuZXJhdGVIVFRQTWV0aG9kKCk7XG5cbiAgQXhpb3MucHJvdG90eXBlW21ldGhvZCArICdGb3JtJ10gPSBnZW5lcmF0ZUhUVFBNZXRob2QodHJ1ZSk7XG59KTtcblxuY29uc3QgQXhpb3MkMSA9IEF4aW9zO1xuXG4vKipcbiAqIEEgYENhbmNlbFRva2VuYCBpcyBhbiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byByZXF1ZXN0IGNhbmNlbGxhdGlvbiBvZiBhbiBvcGVyYXRpb24uXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXhlY3V0b3IgVGhlIGV4ZWN1dG9yIGZ1bmN0aW9uLlxuICpcbiAqIEByZXR1cm5zIHtDYW5jZWxUb2tlbn1cbiAqL1xuY2xhc3MgQ2FuY2VsVG9rZW4ge1xuICBjb25zdHJ1Y3RvcihleGVjdXRvcikge1xuICAgIGlmICh0eXBlb2YgZXhlY3V0b3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2V4ZWN1dG9yIG11c3QgYmUgYSBmdW5jdGlvbi4nKTtcbiAgICB9XG5cbiAgICBsZXQgcmVzb2x2ZVByb21pc2U7XG5cbiAgICB0aGlzLnByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiBwcm9taXNlRXhlY3V0b3IocmVzb2x2ZSkge1xuICAgICAgcmVzb2x2ZVByb21pc2UgPSByZXNvbHZlO1xuICAgIH0pO1xuXG4gICAgY29uc3QgdG9rZW4gPSB0aGlzO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbiAgICB0aGlzLnByb21pc2UudGhlbihjYW5jZWwgPT4ge1xuICAgICAgaWYgKCF0b2tlbi5fbGlzdGVuZXJzKSByZXR1cm47XG5cbiAgICAgIGxldCBpID0gdG9rZW4uX2xpc3RlbmVycy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlIChpLS0gPiAwKSB7XG4gICAgICAgIHRva2VuLl9saXN0ZW5lcnNbaV0oY2FuY2VsKTtcbiAgICAgIH1cbiAgICAgIHRva2VuLl9saXN0ZW5lcnMgPSBudWxsO1xuICAgIH0pO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbiAgICB0aGlzLnByb21pc2UudGhlbiA9IG9uZnVsZmlsbGVkID0+IHtcbiAgICAgIGxldCBfcmVzb2x2ZTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgIHRva2VuLnN1YnNjcmliZShyZXNvbHZlKTtcbiAgICAgICAgX3Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgfSkudGhlbihvbmZ1bGZpbGxlZCk7XG5cbiAgICAgIHByb21pc2UuY2FuY2VsID0gZnVuY3Rpb24gcmVqZWN0KCkge1xuICAgICAgICB0b2tlbi51bnN1YnNjcmliZShfcmVzb2x2ZSk7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9O1xuXG4gICAgZXhlY3V0b3IoZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UsIGNvbmZpZywgcmVxdWVzdCkge1xuICAgICAgaWYgKHRva2VuLnJlYXNvbikge1xuICAgICAgICAvLyBDYW5jZWxsYXRpb24gaGFzIGFscmVhZHkgYmVlbiByZXF1ZXN0ZWRcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0b2tlbi5yZWFzb24gPSBuZXcgQ2FuY2VsZWRFcnJvcihtZXNzYWdlLCBjb25maWcsIHJlcXVlc3QpO1xuICAgICAgcmVzb2x2ZVByb21pc2UodG9rZW4ucmVhc29uKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaHJvd3MgYSBgQ2FuY2VsZWRFcnJvcmAgaWYgY2FuY2VsbGF0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZC5cbiAgICovXG4gIHRocm93SWZSZXF1ZXN0ZWQoKSB7XG4gICAgaWYgKHRoaXMucmVhc29uKSB7XG4gICAgICB0aHJvdyB0aGlzLnJlYXNvbjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3Vic2NyaWJlIHRvIHRoZSBjYW5jZWwgc2lnbmFsXG4gICAqL1xuXG4gIHN1YnNjcmliZShsaXN0ZW5lcikge1xuICAgIGlmICh0aGlzLnJlYXNvbikge1xuICAgICAgbGlzdGVuZXIodGhpcy5yZWFzb24pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9saXN0ZW5lcnMpIHtcbiAgICAgIHRoaXMuX2xpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbGlzdGVuZXJzID0gW2xpc3RlbmVyXTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVW5zdWJzY3JpYmUgZnJvbSB0aGUgY2FuY2VsIHNpZ25hbFxuICAgKi9cblxuICB1bnN1YnNjcmliZShsaXN0ZW5lcikge1xuICAgIGlmICghdGhpcy5fbGlzdGVuZXJzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fbGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuX2xpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgbmV3IGBDYW5jZWxUb2tlbmAgYW5kIGEgZnVuY3Rpb24gdGhhdCwgd2hlbiBjYWxsZWQsXG4gICAqIGNhbmNlbHMgdGhlIGBDYW5jZWxUb2tlbmAuXG4gICAqL1xuICBzdGF0aWMgc291cmNlKCkge1xuICAgIGxldCBjYW5jZWw7XG4gICAgY29uc3QgdG9rZW4gPSBuZXcgQ2FuY2VsVG9rZW4oZnVuY3Rpb24gZXhlY3V0b3IoYykge1xuICAgICAgY2FuY2VsID0gYztcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9rZW4sXG4gICAgICBjYW5jZWxcbiAgICB9O1xuICB9XG59XG5cbmNvbnN0IENhbmNlbFRva2VuJDEgPSBDYW5jZWxUb2tlbjtcblxuLyoqXG4gKiBTeW50YWN0aWMgc3VnYXIgZm9yIGludm9raW5nIGEgZnVuY3Rpb24gYW5kIGV4cGFuZGluZyBhbiBhcnJheSBmb3IgYXJndW1lbnRzLlxuICpcbiAqIENvbW1vbiB1c2UgY2FzZSB3b3VsZCBiZSB0byB1c2UgYEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseWAuXG4gKlxuICogIGBgYGpzXG4gKiAgZnVuY3Rpb24gZih4LCB5LCB6KSB7fVxuICogIHZhciBhcmdzID0gWzEsIDIsIDNdO1xuICogIGYuYXBwbHkobnVsbCwgYXJncyk7XG4gKiAgYGBgXG4gKlxuICogV2l0aCBgc3ByZWFkYCB0aGlzIGV4YW1wbGUgY2FuIGJlIHJlLXdyaXR0ZW4uXG4gKlxuICogIGBgYGpzXG4gKiAgc3ByZWFkKGZ1bmN0aW9uKHgsIHksIHopIHt9KShbMSwgMiwgM10pO1xuICogIGBgYFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKlxuICogQHJldHVybnMge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBzcHJlYWQoY2FsbGJhY2spIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHdyYXAoYXJyKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KG51bGwsIGFycik7XG4gIH07XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBwYXlsb2FkIGlzIGFuIGVycm9yIHRocm93biBieSBBeGlvc1xuICpcbiAqIEBwYXJhbSB7Kn0gcGF5bG9hZCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwYXlsb2FkIGlzIGFuIGVycm9yIHRocm93biBieSBBeGlvcywgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXhpb3NFcnJvcihwYXlsb2FkKSB7XG4gIHJldHVybiB1dGlscy5pc09iamVjdChwYXlsb2FkKSAmJiAocGF5bG9hZC5pc0F4aW9zRXJyb3IgPT09IHRydWUpO1xufVxuXG5jb25zdCBIdHRwU3RhdHVzQ29kZSA9IHtcbiAgQ29udGludWU6IDEwMCxcbiAgU3dpdGNoaW5nUHJvdG9jb2xzOiAxMDEsXG4gIFByb2Nlc3Npbmc6IDEwMixcbiAgRWFybHlIaW50czogMTAzLFxuICBPazogMjAwLFxuICBDcmVhdGVkOiAyMDEsXG4gIEFjY2VwdGVkOiAyMDIsXG4gIE5vbkF1dGhvcml0YXRpdmVJbmZvcm1hdGlvbjogMjAzLFxuICBOb0NvbnRlbnQ6IDIwNCxcbiAgUmVzZXRDb250ZW50OiAyMDUsXG4gIFBhcnRpYWxDb250ZW50OiAyMDYsXG4gIE11bHRpU3RhdHVzOiAyMDcsXG4gIEFscmVhZHlSZXBvcnRlZDogMjA4LFxuICBJbVVzZWQ6IDIyNixcbiAgTXVsdGlwbGVDaG9pY2VzOiAzMDAsXG4gIE1vdmVkUGVybWFuZW50bHk6IDMwMSxcbiAgRm91bmQ6IDMwMixcbiAgU2VlT3RoZXI6IDMwMyxcbiAgTm90TW9kaWZpZWQ6IDMwNCxcbiAgVXNlUHJveHk6IDMwNSxcbiAgVW51c2VkOiAzMDYsXG4gIFRlbXBvcmFyeVJlZGlyZWN0OiAzMDcsXG4gIFBlcm1hbmVudFJlZGlyZWN0OiAzMDgsXG4gIEJhZFJlcXVlc3Q6IDQwMCxcbiAgVW5hdXRob3JpemVkOiA0MDEsXG4gIFBheW1lbnRSZXF1aXJlZDogNDAyLFxuICBGb3JiaWRkZW46IDQwMyxcbiAgTm90Rm91bmQ6IDQwNCxcbiAgTWV0aG9kTm90QWxsb3dlZDogNDA1LFxuICBOb3RBY2NlcHRhYmxlOiA0MDYsXG4gIFByb3h5QXV0aGVudGljYXRpb25SZXF1aXJlZDogNDA3LFxuICBSZXF1ZXN0VGltZW91dDogNDA4LFxuICBDb25mbGljdDogNDA5LFxuICBHb25lOiA0MTAsXG4gIExlbmd0aFJlcXVpcmVkOiA0MTEsXG4gIFByZWNvbmRpdGlvbkZhaWxlZDogNDEyLFxuICBQYXlsb2FkVG9vTGFyZ2U6IDQxMyxcbiAgVXJpVG9vTG9uZzogNDE0LFxuICBVbnN1cHBvcnRlZE1lZGlhVHlwZTogNDE1LFxuICBSYW5nZU5vdFNhdGlzZmlhYmxlOiA0MTYsXG4gIEV4cGVjdGF0aW9uRmFpbGVkOiA0MTcsXG4gIEltQVRlYXBvdDogNDE4LFxuICBNaXNkaXJlY3RlZFJlcXVlc3Q6IDQyMSxcbiAgVW5wcm9jZXNzYWJsZUVudGl0eTogNDIyLFxuICBMb2NrZWQ6IDQyMyxcbiAgRmFpbGVkRGVwZW5kZW5jeTogNDI0LFxuICBUb29FYXJseTogNDI1LFxuICBVcGdyYWRlUmVxdWlyZWQ6IDQyNixcbiAgUHJlY29uZGl0aW9uUmVxdWlyZWQ6IDQyOCxcbiAgVG9vTWFueVJlcXVlc3RzOiA0MjksXG4gIFJlcXVlc3RIZWFkZXJGaWVsZHNUb29MYXJnZTogNDMxLFxuICBVbmF2YWlsYWJsZUZvckxlZ2FsUmVhc29uczogNDUxLFxuICBJbnRlcm5hbFNlcnZlckVycm9yOiA1MDAsXG4gIE5vdEltcGxlbWVudGVkOiA1MDEsXG4gIEJhZEdhdGV3YXk6IDUwMixcbiAgU2VydmljZVVuYXZhaWxhYmxlOiA1MDMsXG4gIEdhdGV3YXlUaW1lb3V0OiA1MDQsXG4gIEh0dHBWZXJzaW9uTm90U3VwcG9ydGVkOiA1MDUsXG4gIFZhcmlhbnRBbHNvTmVnb3RpYXRlczogNTA2LFxuICBJbnN1ZmZpY2llbnRTdG9yYWdlOiA1MDcsXG4gIExvb3BEZXRlY3RlZDogNTA4LFxuICBOb3RFeHRlbmRlZDogNTEwLFxuICBOZXR3b3JrQXV0aGVudGljYXRpb25SZXF1aXJlZDogNTExLFxufTtcblxuT2JqZWN0LmVudHJpZXMoSHR0cFN0YXR1c0NvZGUpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICBIdHRwU3RhdHVzQ29kZVt2YWx1ZV0gPSBrZXk7XG59KTtcblxuY29uc3QgSHR0cFN0YXR1c0NvZGUkMSA9IEh0dHBTdGF0dXNDb2RlO1xuXG4vKipcbiAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBBeGlvc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBkZWZhdWx0Q29uZmlnIFRoZSBkZWZhdWx0IGNvbmZpZyBmb3IgdGhlIGluc3RhbmNlXG4gKlxuICogQHJldHVybnMge0F4aW9zfSBBIG5ldyBpbnN0YW5jZSBvZiBBeGlvc1xuICovXG5mdW5jdGlvbiBjcmVhdGVJbnN0YW5jZShkZWZhdWx0Q29uZmlnKSB7XG4gIGNvbnN0IGNvbnRleHQgPSBuZXcgQXhpb3MkMShkZWZhdWx0Q29uZmlnKTtcbiAgY29uc3QgaW5zdGFuY2UgPSBiaW5kKEF4aW9zJDEucHJvdG90eXBlLnJlcXVlc3QsIGNvbnRleHQpO1xuXG4gIC8vIENvcHkgYXhpb3MucHJvdG90eXBlIHRvIGluc3RhbmNlXG4gIHV0aWxzLmV4dGVuZChpbnN0YW5jZSwgQXhpb3MkMS5wcm90b3R5cGUsIGNvbnRleHQsIHthbGxPd25LZXlzOiB0cnVlfSk7XG5cbiAgLy8gQ29weSBjb250ZXh0IHRvIGluc3RhbmNlXG4gIHV0aWxzLmV4dGVuZChpbnN0YW5jZSwgY29udGV4dCwgbnVsbCwge2FsbE93bktleXM6IHRydWV9KTtcblxuICAvLyBGYWN0b3J5IGZvciBjcmVhdGluZyBuZXcgaW5zdGFuY2VzXG4gIGluc3RhbmNlLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpbnN0YW5jZUNvbmZpZykge1xuICAgIHJldHVybiBjcmVhdGVJbnN0YW5jZShtZXJnZUNvbmZpZyhkZWZhdWx0Q29uZmlnLCBpbnN0YW5jZUNvbmZpZykpO1xuICB9O1xuXG4gIHJldHVybiBpbnN0YW5jZTtcbn1cblxuLy8gQ3JlYXRlIHRoZSBkZWZhdWx0IGluc3RhbmNlIHRvIGJlIGV4cG9ydGVkXG5jb25zdCBheGlvcyA9IGNyZWF0ZUluc3RhbmNlKGRlZmF1bHRzJDEpO1xuXG4vLyBFeHBvc2UgQXhpb3MgY2xhc3MgdG8gYWxsb3cgY2xhc3MgaW5oZXJpdGFuY2VcbmF4aW9zLkF4aW9zID0gQXhpb3MkMTtcblxuLy8gRXhwb3NlIENhbmNlbCAmIENhbmNlbFRva2VuXG5heGlvcy5DYW5jZWxlZEVycm9yID0gQ2FuY2VsZWRFcnJvcjtcbmF4aW9zLkNhbmNlbFRva2VuID0gQ2FuY2VsVG9rZW4kMTtcbmF4aW9zLmlzQ2FuY2VsID0gaXNDYW5jZWw7XG5heGlvcy5WRVJTSU9OID0gVkVSU0lPTjtcbmF4aW9zLnRvRm9ybURhdGEgPSB0b0Zvcm1EYXRhO1xuXG4vLyBFeHBvc2UgQXhpb3NFcnJvciBjbGFzc1xuYXhpb3MuQXhpb3NFcnJvciA9IEF4aW9zRXJyb3I7XG5cbi8vIGFsaWFzIGZvciBDYW5jZWxlZEVycm9yIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG5heGlvcy5DYW5jZWwgPSBheGlvcy5DYW5jZWxlZEVycm9yO1xuXG4vLyBFeHBvc2UgYWxsL3NwcmVhZFxuYXhpb3MuYWxsID0gZnVuY3Rpb24gYWxsKHByb21pc2VzKSB7XG4gIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG59O1xuXG5heGlvcy5zcHJlYWQgPSBzcHJlYWQ7XG5cbi8vIEV4cG9zZSBpc0F4aW9zRXJyb3JcbmF4aW9zLmlzQXhpb3NFcnJvciA9IGlzQXhpb3NFcnJvcjtcblxuLy8gRXhwb3NlIG1lcmdlQ29uZmlnXG5heGlvcy5tZXJnZUNvbmZpZyA9IG1lcmdlQ29uZmlnO1xuXG5heGlvcy5BeGlvc0hlYWRlcnMgPSBBeGlvc0hlYWRlcnMkMTtcblxuYXhpb3MuZm9ybVRvSlNPTiA9IHRoaW5nID0+IGZvcm1EYXRhVG9KU09OKHV0aWxzLmlzSFRNTEZvcm0odGhpbmcpID8gbmV3IEZvcm1EYXRhKHRoaW5nKSA6IHRoaW5nKTtcblxuYXhpb3MuZ2V0QWRhcHRlciA9IGFkYXB0ZXJzLmdldEFkYXB0ZXI7XG5cbmF4aW9zLkh0dHBTdGF0dXNDb2RlID0gSHR0cFN0YXR1c0NvZGUkMTtcblxuYXhpb3MuZGVmYXVsdCA9IGF4aW9zO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGF4aW9zO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXhpb3MuY2pzLm1hcFxuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0bG9hZGVkOiBmYWxzZSxcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG5cdG1vZHVsZS5sb2FkZWQgPSB0cnVlO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiX193ZWJwYWNrX3JlcXVpcmVfXy5ubWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZS5wYXRocyA9IFtdO1xuXHRpZiAoIW1vZHVsZS5jaGlsZHJlbikgbW9kdWxlLmNoaWxkcmVuID0gW107XG5cdHJldHVybiBtb2R1bGU7XG59OyIsIi8vIHN0YXJ0dXBcbi8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLy8gVGhpcyBlbnRyeSBtb2R1bGUgaXMgcmVmZXJlbmNlZCBieSBvdGhlciBtb2R1bGVzIHNvIGl0IGNhbid0IGJlIGlubGluZWRcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyg3NTMwKTtcbiJdLCJuYW1lcyI6WyJyb290IiwiZmFjdG9yeSIsImV4cG9ydHMiLCJtb2R1bGUiLCJkZWZpbmUiLCJhbWQiLCJ0aGlzIiwicGFyYWxsZWwiLCJzZXJpYWwiLCJzZXJpYWxPcmRlcmVkIiwiY2xlYW4iLCJrZXkiLCJqb2JzIiwic3RhdGUiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImJpbmQiLCJkZWZlciIsImNhbGxiYWNrIiwiaXNBc3luYyIsImVyciIsInJlc3VsdCIsImZuIiwibmV4dFRpY2siLCJzZXRJbW1lZGlhdGUiLCJwcm9jZXNzIiwic2V0VGltZW91dCIsImFzeW5jIiwiYWJvcnQiLCJsaXN0IiwiaXRlcmF0b3IiLCJpbmRleCIsIml0ZW0iLCJhYm9ydGVyIiwibGVuZ3RoIiwicnVuSm9iIiwiZXJyb3IiLCJvdXRwdXQiLCJyZXN1bHRzIiwic29ydE1ldGhvZCIsImlzTmFtZWRMaXN0IiwiQXJyYXkiLCJpc0FycmF5IiwiaW5pdFN0YXRlIiwia2V5ZWRMaXN0Iiwic2l6ZSIsInNvcnQiLCJhIiwiYiIsIml0ZXJhdGUiLCJ0ZXJtaW5hdG9yIiwiYXNjZW5kaW5nIiwiaXRlcmF0b3JIYW5kbGVyIiwiZGVzY2VuZGluZyIsIkNvbWJpbmVkU3RyZWFtIiwidXRpbCIsInBhdGgiLCJodHRwIiwiaHR0cHMiLCJwYXJzZVVybCIsImZzIiwiU3RyZWFtIiwibWltZSIsImFzeW5ja2l0IiwicG9wdWxhdGUiLCJGb3JtRGF0YSIsIm9wdGlvbnMiLCJvcHRpb24iLCJfb3ZlcmhlYWRMZW5ndGgiLCJfdmFsdWVMZW5ndGgiLCJfdmFsdWVzVG9NZWFzdXJlIiwiY2FsbCIsImluaGVyaXRzIiwiTElORV9CUkVBSyIsIkRFRkFVTFRfQ09OVEVOVF9UWVBFIiwicHJvdG90eXBlIiwiYXBwZW5kIiwiZmllbGQiLCJ2YWx1ZSIsImZpbGVuYW1lIiwiX2Vycm9yIiwiRXJyb3IiLCJoZWFkZXIiLCJfbXVsdGlQYXJ0SGVhZGVyIiwiZm9vdGVyIiwiX211bHRpUGFydEZvb3RlciIsIl90cmFja0xlbmd0aCIsInZhbHVlTGVuZ3RoIiwia25vd25MZW5ndGgiLCJCdWZmZXIiLCJpc0J1ZmZlciIsImJ5dGVMZW5ndGgiLCJyZWFkYWJsZSIsImhhc093blByb3BlcnR5IiwicHVzaCIsIl9sZW5ndGhSZXRyaWV2ZXIiLCJ1bmRlZmluZWQiLCJlbmQiLCJJbmZpbml0eSIsInN0YXJ0Iiwic3RhdCIsImZpbGVTaXplIiwiaGVhZGVycyIsIm9uIiwicmVzcG9uc2UiLCJwYXVzZSIsInJlc3VtZSIsImNvbnRlbnREaXNwb3NpdGlvbiIsIl9nZXRDb250ZW50RGlzcG9zaXRpb24iLCJjb250ZW50VHlwZSIsIl9nZXRDb250ZW50VHlwZSIsImNvbnRlbnRzIiwiY29uY2F0IiwicHJvcCIsImpvaW4iLCJnZXRCb3VuZGFyeSIsImZpbGVwYXRoIiwibm9ybWFsaXplIiwicmVwbGFjZSIsIm5hbWUiLCJiYXNlbmFtZSIsImNsaWVudCIsIl9odHRwTWVzc2FnZSIsImxvb2t1cCIsIm5leHQiLCJfc3RyZWFtcyIsIl9sYXN0Qm91bmRhcnkiLCJnZXRIZWFkZXJzIiwidXNlckhlYWRlcnMiLCJmb3JtSGVhZGVycyIsInRvTG93ZXJDYXNlIiwic2V0Qm91bmRhcnkiLCJib3VuZGFyeSIsIl9ib3VuZGFyeSIsIl9nZW5lcmF0ZUJvdW5kYXJ5IiwiZ2V0QnVmZmVyIiwiZGF0YUJ1ZmZlciIsImFsbG9jIiwiaSIsImxlbiIsImZyb20iLCJzdWJzdHJpbmciLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJ0b1N0cmluZyIsImdldExlbmd0aFN5bmMiLCJoYXNLbm93bkxlbmd0aCIsImdldExlbmd0aCIsImNiIiwidmFsdWVzIiwic3VibWl0IiwicGFyYW1zIiwicmVxdWVzdCIsImRlZmF1bHRzIiwibWV0aG9kIiwicG9ydCIsInBhdGhuYW1lIiwiaG9zdCIsImhvc3RuYW1lIiwicHJvdG9jb2wiLCJzZXRIZWFkZXIiLCJwaXBlIiwib25SZXNwb25zZSIsInJlc3BvbmNlIiwicmVtb3ZlTGlzdGVuZXIiLCJlbWl0IiwiZHN0Iiwic3JjIiwiRG9tYWluIiwiZGF0YSIsInJlY2VpdmluZyIsInNlbmRpbmciLCJyZXF1aXJlX3RscyIsInNraXBfdmVyaWZpY2F0aW9uIiwid2lsZGNhcmQiLCJzcGFtX2FjdGlvbiIsImNyZWF0ZWRfYXQiLCJzbXRwX3Bhc3N3b3JkIiwic210cF9sb2dpbiIsInR5cGUiLCJyZWNlaXZpbmdfZG5zX3JlY29yZHMiLCJzZW5kaW5nX2Ruc19yZWNvcmRzIiwiZHluYW1pY1Byb3BlcnRpZXMiLCJyZWR1Y2UiLCJhY2MiLCJwcm9wZXJ0eU5hbWUiLCJhc3NpZ24iLCJ1cmxfam9pbl8xIiwiX19pbXBvcnREZWZhdWx0IiwicmVxdWlyZSIsIkVycm9yXzEiLCJkb21haW5fMSIsIkRvbWFpbnNDbGllbnQiLCJkb21haW5DcmVkZW50aWFsc0NsaWVudCIsImRvbWFpblRlbXBsYXRlc0NsaWVudCIsImRvbWFpblRhZ3NDbGllbnQiLCJkb21haW5DcmVkZW50aWFscyIsImRvbWFpblRlbXBsYXRlcyIsImRvbWFpblRhZ3MiLCJfaGFuZGxlQm9vbFZhbHVlcyIsInByb3BzRm9yUmVwbGFjZW1lbnQiLCJyZXBsYWNlZFByb3BzIiwiX19hc3NpZ24iLCJfcGFyc2VNZXNzYWdlIiwiYm9keSIsInBhcnNlRG9tYWluTGlzdCIsIml0ZW1zIiwibWFwIiwiZGVmYXVsdCIsIl9wYXJzZURvbWFpbiIsImRvbWFpbiIsIl9wYXJzZVRyYWNraW5nU2V0dGluZ3MiLCJ0cmFja2luZyIsIl9wYXJzZVRyYWNraW5nVXBkYXRlIiwicXVlcnkiLCJfdGhpcyIsImdldCIsInRoZW4iLCJyZXMiLCJjcmVhdGUiLCJwb3N0T2JqIiwicG9zdFdpdGhGRCIsInVwZGF0ZSIsInB1dERhdGEiLCJwdXRXaXRoRkQiLCJ2ZXJpZnkiLCJwdXQiLCJkZXN0cm95IiwiZGVsZXRlIiwiZ2V0Q29ubmVjdGlvbiIsImNvbm5lY3Rpb24iLCJ1cGRhdGVDb25uZWN0aW9uIiwiZ2V0VHJhY2tpbmciLCJ1cGRhdGVUcmFja2luZyIsImFjdGl2ZSIsInN0YXR1cyIsInN0YXR1c1RleHQiLCJtZXNzYWdlIiwiZ2V0SXBzIiwiX2EiLCJhc3NpZ25JcCIsImlwIiwiZGVsZXRlSXAiLCJsaW5rSXBQb29sIiwicG9vbElkIiwicG9vbF9pZCIsInVubGlua0lwUG9sbCIsInJlcGxhY2VtZW50Iiwic2VhcmNoUGFyYW1zIiwidXBkYXRlREtJTUF1dGhvcml0eSIsInNlbGYiLCJ1cGRhdGVES0lNU2VsZWN0b3IiLCJka2ltU2VsZWN0b3IiLCJ1cGRhdGVXZWJQcmVmaXgiLCJ3ZWJQcmVmaXgiLCJEb21haW5DcmVkZW50aWFsc0NsaWVudCIsImJhc2VSb3V0ZSIsIl9wYXJzZURvbWFpbkNyZWRlbnRpYWxzTGlzdCIsInRvdGFsQ291bnQiLCJ0b3RhbF9jb3VudCIsIl9wYXJzZU1lc3NhZ2VSZXNwb25zZSIsIl9wYXJzZURlbGV0ZWRSZXNwb25zZSIsInNwZWMiLCJjcmVkZW50aWFsc0xvZ2luIiwiTmF2aWdhdGlvblRocnVQYWdlc18xIiwiRG9tYWluVGFnIiwidGFnSW5mbyIsInRhZyIsImRlc2NyaXB0aW9uIiwiRGF0ZSIsIkRvbWFpblRhZ1N0YXRpc3RpYyIsInRhZ1N0YXRpc3RpY0luZm8iLCJyZXNvbHV0aW9uIiwic3RhdHMiLCJ0aW1lIiwiRG9tYWluVGFnc0NsaWVudCIsIl9zdXBlciIsIl9fZXh0ZW5kcyIsInBhcnNlTGlzdCIsInBhZ2VzIiwicGFyc2VQYWdlTGlua3MiLCJfcGFyc2VUYWdTdGF0aXN0aWMiLCJyZXF1ZXN0TGlzdFdpdGhQYWdlcyIsInN0YXRpc3RpYyIsImNvdW50cmllcyIsInByb3ZpZGVycyIsImRldmljZXMiLCJEb21haW5UZW1wbGF0ZUl0ZW0iLCJkb21haW5UZW1wbGF0ZUZyb21BUEkiLCJjcmVhdGVkQXQiLCJjcmVhdGVkQnkiLCJpZCIsInZlcnNpb24iLCJ2ZXJzaW9ucyIsIkRvbWFpblRlbXBsYXRlc0NsaWVudCIsInBhcnNlQ3JlYXRpb25SZXNwb25zZSIsInRlbXBsYXRlIiwicGFyc2VDcmVhdGlvblZlcnNpb25SZXNwb25zZSIsInBhcnNlTXV0YXRpb25SZXNwb25zZSIsInRlbXBsYXRlTmFtZSIsInBhcnNlTm90aWZpY2F0aW9uUmVzcG9uc2UiLCJwYXJzZU11dGF0ZVRlbXBsYXRlVmVyc2lvblJlc3BvbnNlIiwidGVtcGxhdGVWZXJzaW9uIiwiZCIsInBhcnNlTGlzdFRlbXBsYXRlVmVyc2lvbnMiLCJkZXN0cm95QWxsIiwiY3JlYXRlVmVyc2lvbiIsImdldFZlcnNpb24iLCJ1cGRhdGVWZXJzaW9uIiwiZGVzdHJveVZlcnNpb24iLCJsaXN0VmVyc2lvbnMiLCJFdmVudENsaWVudCIsIklwUG9vbHNDbGllbnQiLCJwYXJzZUlwUG9vbHNSZXNwb25zZSIsInNlbnQiLCJwYXRjaFdpdGhGRCIsIklwc0NsaWVudCIsInBhcnNlSXBzUmVzcG9uc2UiLCJSZXF1ZXN0XzEiLCJkb21haW5zQ2xpZW50XzEiLCJFdmVudHNfMSIsIlN0YXRzQ2xpZW50XzEiLCJTdXBwcmVzc2lvbnNDbGllbnRfMSIsIldlYmhvb2tzXzEiLCJNZXNzYWdlc18xIiwiUm91dGVzXzEiLCJ2YWxpZGF0ZV8xIiwiSVBzXzEiLCJJUFBvb2xzXzEiLCJtYWlsaW5nTGlzdHNfMSIsIm1haWxMaXN0TWVtYmVyc18xIiwiZG9tYWluc0NyZWRlbnRpYWxzXzEiLCJtdWx0aXBsZVZhbGlkYXRpb25fMSIsImRvbWFpbnNUZW1wbGF0ZXNfMSIsImRvbWFpbnNUYWdzXzEiLCJTdWJhY2NvdW50c18xIiwiTWFpbGd1bkNsaWVudCIsImZvcm1EYXRhIiwiY29uZmlnIiwidXJsIiwidXNlcm5hbWUiLCJtYWlsTGlzdHNNZW1iZXJzIiwibXVsdGlwbGVWYWxpZGF0aW9uQ2xpZW50IiwiZG9tYWlucyIsIndlYmhvb2tzIiwiZXZlbnRzIiwic3VwcHJlc3Npb25zIiwibWVzc2FnZXMiLCJyb3V0ZXMiLCJpcHMiLCJpcF9wb29scyIsImxpc3RzIiwidmFsaWRhdGUiLCJzdWJhY2NvdW50cyIsInNldFN1YmFjY291bnQiLCJzdWJhY2NvdW50SWQiLCJzZXRTdWJhY2NvdW50SGVhZGVyIiwicmVzZXRTdWJhY2NvdW50IiwicmVzZXRTdWJhY2NvdW50SGVhZGVyIiwiTWFpbExpc3RzTWVtYmVycyIsImNoZWNrQW5kVXBkYXRlRGF0YSIsIm5ld0RhdGEiLCJ2YXJzIiwiSlNPTiIsInN0cmluZ2lmeSIsInN1YnNjcmliZWQiLCJsaXN0TWVtYmVycyIsIm1haWxMaXN0QWRkcmVzcyIsImdldE1lbWJlciIsIm1haWxMaXN0TWVtYmVyQWRkcmVzcyIsIm1lbWJlciIsImNyZWF0ZU1lbWJlciIsInJlcURhdGEiLCJjcmVhdGVNZW1iZXJzIiwibWVtYmVycyIsInVwc2VydCIsInVwZGF0ZU1lbWJlciIsImRlc3Ryb3lNZW1iZXIiLCJNYWlsaW5nTGlzdHNDbGllbnQiLCJwYXJzZVZhbGlkYXRpb25SZXN1bHQiLCJ2YWxpZGF0aW9uUmVzdWx0IiwicG9zdCIsImNhbmNlbFZhbGlkYXRpb24iLCJNZXNzYWdlc0NsaWVudCIsInByZXBhcmVCb29sZWFuVmFsdWVzIiwieWVzTm9Qcm9wZXJ0aWVzIiwiU2V0IiwiaGFzIiwiX3BhcnNlUmVzcG9uc2UiLCJtb2RpZmllZERhdGEiLCJSb3V0ZXNDbGllbnQiLCJyb3V0ZSIsIlN0YXRzQ29udGFpbmVyXzEiLCJTdGF0c0NsaWVudCIsImxvZ2dlciIsImNvbnNvbGUiLCJjb252ZXJ0RGF0ZVRvVVRDIiwiaW5wdXREYXRlIiwid2FybiIsInRvVVRDU3RyaW5nIiwicHJlcGFyZVNlYXJjaFBhcmFtcyIsImVudHJpZXMiLCJhcnJheVdpdGhQYWlycyIsImN1cnJlbnRQYWlyIiwicmVwZWF0ZWRQcm9wZXJ0eSIsIl9fc3ByZWFkQXJyYXkiLCJwYXJzZVN0YXRzIiwiZ2V0RG9tYWluIiwiZ2V0QWNjb3VudCIsIlN0YXRzQ29udGFpbmVyIiwiU3ViYWNjb3VudHNDbGllbnQiLCJlbmFibGUiLCJkaXNhYmxlIiwiU1VCQUNDT1VOVF9IRUFERVIiLCJFbnVtc18xIiwiQm91bmNlIiwiU3VwcHJlc3Npb25Nb2RlbHMiLCJCT1VOQ0VTIiwiYWRkcmVzcyIsImNvZGUiLCJDb21wbGFpbnQiLCJDT01QTEFJTlRTIiwiU3VwcHJlc3Npb24iLCJCb3VuY2VfMSIsIkNvbXBsYWludF8xIiwiVW5zdWJzY3JpYmVfMSIsIldoaXRlTGlzdF8xIiwiY3JlYXRlT3B0aW9ucyIsIlN1cHByZXNzaW9uQ2xpZW50IiwibW9kZWxzIiwiYm91bmNlcyIsImNvbXBsYWludHMiLCJ1bnN1YnNjcmliZXMiLCJ3aGl0ZWxpc3RzIiwiTW9kZWwiLCJfcGFyc2VJdGVtIiwiY3JlYXRlV2hpdGVMaXN0IiwiaXNEYXRhQXJyYXkiLCJwcmVwYXJlUmVzcG9uc2UiLCJjcmVhdGVVbnN1YnNjcmliZSIsInNvbWUiLCJ1bnN1YnNjcmliZSIsInRhZ3MiLCJnZXRNb2RlbCIsIm1vZGVsIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicG9zdERhdGEiLCJVbnN1YnNjcmliZSIsIlVOU1VCU0NSSUJFUyIsIldoaXRlTGlzdCIsIldISVRFTElTVFMiLCJyZWFzb24iLCJNdWx0aXBsZVZhbGlkYXRpb25Kb2IiLCJyZXNwb25zZVN0YXR1c0NvZGUiLCJxdWFudGl0eSIsInJlY29yZHNQcm9jZXNzZWQiLCJyZWNvcmRzX3Byb2Nlc3NlZCIsImRvd25sb2FkX3VybCIsImRvd25sb2FkVXJsIiwiY3N2IiwianNvbiIsIl9iIiwic3VtbWFyeSIsImNhdGNoQWxsIiwiY2F0Y2hfYWxsIiwiZGVsaXZlcmFibGUiLCJkb05vdFNlbmQiLCJkb19ub3Rfc2VuZCIsInVuZGVsaXZlcmFibGUiLCJ1bmtub3duIiwicmlzayIsImhpZ2giLCJsb3ciLCJtZWRpdW0iLCJNdWx0aXBsZVZhbGlkYXRpb25DbGllbnQiLCJoYW5kbGVSZXNwb25zZSIsImpvYiIsInRvdGFsIiwibGlzdElkIiwibXVsdGlwbGVWYWxpZGF0aW9uRGF0YSIsIm11bHRpcGxlVmFsaWRhdGlvbkZpbGUiLCJmaWxlIiwiVmFsaWRhdGVDbGllbnQiLCJtdWx0aXBsZVZhbGlkYXRpb24iLCJXZWJob29rIiwidXJscyIsIldlYmhvb2tzQ2xpZW50IiwiX3BhcnNlV2ViaG9va0xpc3QiLCJfcGFyc2VXZWJob29rV2l0aElEIiwid2ViaG9va1Jlc3BvbnNlIiwid2ViaG9vayIsIl9wYXJzZVdlYmhvb2tUZXN0IiwidGVzdCIsInVybFZhbHVlcyIsIkFQSUVycm9yIiwiYm9keU1lc3NhZ2UiLCJzdGFjayIsImRldGFpbHMiLCJGb3JtRGF0YUJ1aWxkZXIiLCJGb3JtRGF0YUNvbnN0cnVjdG9yIiwiY3JlYXRlRm9ybURhdGEiLCJmaWx0ZXIiLCJmb3JtRGF0YUFjYyIsImluY2x1ZGVzIiwiYWRkRmlsZXNUb0ZEIiwiYWRkTWltZURhdGFUb0ZEIiwiYWRkQ29tbW9uUHJvcGVydHlUb0ZEIiwiaXNGb3JtRGF0YVBhY2thZ2UiLCJmb3JtRGF0YUluc3RhbmNlIiwiZ2V0QXR0YWNobWVudE9wdGlvbnMiLCJpc1N0cmVhbSIsIkJsb2IiLCJicm93c2VyRm9ybURhdGEiLCJibG9iSW5zdGFuY2UiLCJhcHBlbmRGaWxlVG9GRCIsIm9yaWdpbmFsS2V5Iiwib2JqIiwib2JqRGF0YSIsImZkIiwiTmF2aWdhdGlvblRocnVQYWdlcyIsInBhcnNlUGFnZSIsInBhZ2VVcmwiLCJ1cmxTZXBhcmF0b3IiLCJpdGVyYXRvck5hbWUiLCJVUkwiLCJwYWdlVmFsdWUiLCJzcGxpdCIsInBvcCIsIml0ZXJhdG9yUG9zaXRpb24iLCJwYWdlIiwicGFnaW5nIiwidXBkYXRlVXJsQW5kUXVlcnkiLCJjbGllbnRVcmwiLCJxdWVyeUNvcHkiLCJ1cGRhdGVkUXVlcnkiLCJiYXNlNjQiLCJfX2ltcG9ydFN0YXIiLCJheGlvc18xIiwiRm9ybURhdGFCdWlsZGVyXzEiLCJSZXF1ZXN0IiwidGltZW91dCIsIm1ha2VIZWFkZXJzRnJvbU9iamVjdCIsImZvcm1EYXRhQnVpbGRlciIsIm1heEJvZHlMZW5ndGgiLCJwcm94eSIsIm9uQ2FsbE9wdGlvbnMiLCJyZXF1ZXN0SGVhZGVycyIsImpvaW5BbmRUcmFuc2Zvcm1IZWFkZXJzIiwiZ2V0T3duUHJvcGVydHlOYW1lcyIsIlVSTFNlYXJjaFBhcmFtcyIsInVybFZhbHVlIiwidG9Mb2NhbGVVcHBlckNhc2UiLCJfZCIsImVycm9yUmVzcG9uc2UiLCJlcnJfMSIsIl9jIiwiZ2V0UmVzcG9uc2VCb2R5IiwiQXhpb3NIZWFkZXJzIiwiYmFzaWMiLCJlbmNvZGUiLCJzZXRBdXRob3JpemF0aW9uIiwic2V0IiwicmVjZWl2ZWRPbkNhbGxIZWFkZXJzIiwib25DYWxsSGVhZGVycyIsImhlYWRlcnNPYmplY3QiLCJoZWFkZXJzQWNjdW11bGF0b3IiLCJjb21tYW5kIiwiYWRkRGVmYXVsdEhlYWRlcnMiLCJyZXF1ZXN0T3B0aW9ucyIsIlJlc29sdXRpb24iLCJXZWJob29rc0lkcyIsIlllc05vIiwiX19leHBvcnRTdGFyIiwiTWFpbGd1bkNsaWVudF8xIiwiTWFpbGd1biIsImRlZmluZVByb3BlcnR5IiwiZnJlZUV4cG9ydHMiLCJmcmVlR2xvYmFsIiwiZ2xvYmFsIiwid2luZG93IiwiSW52YWxpZENoYXJhY3RlckVycm9yIiwiVEFCTEUiLCJSRUdFWF9TUEFDRV9DSEFSQUNURVJTIiwiaW5wdXQiLCJTdHJpbmciLCJjIiwiYnVmZmVyIiwicGFkZGluZyIsInBvc2l0aW9uIiwiY2hhckNvZGVBdCIsImNoYXJBdCIsImJpdFN0b3JhZ2UiLCJiaXRDb3VudGVyIiwiaW5kZXhPZiIsImZyb21DaGFyQ29kZSIsIkRlbGF5ZWRTdHJlYW0iLCJ3cml0YWJsZSIsImRhdGFTaXplIiwibWF4RGF0YVNpemUiLCJwYXVzZVN0cmVhbXMiLCJfcmVsZWFzZWQiLCJfY3VycmVudFN0cmVhbSIsIl9pbnNpZGVMb29wIiwiX3BlbmRpbmdOZXh0IiwiY29tYmluZWRTdHJlYW0iLCJpc1N0cmVhbUxpa2UiLCJzdHJlYW0iLCJuZXdTdHJlYW0iLCJwYXVzZVN0cmVhbSIsIl9jaGVja0RhdGFTaXplIiwiX2hhbmRsZUVycm9ycyIsImRlc3QiLCJfZ2V0TmV4dCIsIl9yZWFsR2V0TmV4dCIsInNoaWZ0IiwiX3BpcGVOZXh0Iiwid3JpdGUiLCJfZW1pdEVycm9yIiwiX3Jlc2V0IiwiX3VwZGF0ZURhdGFTaXplIiwiZm9ybWF0QXJncyIsImFyZ3MiLCJ1c2VDb2xvcnMiLCJuYW1lc3BhY2UiLCJodW1hbml6ZSIsImRpZmYiLCJjb2xvciIsInNwbGljZSIsImxhc3RDIiwibWF0Y2giLCJzYXZlIiwibmFtZXNwYWNlcyIsInN0b3JhZ2UiLCJzZXRJdGVtIiwicmVtb3ZlSXRlbSIsImxvYWQiLCJyIiwiZ2V0SXRlbSIsImVudiIsIkRFQlVHIiwiX19ud2pzIiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiZG9jdW1lbnQiLCJkb2N1bWVudEVsZW1lbnQiLCJzdHlsZSIsIldlYmtpdEFwcGVhcmFuY2UiLCJmaXJlYnVnIiwiZXhjZXB0aW9uIiwidGFibGUiLCJwYXJzZUludCIsIlJlZ0V4cCIsIiQxIiwibG9jYWxTdG9yYWdlIiwibG9jYWxzdG9yYWdlIiwid2FybmVkIiwiY29sb3JzIiwibG9nIiwiZGVidWciLCJmb3JtYXR0ZXJzIiwiaiIsInYiLCJjcmVhdGVEZWJ1ZyIsInByZXZUaW1lIiwibmFtZXNwYWNlc0NhY2hlIiwiZW5hYmxlZENhY2hlIiwiZW5hYmxlT3ZlcnJpZGUiLCJlbmFibGVkIiwiY3VyciIsIk51bWJlciIsIm1zIiwicHJldiIsImNvZXJjZSIsInVuc2hpZnQiLCJmb3JtYXQiLCJmb3JtYXR0ZXIiLCJ2YWwiLCJhcHBseSIsInNlbGVjdENvbG9yIiwiZXh0ZW5kIiwiZW51bWVyYWJsZSIsImNvbmZpZ3VyYWJsZSIsImluaXQiLCJkZWxpbWl0ZXIiLCJuZXdEZWJ1ZyIsInRvTmFtZXNwYWNlIiwicmVnZXhwIiwibmFtZXMiLCJza2lwcyIsInNsaWNlIiwiaGFzaCIsImFicyIsImJyb3dzZXIiLCJ0dHkiLCJpbnNwZWN0T3B0cyIsInN0ZGVyciIsImNvbG9yQ29kZSIsInByZWZpeCIsImhpZGVEYXRlIiwidG9JU09TdHJpbmciLCJnZXREYXRlIiwiQm9vbGVhbiIsImlzYXR0eSIsImRlcHJlY2F0ZSIsInN1cHBvcnRzQ29sb3IiLCJsZXZlbCIsIl8iLCJrIiwidG9VcHBlckNhc2UiLCJvIiwiaW5zcGVjdCIsInN0ciIsInRyaW0iLCJPIiwic291cmNlIiwiX21heERhdGFTaXplRXhjZWVkZWQiLCJfYnVmZmVyZWRFdmVudHMiLCJkZWxheWVkU3RyZWFtIiwicmVhbEVtaXQiLCJfaGFuZGxlRW1pdCIsImFyZ3VtZW50cyIsInNldEVuY29kaW5nIiwicmVsZWFzZSIsIl9jaGVja0lmTWF4RGF0YVNpemVFeGNlZWRlZCIsIldyaXRhYmxlIiwiYXNzZXJ0IiwidXNlTmF0aXZlVVJMIiwicHJlc2VydmVkVXJsRmllbGRzIiwiZXZlbnRIYW5kbGVycyIsImV2ZW50IiwiYXJnMSIsImFyZzIiLCJhcmczIiwiX3JlZGlyZWN0YWJsZSIsIkludmFsaWRVcmxFcnJvciIsImNyZWF0ZUVycm9yVHlwZSIsIlR5cGVFcnJvciIsIlJlZGlyZWN0aW9uRXJyb3IiLCJUb29NYW55UmVkaXJlY3RzRXJyb3IiLCJNYXhCb2R5TGVuZ3RoRXhjZWVkZWRFcnJvciIsIldyaXRlQWZ0ZXJFbmRFcnJvciIsIm5vb3AiLCJSZWRpcmVjdGFibGVSZXF1ZXN0IiwicmVzcG9uc2VDYWxsYmFjayIsIl9zYW5pdGl6ZU9wdGlvbnMiLCJfb3B0aW9ucyIsIl9lbmRlZCIsIl9lbmRpbmciLCJfcmVkaXJlY3RDb3VudCIsIl9yZWRpcmVjdHMiLCJfcmVxdWVzdEJvZHlMZW5ndGgiLCJfcmVxdWVzdEJvZHlCdWZmZXJzIiwiX29uTmF0aXZlUmVzcG9uc2UiLCJfcHJvY2Vzc1Jlc3BvbnNlIiwiY2F1c2UiLCJfcGVyZm9ybVJlcXVlc3QiLCJ3cmFwIiwicHJvdG9jb2xzIiwibWF4UmVkaXJlY3RzIiwibmF0aXZlUHJvdG9jb2xzIiwic2NoZW1lIiwibmF0aXZlUHJvdG9jb2wiLCJ3cmFwcGVkUHJvdG9jb2wiLCJkZWZpbmVQcm9wZXJ0aWVzIiwic3ByZWFkVXJsT2JqZWN0IiwiaXNTdHJpbmciLCJ2YWxpZGF0ZVVybCIsImlzRnVuY3Rpb24iLCJlcXVhbCIsIndyYXBwZWRSZXF1ZXN0IiwicGFyc2VkIiwicGFyc2UiLCJocmVmIiwidXJsT2JqZWN0IiwidGFyZ2V0Iiwic3ByZWFkIiwic3RhcnRzV2l0aCIsInNlYXJjaCIsInJlbW92ZU1hdGNoaW5nSGVhZGVycyIsInJlZ2V4IiwibGFzdFZhbHVlIiwiYmFzZUNsYXNzIiwiQ3VzdG9tRXJyb3IiLCJwcm9wZXJ0aWVzIiwiY2FwdHVyZVN0YWNrVHJhY2UiLCJjb25zdHJ1Y3RvciIsImRlc3Ryb3lSZXF1ZXN0IiwiX2N1cnJlbnRSZXF1ZXN0IiwiZW5jb2RpbmciLCJjdXJyZW50UmVxdWVzdCIsInJlbW92ZUhlYWRlciIsIm1zZWNzIiwiZGVzdHJveU9uVGltZW91dCIsInNvY2tldCIsImFkZExpc3RlbmVyIiwic3RhcnRUaW1lciIsIl90aW1lb3V0IiwiY2xlYXJUaW1lb3V0IiwiY2xlYXJUaW1lciIsIm9uY2UiLCJwcm9wZXJ0eSIsInNlYXJjaFBvcyIsImFnZW50cyIsImFnZW50IiwiX2N1cnJlbnRVcmwiLCJfaXNSZWRpcmVjdCIsImJ1ZmZlcnMiLCJ3cml0ZU5leHQiLCJmaW5pc2hlZCIsInN0YXR1c0NvZGUiLCJ0cmFja1JlZGlyZWN0cyIsImxvY2F0aW9uIiwiZm9sbG93UmVkaXJlY3RzIiwicmVzcG9uc2VVcmwiLCJyZWRpcmVjdHMiLCJiZWZvcmVSZWRpcmVjdCIsIkhvc3QiLCJyZXEiLCJnZXRIZWFkZXIiLCJyZWxhdGl2ZSIsImJhc2UiLCJjdXJyZW50SG9zdEhlYWRlciIsImN1cnJlbnRVcmxQYXJ0cyIsImN1cnJlbnRIb3N0IiwiY3VycmVudFVybCIsInJlZGlyZWN0VXJsIiwicmVzb2x2ZSIsInN1YmRvbWFpbiIsImRvdCIsImVuZHNXaXRoIiwiaXNTdWJkb21haW4iLCJyZXNwb25zZURldGFpbHMiLCJyZXF1ZXN0RGV0YWlscyIsImZsYWciLCJhcmd2IiwicG9zIiwidGVybWluYXRvclBvcyIsImV4dGVuc2lvbnMiLCJ0eXBlcyIsInByZWZlcmVuY2UiLCJkYiIsImV4dG5hbWUiLCJFWFRSQUNUX1RZUEVfUkVHRVhQIiwiVEVYVF9UWVBFX1JFR0VYUCIsImNoYXJzZXQiLCJleGVjIiwiY2hhcnNldHMiLCJleHRlbnNpb24iLCJleHRzIiwic3Vic3RyIiwidG8iLCJzIiwibSIsImgiLCJ3IiwieSIsInBsdXJhbCIsIm1zQWJzIiwibiIsImlzUGx1cmFsIiwicm91bmQiLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJsb25nIiwiZm10TG9uZyIsImZtdFNob3J0IiwiREVGQVVMVF9QT1JUUyIsImZ0cCIsImdvcGhlciIsIndzIiwid3NzIiwic3RyaW5nRW5kc1dpdGgiLCJnZXRFbnYiLCJnZXRQcm94eUZvclVybCIsInBhcnNlZFVybCIsInByb3RvIiwiTk9fUFJPWFkiLCJldmVyeSIsInBhcnNlZFByb3h5IiwicGFyc2VkUHJveHlIb3N0bmFtZSIsInBhcnNlZFByb3h5UG9ydCIsInNob3VsZFByb3h5Iiwib3MiLCJoYXNGbGFnIiwiZm9yY2VDb2xvciIsImdldFN1cHBvcnRMZXZlbCIsImlzVFRZIiwibWluIiwicGxhdGZvcm0iLCJvc1JlbGVhc2UiLCJub2RlIiwic2lnbiIsIkNJX05BTUUiLCJURUFNQ0lUWV9WRVJTSU9OIiwiQ09MT1JURVJNIiwiVEVSTV9QUk9HUkFNX1ZFUlNJT04iLCJURVJNX1BST0dSQU0iLCJURVJNIiwiaGFzQmFzaWMiLCJoYXMyNTYiLCJoYXMxNm0iLCJ0cmFuc2xhdGVMZXZlbCIsIkZPUkNFX0NPTE9SIiwic3Rkb3V0Iiwic3RyQXJyYXkiLCJyZXN1bHRBcnJheSIsImZpcnN0IiwiY29tcG9uZW50IiwicGFydHMiLCJkZWZpbml0aW9uIiwiRm9ybURhdGEkMSIsInByb3h5RnJvbUVudiIsInpsaWIiLCJFdmVudEVtaXR0ZXIiLCJfaW50ZXJvcERlZmF1bHRMZWdhY3kiLCJlIiwiRm9ybURhdGFfX2RlZmF1bHQiLCJ1cmxfX2RlZmF1bHQiLCJodHRwX19kZWZhdWx0IiwiaHR0cHNfX2RlZmF1bHQiLCJ1dGlsX19kZWZhdWx0IiwiZm9sbG93UmVkaXJlY3RzX19kZWZhdWx0IiwiemxpYl9fZGVmYXVsdCIsInN0cmVhbV9fZGVmYXVsdCIsIkV2ZW50RW1pdHRlcl9fZGVmYXVsdCIsInRoaXNBcmciLCJnZXRQcm90b3R5cGVPZiIsImtpbmRPZiIsImNhY2hlIiwidGhpbmciLCJraW5kT2ZUZXN0IiwidHlwZU9mVGVzdCIsImlzVW5kZWZpbmVkIiwiaXNBcnJheUJ1ZmZlciIsImlzTnVtYmVyIiwiaXNPYmplY3QiLCJpc1BsYWluT2JqZWN0IiwiU3ltYm9sIiwidG9TdHJpbmdUYWciLCJpc0RhdGUiLCJpc0ZpbGUiLCJpc0Jsb2IiLCJpc0ZpbGVMaXN0IiwiaXNVUkxTZWFyY2hQYXJhbXMiLCJhbGxPd25LZXlzIiwibCIsImZpbmRLZXkiLCJfa2V5IiwiX2dsb2JhbCIsImdsb2JhbFRoaXMiLCJpc0NvbnRleHREZWZpbmVkIiwiY29udGV4dCIsImlzVHlwZWRBcnJheSIsIlR5cGVkQXJyYXkiLCJVaW50OEFycmF5IiwiaXNIVE1MRm9ybSIsImlzUmVnRXhwIiwicmVkdWNlRGVzY3JpcHRvcnMiLCJyZWR1Y2VyIiwiZGVzY3JpcHRvcnMiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwicmVkdWNlZERlc2NyaXB0b3JzIiwiZGVzY3JpcHRvciIsInJldCIsIkFMUEhBIiwiRElHSVQiLCJBTFBIQUJFVCIsIkFMUEhBX0RJR0lUIiwiaXNBc3luY0ZuIiwidXRpbHMiLCJpc0Zvcm1EYXRhIiwia2luZCIsImlzQXJyYXlCdWZmZXJWaWV3IiwiQXJyYXlCdWZmZXIiLCJpc1ZpZXciLCJpc0Jvb2xlYW4iLCJtZXJnZSIsImNhc2VsZXNzIiwiYXNzaWduVmFsdWUiLCJ0YXJnZXRLZXkiLCJzdHJpcEJPTSIsImNvbnRlbnQiLCJzdXBlckNvbnN0cnVjdG9yIiwicHJvcHMiLCJ0b0ZsYXRPYmplY3QiLCJzb3VyY2VPYmoiLCJkZXN0T2JqIiwicHJvcEZpbHRlciIsIm1lcmdlZCIsInNlYXJjaFN0cmluZyIsImxhc3RJbmRleCIsInRvQXJyYXkiLCJhcnIiLCJmb3JFYWNoRW50cnkiLCJkb25lIiwicGFpciIsIm1hdGNoQWxsIiwicmVnRXhwIiwibWF0Y2hlcyIsImhhc093blByb3AiLCJmcmVlemVNZXRob2RzIiwidG9PYmplY3RTZXQiLCJhcnJheU9yU3RyaW5nIiwidG9DYW1lbENhc2UiLCJwMSIsInAyIiwidG9GaW5pdGVOdW1iZXIiLCJkZWZhdWx0VmFsdWUiLCJnZW5lcmF0ZVN0cmluZyIsImFscGhhYmV0IiwiaXNTcGVjQ29tcGxpYW50Rm9ybSIsInRvSlNPTk9iamVjdCIsInZpc2l0IiwicmVkdWNlZFZhbHVlIiwiaXNUaGVuYWJsZSIsImNhdGNoIiwiQXhpb3NFcnJvciIsInRvSlNPTiIsIm51bWJlciIsImZpbGVOYW1lIiwibGluZU51bWJlciIsImNvbHVtbk51bWJlciIsInByb3RvdHlwZSQxIiwiaXNWaXNpdGFibGUiLCJyZW1vdmVCcmFja2V0cyIsInJlbmRlcktleSIsImRvdHMiLCJ0b2tlbiIsImN1c3RvbVByb3BzIiwiYXhpb3NFcnJvciIsInByZWRpY2F0ZXMiLCJ0b0Zvcm1EYXRhIiwibWV0YVRva2VucyIsImluZGV4ZXMiLCJ2aXNpdG9yIiwiZGVmYXVsdFZpc2l0b3IiLCJ1c2VCbG9iIiwiY29udmVydFZhbHVlIiwiaXNGbGF0QXJyYXkiLCJlbCIsImV4cG9zZWRIZWxwZXJzIiwiYnVpbGQiLCJlbmNvZGUkMSIsImNoYXJNYXAiLCJBeGlvc1VSTFNlYXJjaFBhcmFtcyIsIl9wYWlycyIsImJ1aWxkVVJMIiwiX2VuY29kZSIsInNlcmlhbGl6ZUZuIiwic2VyaWFsaXplIiwic2VyaWFsaXplZFBhcmFtcyIsImhhc2htYXJrSW5kZXgiLCJlbmNvZGVyIiwiSW50ZXJjZXB0b3JNYW5hZ2VyJDEiLCJJbnRlcmNlcHRvck1hbmFnZXIiLCJoYW5kbGVycyIsInVzZSIsImZ1bGZpbGxlZCIsInJlamVjdGVkIiwic3luY2hyb25vdXMiLCJydW5XaGVuIiwiZWplY3QiLCJjbGVhciIsInRyYW5zaXRpb25hbERlZmF1bHRzIiwic2lsZW50SlNPTlBhcnNpbmciLCJmb3JjZWRKU09OUGFyc2luZyIsImNsYXJpZnlUaW1lb3V0RXJyb3IiLCJpc05vZGUiLCJjbGFzc2VzIiwiZm9ybURhdGFUb0pTT04iLCJidWlsZFBhdGgiLCJpc051bWVyaWNLZXkiLCJpc0xhc3QiLCJhcnJheVRvT2JqZWN0IiwicGFyc2VQcm9wUGF0aCIsInRyYW5zaXRpb25hbCIsImFkYXB0ZXIiLCJ0cmFuc2Zvcm1SZXF1ZXN0IiwiZ2V0Q29udGVudFR5cGUiLCJoYXNKU09OQ29udGVudFR5cGUiLCJpc09iamVjdFBheWxvYWQiLCJzZXRDb250ZW50VHlwZSIsImhlbHBlcnMiLCJ0b1VSTEVuY29kZWRGb3JtIiwiZm9ybVNlcmlhbGl6ZXIiLCJfRm9ybURhdGEiLCJyYXdWYWx1ZSIsInBhcnNlciIsInN0cmluZ2lmeVNhZmVseSIsInRyYW5zZm9ybVJlc3BvbnNlIiwiSlNPTlJlcXVlc3RlZCIsInJlc3BvbnNlVHlwZSIsInN0cmljdEpTT05QYXJzaW5nIiwiRVJSX0JBRF9SRVNQT05TRSIsInhzcmZDb29raWVOYW1lIiwieHNyZkhlYWRlck5hbWUiLCJtYXhDb250ZW50TGVuZ3RoIiwidmFsaWRhdGVTdGF0dXMiLCJjb21tb24iLCJkZWZhdWx0cyQxIiwiaWdub3JlRHVwbGljYXRlT2YiLCIkaW50ZXJuYWxzIiwibm9ybWFsaXplSGVhZGVyIiwibm9ybWFsaXplVmFsdWUiLCJtYXRjaEhlYWRlclZhbHVlIiwiaXNIZWFkZXJOYW1lRmlsdGVyIiwidmFsdWVPclJld3JpdGUiLCJyZXdyaXRlIiwiX3ZhbHVlIiwiX2hlYWRlciIsIl9yZXdyaXRlIiwibEhlYWRlciIsInNldEhlYWRlcnMiLCJyYXdIZWFkZXJzIiwibGluZSIsInBhcnNlSGVhZGVycyIsInRva2VucyIsInRva2Vuc1JFIiwicGFyc2VUb2tlbnMiLCJtYXRjaGVyIiwiZGVsZXRlZCIsImRlbGV0ZUhlYWRlciIsIm5vcm1hbGl6ZWQiLCJjaGFyIiwiZm9ybWF0SGVhZGVyIiwidGFyZ2V0cyIsImFzU3RyaW5ncyIsInN0YXRpYyIsImNvbXB1dGVkIiwiYWNjZXNzb3JzIiwiZGVmaW5lQWNjZXNzb3IiLCJhY2Nlc3Nvck5hbWUiLCJtZXRob2ROYW1lIiwiYnVpbGRBY2Nlc3NvcnMiLCJhY2Nlc3NvciIsIm1hcHBlZCIsImhlYWRlclZhbHVlIiwiQXhpb3NIZWFkZXJzJDEiLCJ0cmFuc2Zvcm1EYXRhIiwiZm5zIiwiaXNDYW5jZWwiLCJfX0NBTkNFTF9fIiwiQ2FuY2VsZWRFcnJvciIsIkVSUl9DQU5DRUxFRCIsInNldHRsZSIsInJlamVjdCIsIkVSUl9CQURfUkVRVUVTVCIsImJ1aWxkRnVsbFBhdGgiLCJiYXNlVVJMIiwicmVxdWVzdGVkVVJMIiwiaXNBYnNvbHV0ZVVSTCIsInJlbGF0aXZlVVJMIiwiY29tYmluZVVSTHMiLCJWRVJTSU9OIiwicGFyc2VQcm90b2NvbCIsIkRBVEFfVVJMX1BBVFRFUk4iLCJzcGVlZG9tZXRlciIsInNhbXBsZXNDb3VudCIsImJ5dGVzIiwidGltZXN0YW1wcyIsImZpcnN0U2FtcGxlVFMiLCJoZWFkIiwidGFpbCIsImNodW5rTGVuZ3RoIiwibm93Iiwic3RhcnRlZEF0IiwiYnl0ZXNDb3VudCIsInBhc3NlZCIsImtJbnRlcm5hbHMiLCJBeGlvc1RyYW5zZm9ybVN0cmVhbSIsIlRyYW5zZm9ybSIsInN1cGVyIiwicmVhZGFibGVIaWdoV2F0ZXJNYXJrIiwibWF4UmF0ZSIsImNodW5rU2l6ZSIsIm1pbkNodW5rU2l6ZSIsInRpbWVXaW5kb3ciLCJ0aWNrc1JhdGUiLCJpbnRlcm5hbHMiLCJieXRlc1NlZW4iLCJpc0NhcHR1cmVkIiwibm90aWZpZWRCeXRlc0xvYWRlZCIsInRzIiwib25SZWFkQ2FsbGJhY2siLCJfc3BlZWRvbWV0ZXIiLCJieXRlc05vdGlmaWVkIiwidXBkYXRlUHJvZ3Jlc3MiLCJmcmVxIiwidGltZXN0YW1wIiwidGhyZXNob2xkIiwidGltZXIiLCJmb3JjZSIsInRocm90dGxlIiwidG90YWxCeXRlcyIsImJ5dGVzVHJhbnNmZXJyZWQiLCJwcm9ncmVzc0J5dGVzIiwiZGVzdHJveWVkIiwicmF0ZSIsIm9uRmluaXNoIiwiX3JlYWQiLCJfdHJhbnNmb3JtIiwiY2h1bmsiLCJieXRlc1RocmVzaG9sZCIsIm1heCIsInRyYW5zZm9ybUNodW5rIiwiX2NodW5rIiwiX2NhbGxiYWNrIiwiYnl0ZXNMZWZ0IiwiY2h1bmtSZW1haW5kZXIiLCJtYXhDaHVua1NpemUiLCJzdWJhcnJheSIsInB1c2hDaHVuayIsInRyYW5zZm9ybU5leHRDaHVuayIsInNldExlbmd0aCIsIkF4aW9zVHJhbnNmb3JtU3RyZWFtJDEiLCJhc3luY0l0ZXJhdG9yIiwicmVhZEJsb2IkMSIsImJsb2IiLCJhcnJheUJ1ZmZlciIsIkJPVU5EQVJZX0FMUEhBQkVUIiwidGV4dEVuY29kZXIiLCJUZXh0RW5jb2RlciIsIkNSTEYiLCJDUkxGX0JZVEVTIiwiRm9ybURhdGFQYXJ0IiwiZXNjYXBlTmFtZSIsImlzU3RyaW5nVmFsdWUiLCJjb250ZW50TGVuZ3RoIiwiZm9ybURhdGFUb1N0cmVhbSQxIiwiZm9ybSIsImhlYWRlcnNIYW5kbGVyIiwiYm91bmRhcnlCeXRlcyIsImZvb3RlckJ5dGVzIiwicGFydCIsImNvbXB1dGVkSGVhZGVycyIsIlJlYWRhYmxlIiwiWmxpYkhlYWRlclRyYW5zZm9ybVN0cmVhbSIsIl9fdHJhbnNmb3JtIiwiWmxpYkhlYWRlclRyYW5zZm9ybVN0cmVhbSQxIiwiY2FsbGJhY2tpZnkkMSIsInpsaWJPcHRpb25zIiwiZmx1c2giLCJjb25zdGFudHMiLCJaX1NZTkNfRkxVU0giLCJmaW5pc2hGbHVzaCIsImJyb3RsaU9wdGlvbnMiLCJCUk9UTElfT1BFUkFUSU9OX0ZMVVNIIiwiaXNCcm90bGlTdXBwb3J0ZWQiLCJjcmVhdGVCcm90bGlEZWNvbXByZXNzIiwiaHR0cEZvbGxvdyIsImh0dHBzRm9sbG93IiwiaXNIdHRwcyIsInN1cHBvcnRlZFByb3RvY29scyIsImRpc3BhdGNoQmVmb3JlUmVkaXJlY3QiLCJiZWZvcmVSZWRpcmVjdHMiLCJzZXRQcm94eSIsImNvbmZpZ1Byb3h5IiwicHJveHlVcmwiLCJhdXRoIiwicGFzc3dvcmQiLCJwcm94eUhvc3QiLCJyZWRpcmVjdE9wdGlvbnMiLCJpc0h0dHBBZGFwdGVyU3VwcG9ydGVkIiwiYnVpbGRBZGRyZXNzRW50cnkiLCJmYW1pbHkiLCJyZXNvbHZlRmFtaWx5IiwiaHR0cEFkYXB0ZXIiLCJhc3luY0V4ZWN1dG9yIiwib25Eb25lIiwicmVzcG9uc2VFbmNvZGluZyIsImlzRG9uZSIsIl9sb29rdXAiLCJvcHQiLCJhcmcwIiwiYWRkcmVzc2VzIiwiYWRkciIsImFsbCIsImVtaXR0ZXIiLCJvbkZpbmlzaGVkIiwiY2FuY2VsVG9rZW4iLCJzaWduYWwiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwicmVtb3ZlQWxsTGlzdGVuZXJzIiwiaXNSZWplY3RlZCIsInN1YnNjcmliZSIsImFib3J0ZWQiLCJhZGRFdmVudExpc3RlbmVyIiwiZnVsbFBhdGgiLCJjb252ZXJ0ZWREYXRhIiwidXJpIiwiYXNCbG9iIiwiX0Jsb2IiLCJFUlJfSU5WQUxJRF9VUkwiLCJpc0Jhc2U2NCIsImRlY29kZVVSSUNvbXBvbmVudCIsIkVSUl9OT1RfU1VQUE9SVCIsImZyb21EYXRhVVJJIiwib25Eb3dubG9hZFByb2dyZXNzIiwib25VcGxvYWRQcm9ncmVzcyIsIm1heFVwbG9hZFJhdGUiLCJtYXhEb3dubG9hZFJhdGUiLCJ1c2VyQm91bmRhcnkiLCJoYXNDb250ZW50TGVuZ3RoIiwicHJvbWlzaWZ5Iiwic2V0Q29udGVudExlbmd0aCIsImdldENvbnRlbnRMZW5ndGgiLCJvYmplY3RNb2RlIiwicGlwZWxpbmUiLCJwcm9ncmVzcyIsInVwbG9hZCIsInBhcmFtc1NlcmlhbGl6ZXIiLCJjdXN0b21FcnIiLCJleGlzdHMiLCJodHRwQWdlbnQiLCJodHRwc0FnZW50IiwidHJhbnNwb3J0Iiwic29ja2V0UGF0aCIsImlzSHR0cHNSZXF1ZXN0IiwiaW5zZWN1cmVIVFRQUGFyc2VyIiwic3RyZWFtcyIsInJlc3BvbnNlTGVuZ3RoIiwidHJhbnNmb3JtU3RyZWFtIiwiZG93bmxvYWQiLCJyZXNwb25zZVN0cmVhbSIsImxhc3RSZXF1ZXN0IiwiZGVjb21wcmVzcyIsImNyZWF0ZVVuemlwIiwib2ZmTGlzdGVuZXJzIiwic3RhdHVzTWVzc2FnZSIsInJlc3BvbnNlQnVmZmVyIiwidG90YWxSZXNwb25zZUJ5dGVzIiwicmVzcG9uc2VEYXRhIiwic2V0S2VlcEFsaXZlIiwiaXNOYU4iLCJFUlJfQkFEX09QVElPTl9WQUxVRSIsInRpbWVvdXRFcnJvck1lc3NhZ2UiLCJFVElNRURPVVQiLCJFQ09OTkFCT1JURUQiLCJlbmRlZCIsImVycm9yZWQiLCJQcm9taXNlIiwiX3JlamVjdCIsIm9uRG9uZUhhbmRsZXIiLCJjb29raWVzIiwiaXNTdGFuZGFyZEJyb3dzZXJFbnYiLCJleHBpcmVzIiwic2VjdXJlIiwiY29va2llIiwidG9HTVRTdHJpbmciLCJyZWFkIiwicmVtb3ZlIiwiaXNVUkxTYW1lT3JpZ2luIiwibXNpZSIsInVybFBhcnNpbmdOb2RlIiwiY3JlYXRlRWxlbWVudCIsIm9yaWdpblVSTCIsInJlc29sdmVVUkwiLCJzZXRBdHRyaWJ1dGUiLCJyZXF1ZXN0VVJMIiwicHJvZ3Jlc3NFdmVudFJlZHVjZXIiLCJsaXN0ZW5lciIsImlzRG93bmxvYWRTdHJlYW0iLCJsb2FkZWQiLCJsZW5ndGhDb21wdXRhYmxlIiwiZXN0aW1hdGVkIiwia25vd25BZGFwdGVycyIsInhociIsIlhNTEh0dHBSZXF1ZXN0IiwicmVxdWVzdERhdGEiLCJvbkNhbmNlbGVkIiwiaXNTdGFuZGFyZEJyb3dzZXJXZWJXb3JrZXJFbnYiLCJ1bmVzY2FwZSIsImJ0b2EiLCJvbmxvYWRlbmQiLCJyZXNwb25zZUhlYWRlcnMiLCJnZXRBbGxSZXNwb25zZUhlYWRlcnMiLCJyZXNwb25zZVRleHQiLCJvcGVuIiwib25yZWFkeXN0YXRlY2hhbmdlIiwicmVhZHlTdGF0ZSIsInJlc3BvbnNlVVJMIiwib25hYm9ydCIsIm9uZXJyb3IiLCJFUlJfTkVUV09SSyIsIm9udGltZW91dCIsInhzcmZWYWx1ZSIsInNldFJlcXVlc3RIZWFkZXIiLCJ3aXRoQ3JlZGVudGlhbHMiLCJjYW5jZWwiLCJzZW5kIiwicmVuZGVyUmVhc29uIiwiaXNSZXNvbHZlZEhhbmRsZSIsImFkYXB0ZXJzIiwibmFtZU9yQWRhcHRlciIsInJlamVjdGVkUmVhc29ucyIsInJlYXNvbnMiLCJ0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkIiwidGhyb3dJZlJlcXVlc3RlZCIsImRpc3BhdGNoUmVxdWVzdCIsImhlYWRlcnNUb09iamVjdCIsIm1lcmdlQ29uZmlnIiwiY29uZmlnMSIsImNvbmZpZzIiLCJnZXRNZXJnZWRWYWx1ZSIsIm1lcmdlRGVlcFByb3BlcnRpZXMiLCJ2YWx1ZUZyb21Db25maWcyIiwiZGVmYXVsdFRvQ29uZmlnMiIsIm1lcmdlRGlyZWN0S2V5cyIsIm1lcmdlTWFwIiwidGltZW91dE1lc3NhZ2UiLCJjb25maWdWYWx1ZSIsInZhbGlkYXRvcnMkMSIsImRlcHJlY2F0ZWRXYXJuaW5ncyIsInZhbGlkYXRvciIsImZvcm1hdE1lc3NhZ2UiLCJkZXNjIiwib3B0cyIsIkVSUl9ERVBSRUNBVEVEIiwiYXNzZXJ0T3B0aW9ucyIsInNjaGVtYSIsImFsbG93VW5rbm93biIsIkVSUl9CQURfT1BUSU9OIiwidmFsaWRhdG9ycyIsIkF4aW9zIiwiaW5zdGFuY2VDb25maWciLCJpbnRlcmNlcHRvcnMiLCJjb25maWdPclVybCIsImJvb2xlYW4iLCJmdW5jdGlvbiIsImNvbnRleHRIZWFkZXJzIiwicmVxdWVzdEludGVyY2VwdG9yQ2hhaW4iLCJzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMiLCJpbnRlcmNlcHRvciIsInJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbiIsInByb21pc2UiLCJjaGFpbiIsIm5ld0NvbmZpZyIsIm9uRnVsZmlsbGVkIiwib25SZWplY3RlZCIsImdldFVyaSIsImdlbmVyYXRlSFRUUE1ldGhvZCIsImlzRm9ybSIsIkF4aW9zJDEiLCJDYW5jZWxUb2tlbiIsImV4ZWN1dG9yIiwicmVzb2x2ZVByb21pc2UiLCJfbGlzdGVuZXJzIiwib25mdWxmaWxsZWQiLCJfcmVzb2x2ZSIsIkNhbmNlbFRva2VuJDEiLCJIdHRwU3RhdHVzQ29kZSIsIkNvbnRpbnVlIiwiU3dpdGNoaW5nUHJvdG9jb2xzIiwiUHJvY2Vzc2luZyIsIkVhcmx5SGludHMiLCJPayIsIkNyZWF0ZWQiLCJBY2NlcHRlZCIsIk5vbkF1dGhvcml0YXRpdmVJbmZvcm1hdGlvbiIsIk5vQ29udGVudCIsIlJlc2V0Q29udGVudCIsIlBhcnRpYWxDb250ZW50IiwiTXVsdGlTdGF0dXMiLCJBbHJlYWR5UmVwb3J0ZWQiLCJJbVVzZWQiLCJNdWx0aXBsZUNob2ljZXMiLCJNb3ZlZFBlcm1hbmVudGx5IiwiRm91bmQiLCJTZWVPdGhlciIsIk5vdE1vZGlmaWVkIiwiVXNlUHJveHkiLCJVbnVzZWQiLCJUZW1wb3JhcnlSZWRpcmVjdCIsIlBlcm1hbmVudFJlZGlyZWN0IiwiQmFkUmVxdWVzdCIsIlVuYXV0aG9yaXplZCIsIlBheW1lbnRSZXF1aXJlZCIsIkZvcmJpZGRlbiIsIk5vdEZvdW5kIiwiTWV0aG9kTm90QWxsb3dlZCIsIk5vdEFjY2VwdGFibGUiLCJQcm94eUF1dGhlbnRpY2F0aW9uUmVxdWlyZWQiLCJSZXF1ZXN0VGltZW91dCIsIkNvbmZsaWN0IiwiR29uZSIsIkxlbmd0aFJlcXVpcmVkIiwiUHJlY29uZGl0aW9uRmFpbGVkIiwiUGF5bG9hZFRvb0xhcmdlIiwiVXJpVG9vTG9uZyIsIlVuc3VwcG9ydGVkTWVkaWFUeXBlIiwiUmFuZ2VOb3RTYXRpc2ZpYWJsZSIsIkV4cGVjdGF0aW9uRmFpbGVkIiwiSW1BVGVhcG90IiwiTWlzZGlyZWN0ZWRSZXF1ZXN0IiwiVW5wcm9jZXNzYWJsZUVudGl0eSIsIkxvY2tlZCIsIkZhaWxlZERlcGVuZGVuY3kiLCJUb29FYXJseSIsIlVwZ3JhZGVSZXF1aXJlZCIsIlByZWNvbmRpdGlvblJlcXVpcmVkIiwiVG9vTWFueVJlcXVlc3RzIiwiUmVxdWVzdEhlYWRlckZpZWxkc1Rvb0xhcmdlIiwiVW5hdmFpbGFibGVGb3JMZWdhbFJlYXNvbnMiLCJJbnRlcm5hbFNlcnZlckVycm9yIiwiTm90SW1wbGVtZW50ZWQiLCJCYWRHYXRld2F5IiwiU2VydmljZVVuYXZhaWxhYmxlIiwiR2F0ZXdheVRpbWVvdXQiLCJIdHRwVmVyc2lvbk5vdFN1cHBvcnRlZCIsIlZhcmlhbnRBbHNvTmVnb3RpYXRlcyIsIkluc3VmZmljaWVudFN0b3JhZ2UiLCJMb29wRGV0ZWN0ZWQiLCJOb3RFeHRlbmRlZCIsIk5ldHdvcmtBdXRoZW50aWNhdGlvblJlcXVpcmVkIiwiSHR0cFN0YXR1c0NvZGUkMSIsImF4aW9zIiwiY3JlYXRlSW5zdGFuY2UiLCJkZWZhdWx0Q29uZmlnIiwiaW5zdGFuY2UiLCJDYW5jZWwiLCJwcm9taXNlcyIsImlzQXhpb3NFcnJvciIsInBheWxvYWQiLCJmb3JtVG9KU09OIiwiZ2V0QWRhcHRlciIsIl9fd2VicGFja19tb2R1bGVfY2FjaGVfXyIsIl9fd2VicGFja19yZXF1aXJlX18iLCJtb2R1bGVJZCIsImNhY2hlZE1vZHVsZSIsIl9fd2VicGFja19tb2R1bGVzX18iLCJubWQiLCJwYXRocyIsImNoaWxkcmVuIiwiX193ZWJwYWNrX2V4cG9ydHNfXyJdLCJzb3VyY2VSb290IjoiIn0= - if (err) { - abort() - } - }) - } +/***/ }), - res.on('drain', resume) +/***/ 7426: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - this.res = res +/*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015-2022 Douglas Christopher Wilson + * MIT Licensed + */ - const needDrain = res.writableNeedDrain !== undefined - ? res.writableNeedDrain - : res._writableState && res._writableState.needDrain +/** + * Module exports. + */ - return needDrain !== true - } +module.exports = __nccwpck_require__(3765) - onData (chunk) { - const { res } = this - return res ? res.write(chunk) : true - } +/***/ }), - onComplete (trailers) { - const { res } = this +/***/ 3583: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - removeSignal(this) +"use strict"; +/*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ - if (!res) { - return - } - this.trailers = util.parseHeaders(trailers) - res.end() - } +/** + * Module dependencies. + * @private + */ - onError (err) { - const { res, callback, opaque, body } = this +var db = __nccwpck_require__(7426) +var extname = (__nccwpck_require__(1017).extname) - removeSignal(this) +/** + * Module variables. + * @private + */ - this.factory = null +var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/ +var TEXT_TYPE_REGEXP = /^text\//i - if (res) { - this.res = null - util.destroy(res, err) - } else if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } +/** + * Module exports. + * @public + */ - if (body) { - this.body = null - util.destroy(body, err) - } +exports.charset = charset +exports.charsets = { lookup: charset } +exports.contentType = contentType +exports.extension = extension +exports.extensions = Object.create(null) +exports.lookup = lookup +exports.types = Object.create(null) + +// Populate the extensions/types maps +populateMaps(exports.extensions, exports.types) + +/** + * Get the default charset for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + +function charset (type) { + if (!type || typeof type !== 'string') { + return false } -} -function stream (opts, factory, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - stream.call(this, opts, factory, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type) + var mime = match && db[match[1].toLowerCase()] + + if (mime && mime.charset) { + return mime.charset } - try { - this.dispatch(opts, new StreamHandler(opts, factory, callback)) - } catch (err) { - if (typeof callback !== 'function') { - throw err - } - const opaque = opts && opts.opaque - queueMicrotask(() => callback(err, { opaque })) + // default text/* to utf-8 + if (match && TEXT_TYPE_REGEXP.test(match[1])) { + return 'UTF-8' } + + return false } -module.exports = stream +/** + * Create a full Content-Type header given a MIME type or extension. + * + * @param {string} str + * @return {boolean|string} + */ +function contentType (str) { + // TODO: should this even be in this module? + if (!str || typeof str !== 'string') { + return false + } -/***/ }), + var mime = str.indexOf('/') === -1 + ? exports.lookup(str) + : str -/***/ 6923: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (!mime) { + return false + } -"use strict"; + // TODO: use content-type or other module + if (mime.indexOf('charset') === -1) { + var charset = exports.charset(mime) + if (charset) mime += '; charset=' + charset.toLowerCase() + } + return mime +} -const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) -const { AsyncResource } = __nccwpck_require__(852) -const util = __nccwpck_require__(3983) -const { addSignal, removeSignal } = __nccwpck_require__(7032) -const assert = __nccwpck_require__(9491) +/** + * Get the default extension for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ -class UpgradeHandler extends AsyncResource { - constructor (opts, callback) { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('invalid opts') - } +function extension (type) { + if (!type || typeof type !== 'string') { + return false + } - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type) - const { signal, opaque, responseHeaders } = opts + // get extensions + var exts = match && exports.extensions[match[1].toLowerCase()] - if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { - throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') - } + if (!exts || !exts.length) { + return false + } - super('UNDICI_UPGRADE') + return exts[0] +} - this.responseHeaders = responseHeaders || null - this.opaque = opaque || null - this.callback = callback - this.abort = null - this.context = null +/** + * Lookup the MIME type for a file path/extension. + * + * @param {string} path + * @return {boolean|string} + */ - addSignal(this, signal) +function lookup (path) { + if (!path || typeof path !== 'string') { + return false } - onConnect (abort, context) { - if (!this.callback) { - throw new RequestAbortedError() - } + // get the extension ("ext" or ".ext" or full path) + var extension = extname('x.' + path) + .toLowerCase() + .substr(1) - this.abort = abort - this.context = null + if (!extension) { + return false } - onHeaders () { - throw new SocketError('bad upgrade', null) - } + return exports.types[extension] || false +} - onUpgrade (statusCode, rawHeaders, socket) { - const { callback, opaque, context } = this +/** + * Populate the extensions and types maps. + * @private + */ - assert.strictEqual(statusCode, 101) +function populateMaps (extensions, types) { + // source preference (least -> most) + var preference = ['nginx', 'apache', undefined, 'iana'] - removeSignal(this) + Object.keys(db).forEach(function forEachMimeType (type) { + var mime = db[type] + var exts = mime.extensions - this.callback = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - this.runInAsyncScope(callback, null, null, { - headers, - socket, - opaque, - context - }) - } + if (!exts || !exts.length) { + return + } - onError (err) { - const { callback, opaque } = this + // mime -> extensions + extensions[type] = exts - removeSignal(this) + // extension -> mime + for (var i = 0; i < exts.length; i++) { + var extension = exts[i] - if (callback) { - this.callback = null - queueMicrotask(() => { - this.runInAsyncScope(callback, null, err, { opaque }) - }) - } - } -} + if (types[extension]) { + var from = preference.indexOf(db[types[extension]].source) + var to = preference.indexOf(mime.source) -function upgrade (opts, callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - upgrade.call(this, opts, (err, data) => { - return err ? reject(err) : resolve(data) - }) - }) - } + if (types[extension] !== 'application/octet-stream' && + (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) { + // skip the remapping + continue + } + } - try { - const upgradeHandler = new UpgradeHandler(opts, callback) - this.dispatch({ - ...opts, - method: opts.method || 'GET', - upgrade: opts.protocol || 'Websocket' - }, upgradeHandler) - } catch (err) { - if (typeof callback !== 'function') { - throw err + // set the extension -> mime + types[extension] = type } - const opaque = opts && opts.opaque - queueMicrotask(() => callback(err, { opaque })) - } + }) } -module.exports = upgrade - /***/ }), -/***/ 4059: +/***/ 4294: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; - - -module.exports.request = __nccwpck_require__(5448) -module.exports.stream = __nccwpck_require__(5395) -module.exports.pipeline = __nccwpck_require__(8752) -module.exports.upgrade = __nccwpck_require__(6923) -module.exports.connect = __nccwpck_require__(9744) +module.exports = __nccwpck_require__(4219); /***/ }), -/***/ 3858: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4219: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -// Ported from https://github.com/nodejs/undici/pull/907 +var net = __nccwpck_require__(1808); +var tls = __nccwpck_require__(4404); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var events = __nccwpck_require__(2361); +var assert = __nccwpck_require__(9491); +var util = __nccwpck_require__(3837); -const assert = __nccwpck_require__(9491) -const { Readable } = __nccwpck_require__(2781) -const { RequestAbortedError, NotSupportedError, InvalidArgumentError } = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { ReadableStreamFrom, toUSVString } = __nccwpck_require__(3983) - -let Blob -const kConsume = Symbol('kConsume') -const kReading = Symbol('kReading') -const kBody = Symbol('kBody') -const kAbort = Symbol('abort') -const kContentType = Symbol('kContentType') +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; -const noop = () => {} -module.exports = class BodyReadable extends Readable { - constructor ({ - resume, - abort, - contentType = '', - highWaterMark = 64 * 1024 // Same as nodejs fs streams. - }) { - super({ - autoDestroy: true, - read: resume, - highWaterMark - }) +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} - this._readableState.dataEmitted = false +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} - this[kAbort] = abort - this[kConsume] = null - this[kBody] = null - this[kContentType] = contentType +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} - // Is stream being consumed through Readable API? - // This is an optimization so that we avoid checking - // for 'data' and 'readable' listeners in the hot path - // inside push(). - this[kReading] = false - } +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} - destroy (err) { - if (this.destroyed) { - // Node < 16 - return this - } - if (!err && !this._readableState.endEmitted) { - err = new RequestAbortedError() - } +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; - if (err) { - this[kAbort]() + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); - return super.destroy(err) +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; } - emit (ev, ...args) { - if (ev === 'data') { - // Node < 16.7 - this._readableState.dataEmitted = true - } else if (ev === 'error') { - // Node < 16 - this._readableState.errorEmitted = true + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); } - return super.emit(ev, ...args) - } - on (ev, ...args) { - if (ev === 'data' || ev === 'readable') { - this[kReading] = true + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); } - return super.on(ev, ...args) - } + }); +}; - addListener (ev, ...args) { - return this.on(ev, ...args) - } +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); - off (ev, ...args) { - const ret = super.off(ev, ...args) - if (ev === 'data' || ev === 'readable') { - this[kReading] = ( - this.listenerCount('data') > 0 || - this.listenerCount('readable') > 0 - ) + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port } - return ret + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; } - - removeListener (ev, ...args) { - return this.off(ev, ...args) + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); } - push (chunk) { - if (this[kConsume] && chunk !== null && this.readableLength === 0) { - consumePush(this[kConsume], chunk) - return this[kReading] ? super.push(chunk) : true - } - return super.push(chunk) - } + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); - // https://fetch.spec.whatwg.org/#dom-body-text - async text () { - return consume(this, 'text') + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; } - // https://fetch.spec.whatwg.org/#dom-body-json - async json () { - return consume(this, 'json') + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); } - // https://fetch.spec.whatwg.org/#dom-body-blob - async blob () { - return consume(this, 'blob') - } + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); - // https://fetch.spec.whatwg.org/#dom-body-arraybuffer - async arrayBuffer () { - return consume(this, 'arrayBuffer') + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); } - // https://fetch.spec.whatwg.org/#dom-body-formdata - async formData () { - // TODO: Implement. - throw new NotSupportedError() - } + function onError(cause) { + connectReq.removeAllListeners(); - // https://fetch.spec.whatwg.org/#dom-body-bodyused - get bodyUsed () { - return util.isDisturbed(this) + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); } +}; - // https://fetch.spec.whatwg.org/#dom-body-body - get body () { - if (!this[kBody]) { - this[kBody] = ReadableStreamFrom(this) - if (this[kConsume]) { - // TODO: Is this the best way to force a lock? - this[kBody].getReader() // Ensure stream is locked. - assert(this[kBody].locked) - } - } - return this[kBody] +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; } + this.sockets.splice(pos, 1); - dump (opts) { - let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 - const signal = opts && opts.signal + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; - if (signal) { - try { - if (typeof signal !== 'object' || !('aborted' in signal)) { - throw new InvalidArgumentError('signal must be an AbortSignal') - } - util.throwIfAborted(signal) - } catch (err) { - return Promise.reject(err) - } - } +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); - if (this.closed) { - return Promise.resolve(null) - } + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} - return new Promise((resolve, reject) => { - const signalListenerCleanup = signal - ? util.addAbortListener(signal, () => { - this.destroy() - }) - : noop - this - .on('close', function () { - signalListenerCleanup() - if (signal && signal.aborted) { - reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) - } else { - resolve(null) - } - }) - .on('error', noop) - .on('data', function (chunk) { - limit -= chunk.length - if (limit <= 0) { - this.destroy() - } - }) - .resume() - }) +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; } + return host; // for v0.11 or later } -// https://streams.spec.whatwg.org/#readablestream-locked -function isLocked (self) { - // Consume is an implicit lock. - return (self[kBody] && self[kBody].locked === true) || self[kConsume] +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; } -// https://fetch.spec.whatwg.org/#body-unusable -function isUnusable (self) { - return util.isDisturbed(self) || isLocked(self) -} -async function consume (stream, type) { - if (isUnusable(stream)) { - throw new TypeError('unusable') +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); } +} else { + debug = function() {}; +} +exports.debug = debug; // for test - assert(!stream[kConsume]) - return new Promise((resolve, reject) => { - stream[kConsume] = { - type, - stream, - resolve, - reject, - length: 0, - body: [] - } +/***/ }), - stream - .on('error', function (err) { - consumeFinish(this[kConsume], err) - }) - .on('close', function () { - if (this[kConsume].body !== null) { - consumeFinish(this[kConsume], new RequestAbortedError()) - } - }) +/***/ 1773: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - process.nextTick(consumeStart, stream[kConsume]) - }) +"use strict"; + + +const Client = __nccwpck_require__(3598) +const Dispatcher = __nccwpck_require__(412) +const errors = __nccwpck_require__(8045) +const Pool = __nccwpck_require__(4634) +const BalancedPool = __nccwpck_require__(7931) +const Agent = __nccwpck_require__(7890) +const util = __nccwpck_require__(3983) +const { InvalidArgumentError } = errors +const api = __nccwpck_require__(4059) +const buildConnector = __nccwpck_require__(2067) +const MockClient = __nccwpck_require__(8687) +const MockAgent = __nccwpck_require__(6771) +const MockPool = __nccwpck_require__(6193) +const mockErrors = __nccwpck_require__(888) +const ProxyAgent = __nccwpck_require__(7858) +const RetryHandler = __nccwpck_require__(2286) +const { getGlobalDispatcher, setGlobalDispatcher } = __nccwpck_require__(1892) +const DecoratorHandler = __nccwpck_require__(6930) +const RedirectHandler = __nccwpck_require__(2860) +const createRedirectInterceptor = __nccwpck_require__(8861) + +let hasCrypto +try { + __nccwpck_require__(6113) + hasCrypto = true +} catch { + hasCrypto = false } -function consumeStart (consume) { - if (consume.body === null) { - return - } +Object.assign(Dispatcher.prototype, api) - const { _readableState: state } = consume.stream +module.exports.Dispatcher = Dispatcher +module.exports.Client = Client +module.exports.Pool = Pool +module.exports.BalancedPool = BalancedPool +module.exports.Agent = Agent +module.exports.ProxyAgent = ProxyAgent +module.exports.RetryHandler = RetryHandler - for (const chunk of state.buffer) { - consumePush(consume, chunk) - } +module.exports.DecoratorHandler = DecoratorHandler +module.exports.RedirectHandler = RedirectHandler +module.exports.createRedirectInterceptor = createRedirectInterceptor - if (state.endEmitted) { - consumeEnd(this[kConsume]) - } else { - consume.stream.on('end', function () { - consumeEnd(this[kConsume]) - }) - } +module.exports.buildConnector = buildConnector +module.exports.errors = errors - consume.stream.resume() +function makeDispatcher (fn) { + return (url, opts, handler) => { + if (typeof opts === 'function') { + handler = opts + opts = null + } - while (consume.stream.read() != null) { - // Loop - } -} + if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) { + throw new InvalidArgumentError('invalid url') + } -function consumeEnd (consume) { - const { type, body, resolve, stream, length } = consume + if (opts != null && typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } - try { - if (type === 'text') { - resolve(toUSVString(Buffer.concat(body))) - } else if (type === 'json') { - resolve(JSON.parse(Buffer.concat(body))) - } else if (type === 'arrayBuffer') { - const dst = new Uint8Array(length) + if (opts && opts.path != null) { + if (typeof opts.path !== 'string') { + throw new InvalidArgumentError('invalid opts.path') + } - let pos = 0 - for (const buf of body) { - dst.set(buf, pos) - pos += buf.byteLength + let path = opts.path + if (!opts.path.startsWith('/')) { + path = `/${path}` } - resolve(dst.buffer) - } else if (type === 'blob') { - if (!Blob) { - Blob = (__nccwpck_require__(4300).Blob) + url = new URL(util.parseOrigin(url).origin + path) + } else { + if (!opts) { + opts = typeof url === 'object' ? url : {} } - resolve(new Blob(body, { type: stream[kContentType] })) + + url = util.parseURL(url) } - consumeFinish(consume) - } catch (err) { - stream.destroy(err) - } -} + const { agent, dispatcher = getGlobalDispatcher() } = opts -function consumePush (consume, chunk) { - consume.length += chunk.length - consume.body.push(chunk) -} + if (agent) { + throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?') + } -function consumeFinish (consume, err) { - if (consume.body === null) { - return + return fn.call(dispatcher, { + ...opts, + origin: url.origin, + path: url.search ? `${url.pathname}${url.search}` : url.pathname, + method: opts.method || (opts.body ? 'PUT' : 'GET') + }, handler) } +} - if (err) { - consume.reject(err) - } else { - consume.resolve() - } +module.exports.setGlobalDispatcher = setGlobalDispatcher +module.exports.getGlobalDispatcher = getGlobalDispatcher - consume.type = null - consume.stream = null - consume.resolve = null - consume.reject = null - consume.length = 0 - consume.body = null -} +if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) { + let fetchImpl = null + module.exports.fetch = async function fetch (resource) { + if (!fetchImpl) { + fetchImpl = (__nccwpck_require__(4881).fetch) + } + try { + return await fetchImpl(...arguments) + } catch (err) { + if (typeof err === 'object') { + Error.captureStackTrace(err, this) + } -/***/ }), + throw err + } + } + module.exports.Headers = __nccwpck_require__(554).Headers + module.exports.Response = __nccwpck_require__(7823).Response + module.exports.Request = __nccwpck_require__(8359).Request + module.exports.FormData = __nccwpck_require__(2015).FormData + module.exports.File = __nccwpck_require__(8511).File + module.exports.FileReader = __nccwpck_require__(1446).FileReader -/***/ 7474: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const { setGlobalOrigin, getGlobalOrigin } = __nccwpck_require__(1246) -const assert = __nccwpck_require__(9491) -const { - ResponseStatusCodeError -} = __nccwpck_require__(8045) -const { toUSVString } = __nccwpck_require__(3983) + module.exports.setGlobalOrigin = setGlobalOrigin + module.exports.getGlobalOrigin = getGlobalOrigin -async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) { - assert(body) + const { CacheStorage } = __nccwpck_require__(7907) + const { kConstruct } = __nccwpck_require__(9174) - let chunks = [] - let limit = 0 + // Cache & CacheStorage are tightly coupled with fetch. Even if it may run + // in an older version of Node, it doesn't have any use without fetch. + module.exports.caches = new CacheStorage(kConstruct) +} - for await (const chunk of body) { - chunks.push(chunk) - limit += chunk.length - if (limit > 128 * 1024) { - chunks = null - break - } - } +if (util.nodeMajor >= 16) { + const { deleteCookie, getCookies, getSetCookies, setCookie } = __nccwpck_require__(1724) - if (statusCode === 204 || !contentType || !chunks) { - process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) - return - } + module.exports.deleteCookie = deleteCookie + module.exports.getCookies = getCookies + module.exports.getSetCookies = getSetCookies + module.exports.setCookie = setCookie - try { - if (contentType.startsWith('application/json')) { - const payload = JSON.parse(toUSVString(Buffer.concat(chunks))) - process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) - return - } + const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) - if (contentType.startsWith('text/')) { - const payload = toUSVString(Buffer.concat(chunks)) - process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) - return - } - } catch (err) { - // Process in a fallback if error - } + module.exports.parseMIMEType = parseMIMEType + module.exports.serializeAMimeType = serializeAMimeType +} - process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) +if (util.nodeMajor >= 18 && hasCrypto) { + const { WebSocket } = __nccwpck_require__(4284) + + module.exports.WebSocket = WebSocket } -module.exports = { getResolveErrorBodyCallback } +module.exports.request = makeDispatcher(api.request) +module.exports.stream = makeDispatcher(api.stream) +module.exports.pipeline = makeDispatcher(api.pipeline) +module.exports.connect = makeDispatcher(api.connect) +module.exports.upgrade = makeDispatcher(api.upgrade) + +module.exports.MockClient = MockClient +module.exports.MockPool = MockPool +module.exports.MockAgent = MockAgent +module.exports.mockErrors = mockErrors /***/ }), -/***/ 7931: +/***/ 7890: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { - BalancedPoolMissingUpstreamError, - InvalidArgumentError -} = __nccwpck_require__(8045) -const { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kRemoveClient, - kGetDispatcher -} = __nccwpck_require__(3198) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = __nccwpck_require__(2785) +const DispatcherBase = __nccwpck_require__(4839) const Pool = __nccwpck_require__(4634) -const { kUrl, kInterceptors } = __nccwpck_require__(2785) -const { parseOrigin } = __nccwpck_require__(3983) -const kFactory = Symbol('factory') +const Client = __nccwpck_require__(3598) +const util = __nccwpck_require__(3983) +const createRedirectInterceptor = __nccwpck_require__(8861) +const { WeakRef, FinalizationRegistry } = __nccwpck_require__(6436)() +const kOnConnect = Symbol('onConnect') +const kOnDisconnect = Symbol('onDisconnect') +const kOnConnectionError = Symbol('onConnectionError') +const kMaxRedirections = Symbol('maxRedirections') +const kOnDrain = Symbol('onDrain') +const kFactory = Symbol('factory') +const kFinalizer = Symbol('finalizer') const kOptions = Symbol('options') -const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor') -const kCurrentWeight = Symbol('kCurrentWeight') -const kIndex = Symbol('kIndex') -const kWeight = Symbol('kWeight') -const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') -const kErrorPenalty = Symbol('kErrorPenalty') - -function getGreatestCommonDivisor (a, b) { - if (b === 0) return a - return getGreatestCommonDivisor(b, a % b) -} function defaultFactory (origin, opts) { - return new Pool(origin, opts) + return opts && opts.connections === 1 + ? new Client(origin, opts) + : new Pool(origin, opts) } -class BalancedPool extends PoolBase { - constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) { +class Agent extends DispatcherBase { + constructor ({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { super() - this[kOptions] = opts - this[kIndex] = -1 - this[kCurrentWeight] = 0 - - this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100 - this[kErrorPenalty] = this[kOptions].errorPenalty || 15 - - if (!Array.isArray(upstreams)) { - upstreams = [upstreams] - } - if (typeof factory !== 'function') { throw new InvalidArgumentError('factory must be a function.') } - this[kInterceptors] = opts.interceptors && opts.interceptors.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) - ? opts.interceptors.BalancedPool - : [] - this[kFactory] = factory - - for (const upstream of upstreams) { - this.addUpstream(upstream) + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') } - this._updateBalancedPoolStats() - } - - addUpstream (upstream) { - const upstreamOrigin = parseOrigin(upstream).origin - if (this[kClients].find((pool) => ( - pool[kUrl].origin === upstreamOrigin && - pool.closed !== true && - pool.destroyed !== true - ))) { - return this + if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { + throw new InvalidArgumentError('maxRedirections must be a positive number') } - const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])) - this[kAddClient](pool) - pool.on('connect', () => { - pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]) - }) + if (connect && typeof connect !== 'function') { + connect = { ...connect } + } - pool.on('connectionError', () => { - pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) - this._updateBalancedPoolStats() - }) + this[kInterceptors] = options.interceptors && options.interceptors.Agent && Array.isArray(options.interceptors.Agent) + ? options.interceptors.Agent + : [createRedirectInterceptor({ maxRedirections })] - pool.on('disconnect', (...args) => { - const err = args[2] - if (err && err.code === 'UND_ERR_SOCKET') { - // decrease the weight of the pool. - pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) - this._updateBalancedPoolStats() + this[kOptions] = { ...util.deepClone(options), connect } + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined + this[kMaxRedirections] = maxRedirections + this[kFactory] = factory + this[kClients] = new Map() + this[kFinalizer] = new FinalizationRegistry(/* istanbul ignore next: gc is undeterministic */ key => { + const ref = this[kClients].get(key) + if (ref !== undefined && ref.deref() === undefined) { + this[kClients].delete(key) } }) - for (const client of this[kClients]) { - client[kWeight] = this[kMaxWeightPerServer] - } + const agent = this - this._updateBalancedPoolStats() + this[kOnDrain] = (origin, targets) => { + agent.emit('drain', origin, [agent, ...targets]) + } - return this - } + this[kOnConnect] = (origin, targets) => { + agent.emit('connect', origin, [agent, ...targets]) + } - _updateBalancedPoolStats () { - this[kGreatestCommonDivisor] = this[kClients].map(p => p[kWeight]).reduce(getGreatestCommonDivisor, 0) - } - - removeUpstream (upstream) { - const upstreamOrigin = parseOrigin(upstream).origin - - const pool = this[kClients].find((pool) => ( - pool[kUrl].origin === upstreamOrigin && - pool.closed !== true && - pool.destroyed !== true - )) - - if (pool) { - this[kRemoveClient](pool) + this[kOnDisconnect] = (origin, targets, err) => { + agent.emit('disconnect', origin, [agent, ...targets], err) } - return this + this[kOnConnectionError] = (origin, targets, err) => { + agent.emit('connectionError', origin, [agent, ...targets], err) + } } - get upstreams () { - return this[kClients] - .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) - .map((p) => p[kUrl].origin) + get [kRunning] () { + let ret = 0 + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore next: gc is undeterministic */ + if (client) { + ret += client[kRunning] + } + } + return ret } - [kGetDispatcher] () { - // We validate that pools is greater than 0, - // otherwise we would have to wait until an upstream - // is added, which might never happen. - if (this[kClients].length === 0) { - throw new BalancedPoolMissingUpstreamError() + [kDispatch] (opts, handler) { + let key + if (opts.origin && (typeof opts.origin === 'string' || opts.origin instanceof URL)) { + key = String(opts.origin) + } else { + throw new InvalidArgumentError('opts.origin must be a non-empty string or URL.') } - const dispatcher = this[kClients].find(dispatcher => ( - !dispatcher[kNeedDrain] && - dispatcher.closed !== true && - dispatcher.destroyed !== true - )) + const ref = this[kClients].get(key) + let dispatcher = ref ? ref.deref() : null if (!dispatcher) { - return - } - - const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true) + dispatcher = this[kFactory](opts.origin, this[kOptions]) + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) - if (allClientsBusy) { - return + this[kClients].set(key, new WeakRef(dispatcher)) + this[kFinalizer].register(dispatcher, key) } - let counter = 0 - - let maxWeightIndex = this[kClients].findIndex(pool => !pool[kNeedDrain]) - - while (counter++ < this[kClients].length) { - this[kIndex] = (this[kIndex] + 1) % this[kClients].length - const pool = this[kClients][this[kIndex]] + return dispatcher.dispatch(opts, handler) + } - // find pool index with the largest weight - if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { - maxWeightIndex = this[kIndex] + async [kClose] () { + const closePromises = [] + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore else: gc is undeterministic */ + if (client) { + closePromises.push(client.close()) } + } - // decrease the current weight every `this[kClients].length`. - if (this[kIndex] === 0) { - // Set the current weight to the next lower weight. - this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor] + await Promise.all(closePromises) + } - if (this[kCurrentWeight] <= 0) { - this[kCurrentWeight] = this[kMaxWeightPerServer] - } - } - if (pool[kWeight] >= this[kCurrentWeight] && (!pool[kNeedDrain])) { - return pool + async [kDestroy] (err) { + const destroyPromises = [] + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore else: gc is undeterministic */ + if (client) { + destroyPromises.push(client.destroy(err)) } } - this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight] - this[kIndex] = maxWeightIndex - return this[kClients][maxWeightIndex] + await Promise.all(destroyPromises) } } -module.exports = BalancedPool +module.exports = Agent /***/ }), -/***/ 6101: +/***/ 7032: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +const { addAbortListener } = __nccwpck_require__(3983) +const { RequestAbortedError } = __nccwpck_require__(8045) +const kListener = Symbol('kListener') +const kSignal = Symbol('kSignal') -const { kConstruct } = __nccwpck_require__(9174) -const { urlEquals, fieldValues: getFieldValues } = __nccwpck_require__(2396) -const { kEnumerableProperty, isDisturbed } = __nccwpck_require__(3983) -const { kHeadersList } = __nccwpck_require__(2785) -const { webidl } = __nccwpck_require__(1744) -const { Response, cloneResponse } = __nccwpck_require__(7823) -const { Request } = __nccwpck_require__(8359) -const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) -const { fetching } = __nccwpck_require__(4881) -const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = __nccwpck_require__(2538) -const assert = __nccwpck_require__(9491) -const { getGlobalDispatcher } = __nccwpck_require__(1892) +function abort (self) { + if (self.abort) { + self.abort() + } else { + self.onError(new RequestAbortedError()) + } +} -/** - * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation - * @typedef {Object} CacheBatchOperation - * @property {'delete' | 'put'} type - * @property {any} request - * @property {any} response - * @property {import('../../types/cache').CacheQueryOptions} options - */ +function addSignal (self, signal) { + self[kSignal] = null + self[kListener] = null -/** - * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list - * @typedef {[any, any][]} requestResponseList - */ + if (!signal) { + return + } -class Cache { - /** - * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list - * @type {requestResponseList} - */ - #relevantRequestResponseList + if (signal.aborted) { + abort(self) + return + } - constructor () { - if (arguments[0] !== kConstruct) { - webidl.illegalConstructor() - } + self[kSignal] = signal + self[kListener] = () => { + abort(self) + } - this.#relevantRequestResponseList = arguments[1] + addAbortListener(self[kSignal], self[kListener]) +} + +function removeSignal (self) { + if (!self[kSignal]) { + return } - async match (request, options = {}) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.match' }) + if ('removeEventListener' in self[kSignal]) { + self[kSignal].removeEventListener('abort', self[kListener]) + } else { + self[kSignal].removeListener('abort', self[kListener]) + } - request = webidl.converters.RequestInfo(request) - options = webidl.converters.CacheQueryOptions(options) + self[kSignal] = null + self[kListener] = null +} - const p = await this.matchAll(request, options) +module.exports = { + addSignal, + removeSignal +} - if (p.length === 0) { - return - } - return p[0] - } +/***/ }), - async matchAll (request = undefined, options = {}) { - webidl.brandCheck(this, Cache) +/***/ 9744: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (request !== undefined) request = webidl.converters.RequestInfo(request) - options = webidl.converters.CacheQueryOptions(options) +"use strict"; - // 1. - let r = null - // 2. - if (request !== undefined) { - if (request instanceof Request) { - // 2.1.1 - r = request[kState] +const { AsyncResource } = __nccwpck_require__(852) +const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { addSignal, removeSignal } = __nccwpck_require__(7032) - // 2.1.2 - if (r.method !== 'GET' && !options.ignoreMethod) { - return [] - } - } else if (typeof request === 'string') { - // 2.2.1 - r = new Request(request)[kState] - } +class ConnectHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - // 5. - // 5.1 - const responses = [] + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - // 5.2 - if (request === undefined) { - // 5.2.1 - for (const requestResponse of this.#relevantRequestResponseList) { - responses.push(requestResponse[1]) - } - } else { // 5.3 - // 5.3.1 - const requestResponses = this.#queryCache(r, options) + const { signal, opaque, responseHeaders } = opts - // 5.3.2 - for (const requestResponse of requestResponses) { - responses.push(requestResponse[1]) - } + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') } - // 5.4 - // We don't implement CORs so we don't need to loop over the responses, yay! + super('UNDICI_CONNECT') - // 5.5.1 - const responseList = [] + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.callback = callback + this.abort = null - // 5.5.2 - for (const response of responses) { - // 5.5.2.1 - const responseObject = new Response(response.body?.source ?? null) - const body = responseObject[kState].body - responseObject[kState] = response - responseObject[kState].body = body - responseObject[kHeaders][kHeadersList] = response.headersList - responseObject[kHeaders][kGuard] = 'immutable' + addSignal(this, signal) + } - responseList.push(responseObject) + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() } - // 6. - return Object.freeze(responseList) + this.abort = abort + this.context = context } - async add (request) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.add' }) - - request = webidl.converters.RequestInfo(request) + onHeaders () { + throw new SocketError('bad connect', null) + } - // 1. - const requests = [request] + onUpgrade (statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this - // 2. - const responseArrayPromise = this.addAll(requests) + removeSignal(this) - // 3. - return await responseArrayPromise - } + this.callback = null - async addAll (requests) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.addAll' }) + let headers = rawHeaders + // Indicates is an HTTP2Session + if (headers != null) { + headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + } - requests = webidl.converters['sequence'](requests) + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + socket, + opaque, + context + }) + } - // 1. - const responsePromises = [] + onError (err) { + const { callback, opaque } = this - // 2. - const requestList = [] + removeSignal(this) - // 3. - for (const request of requests) { - if (typeof request === 'string') { - continue - } + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } +} - // 3.1 - const r = request[kState] +function connect (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + connect.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } - // 3.2 - if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { - throw webidl.errors.exception({ - header: 'Cache.addAll', - message: 'Expected http/s scheme when method is not GET.' - }) - } + try { + const connectHandler = new ConnectHandler(opts, callback) + this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} - // 4. - /** @type {ReturnType[]} */ - const fetchControllers = [] +module.exports = connect - // 5. - for (const request of requests) { - // 5.1 - const r = new Request(request)[kState] - // 5.2 - if (!urlIsHttpHttpsScheme(r.url)) { - throw webidl.errors.exception({ - header: 'Cache.addAll', - message: 'Expected http/s scheme.' - }) - } +/***/ }), - // 5.4 - r.initiator = 'fetch' - r.destination = 'subresource' +/***/ 8752: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 5.5 - requestList.push(r) +"use strict"; - // 5.6 - const responsePromise = createDeferredPromise() - // 5.7 - fetchControllers.push(fetching({ - request: r, - dispatcher: getGlobalDispatcher(), - processResponse (response) { - // 1. - if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) { - responsePromise.reject(webidl.errors.exception({ - header: 'Cache.addAll', - message: 'Received an invalid status code or the request failed.' - })) - } else if (response.headersList.contains('vary')) { // 2. - // 2.1 - const fieldValues = getFieldValues(response.headersList.get('vary')) +const { + Readable, + Duplex, + PassThrough +} = __nccwpck_require__(2781) +const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) +const assert = __nccwpck_require__(9491) - // 2.2 - for (const fieldValue of fieldValues) { - // 2.2.1 - if (fieldValue === '*') { - responsePromise.reject(webidl.errors.exception({ - header: 'Cache.addAll', - message: 'invalid vary field value' - })) +const kResume = Symbol('resume') - for (const controller of fetchControllers) { - controller.abort() - } +class PipelineRequest extends Readable { + constructor () { + super({ autoDestroy: true }) - return - } - } - } - }, - processResponseEndOfBody (response) { - // 1. - if (response.aborted) { - responsePromise.reject(new DOMException('aborted', 'AbortError')) - return - } + this[kResume] = null + } - // 2. - responsePromise.resolve(response) - } - })) + _read () { + const { [kResume]: resume } = this - // 5.8 - responsePromises.push(responsePromise.promise) + if (resume) { + this[kResume] = null + resume() } + } - // 6. - const p = Promise.all(responsePromises) + _destroy (err, callback) { + this._read() - // 7. - const responses = await p + callback(err) + } +} - // 7.1 - const operations = [] +class PipelineResponse extends Readable { + constructor (resume) { + super({ autoDestroy: true }) + this[kResume] = resume + } - // 7.2 - let index = 0 + _read () { + this[kResume]() + } - // 7.3 - for (const response of responses) { - // 7.3.1 - /** @type {CacheBatchOperation} */ - const operation = { - type: 'put', // 7.3.2 - request: requestList[index], // 7.3.3 - response // 7.3.4 - } + _destroy (err, callback) { + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() + } - operations.push(operation) // 7.3.5 + callback(err) + } +} - index++ // 7.3.6 +class PipelineHandler extends AsyncResource { + constructor (opts, handler) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - // 7.5 - const cacheJobPromise = createDeferredPromise() + if (typeof handler !== 'function') { + throw new InvalidArgumentError('invalid handler') + } - // 7.6.1 - let errorData = null + const { signal, method, opaque, onInfo, responseHeaders } = opts - // 7.6.2 - try { - this.#batchCacheOperations(operations) - } catch (e) { - errorData = e + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') } - // 7.6.3 - queueMicrotask(() => { - // 7.6.3.1 - if (errorData === null) { - cacheJobPromise.resolve(undefined) - } else { - // 7.6.3.2 - cacheJobPromise.reject(errorData) - } - }) - - // 7.7 - return cacheJobPromise.promise - } + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } - async put (request, response) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 2, { header: 'Cache.put' }) + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } - request = webidl.converters.RequestInfo(request) - response = webidl.converters.Response(response) + super('UNDICI_PIPELINE') - // 1. - let innerRequest = null + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.handler = handler + this.abort = null + this.context = null + this.onInfo = onInfo || null - // 2. - if (request instanceof Request) { - innerRequest = request[kState] - } else { // 3. - innerRequest = new Request(request)[kState] - } + this.req = new PipelineRequest().on('error', util.nop) - // 4. - if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') { - throw webidl.errors.exception({ - header: 'Cache.put', - message: 'Expected an http/s scheme when method is not GET' - }) - } + this.ret = new Duplex({ + readableObjectMode: opts.objectMode, + autoDestroy: true, + read: () => { + const { body } = this - // 5. - const innerResponse = response[kState] + if (body && body.resume) { + body.resume() + } + }, + write: (chunk, encoding, callback) => { + const { req } = this - // 6. - if (innerResponse.status === 206) { - throw webidl.errors.exception({ - header: 'Cache.put', - message: 'Got 206 status' - }) - } + if (req.push(chunk, encoding) || req._readableState.destroyed) { + callback() + } else { + req[kResume] = callback + } + }, + destroy: (err, callback) => { + const { body, req, res, ret, abort } = this - // 7. - if (innerResponse.headersList.contains('vary')) { - // 7.1. - const fieldValues = getFieldValues(innerResponse.headersList.get('vary')) + if (!err && !ret._readableState.endEmitted) { + err = new RequestAbortedError() + } - // 7.2. - for (const fieldValue of fieldValues) { - // 7.2.1 - if (fieldValue === '*') { - throw webidl.errors.exception({ - header: 'Cache.put', - message: 'Got * vary field value' - }) + if (abort && err) { + abort() } - } - } - // 8. - if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { - throw webidl.errors.exception({ - header: 'Cache.put', - message: 'Response body is locked or disturbed' - }) - } + util.destroy(body, err) + util.destroy(req, err) + util.destroy(res, err) - // 9. - const clonedResponse = cloneResponse(innerResponse) + removeSignal(this) - // 10. - const bodyReadPromise = createDeferredPromise() + callback(err) + } + }).on('prefinish', () => { + const { req } = this - // 11. - if (innerResponse.body != null) { - // 11.1 - const stream = innerResponse.body.stream + // Node < 15 does not call _final in same tick. + req.push(null) + }) - // 11.2 - const reader = stream.getReader() + this.res = null - // 11.3 - readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject) - } else { - bodyReadPromise.resolve(undefined) - } + addSignal(this, signal) + } - // 12. - /** @type {CacheBatchOperation[]} */ - const operations = [] + onConnect (abort, context) { + const { ret, res } = this - // 13. - /** @type {CacheBatchOperation} */ - const operation = { - type: 'put', // 14. - request: innerRequest, // 15. - response: clonedResponse // 16. + assert(!res, 'pipeline cannot be retried') + + if (ret.destroyed) { + throw new RequestAbortedError() } - // 17. - operations.push(operation) + this.abort = abort + this.context = context + } - // 19. - const bytes = await bodyReadPromise.promise + onHeaders (statusCode, rawHeaders, resume) { + const { opaque, handler, context } = this - if (clonedResponse.body != null) { - clonedResponse.body.source = bytes + if (statusCode < 200) { + if (this.onInfo) { + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + this.onInfo({ statusCode, headers }) + } + return } - // 19.1 - const cacheJobPromise = createDeferredPromise() - - // 19.2.1 - let errorData = null + this.res = new PipelineResponse(resume) - // 19.2.2 + let body try { - this.#batchCacheOperations(operations) - } catch (e) { - errorData = e + this.handler = null + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + body = this.runInAsyncScope(handler, null, { + statusCode, + headers, + opaque, + body: this.res, + context + }) + } catch (err) { + this.res.on('error', util.nop) + throw err } - // 19.2.3 - queueMicrotask(() => { - // 19.2.3.1 - if (errorData === null) { - cacheJobPromise.resolve() - } else { // 19.2.3.2 - cacheJobPromise.reject(errorData) - } - }) - - return cacheJobPromise.promise - } + if (!body || typeof body.on !== 'function') { + throw new InvalidReturnValueError('expected Readable') + } - async delete (request, options = {}) { - webidl.brandCheck(this, Cache) - webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.delete' }) + body + .on('data', (chunk) => { + const { ret, body } = this - request = webidl.converters.RequestInfo(request) - options = webidl.converters.CacheQueryOptions(options) + if (!ret.push(chunk) && body.pause) { + body.pause() + } + }) + .on('error', (err) => { + const { ret } = this - /** - * @type {Request} - */ - let r = null + util.destroy(ret, err) + }) + .on('end', () => { + const { ret } = this - if (request instanceof Request) { - r = request[kState] + ret.push(null) + }) + .on('close', () => { + const { ret } = this - if (r.method !== 'GET' && !options.ignoreMethod) { - return false - } - } else { - assert(typeof request === 'string') + if (!ret._readableState.ended) { + util.destroy(ret, new RequestAbortedError()) + } + }) - r = new Request(request)[kState] - } + this.body = body + } - /** @type {CacheBatchOperation[]} */ - const operations = [] + onData (chunk) { + const { res } = this + return res.push(chunk) + } - /** @type {CacheBatchOperation} */ - const operation = { - type: 'delete', - request: r, - options - } - - operations.push(operation) + onComplete (trailers) { + const { res } = this + res.push(null) + } - const cacheJobPromise = createDeferredPromise() + onError (err) { + const { ret } = this + this.handler = null + util.destroy(ret, err) + } +} - let errorData = null - let requestResponses +function pipeline (opts, handler) { + try { + const pipelineHandler = new PipelineHandler(opts, handler) + this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler) + return pipelineHandler.ret + } catch (err) { + return new PassThrough().destroy(err) + } +} - try { - requestResponses = this.#batchCacheOperations(operations) - } catch (e) { - errorData = e - } +module.exports = pipeline - queueMicrotask(() => { - if (errorData === null) { - cacheJobPromise.resolve(!!requestResponses?.length) - } else { - cacheJobPromise.reject(errorData) - } - }) - return cacheJobPromise.promise - } +/***/ }), - /** - * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys - * @param {any} request - * @param {import('../../types/cache').CacheQueryOptions} options - * @returns {readonly Request[]} - */ - async keys (request = undefined, options = {}) { - webidl.brandCheck(this, Cache) +/***/ 5448: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (request !== undefined) request = webidl.converters.RequestInfo(request) - options = webidl.converters.CacheQueryOptions(options) +"use strict"; - // 1. - let r = null - // 2. - if (request !== undefined) { - // 2.1 - if (request instanceof Request) { - // 2.1.1 - r = request[kState] +const Readable = __nccwpck_require__(3858) +const { + InvalidArgumentError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) - // 2.1.2 - if (r.method !== 'GET' && !options.ignoreMethod) { - return [] - } - } else if (typeof request === 'string') { // 2.2 - r = new Request(request)[kState] - } +class RequestHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - // 4. - const promise = createDeferredPromise() + const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError, highWaterMark } = opts - // 5. - // 5.1 - const requests = [] + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - // 5.2 - if (request === undefined) { - // 5.2.1 - for (const requestResponse of this.#relevantRequestResponseList) { - // 5.2.1.1 - requests.push(requestResponse[0]) + if (highWaterMark && (typeof highWaterMark !== 'number' || highWaterMark < 0)) { + throw new InvalidArgumentError('invalid highWaterMark') } - } else { // 5.3 - // 5.3.1 - const requestResponses = this.#queryCache(r, options) - // 5.3.2 - for (const requestResponse of requestResponses) { - // 5.3.2.1 - requests.push(requestResponse[0]) + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') } - } - // 5.4 - queueMicrotask(() => { - // 5.4.1 - const requestList = [] + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } - // 5.4.2 - for (const request of requests) { - const requestObject = new Request('https://a') - requestObject[kState] = request - requestObject[kHeaders][kHeadersList] = request.headersList - requestObject[kHeaders][kGuard] = 'immutable' - requestObject[kRealm] = request.client + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } - // 5.4.2.1 - requestList.push(requestObject) + super('UNDICI_REQUEST') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err) } + throw err + } - // 5.4.3 - promise.resolve(Object.freeze(requestList)) - }) + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.res = null + this.abort = null + this.body = body + this.trailers = {} + this.context = null + this.onInfo = onInfo || null + this.throwOnError = throwOnError + this.highWaterMark = highWaterMark - return promise.promise + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err) + }) + } + + addSignal(this, signal) } - /** - * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm - * @param {CacheBatchOperation[]} operations - * @returns {requestResponseList} - */ - #batchCacheOperations (operations) { - // 1. - const cache = this.#relevantRequestResponseList + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } - // 2. - const backupCache = [...cache] + this.abort = abort + this.context = context + } - // 3. - const addedItems = [] + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const { callback, opaque, abort, context, responseHeaders, highWaterMark } = this - // 4.1 - const resultList = [] + const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - try { - // 4.2 - for (const operation of operations) { - // 4.2.1 - if (operation.type !== 'delete' && operation.type !== 'put') { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'operation type does not match "delete" or "put"' - }) - } + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }) + } + return + } - // 4.2.2 - if (operation.type === 'delete' && operation.response != null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'delete operation should not have an associated response' - }) - } + const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers + const contentType = parsedHeaders['content-type'] + const body = new Readable({ resume, abort, contentType, highWaterMark }) - // 4.2.3 - if (this.#queryCache(operation.request, operation.options, addedItems).length) { - throw new DOMException('???', 'InvalidStateError') - } + this.callback = null + this.res = body + if (callback !== null) { + if (this.throwOnError && statusCode >= 400) { + this.runInAsyncScope(getResolveErrorBodyCallback, null, + { callback, body, contentType, statusCode, statusMessage, headers } + ) + } else { + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + trailers: this.trailers, + opaque, + body, + context + }) + } + } + } - // 4.2.4 - let requestResponses + onData (chunk) { + const { res } = this + return res.push(chunk) + } - // 4.2.5 - if (operation.type === 'delete') { - // 4.2.5.1 - requestResponses = this.#queryCache(operation.request, operation.options) + onComplete (trailers) { + const { res } = this - // TODO: the spec is wrong, this is needed to pass WPTs - if (requestResponses.length === 0) { - return [] - } + removeSignal(this) - // 4.2.5.2 - for (const requestResponse of requestResponses) { - const idx = cache.indexOf(requestResponse) - assert(idx !== -1) + util.parseHeaders(trailers, this.trailers) - // 4.2.5.2.1 - cache.splice(idx, 1) - } - } else if (operation.type === 'put') { // 4.2.6 - // 4.2.6.1 - if (operation.response == null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'put operation should have an associated response' - }) - } + res.push(null) + } - // 4.2.6.2 - const r = operation.request + onError (err) { + const { res, callback, body, opaque } = this - // 4.2.6.3 - if (!urlIsHttpHttpsScheme(r.url)) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'expected http or https scheme' - }) - } + removeSignal(this) - // 4.2.6.4 - if (r.method !== 'GET') { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'not get method' - }) - } + if (callback) { + // TODO: Does this need queueMicrotask? + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } - // 4.2.6.5 - if (operation.options != null) { - throw webidl.errors.exception({ - header: 'Cache.#batchCacheOperations', - message: 'options must not be defined' - }) - } + if (res) { + this.res = null + // Ensure all queued handlers are invoked before destroying res. + queueMicrotask(() => { + util.destroy(res, err) + }) + } - // 4.2.6.6 - requestResponses = this.#queryCache(operation.request) + if (body) { + this.body = null + util.destroy(body, err) + } + } +} - // 4.2.6.7 - for (const requestResponse of requestResponses) { - const idx = cache.indexOf(requestResponse) - assert(idx !== -1) +function request (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + request.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } - // 4.2.6.7.1 - cache.splice(idx, 1) - } + try { + this.dispatch(opts, new RequestHandler(opts, callback)) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } +} - // 4.2.6.8 - cache.push([operation.request, operation.response]) +module.exports = request +module.exports.RequestHandler = RequestHandler - // 4.2.6.10 - addedItems.push([operation.request, operation.response]) - } - // 4.2.7 - resultList.push([operation.request, operation.response]) - } +/***/ }), - // 4.3 - return resultList - } catch (e) { // 5. - // 5.1 - this.#relevantRequestResponseList.length = 0 +/***/ 5395: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 5.2 - this.#relevantRequestResponseList = backupCache +"use strict"; - // 5.3 - throw e + +const { finished, PassThrough } = __nccwpck_require__(2781) +const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) +const { AsyncResource } = __nccwpck_require__(852) +const { addSignal, removeSignal } = __nccwpck_require__(7032) + +class StreamHandler extends AsyncResource { + constructor (opts, factory, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - } - /** - * @see https://w3c.github.io/ServiceWorker/#query-cache - * @param {any} requestQuery - * @param {import('../../types/cache').CacheQueryOptions} options - * @param {requestResponseList} targetStorage - * @returns {requestResponseList} - */ - #queryCache (requestQuery, options, targetStorage) { - /** @type {requestResponseList} */ - const resultList = [] + const { signal, method, opaque, body, onInfo, responseHeaders, throwOnError } = opts - const storage = targetStorage ?? this.#relevantRequestResponseList + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - for (const requestResponse of storage) { - const [cachedRequest, cachedResponse] = requestResponse - if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { - resultList.push(requestResponse) + if (typeof factory !== 'function') { + throw new InvalidArgumentError('invalid factory') } - } - return resultList - } + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } - /** - * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm - * @param {any} requestQuery - * @param {any} request - * @param {any | null} response - * @param {import('../../types/cache').CacheQueryOptions | undefined} options - * @returns {boolean} - */ - #requestMatchesCachedItem (requestQuery, request, response = null, options) { - // if (options?.ignoreMethod === false && request.method === 'GET') { - // return false - // } + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } - const queryURL = new URL(requestQuery.url) + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } - const cachedURL = new URL(request.url) + super('UNDICI_STREAM') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err) + } + throw err + } - if (options?.ignoreSearch) { - cachedURL.search = '' + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.factory = factory + this.callback = callback + this.res = null + this.abort = null + this.context = null + this.trailers = null + this.body = body + this.onInfo = onInfo || null + this.throwOnError = throwOnError || false - queryURL.search = '' + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err) + }) } - if (!urlEquals(queryURL, cachedURL, true)) { - return false - } + addSignal(this, signal) + } - if ( - response == null || - options?.ignoreVary || - !response.headersList.contains('vary') - ) { - return true + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() } - const fieldValues = getFieldValues(response.headersList.get('vary')) + this.abort = abort + this.context = context + } - for (const fieldValue of fieldValues) { - if (fieldValue === '*') { - return false - } + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const { factory, opaque, context, callback, responseHeaders } = this - const requestValue = request.headersList.get(fieldValue) - const queryValue = requestQuery.headersList.get(fieldValue) + const headers = responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) - // If one has the header and the other doesn't, or one has - // a different value than the other, return false - if (requestValue !== queryValue) { - return false + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }) } + return } - return true - } -} + this.factory = null -Object.defineProperties(Cache.prototype, { - [Symbol.toStringTag]: { - value: 'Cache', - configurable: true - }, - match: kEnumerableProperty, - matchAll: kEnumerableProperty, - add: kEnumerableProperty, - addAll: kEnumerableProperty, - put: kEnumerableProperty, - delete: kEnumerableProperty, - keys: kEnumerableProperty -}) + let res -const cacheQueryOptionConverters = [ - { - key: 'ignoreSearch', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'ignoreMethod', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'ignoreVary', - converter: webidl.converters.boolean, - defaultValue: false - } -] - -webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters) - -webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ - ...cacheQueryOptionConverters, - { - key: 'cacheName', - converter: webidl.converters.DOMString - } -]) + if (this.throwOnError && statusCode >= 400) { + const parsedHeaders = responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers + const contentType = parsedHeaders['content-type'] + res = new PassThrough() -webidl.converters.Response = webidl.interfaceConverter(Response) + this.callback = null + this.runInAsyncScope(getResolveErrorBodyCallback, null, + { callback, body: res, contentType, statusCode, statusMessage, headers } + ) + } else { + if (factory === null) { + return + } -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.RequestInfo -) + res = this.runInAsyncScope(factory, null, { + statusCode, + headers, + opaque, + context + }) -module.exports = { - Cache -} + if ( + !res || + typeof res.write !== 'function' || + typeof res.end !== 'function' || + typeof res.on !== 'function' + ) { + throw new InvalidReturnValueError('expected Writable') + } + // TODO: Avoid finished. It registers an unnecessary amount of listeners. + finished(res, { readable: false }, (err) => { + const { callback, res, opaque, trailers, abort } = this -/***/ }), + this.res = null + if (err || !res.readable) { + util.destroy(res, err) + } -/***/ 7907: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.callback = null + this.runInAsyncScope(callback, null, err || null, { opaque, trailers }) -"use strict"; + if (err) { + abort() + } + }) + } + res.on('drain', resume) -const { kConstruct } = __nccwpck_require__(9174) -const { Cache } = __nccwpck_require__(6101) -const { webidl } = __nccwpck_require__(1744) -const { kEnumerableProperty } = __nccwpck_require__(3983) + this.res = res -class CacheStorage { - /** - * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map - * @type {Map} - */ - async has (cacheName) { - webidl.brandCheck(this, CacheStorage) - webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.has' }) - cacheName = webidl.converters.DOMString(cacheName) + this.trailers = util.parseHeaders(trailers) - // 2.1.1 - // 2.2 - return this.#caches.has(cacheName) + res.end() } - /** - * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open - * @param {string} cacheName - * @returns {Promise} - */ - async open (cacheName) { - webidl.brandCheck(this, CacheStorage) - webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.open' }) - - cacheName = webidl.converters.DOMString(cacheName) + onError (err) { + const { res, callback, opaque, body } = this - // 2.1 - if (this.#caches.has(cacheName)) { - // await caches.open('v1') !== await caches.open('v1') + removeSignal(this) - // 2.1.1 - const cache = this.#caches.get(cacheName) + this.factory = null - // 2.1.1.1 - return new Cache(kConstruct, cache) + if (res) { + this.res = null + util.destroy(res, err) + } else if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) } - // 2.2 - const cache = [] - - // 2.3 - this.#caches.set(cacheName, cache) - - // 2.4 - return new Cache(kConstruct, cache) + if (body) { + this.body = null + util.destroy(body, err) + } } +} - /** - * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete - * @param {string} cacheName - * @returns {Promise} - */ - async delete (cacheName) { - webidl.brandCheck(this, CacheStorage) - webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.delete' }) - - cacheName = webidl.converters.DOMString(cacheName) - - return this.#caches.delete(cacheName) +function stream (opts, factory, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + stream.call(this, opts, factory, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) } - /** - * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys - * @returns {string[]} - */ - async keys () { - webidl.brandCheck(this, CacheStorage) - - // 2.1 - const keys = this.#caches.keys() - - // 2.2 - return [...keys] + try { + this.dispatch(opts, new StreamHandler(opts, factory, callback)) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) } } -Object.defineProperties(CacheStorage.prototype, { - [Symbol.toStringTag]: { - value: 'CacheStorage', - configurable: true - }, - match: kEnumerableProperty, - has: kEnumerableProperty, - open: kEnumerableProperty, - delete: kEnumerableProperty, - keys: kEnumerableProperty -}) - -module.exports = { - CacheStorage -} +module.exports = stream /***/ }), -/***/ 9174: +/***/ 6923: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = { - kConstruct: (__nccwpck_require__(2785).kConstruct) -} +const { InvalidArgumentError, RequestAbortedError, SocketError } = __nccwpck_require__(8045) +const { AsyncResource } = __nccwpck_require__(852) +const util = __nccwpck_require__(3983) +const { addSignal, removeSignal } = __nccwpck_require__(7032) +const assert = __nccwpck_require__(9491) +class UpgradeHandler extends AsyncResource { + constructor (opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } -/***/ }), + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } -/***/ 2396: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const { signal, opaque, responseHeaders } = opts -"use strict"; + if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') { + throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget') + } + super('UNDICI_UPGRADE') -const assert = __nccwpck_require__(9491) -const { URLSerializer } = __nccwpck_require__(685) -const { isValidHeaderName } = __nccwpck_require__(2538) + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.abort = null + this.context = null -/** - * @see https://url.spec.whatwg.org/#concept-url-equals - * @param {URL} A - * @param {URL} B - * @param {boolean | undefined} excludeFragment - * @returns {boolean} - */ -function urlEquals (A, B, excludeFragment = false) { - const serializedA = URLSerializer(A, excludeFragment) + addSignal(this, signal) + } - const serializedB = URLSerializer(B, excludeFragment) + onConnect (abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } - return serializedA === serializedB -} + this.abort = abort + this.context = null + } -/** - * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 - * @param {string} header - */ -function fieldValues (header) { - assert(header !== null) + onHeaders () { + throw new SocketError('bad upgrade', null) + } - const values = [] + onUpgrade (statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this - for (let value of header.split(',')) { - value = value.trim() + assert.strictEqual(statusCode, 101) - if (!value.length) { - continue - } else if (!isValidHeaderName(value)) { - continue - } + removeSignal(this) - values.push(value) + this.callback = null + const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + this.runInAsyncScope(callback, null, null, { + headers, + socket, + opaque, + context + }) } - return values + onError (err) { + const { callback, opaque } = this + + removeSignal(this) + + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } } -module.exports = { - urlEquals, - fieldValues +function upgrade (opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + upgrade.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const upgradeHandler = new UpgradeHandler(opts, callback) + this.dispatch({ + ...opts, + method: opts.method || 'GET', + upgrade: opts.protocol || 'Websocket' + }, upgradeHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } } +module.exports = upgrade + /***/ }), -/***/ 3598: +/***/ 4059: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// @ts-check +module.exports.request = __nccwpck_require__(5448) +module.exports.stream = __nccwpck_require__(5395) +module.exports.pipeline = __nccwpck_require__(8752) +module.exports.upgrade = __nccwpck_require__(6923) +module.exports.connect = __nccwpck_require__(9744) + + +/***/ }), + +/***/ 3858: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; +// Ported from https://github.com/nodejs/undici/pull/907 + -/* global WebAssembly */ const assert = __nccwpck_require__(9491) -const net = __nccwpck_require__(1808) -const http = __nccwpck_require__(3685) -const { pipeline } = __nccwpck_require__(2781) +const { Readable } = __nccwpck_require__(2781) +const { RequestAbortedError, NotSupportedError, InvalidArgumentError } = __nccwpck_require__(8045) const util = __nccwpck_require__(3983) -const timers = __nccwpck_require__(9459) -const Request = __nccwpck_require__(2905) -const DispatcherBase = __nccwpck_require__(4839) -const { - RequestContentLengthMismatchError, - ResponseContentLengthMismatchError, - InvalidArgumentError, - RequestAbortedError, - HeadersTimeoutError, - HeadersOverflowError, - SocketError, - InformationalError, - BodyTimeoutError, - HTTPParserError, - ResponseExceededMaxSizeError, - ClientDestroyedError -} = __nccwpck_require__(8045) -const buildConnector = __nccwpck_require__(2067) -const { - kUrl, - kReset, - kServerName, - kClient, - kBusy, - kParser, - kConnect, - kBlocking, - kResuming, - kRunning, - kPending, - kSize, - kWriting, - kQueue, - kConnected, - kConnecting, - kNeedDrain, - kNoRef, - kKeepAliveDefaultTimeout, - kHostHeader, - kPendingIdx, - kRunningIdx, - kError, - kPipelining, - kSocket, - kKeepAliveTimeoutValue, - kMaxHeadersSize, - kKeepAliveMaxTimeout, - kKeepAliveTimeoutThreshold, - kHeadersTimeout, - kBodyTimeout, - kStrictContentLength, - kConnector, - kMaxRedirections, - kMaxRequests, - kCounter, - kClose, - kDestroy, - kDispatch, - kInterceptors, - kLocalAddress, - kMaxResponseSize, - kHTTPConnVersion, - // HTTP2 - kHost, - kHTTP2Session, - kHTTP2SessionState, - kHTTP2BuildRequest, - kHTTP2CopyHeaders, - kHTTP1BuildRequest -} = __nccwpck_require__(2785) +const { ReadableStreamFrom, toUSVString } = __nccwpck_require__(3983) -/** @type {import('http2')} */ -let http2 -try { - http2 = __nccwpck_require__(5158) -} catch { - // @ts-ignore - http2 = { constants: {} } -} +let Blob -const { - constants: { - HTTP2_HEADER_AUTHORITY, - HTTP2_HEADER_METHOD, - HTTP2_HEADER_PATH, - HTTP2_HEADER_SCHEME, - HTTP2_HEADER_CONTENT_LENGTH, - HTTP2_HEADER_EXPECT, - HTTP2_HEADER_STATUS - } -} = http2 +const kConsume = Symbol('kConsume') +const kReading = Symbol('kReading') +const kBody = Symbol('kBody') +const kAbort = Symbol('abort') +const kContentType = Symbol('kContentType') -// Experimental -let h2ExperimentalWarned = false +const noop = () => {} -const FastBuffer = Buffer[Symbol.species] +module.exports = class BodyReadable extends Readable { + constructor ({ + resume, + abort, + contentType = '', + highWaterMark = 64 * 1024 // Same as nodejs fs streams. + }) { + super({ + autoDestroy: true, + read: resume, + highWaterMark + }) -const kClosedResolve = Symbol('kClosedResolve') + this._readableState.dataEmitted = false -const channels = {} + this[kAbort] = abort + this[kConsume] = null + this[kBody] = null + this[kContentType] = contentType -try { - const diagnosticsChannel = __nccwpck_require__(7643) - channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders') - channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect') - channels.connectError = diagnosticsChannel.channel('undici:client:connectError') - channels.connected = diagnosticsChannel.channel('undici:client:connected') -} catch { - channels.sendHeaders = { hasSubscribers: false } - channels.beforeConnect = { hasSubscribers: false } - channels.connectError = { hasSubscribers: false } - channels.connected = { hasSubscribers: false } -} - -/** - * @type {import('../types/client').default} - */ -class Client extends DispatcherBase { - /** - * - * @param {string|URL} url - * @param {import('../types/client').Client.Options} options - */ - constructor (url, { - interceptors, - maxHeaderSize, - headersTimeout, - socketTimeout, - requestTimeout, - connectTimeout, - bodyTimeout, - idleTimeout, - keepAlive, - keepAliveTimeout, - maxKeepAliveTimeout, - keepAliveMaxTimeout, - keepAliveTimeoutThreshold, - socketPath, - pipelining, - tls, - strictContentLength, - maxCachedSessions, - maxRedirections, - connect, - maxRequestsPerClient, - localAddress, - maxResponseSize, - autoSelectFamily, - autoSelectFamilyAttemptTimeout, - // h2 - allowH2, - maxConcurrentStreams - } = {}) { - super() + // Is stream being consumed through Readable API? + // This is an optimization so that we avoid checking + // for 'data' and 'readable' listeners in the hot path + // inside push(). + this[kReading] = false + } - if (keepAlive !== undefined) { - throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') + destroy (err) { + if (this.destroyed) { + // Node < 16 + return this } - if (socketTimeout !== undefined) { - throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() } - if (requestTimeout !== undefined) { - throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') + if (err) { + this[kAbort]() } - if (idleTimeout !== undefined) { - throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') - } + return super.destroy(err) + } - if (maxKeepAliveTimeout !== undefined) { - throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') + emit (ev, ...args) { + if (ev === 'data') { + // Node < 16.7 + this._readableState.dataEmitted = true + } else if (ev === 'error') { + // Node < 16 + this._readableState.errorEmitted = true } + return super.emit(ev, ...args) + } - if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { - throw new InvalidArgumentError('invalid maxHeaderSize') + on (ev, ...args) { + if (ev === 'data' || ev === 'readable') { + this[kReading] = true } + return super.on(ev, ...args) + } - if (socketPath != null && typeof socketPath !== 'string') { - throw new InvalidArgumentError('invalid socketPath') - } + addListener (ev, ...args) { + return this.on(ev, ...args) + } - if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { - throw new InvalidArgumentError('invalid connectTimeout') + off (ev, ...args) { + const ret = super.off(ev, ...args) + if (ev === 'data' || ev === 'readable') { + this[kReading] = ( + this.listenerCount('data') > 0 || + this.listenerCount('readable') > 0 + ) } + return ret + } - if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { - throw new InvalidArgumentError('invalid keepAliveTimeout') - } + removeListener (ev, ...args) { + return this.off(ev, ...args) + } - if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { - throw new InvalidArgumentError('invalid keepAliveMaxTimeout') + push (chunk) { + if (this[kConsume] && chunk !== null && this.readableLength === 0) { + consumePush(this[kConsume], chunk) + return this[kReading] ? super.push(chunk) : true } + return super.push(chunk) + } - if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { - throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') - } + // https://fetch.spec.whatwg.org/#dom-body-text + async text () { + return consume(this, 'text') + } - if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { - throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') - } + // https://fetch.spec.whatwg.org/#dom-body-json + async json () { + return consume(this, 'json') + } - if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { - throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') - } + // https://fetch.spec.whatwg.org/#dom-body-blob + async blob () { + return consume(this, 'blob') + } - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') - } + // https://fetch.spec.whatwg.org/#dom-body-arraybuffer + async arrayBuffer () { + return consume(this, 'arrayBuffer') + } - if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { - throw new InvalidArgumentError('maxRedirections must be a positive number') - } + // https://fetch.spec.whatwg.org/#dom-body-formdata + async formData () { + // TODO: Implement. + throw new NotSupportedError() + } - if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { - throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') - } + // https://fetch.spec.whatwg.org/#dom-body-bodyused + get bodyUsed () { + return util.isDisturbed(this) + } - if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { - throw new InvalidArgumentError('localAddress must be valid string IP address') + // https://fetch.spec.whatwg.org/#dom-body-body + get body () { + if (!this[kBody]) { + this[kBody] = ReadableStreamFrom(this) + if (this[kConsume]) { + // TODO: Is this the best way to force a lock? + this[kBody].getReader() // Ensure stream is locked. + assert(this[kBody].locked) + } } + return this[kBody] + } - if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { - throw new InvalidArgumentError('maxResponseSize must be a positive number') - } + dump (opts) { + let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 + const signal = opts && opts.signal - if ( - autoSelectFamilyAttemptTimeout != null && - (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) - ) { - throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') + if (signal) { + try { + if (typeof signal !== 'object' || !('aborted' in signal)) { + throw new InvalidArgumentError('signal must be an AbortSignal') + } + util.throwIfAborted(signal) + } catch (err) { + return Promise.reject(err) + } } - // h2 - if (allowH2 != null && typeof allowH2 !== 'boolean') { - throw new InvalidArgumentError('allowH2 must be a valid boolean value') + if (this.closed) { + return Promise.resolve(null) } - if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { - throw new InvalidArgumentError('maxConcurrentStreams must be a possitive integer, greater than 0') - } + return new Promise((resolve, reject) => { + const signalListenerCleanup = signal + ? util.addAbortListener(signal, () => { + this.destroy() + }) + : noop - if (typeof connect !== 'function') { - connect = buildConnector({ - ...tls, - maxCachedSessions, - allowH2, - socketPath, - timeout: connectTimeout, - ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), - ...connect - }) - } + this + .on('close', function () { + signalListenerCleanup() + if (signal && signal.aborted) { + reject(signal.reason || Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) + } else { + resolve(null) + } + }) + .on('error', noop) + .on('data', function (chunk) { + limit -= chunk.length + if (limit <= 0) { + this.destroy() + } + }) + .resume() + }) + } +} - this[kInterceptors] = interceptors && interceptors.Client && Array.isArray(interceptors.Client) - ? interceptors.Client - : [createRedirectInterceptor({ maxRedirections })] - this[kUrl] = util.parseOrigin(url) - this[kConnector] = connect - this[kSocket] = null - this[kPipelining] = pipelining != null ? pipelining : 1 - this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize - this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout - this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout - this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold - this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout] - this[kServerName] = null - this[kLocalAddress] = localAddress != null ? localAddress : null - this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming - this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming - this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n` - this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3 - this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3 - this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength - this[kMaxRedirections] = maxRedirections - this[kMaxRequests] = maxRequestsPerClient - this[kClosedResolve] = null - this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 - this[kHTTPConnVersion] = 'h1' - - // HTTP/2 - this[kHTTP2Session] = null - this[kHTTP2SessionState] = !allowH2 - ? null - : { - // streams: null, // Fixed queue of streams - For future support of `push` - openStreams: 0, // Keep track of them to decide wether or not unref the session - maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server - } - this[kHost] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}` +// https://streams.spec.whatwg.org/#readablestream-locked +function isLocked (self) { + // Consume is an implicit lock. + return (self[kBody] && self[kBody].locked === true) || self[kConsume] +} - // kQueue is built up of 3 sections separated by - // the kRunningIdx and kPendingIdx indices. - // | complete | running | pending | - // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length - // kRunningIdx points to the first running element. - // kPendingIdx points to the first pending element. - // This implements a fast queue with an amortized - // time of O(1). +// https://fetch.spec.whatwg.org/#body-unusable +function isUnusable (self) { + return util.isDisturbed(self) || isLocked(self) +} - this[kQueue] = [] - this[kRunningIdx] = 0 - this[kPendingIdx] = 0 +async function consume (stream, type) { + if (isUnusable(stream)) { + throw new TypeError('unusable') } - get pipelining () { - return this[kPipelining] - } + assert(!stream[kConsume]) - set pipelining (value) { - this[kPipelining] = value - resume(this, true) - } + return new Promise((resolve, reject) => { + stream[kConsume] = { + type, + stream, + resolve, + reject, + length: 0, + body: [] + } - get [kPending] () { - return this[kQueue].length - this[kPendingIdx] - } + stream + .on('error', function (err) { + consumeFinish(this[kConsume], err) + }) + .on('close', function () { + if (this[kConsume].body !== null) { + consumeFinish(this[kConsume], new RequestAbortedError()) + } + }) - get [kRunning] () { - return this[kPendingIdx] - this[kRunningIdx] - } + process.nextTick(consumeStart, stream[kConsume]) + }) +} - get [kSize] () { - return this[kQueue].length - this[kRunningIdx] +function consumeStart (consume) { + if (consume.body === null) { + return } - get [kConnected] () { - return !!this[kSocket] && !this[kConnecting] && !this[kSocket].destroyed - } + const { _readableState: state } = consume.stream - get [kBusy] () { - const socket = this[kSocket] - return ( - (socket && (socket[kReset] || socket[kWriting] || socket[kBlocking])) || - (this[kSize] >= (this[kPipelining] || 1)) || - this[kPending] > 0 - ) + for (const chunk of state.buffer) { + consumePush(consume, chunk) } - /* istanbul ignore: only used for test */ - [kConnect] (cb) { - connect(this) - this.once('connect', cb) + if (state.endEmitted) { + consumeEnd(this[kConsume]) + } else { + consume.stream.on('end', function () { + consumeEnd(this[kConsume]) + }) } - [kDispatch] (opts, handler) { - const origin = opts.origin || this[kUrl].origin - - const request = this[kHTTPConnVersion] === 'h2' - ? Request[kHTTP2BuildRequest](origin, opts, handler) - : Request[kHTTP1BuildRequest](origin, opts, handler) - - this[kQueue].push(request) - if (this[kResuming]) { - // Do nothing. - } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { - // Wait a tick in case stream/iterator is ended in the same tick. - this[kResuming] = 1 - process.nextTick(resume, this) - } else { - resume(this, true) - } - - if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { - this[kNeedDrain] = 2 - } - - return this[kNeedDrain] < 2 - } + consume.stream.resume() - async [kClose] () { - // TODO: for H2 we need to gracefully flush the remaining enqueued - // request and close each stream. - return new Promise((resolve) => { - if (!this[kSize]) { - resolve(null) - } else { - this[kClosedResolve] = resolve - } - }) + while (consume.stream.read() != null) { + // Loop } +} - async [kDestroy] (err) { - return new Promise((resolve) => { - const requests = this[kQueue].splice(this[kPendingIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - errorRequest(this, request, err) - } +function consumeEnd (consume) { + const { type, body, resolve, stream, length } = consume - const callback = () => { - if (this[kClosedResolve]) { - // TODO (fix): Should we error here with ClientDestroyedError? - this[kClosedResolve]() - this[kClosedResolve] = null - } - resolve() - } + try { + if (type === 'text') { + resolve(toUSVString(Buffer.concat(body))) + } else if (type === 'json') { + resolve(JSON.parse(Buffer.concat(body))) + } else if (type === 'arrayBuffer') { + const dst = new Uint8Array(length) - if (this[kHTTP2Session] != null) { - util.destroy(this[kHTTP2Session], err) - this[kHTTP2Session] = null - this[kHTTP2SessionState] = null + let pos = 0 + for (const buf of body) { + dst.set(buf, pos) + pos += buf.byteLength } - if (!this[kSocket]) { - queueMicrotask(callback) - } else { - util.destroy(this[kSocket].on('close', callback), err) + resolve(dst.buffer) + } else if (type === 'blob') { + if (!Blob) { + Blob = (__nccwpck_require__(4300).Blob) } + resolve(new Blob(body, { type: stream[kContentType] })) + } - resume(this) - }) + consumeFinish(consume) + } catch (err) { + stream.destroy(err) } } -function onHttp2SessionError (err) { - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') - - this[kSocket][kError] = err - - onError(this[kClient], err) +function consumePush (consume, chunk) { + consume.length += chunk.length + consume.body.push(chunk) } -function onHttp2FrameError (type, code, id) { - const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) +function consumeFinish (consume, err) { + if (consume.body === null) { + return + } - if (id === 0) { - this[kSocket][kError] = err - onError(this[kClient], err) + if (err) { + consume.reject(err) + } else { + consume.resolve() } -} -function onHttp2SessionEnd () { - util.destroy(this, new SocketError('other side closed')) - util.destroy(this[kSocket], new SocketError('other side closed')) + consume.type = null + consume.stream = null + consume.resolve = null + consume.reject = null + consume.length = 0 + consume.body = null } -function onHTTP2GoAway (code) { - const client = this[kClient] - const err = new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${code}`) - client[kSocket] = null - client[kHTTP2Session] = null - - if (client.destroyed) { - assert(this[kPending] === 0) - - // Fail entire queue. - const requests = client[kQueue].splice(client[kRunningIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - errorRequest(this, request, err) - } - } else if (client[kRunning] > 0) { - // Fail head of pipeline. - const request = client[kQueue][client[kRunningIdx]] - client[kQueue][client[kRunningIdx]++] = null - errorRequest(client, request, err) - } +/***/ }), - client[kPendingIdx] = client[kRunningIdx] +/***/ 7474: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - assert(client[kRunning] === 0) +const assert = __nccwpck_require__(9491) +const { + ResponseStatusCodeError +} = __nccwpck_require__(8045) +const { toUSVString } = __nccwpck_require__(3983) - client.emit('disconnect', - client[kUrl], - [client], - err - ) +async function getResolveErrorBodyCallback ({ callback, body, contentType, statusCode, statusMessage, headers }) { + assert(body) - resume(client) -} + let chunks = [] + let limit = 0 -const constants = __nccwpck_require__(953) -const createRedirectInterceptor = __nccwpck_require__(8861) -const EMPTY_BUF = Buffer.alloc(0) + for await (const chunk of body) { + chunks.push(chunk) + limit += chunk.length + if (limit > 128 * 1024) { + chunks = null + break + } + } -async function lazyllhttp () { - const llhttpWasmData = process.env.JEST_WORKER_ID ? __nccwpck_require__(1145) : undefined + if (statusCode === 204 || !contentType || !chunks) { + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) + return + } - let mod try { - mod = await WebAssembly.compile(Buffer.from(__nccwpck_require__(5627), 'base64')) - } catch (e) { - /* istanbul ignore next */ + if (contentType.startsWith('application/json')) { + const payload = JSON.parse(toUSVString(Buffer.concat(chunks))) + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) + return + } - // We could check if the error was caused by the simd option not - // being enabled, but the occurring of this other error - // * https://github.com/emscripten-core/emscripten/issues/11495 - // got me to remove that check to avoid breaking Node 12. - mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || __nccwpck_require__(1145), 'base64')) + if (contentType.startsWith('text/')) { + const payload = toUSVString(Buffer.concat(chunks)) + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers, payload)) + return + } + } catch (err) { + // Process in a fallback if error } - return await WebAssembly.instantiate(mod, { - env: { - /* eslint-disable camelcase */ + process.nextTick(callback, new ResponseStatusCodeError(`Response status code ${statusCode}${statusMessage ? `: ${statusMessage}` : ''}`, statusCode, headers)) +} - wasm_on_url: (p, at, len) => { - /* istanbul ignore next */ - return 0 - }, - wasm_on_status: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_message_begin: (p) => { - assert.strictEqual(currentParser.ptr, p) - return currentParser.onMessageBegin() || 0 - }, - wasm_on_header_field: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_header_value: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { - assert.strictEqual(currentParser.ptr, p) - return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0 - }, - wasm_on_body: (p, at, len) => { - assert.strictEqual(currentParser.ptr, p) - const start = at - currentBufferPtr + currentBufferRef.byteOffset - return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 - }, - wasm_on_message_complete: (p) => { - assert.strictEqual(currentParser.ptr, p) - return currentParser.onMessageComplete() || 0 - } +module.exports = { getResolveErrorBodyCallback } - /* eslint-enable camelcase */ - } - }) -} -let llhttpInstance = null -let llhttpPromise = lazyllhttp() -llhttpPromise.catch() +/***/ }), -let currentParser = null -let currentBufferRef = null -let currentBufferSize = 0 -let currentBufferPtr = null +/***/ 7931: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const TIMEOUT_HEADERS = 1 -const TIMEOUT_BODY = 2 -const TIMEOUT_IDLE = 3 +"use strict"; -class Parser { - constructor (client, socket, { exports }) { - assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0) - this.llhttp = exports - this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE) - this.client = client - this.socket = socket - this.timeout = null - this.timeoutValue = null - this.timeoutType = null - this.statusCode = null - this.statusText = '' - this.upgrade = false - this.headers = [] - this.headersSize = 0 - this.headersMaxSize = client[kMaxHeadersSize] - this.shouldKeepAlive = false - this.paused = false - this.resume = this.resume.bind(this) +const { + BalancedPoolMissingUpstreamError, + InvalidArgumentError +} = __nccwpck_require__(8045) +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher +} = __nccwpck_require__(3198) +const Pool = __nccwpck_require__(4634) +const { kUrl, kInterceptors } = __nccwpck_require__(2785) +const { parseOrigin } = __nccwpck_require__(3983) +const kFactory = Symbol('factory') - this.bytesRead = 0 +const kOptions = Symbol('options') +const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor') +const kCurrentWeight = Symbol('kCurrentWeight') +const kIndex = Symbol('kIndex') +const kWeight = Symbol('kWeight') +const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') +const kErrorPenalty = Symbol('kErrorPenalty') - this.keepAlive = '' - this.contentLength = '' - this.connection = '' - this.maxResponseSize = client[kMaxResponseSize] - } +function getGreatestCommonDivisor (a, b) { + if (b === 0) return a + return getGreatestCommonDivisor(b, a % b) +} - setTimeout (value, type) { - this.timeoutType = type - if (value !== this.timeoutValue) { - timers.clearTimeout(this.timeout) - if (value) { - this.timeout = timers.setTimeout(onParserTimeout, value, this) - // istanbul ignore else: only for jest - if (this.timeout.unref) { - this.timeout.unref() - } - } else { - this.timeout = null - } - this.timeoutValue = value - } else if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } - } - } +function defaultFactory (origin, opts) { + return new Pool(origin, opts) +} - resume () { - if (this.socket.destroyed || !this.paused) { - return - } +class BalancedPool extends PoolBase { + constructor (upstreams = [], { factory = defaultFactory, ...opts } = {}) { + super() - assert(this.ptr != null) - assert(currentParser == null) + this[kOptions] = opts + this[kIndex] = -1 + this[kCurrentWeight] = 0 - this.llhttp.llhttp_resume(this.ptr) + this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100 + this[kErrorPenalty] = this[kOptions].errorPenalty || 15 - assert(this.timeoutType === TIMEOUT_BODY) - if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } + if (!Array.isArray(upstreams)) { + upstreams = [upstreams] } - this.paused = false - this.execute(this.socket.read() || EMPTY_BUF) // Flush parser. - this.readMore() - } + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } - readMore () { - while (!this.paused && this.ptr) { - const chunk = this.socket.read() - if (chunk === null) { - break - } - this.execute(chunk) + this[kInterceptors] = opts.interceptors && opts.interceptors.BalancedPool && Array.isArray(opts.interceptors.BalancedPool) + ? opts.interceptors.BalancedPool + : [] + this[kFactory] = factory + + for (const upstream of upstreams) { + this.addUpstream(upstream) } + this._updateBalancedPoolStats() } - execute (data) { - assert(this.ptr != null) - assert(currentParser == null) - assert(!this.paused) - - const { socket, llhttp } = this + addUpstream (upstream) { + const upstreamOrigin = parseOrigin(upstream).origin - if (data.length > currentBufferSize) { - if (currentBufferPtr) { - llhttp.free(currentBufferPtr) - } - currentBufferSize = Math.ceil(data.length / 4096) * 4096 - currentBufferPtr = llhttp.malloc(currentBufferSize) + if (this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + ))) { + return this } + const pool = this[kFactory](upstreamOrigin, Object.assign({}, this[kOptions])) - new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data) + this[kAddClient](pool) + pool.on('connect', () => { + pool[kWeight] = Math.min(this[kMaxWeightPerServer], pool[kWeight] + this[kErrorPenalty]) + }) - // Call `execute` on the wasm parser. - // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, - // and finally the length of bytes to parse. - // The return value is an error code or `constants.ERROR.OK`. - try { - let ret + pool.on('connectionError', () => { + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() + }) - try { - currentBufferRef = data - currentParser = this - ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length) - /* eslint-disable-next-line no-useless-catch */ - } catch (err) { - /* istanbul ignore next: difficult to make a test case for */ - throw err - } finally { - currentParser = null - currentBufferRef = null + pool.on('disconnect', (...args) => { + const err = args[2] + if (err && err.code === 'UND_ERR_SOCKET') { + // decrease the weight of the pool. + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() } + }) - const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr - - if (ret === constants.ERROR.PAUSED_UPGRADE) { - this.onUpgrade(data.slice(offset)) - } else if (ret === constants.ERROR.PAUSED) { - this.paused = true - socket.unshift(data.slice(offset)) - } else if (ret !== constants.ERROR.OK) { - const ptr = llhttp.llhttp_get_error_reason(this.ptr) - let message = '' - /* istanbul ignore else: difficult to make a test case for */ - if (ptr) { - const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0) - message = - 'Response does not match the HTTP/1.1 protocol (' + - Buffer.from(llhttp.memory.buffer, ptr, len).toString() + - ')' - } - throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset)) - } - } catch (err) { - util.destroy(socket, err) + for (const client of this[kClients]) { + client[kWeight] = this[kMaxWeightPerServer] } + + this._updateBalancedPoolStats() + + return this } - destroy () { - assert(this.ptr != null) - assert(currentParser == null) + _updateBalancedPoolStats () { + this[kGreatestCommonDivisor] = this[kClients].map(p => p[kWeight]).reduce(getGreatestCommonDivisor, 0) + } - this.llhttp.llhttp_free(this.ptr) - this.ptr = null + removeUpstream (upstream) { + const upstreamOrigin = parseOrigin(upstream).origin - timers.clearTimeout(this.timeout) - this.timeout = null - this.timeoutValue = null - this.timeoutType = null + const pool = this[kClients].find((pool) => ( + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + )) - this.paused = false - } + if (pool) { + this[kRemoveClient](pool) + } - onStatus (buf) { - this.statusText = buf.toString() + return this } - onMessageBegin () { - const { socket, client } = this + get upstreams () { + return this[kClients] + .filter(dispatcher => dispatcher.closed !== true && dispatcher.destroyed !== true) + .map((p) => p[kUrl].origin) + } - /* istanbul ignore next: difficult to make a test case for */ - if (socket.destroyed) { - return -1 + [kGetDispatcher] () { + // We validate that pools is greater than 0, + // otherwise we would have to wait until an upstream + // is added, which might never happen. + if (this[kClients].length === 0) { + throw new BalancedPoolMissingUpstreamError() } - const request = client[kQueue][client[kRunningIdx]] - if (!request) { - return -1 + const dispatcher = this[kClients].find(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )) + + if (!dispatcher) { + return } - } - onHeaderField (buf) { - const len = this.headers.length + const allClientsBusy = this[kClients].map(pool => pool[kNeedDrain]).reduce((a, b) => a && b, true) - if ((len & 1) === 0) { - this.headers.push(buf) - } else { - this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + if (allClientsBusy) { + return } - this.trackHeader(buf.length) - } + let counter = 0 - onHeaderValue (buf) { - let len = this.headers.length + let maxWeightIndex = this[kClients].findIndex(pool => !pool[kNeedDrain]) - if ((len & 1) === 1) { - this.headers.push(buf) - len += 1 - } else { - this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) - } + while (counter++ < this[kClients].length) { + this[kIndex] = (this[kIndex] + 1) % this[kClients].length + const pool = this[kClients][this[kIndex]] - const key = this.headers[len - 2] - if (key.length === 10 && key.toString().toLowerCase() === 'keep-alive') { - this.keepAlive += buf.toString() - } else if (key.length === 10 && key.toString().toLowerCase() === 'connection') { - this.connection += buf.toString() - } else if (key.length === 14 && key.toString().toLowerCase() === 'content-length') { - this.contentLength += buf.toString() - } + // find pool index with the largest weight + if (pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && !pool[kNeedDrain]) { + maxWeightIndex = this[kIndex] + } - this.trackHeader(buf.length) - } + // decrease the current weight every `this[kClients].length`. + if (this[kIndex] === 0) { + // Set the current weight to the next lower weight. + this[kCurrentWeight] = this[kCurrentWeight] - this[kGreatestCommonDivisor] - trackHeader (len) { - this.headersSize += len - if (this.headersSize >= this.headersMaxSize) { - util.destroy(this.socket, new HeadersOverflowError()) + if (this[kCurrentWeight] <= 0) { + this[kCurrentWeight] = this[kMaxWeightPerServer] + } + } + if (pool[kWeight] >= this[kCurrentWeight] && (!pool[kNeedDrain])) { + return pool + } } + + this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight] + this[kIndex] = maxWeightIndex + return this[kClients][maxWeightIndex] } +} - onUpgrade (head) { - const { upgrade, client, socket, headers, statusCode } = this +module.exports = BalancedPool - assert(upgrade) - const request = client[kQueue][client[kRunningIdx]] - assert(request) +/***/ }), - assert(!socket.destroyed) - assert(socket === client[kSocket]) - assert(!this.paused) - assert(request.upgrade || request.method === 'CONNECT') +/***/ 6101: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - this.statusCode = null - this.statusText = '' - this.shouldKeepAlive = null +"use strict"; - assert(this.headers.length % 2 === 0) - this.headers = [] - this.headersSize = 0 - socket.unshift(head) +const { kConstruct } = __nccwpck_require__(9174) +const { urlEquals, fieldValues: getFieldValues } = __nccwpck_require__(2396) +const { kEnumerableProperty, isDisturbed } = __nccwpck_require__(3983) +const { kHeadersList } = __nccwpck_require__(2785) +const { webidl } = __nccwpck_require__(1744) +const { Response, cloneResponse } = __nccwpck_require__(7823) +const { Request } = __nccwpck_require__(8359) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const { fetching } = __nccwpck_require__(4881) +const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = __nccwpck_require__(2538) +const assert = __nccwpck_require__(9491) +const { getGlobalDispatcher } = __nccwpck_require__(1892) - socket[kParser].destroy() - socket[kParser] = null +/** + * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation + * @typedef {Object} CacheBatchOperation + * @property {'delete' | 'put'} type + * @property {any} request + * @property {any} response + * @property {import('../../types/cache').CacheQueryOptions} options + */ - socket[kClient] = null - socket[kError] = null - socket - .removeListener('error', onSocketError) - .removeListener('readable', onSocketReadable) - .removeListener('end', onSocketEnd) - .removeListener('close', onSocketClose) +/** + * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list + * @typedef {[any, any][]} requestResponseList + */ - client[kSocket] = null - client[kQueue][client[kRunningIdx]++] = null - client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) +class Cache { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list + * @type {requestResponseList} + */ + #relevantRequestResponseList - try { - request.onUpgrade(statusCode, headers, socket) - } catch (err) { - util.destroy(socket, err) + constructor () { + if (arguments[0] !== kConstruct) { + webidl.illegalConstructor() } - resume(client) + this.#relevantRequestResponseList = arguments[1] } - onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { - const { client, socket, headers, statusText } = this - - /* istanbul ignore next: difficult to make a test case for */ - if (socket.destroyed) { - return -1 - } + async match (request, options = {}) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.match' }) - const request = client[kQueue][client[kRunningIdx]] - - /* istanbul ignore next: difficult to make a test case for */ - if (!request) { - return -1 - } + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - assert(!this.upgrade) - assert(this.statusCode < 200) + const p = await this.matchAll(request, options) - if (statusCode === 100) { - util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) - return -1 + if (p.length === 0) { + return } - /* this can only happen if server is misbehaving */ - if (upgrade && !request.upgrade) { - util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))) - return -1 - } + return p[0] + } - assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS) + async matchAll (request = undefined, options = {}) { + webidl.brandCheck(this, Cache) - this.statusCode = statusCode - this.shouldKeepAlive = ( - shouldKeepAlive || - // Override llhttp value which does not allow keepAlive for HEAD. - (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive') - ) + if (request !== undefined) request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - if (this.statusCode >= 200) { - const bodyTimeout = request.bodyTimeout != null - ? request.bodyTimeout - : client[kBodyTimeout] - this.setTimeout(bodyTimeout, TIMEOUT_BODY) - } else if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } - } + // 1. + let r = null - if (request.method === 'CONNECT') { - assert(client[kRunning] === 1) - this.upgrade = true - return 2 - } + // 2. + if (request !== undefined) { + if (request instanceof Request) { + // 2.1.1 + r = request[kState] - if (upgrade) { - assert(client[kRunning] === 1) - this.upgrade = true - return 2 + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { + // 2.2.1 + r = new Request(request)[kState] + } } - assert(this.headers.length % 2 === 0) - this.headers = [] - this.headersSize = 0 + // 5. + // 5.1 + const responses = [] - if (this.shouldKeepAlive && client[kPipelining]) { - const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + responses.push(requestResponse[1]) + } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) - if (keepAliveTimeout != null) { - const timeout = Math.min( - keepAliveTimeout - client[kKeepAliveTimeoutThreshold], - client[kKeepAliveMaxTimeout] - ) - if (timeout <= 0) { - socket[kReset] = true - } else { - client[kKeepAliveTimeoutValue] = timeout - } - } else { - client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] + // 5.3.2 + for (const requestResponse of requestResponses) { + responses.push(requestResponse[1]) } - } else { - // Stop more requests from being dispatched. - socket[kReset] = true } - const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false - - if (request.aborted) { - return -1 - } + // 5.4 + // We don't implement CORs so we don't need to loop over the responses, yay! - if (request.method === 'HEAD') { - return 1 - } + // 5.5.1 + const responseList = [] - if (statusCode < 200) { - return 1 - } + // 5.5.2 + for (const response of responses) { + // 5.5.2.1 + const responseObject = new Response(response.body?.source ?? null) + const body = responseObject[kState].body + responseObject[kState] = response + responseObject[kState].body = body + responseObject[kHeaders][kHeadersList] = response.headersList + responseObject[kHeaders][kGuard] = 'immutable' - if (socket[kBlocking]) { - socket[kBlocking] = false - resume(client) + responseList.push(responseObject) } - return pause ? constants.ERROR.PAUSED : 0 + // 6. + return Object.freeze(responseList) } - onBody (buf) { - const { client, socket, statusCode, maxResponseSize } = this + async add (request) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.add' }) - if (socket.destroyed) { - return -1 - } + request = webidl.converters.RequestInfo(request) - const request = client[kQueue][client[kRunningIdx]] - assert(request) + // 1. + const requests = [request] - assert.strictEqual(this.timeoutType, TIMEOUT_BODY) - if (this.timeout) { - // istanbul ignore else: only for jest - if (this.timeout.refresh) { - this.timeout.refresh() - } - } + // 2. + const responseArrayPromise = this.addAll(requests) - assert(statusCode >= 200) + // 3. + return await responseArrayPromise + } - if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { - util.destroy(socket, new ResponseExceededMaxSizeError()) - return -1 - } + async addAll (requests) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.addAll' }) - this.bytesRead += buf.length + requests = webidl.converters['sequence'](requests) - if (request.onData(buf) === false) { - return constants.ERROR.PAUSED - } - } + // 1. + const responsePromises = [] - onMessageComplete () { - const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this + // 2. + const requestList = [] - if (socket.destroyed && (!statusCode || shouldKeepAlive)) { - return -1 - } + // 3. + for (const request of requests) { + if (typeof request === 'string') { + continue + } - if (upgrade) { - return + // 3.1 + const r = request[kState] + + // 3.2 + if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Expected http/s scheme when method is not GET.' + }) + } } - const request = client[kQueue][client[kRunningIdx]] - assert(request) + // 4. + /** @type {ReturnType[]} */ + const fetchControllers = [] - assert(statusCode >= 100) + // 5. + for (const request of requests) { + // 5.1 + const r = new Request(request)[kState] - this.statusCode = null - this.statusText = '' - this.bytesRead = 0 - this.contentLength = '' - this.keepAlive = '' - this.connection = '' + // 5.2 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Expected http/s scheme.' + }) + } - assert(this.headers.length % 2 === 0) - this.headers = [] - this.headersSize = 0 + // 5.4 + r.initiator = 'fetch' + r.destination = 'subresource' - if (statusCode < 200) { - return - } + // 5.5 + requestList.push(r) - /* istanbul ignore next: should be handled by llhttp? */ - if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) { - util.destroy(socket, new ResponseContentLengthMismatchError()) - return -1 - } + // 5.6 + const responsePromise = createDeferredPromise() - request.onComplete(headers) + // 5.7 + fetchControllers.push(fetching({ + request: r, + dispatcher: getGlobalDispatcher(), + processResponse (response) { + // 1. + if (response.type === 'error' || response.status === 206 || response.status < 200 || response.status > 299) { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Received an invalid status code or the request failed.' + })) + } else if (response.headersList.contains('vary')) { // 2. + // 2.1 + const fieldValues = getFieldValues(response.headersList.get('vary')) - client[kQueue][client[kRunningIdx]++] = null - - if (socket[kWriting]) { - assert.strictEqual(client[kRunning], 0) - // Response completed before request. - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (!shouldKeepAlive) { - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (socket[kReset] && client[kRunning] === 0) { - // Destroy socket once all requests have completed. - // The request at the tail of the pipeline is the one - // that requested reset and no further requests should - // have been queued since then. - util.destroy(socket, new InformationalError('reset')) - return constants.ERROR.PAUSED - } else if (client[kPipelining] === 1) { - // We must wait a full event loop cycle to reuse this socket to make sure - // that non-spec compliant servers are not closing the connection even if they - // said they won't. - setImmediate(resume, client) - } else { - resume(client) - } - } -} - -function onParserTimeout (parser) { - const { socket, timeoutType, client } = parser - - /* istanbul ignore else */ - if (timeoutType === TIMEOUT_HEADERS) { - if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { - assert(!parser.paused, 'cannot be paused while waiting for headers') - util.destroy(socket, new HeadersTimeoutError()) - } - } else if (timeoutType === TIMEOUT_BODY) { - if (!parser.paused) { - util.destroy(socket, new BodyTimeoutError()) - } - } else if (timeoutType === TIMEOUT_IDLE) { - assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) - util.destroy(socket, new InformationalError('socket idle timeout')) - } -} + // 2.2 + for (const fieldValue of fieldValues) { + // 2.2.1 + if (fieldValue === '*') { + responsePromise.reject(webidl.errors.exception({ + header: 'Cache.addAll', + message: 'invalid vary field value' + })) -function onSocketReadable () { - const { [kParser]: parser } = this - if (parser) { - parser.readMore() - } -} + for (const controller of fetchControllers) { + controller.abort() + } -function onSocketError (err) { - const { [kClient]: client, [kParser]: parser } = this + return + } + } + } + }, + processResponseEndOfBody (response) { + // 1. + if (response.aborted) { + responsePromise.reject(new DOMException('aborted', 'AbortError')) + return + } - assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + // 2. + responsePromise.resolve(response) + } + })) - if (client[kHTTPConnVersion] !== 'h2') { - // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded - // to the user. - if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so for as a valid response. - parser.onMessageComplete() - return + // 5.8 + responsePromises.push(responsePromise.promise) } - } - this[kError] = err + // 6. + const p = Promise.all(responsePromises) - onError(this[kClient], err) -} + // 7. + const responses = await p -function onError (client, err) { - if ( - client[kRunning] === 0 && - err.code !== 'UND_ERR_INFO' && - err.code !== 'UND_ERR_SOCKET' - ) { - // Error is not caused by running request and not a recoverable - // socket error. + // 7.1 + const operations = [] - assert(client[kPendingIdx] === client[kRunningIdx]) + // 7.2 + let index = 0 - const requests = client[kQueue].splice(client[kRunningIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - errorRequest(client, request, err) - } - assert(client[kSize] === 0) - } -} + // 7.3 + for (const response of responses) { + // 7.3.1 + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 7.3.2 + request: requestList[index], // 7.3.3 + response // 7.3.4 + } -function onSocketEnd () { - const { [kParser]: parser, [kClient]: client } = this + operations.push(operation) // 7.3.5 - if (client[kHTTPConnVersion] !== 'h2') { - if (parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete() - return + index++ // 7.3.6 } - } - util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) -} + // 7.5 + const cacheJobPromise = createDeferredPromise() -function onSocketClose () { - const { [kClient]: client, [kParser]: parser } = this + // 7.6.1 + let errorData = null - if (client[kHTTPConnVersion] === 'h1' && parser) { - if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete() + // 7.6.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e } - this[kParser].destroy() - this[kParser] = null + // 7.6.3 + queueMicrotask(() => { + // 7.6.3.1 + if (errorData === null) { + cacheJobPromise.resolve(undefined) + } else { + // 7.6.3.2 + cacheJobPromise.reject(errorData) + } + }) + + // 7.7 + return cacheJobPromise.promise } - const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) + async put (request, response) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 2, { header: 'Cache.put' }) - client[kSocket] = null + request = webidl.converters.RequestInfo(request) + response = webidl.converters.Response(response) - if (client.destroyed) { - assert(client[kPending] === 0) + // 1. + let innerRequest = null - // Fail entire queue. - const requests = client[kQueue].splice(client[kRunningIdx]) - for (let i = 0; i < requests.length; i++) { - const request = requests[i] - errorRequest(client, request, err) + // 2. + if (request instanceof Request) { + innerRequest = request[kState] + } else { // 3. + innerRequest = new Request(request)[kState] } - } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { - // Fail head of pipeline. - const request = client[kQueue][client[kRunningIdx]] - client[kQueue][client[kRunningIdx]++] = null - - errorRequest(client, request, err) - } - client[kPendingIdx] = client[kRunningIdx] + // 4. + if (!urlIsHttpHttpsScheme(innerRequest.url) || innerRequest.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Expected an http/s scheme when method is not GET' + }) + } - assert(client[kRunning] === 0) + // 5. + const innerResponse = response[kState] - client.emit('disconnect', client[kUrl], [client], err) + // 6. + if (innerResponse.status === 206) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Got 206 status' + }) + } - resume(client) -} + // 7. + if (innerResponse.headersList.contains('vary')) { + // 7.1. + const fieldValues = getFieldValues(innerResponse.headersList.get('vary')) -async function connect (client) { - assert(!client[kConnecting]) - assert(!client[kSocket]) + // 7.2. + for (const fieldValue of fieldValues) { + // 7.2.1 + if (fieldValue === '*') { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Got * vary field value' + }) + } + } + } - let { host, hostname, protocol, port } = client[kUrl] + // 8. + if (innerResponse.body && (isDisturbed(innerResponse.body.stream) || innerResponse.body.stream.locked)) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Response body is locked or disturbed' + }) + } - // Resolve ipv6 - if (hostname[0] === '[') { - const idx = hostname.indexOf(']') + // 9. + const clonedResponse = cloneResponse(innerResponse) - assert(idx !== -1) - const ip = hostname.substring(1, idx) + // 10. + const bodyReadPromise = createDeferredPromise() - assert(net.isIP(ip)) - hostname = ip - } + // 11. + if (innerResponse.body != null) { + // 11.1 + const stream = innerResponse.body.stream - client[kConnecting] = true + // 11.2 + const reader = stream.getReader() - if (channels.beforeConnect.hasSubscribers) { - channels.beforeConnect.publish({ - connectParams: { - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector] - }) - } + // 11.3 + readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject) + } else { + bodyReadPromise.resolve(undefined) + } - try { - const socket = await new Promise((resolve, reject) => { - client[kConnector]({ - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, (err, socket) => { - if (err) { - reject(err) - } else { - resolve(socket) - } - }) - }) + // 12. + /** @type {CacheBatchOperation[]} */ + const operations = [] - if (client.destroyed) { - util.destroy(socket.on('error', () => {}), new ClientDestroyedError()) - return + // 13. + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 14. + request: innerRequest, // 15. + response: clonedResponse // 16. } - client[kConnecting] = false - - assert(socket) + // 17. + operations.push(operation) - const isH2 = socket.alpnProtocol === 'h2' - if (isH2) { - if (!h2ExperimentalWarned) { - h2ExperimentalWarned = true - process.emitWarning('H2 support is experimental, expect them to change at any time.', { - code: 'UNDICI-H2' - }) - } + // 19. + const bytes = await bodyReadPromise.promise - const session = http2.connect(client[kUrl], { - createConnection: () => socket, - peerMaxConcurrentStreams: client[kHTTP2SessionState].maxConcurrentStreams - }) + if (clonedResponse.body != null) { + clonedResponse.body.source = bytes + } - client[kHTTPConnVersion] = 'h2' - session[kClient] = client - session[kSocket] = socket - session.on('error', onHttp2SessionError) - session.on('frameError', onHttp2FrameError) - session.on('end', onHttp2SessionEnd) - session.on('goaway', onHTTP2GoAway) - session.on('close', onSocketClose) - session.unref() + // 19.1 + const cacheJobPromise = createDeferredPromise() - client[kHTTP2Session] = session - socket[kHTTP2Session] = session - } else { - if (!llhttpInstance) { - llhttpInstance = await llhttpPromise - llhttpPromise = null - } + // 19.2.1 + let errorData = null - socket[kNoRef] = false - socket[kWriting] = false - socket[kReset] = false - socket[kBlocking] = false - socket[kParser] = new Parser(client, socket, llhttpInstance) + // 19.2.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e } - socket[kCounter] = 0 - socket[kMaxRequests] = client[kMaxRequests] - socket[kClient] = client - socket[kError] = null + // 19.2.3 + queueMicrotask(() => { + // 19.2.3.1 + if (errorData === null) { + cacheJobPromise.resolve() + } else { // 19.2.3.2 + cacheJobPromise.reject(errorData) + } + }) - socket - .on('error', onSocketError) - .on('readable', onSocketReadable) - .on('end', onSocketEnd) - .on('close', onSocketClose) + return cacheJobPromise.promise + } - client[kSocket] = socket + async delete (request, options = {}) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.delete' }) - if (channels.connected.hasSubscribers) { - channels.connected.publish({ - connectParams: { - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector], - socket - }) - } - client.emit('connect', client[kUrl], [client]) - } catch (err) { - if (client.destroyed) { - return - } + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - client[kConnecting] = false + /** + * @type {Request} + */ + let r = null - if (channels.connectError.hasSubscribers) { - channels.connectError.publish({ - connectParams: { - host, - hostname, - protocol, - port, - servername: client[kServerName], - localAddress: client[kLocalAddress] - }, - connector: client[kConnector], - error: err - }) - } + if (request instanceof Request) { + r = request[kState] - if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { - assert(client[kRunning] === 0) - while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { - const request = client[kQueue][client[kPendingIdx]++] - errorRequest(client, request, err) + if (r.method !== 'GET' && !options.ignoreMethod) { + return false } } else { - onError(client, err) + assert(typeof request === 'string') + + r = new Request(request)[kState] } - client.emit('connectionError', client[kUrl], [client], err) - } + /** @type {CacheBatchOperation[]} */ + const operations = [] - resume(client) -} + /** @type {CacheBatchOperation} */ + const operation = { + type: 'delete', + request: r, + options + } -function emitDrain (client) { - client[kNeedDrain] = 0 - client.emit('drain', client[kUrl], [client]) -} + operations.push(operation) -function resume (client, sync) { - if (client[kResuming] === 2) { - return - } + const cacheJobPromise = createDeferredPromise() - client[kResuming] = 2 + let errorData = null + let requestResponses - _resume(client, sync) - client[kResuming] = 0 + try { + requestResponses = this.#batchCacheOperations(operations) + } catch (e) { + errorData = e + } - if (client[kRunningIdx] > 256) { - client[kQueue].splice(0, client[kRunningIdx]) - client[kPendingIdx] -= client[kRunningIdx] - client[kRunningIdx] = 0 + queueMicrotask(() => { + if (errorData === null) { + cacheJobPromise.resolve(!!requestResponses?.length) + } else { + cacheJobPromise.reject(errorData) + } + }) + + return cacheJobPromise.promise } -} -function _resume (client, sync) { - while (true) { - if (client.destroyed) { - assert(client[kPending] === 0) - return - } + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys + * @param {any} request + * @param {import('../../types/cache').CacheQueryOptions} options + * @returns {readonly Request[]} + */ + async keys (request = undefined, options = {}) { + webidl.brandCheck(this, Cache) - if (client[kClosedResolve] && !client[kSize]) { - client[kClosedResolve]() - client[kClosedResolve] = null - return - } + if (request !== undefined) request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - const socket = client[kSocket] + // 1. + let r = null - if (socket && !socket.destroyed && socket.alpnProtocol !== 'h2') { - if (client[kSize] === 0) { - if (!socket[kNoRef] && socket.unref) { - socket.unref() - socket[kNoRef] = true - } - } else if (socket[kNoRef] && socket.ref) { - socket.ref() - socket[kNoRef] = false - } + // 2. + if (request !== undefined) { + // 2.1 + if (request instanceof Request) { + // 2.1.1 + r = request[kState] - if (client[kSize] === 0) { - if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { - socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE) - } - } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { - if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { - const request = client[kQueue][client[kRunningIdx]] - const headersTimeout = request.headersTimeout != null - ? request.headersTimeout - : client[kHeadersTimeout] - socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] } + } else if (typeof request === 'string') { // 2.2 + r = new Request(request)[kState] } } - if (client[kBusy]) { - client[kNeedDrain] = 2 - } else if (client[kNeedDrain] === 2) { - if (sync) { - client[kNeedDrain] = 1 - process.nextTick(emitDrain, client) - } else { - emitDrain(client) + // 4. + const promise = createDeferredPromise() + + // 5. + // 5.1 + const requests = [] + + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + // 5.2.1.1 + requests.push(requestResponse[0]) } - continue - } + } else { // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) - if (client[kPending] === 0) { - return + // 5.3.2 + for (const requestResponse of requestResponses) { + // 5.3.2.1 + requests.push(requestResponse[0]) + } } - if (client[kRunning] >= (client[kPipelining] || 1)) { - return - } + // 5.4 + queueMicrotask(() => { + // 5.4.1 + const requestList = [] - const request = client[kQueue][client[kPendingIdx]] + // 5.4.2 + for (const request of requests) { + const requestObject = new Request('https://a') + requestObject[kState] = request + requestObject[kHeaders][kHeadersList] = request.headersList + requestObject[kHeaders][kGuard] = 'immutable' + requestObject[kRealm] = request.client - if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { - if (client[kRunning] > 0) { - return + // 5.4.2.1 + requestList.push(requestObject) } - client[kServerName] = request.servername + // 5.4.3 + promise.resolve(Object.freeze(requestList)) + }) - if (socket && socket.servername !== request.servername) { - util.destroy(socket, new InformationalError('servername changed')) - return - } - } + return promise.promise + } - if (client[kConnecting]) { - return - } + /** + * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm + * @param {CacheBatchOperation[]} operations + * @returns {requestResponseList} + */ + #batchCacheOperations (operations) { + // 1. + const cache = this.#relevantRequestResponseList - if (!socket && !client[kHTTP2Session]) { - connect(client) - return - } + // 2. + const backupCache = [...cache] - if (socket.destroyed || socket[kWriting] || socket[kReset] || socket[kBlocking]) { - return - } + // 3. + const addedItems = [] - if (client[kRunning] > 0 && !request.idempotent) { - // Non-idempotent request cannot be retried. - // Ensure that no other requests are inflight and - // could cause failure. - return - } + // 4.1 + const resultList = [] - if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { - // Don't dispatch an upgrade until all preceding requests have completed. - // A misbehaving server might upgrade the connection before all pipelined - // request has completed. - return - } + try { + // 4.2 + for (const operation of operations) { + // 4.2.1 + if (operation.type !== 'delete' && operation.type !== 'put') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'operation type does not match "delete" or "put"' + }) + } - if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && - (util.isStream(request.body) || util.isAsyncIterable(request.body))) { - // Request with stream or iterator body can error while other requests - // are inflight and indirectly error those as well. - // Ensure this doesn't happen by waiting for inflight - // to complete before dispatching. + // 4.2.2 + if (operation.type === 'delete' && operation.response != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'delete operation should not have an associated response' + }) + } - // Request with stream or iterator body cannot be retried. - // Ensure that no other requests are inflight and - // could cause failure. - return - } + // 4.2.3 + if (this.#queryCache(operation.request, operation.options, addedItems).length) { + throw new DOMException('???', 'InvalidStateError') + } - if (!request.aborted && write(client, request)) { - client[kPendingIdx]++ - } else { - client[kQueue].splice(client[kPendingIdx], 1) - } - } -} + // 4.2.4 + let requestResponses -// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 -function shouldSendContentLength (method) { - return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' -} + // 4.2.5 + if (operation.type === 'delete') { + // 4.2.5.1 + requestResponses = this.#queryCache(operation.request, operation.options) -function write (client, request) { - if (client[kHTTPConnVersion] === 'h2') { - writeH2(client, client[kHTTP2Session], request) - return - } + // TODO: the spec is wrong, this is needed to pass WPTs + if (requestResponses.length === 0) { + return [] + } - const { body, method, path, host, upgrade, headers, blocking, reset } = request + // 4.2.5.2 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) - // https://tools.ietf.org/html/rfc7231#section-4.3.1 - // https://tools.ietf.org/html/rfc7231#section-4.3.2 - // https://tools.ietf.org/html/rfc7231#section-4.3.5 + // 4.2.5.2.1 + cache.splice(idx, 1) + } + } else if (operation.type === 'put') { // 4.2.6 + // 4.2.6.1 + if (operation.response == null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'put operation should have an associated response' + }) + } - // Sending a payload body on a request that does not - // expect it can cause undefined behavior on some - // servers and corrupt connection state. Do not - // re-use the connection for further requests. + // 4.2.6.2 + const r = operation.request - const expectsPayload = ( - method === 'PUT' || - method === 'POST' || - method === 'PATCH' - ) + // 4.2.6.3 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'expected http or https scheme' + }) + } - if (body && typeof body.read === 'function') { - // Try to read EOF in order to get length. - body.read(0) - } + // 4.2.6.4 + if (r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'not get method' + }) + } - const bodyLength = util.bodyLength(body) + // 4.2.6.5 + if (operation.options != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'options must not be defined' + }) + } - let contentLength = bodyLength + // 4.2.6.6 + requestResponses = this.#queryCache(operation.request) - if (contentLength === null) { - contentLength = request.contentLength - } + // 4.2.6.7 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) - if (contentLength === 0 && !expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD NOT send a Content-Length header field when - // the request message does not contain a payload body and the method - // semantics do not anticipate such a body. - - contentLength = null - } - - // https://github.com/nodejs/undici/issues/2046 - // A user agent may send a Content-Length header with 0 value, this should be allowed. - if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { - if (client[kStrictContentLength]) { - errorRequest(client, request, new RequestContentLengthMismatchError()) - return false - } + // 4.2.6.7.1 + cache.splice(idx, 1) + } - process.emitWarning(new RequestContentLengthMismatchError()) - } + // 4.2.6.8 + cache.push([operation.request, operation.response]) - const socket = client[kSocket] + // 4.2.6.10 + addedItems.push([operation.request, operation.response]) + } - try { - request.onConnect((err) => { - if (request.aborted || request.completed) { - return + // 4.2.7 + resultList.push([operation.request, operation.response]) } - errorRequest(client, request, err || new RequestAbortedError()) + // 4.3 + return resultList + } catch (e) { // 5. + // 5.1 + this.#relevantRequestResponseList.length = 0 - util.destroy(socket, new InformationalError('aborted')) - }) - } catch (err) { - errorRequest(client, request, err) - } + // 5.2 + this.#relevantRequestResponseList = backupCache - if (request.aborted) { - return false + // 5.3 + throw e + } } - if (method === 'HEAD') { - // https://github.com/mcollina/undici/issues/258 - // Close after a HEAD request to interop with misbehaving servers - // that may send a body in the response. + /** + * @see https://w3c.github.io/ServiceWorker/#query-cache + * @param {any} requestQuery + * @param {import('../../types/cache').CacheQueryOptions} options + * @param {requestResponseList} targetStorage + * @returns {requestResponseList} + */ + #queryCache (requestQuery, options, targetStorage) { + /** @type {requestResponseList} */ + const resultList = [] - socket[kReset] = true - } + const storage = targetStorage ?? this.#relevantRequestResponseList - if (upgrade || method === 'CONNECT') { - // On CONNECT or upgrade, block pipeline from dispatching further - // requests on this connection. + for (const requestResponse of storage) { + const [cachedRequest, cachedResponse] = requestResponse + if (this.#requestMatchesCachedItem(requestQuery, cachedRequest, cachedResponse, options)) { + resultList.push(requestResponse) + } + } - socket[kReset] = true + return resultList } - if (reset != null) { - socket[kReset] = reset - } + /** + * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm + * @param {any} requestQuery + * @param {any} request + * @param {any | null} response + * @param {import('../../types/cache').CacheQueryOptions | undefined} options + * @returns {boolean} + */ + #requestMatchesCachedItem (requestQuery, request, response = null, options) { + // if (options?.ignoreMethod === false && request.method === 'GET') { + // return false + // } - if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { - socket[kReset] = true - } + const queryURL = new URL(requestQuery.url) - if (blocking) { - socket[kBlocking] = true - } + const cachedURL = new URL(request.url) - let header = `${method} ${path} HTTP/1.1\r\n` + if (options?.ignoreSearch) { + cachedURL.search = '' - if (typeof host === 'string') { - header += `host: ${host}\r\n` - } else { - header += client[kHostHeader] - } + queryURL.search = '' + } - if (upgrade) { - header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n` - } else if (client[kPipelining] && !socket[kReset]) { - header += 'connection: keep-alive\r\n' - } else { - header += 'connection: close\r\n' - } + if (!urlEquals(queryURL, cachedURL, true)) { + return false + } - if (headers) { - header += headers - } + if ( + response == null || + options?.ignoreVary || + !response.headersList.contains('vary') + ) { + return true + } - if (channels.sendHeaders.hasSubscribers) { - channels.sendHeaders.publish({ request, headers: header, socket }) - } + const fieldValues = getFieldValues(response.headersList.get('vary')) - /* istanbul ignore else: assertion */ - if (!body || bodyLength === 0) { - if (contentLength === 0) { - socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') - } else { - assert(contentLength === null, 'no body must not have content length') - socket.write(`${header}\r\n`, 'latin1') - } - request.onRequestSent() - } else if (util.isBuffer(body)) { - assert(contentLength === body.byteLength, 'buffer body must have content length') + for (const fieldValue of fieldValues) { + if (fieldValue === '*') { + return false + } - socket.cork() - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - socket.write(body) - socket.uncork() - request.onBodySent(body) - request.onRequestSent() - if (!expectsPayload) { - socket[kReset] = true - } - } else if (util.isBlobLike(body)) { - if (typeof body.stream === 'function') { - writeIterable({ body: body.stream(), client, request, socket, contentLength, header, expectsPayload }) - } else { - writeBlob({ body, client, request, socket, contentLength, header, expectsPayload }) + const requestValue = request.headersList.get(fieldValue) + const queryValue = requestQuery.headersList.get(fieldValue) + + // If one has the header and the other doesn't, or one has + // a different value than the other, return false + if (requestValue !== queryValue) { + return false + } } - } else if (util.isStream(body)) { - writeStream({ body, client, request, socket, contentLength, header, expectsPayload }) - } else if (util.isIterable(body)) { - writeIterable({ body, client, request, socket, contentLength, header, expectsPayload }) - } else { - assert(false) - } - return true + return true + } } -function writeH2 (client, session, request) { - const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request - - let headers - if (typeof reqHeaders === 'string') headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()) - else headers = reqHeaders +Object.defineProperties(Cache.prototype, { + [Symbol.toStringTag]: { + value: 'Cache', + configurable: true + }, + match: kEnumerableProperty, + matchAll: kEnumerableProperty, + add: kEnumerableProperty, + addAll: kEnumerableProperty, + put: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty +}) - if (upgrade) { - errorRequest(client, request, new Error('Upgrade not supported for H2')) - return false +const cacheQueryOptionConverters = [ + { + key: 'ignoreSearch', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'ignoreMethod', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'ignoreVary', + converter: webidl.converters.boolean, + defaultValue: false } +] - try { - // TODO(HTTP/2): Should we call onConnect immediately or on stream ready event? - request.onConnect((err) => { - if (request.aborted || request.completed) { - return - } +webidl.converters.CacheQueryOptions = webidl.dictionaryConverter(cacheQueryOptionConverters) - errorRequest(client, request, err || new RequestAbortedError()) - }) - } catch (err) { - errorRequest(client, request, err) +webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ + ...cacheQueryOptionConverters, + { + key: 'cacheName', + converter: webidl.converters.DOMString } +]) - if (request.aborted) { - return false - } +webidl.converters.Response = webidl.interfaceConverter(Response) - /** @type {import('node:http2').ClientHttp2Stream} */ - let stream - const h2State = client[kHTTP2SessionState] +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.RequestInfo +) - headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost] - headers[HTTP2_HEADER_METHOD] = method +module.exports = { + Cache +} - if (method === 'CONNECT') { - session.ref() - // we are already connected, streams are pending, first request - // will create a new stream. We trigger a request to create the stream and wait until - // `ready` event is triggered - // We disabled endStream to allow the user to write to the stream - stream = session.request(headers, { endStream: false, signal }) - if (stream.id && !stream.pending) { - request.onUpgrade(null, null, stream) - ++h2State.openStreams - } else { - stream.once('ready', () => { - request.onUpgrade(null, null, stream) - ++h2State.openStreams - }) - } +/***/ }), - stream.once('close', () => { - h2State.openStreams -= 1 - // TODO(HTTP/2): unref only if current streams count is 0 - if (h2State.openStreams === 0) session.unref() - }) +/***/ 7907: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return true +"use strict"; + + +const { kConstruct } = __nccwpck_require__(9174) +const { Cache } = __nccwpck_require__(6101) +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) + +class CacheStorage { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map + * @type {Map} + */ + async has (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.has' }) - if (contentLength == null) { - contentLength = request.contentLength + cacheName = webidl.converters.DOMString(cacheName) + + // 2.1.1 + // 2.2 + return this.#caches.has(cacheName) } - if (contentLength === 0 || !expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD NOT send a Content-Length header field when - // the request message does not contain a payload body and the method - // semantics do not anticipate such a body. + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open + * @param {string} cacheName + * @returns {Promise} + */ + async open (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.open' }) - contentLength = null - } + cacheName = webidl.converters.DOMString(cacheName) - // https://github.com/nodejs/undici/issues/2046 - // A user agent may send a Content-Length header with 0 value, this should be allowed. - if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { - if (client[kStrictContentLength]) { - errorRequest(client, request, new RequestContentLengthMismatchError()) - return false + // 2.1 + if (this.#caches.has(cacheName)) { + // await caches.open('v1') !== await caches.open('v1') + + // 2.1.1 + const cache = this.#caches.get(cacheName) + + // 2.1.1.1 + return new Cache(kConstruct, cache) } - process.emitWarning(new RequestContentLengthMismatchError()) + // 2.2 + const cache = [] + + // 2.3 + this.#caches.set(cacheName, cache) + + // 2.4 + return new Cache(kConstruct, cache) } - if (contentLength != null) { - assert(body, 'no body must not have content length') - headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete + * @param {string} cacheName + * @returns {Promise} + */ + async delete (cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.delete' }) + + cacheName = webidl.converters.DOMString(cacheName) + + return this.#caches.delete(cacheName) } - session.ref() + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys + * @returns {string[]} + */ + async keys () { + webidl.brandCheck(this, CacheStorage) - const shouldEndStream = method === 'GET' || method === 'HEAD' - if (expectContinue) { - headers[HTTP2_HEADER_EXPECT] = '100-continue' - stream = session.request(headers, { endStream: shouldEndStream, signal }) + // 2.1 + const keys = this.#caches.keys() - stream.once('continue', writeBodyH2) - } else { - stream = session.request(headers, { - endStream: shouldEndStream, - signal - }) - writeBodyH2() + // 2.2 + return [...keys] } +} - // Increment counter as we have new several streams open - ++h2State.openStreams +Object.defineProperties(CacheStorage.prototype, { + [Symbol.toStringTag]: { + value: 'CacheStorage', + configurable: true + }, + match: kEnumerableProperty, + has: kEnumerableProperty, + open: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty +}) - stream.once('response', headers => { - const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers +module.exports = { + CacheStorage +} - if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), '') === false) { - stream.pause() - } - }) - stream.once('end', () => { - request.onComplete([]) - }) +/***/ }), - stream.on('data', (chunk) => { - if (request.onData(chunk) === false) { - stream.pause() - } - }) +/***/ 9174: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - stream.once('close', () => { - h2State.openStreams -= 1 - // TODO(HTTP/2): unref only if current streams count is 0 - if (h2State.openStreams === 0) { - session.unref() - } - }) +"use strict"; - stream.once('error', function (err) { - if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { - h2State.streams -= 1 - util.destroy(stream, err) - } - }) - stream.once('frameError', (type, code) => { - const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) - errorRequest(client, request, err) +module.exports = { + kConstruct: (__nccwpck_require__(2785).kConstruct) +} - if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { - h2State.streams -= 1 - util.destroy(stream, err) - } - }) - // stream.on('aborted', () => { - // // TODO(HTTP/2): Support aborted - // }) +/***/ }), - // stream.on('timeout', () => { - // // TODO(HTTP/2): Support timeout - // }) +/***/ 2396: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // stream.on('push', headers => { - // // TODO(HTTP/2): Suppor push - // }) +"use strict"; - // stream.on('trailers', headers => { - // // TODO(HTTP/2): Support trailers - // }) - return true +const assert = __nccwpck_require__(9491) +const { URLSerializer } = __nccwpck_require__(685) +const { isValidHeaderName } = __nccwpck_require__(2538) - function writeBodyH2 () { - /* istanbul ignore else: assertion */ - if (!body) { - request.onRequestSent() - } else if (util.isBuffer(body)) { - assert(contentLength === body.byteLength, 'buffer body must have content length') - stream.cork() - stream.write(body) - stream.uncork() - stream.end() - request.onBodySent(body) - request.onRequestSent() - } else if (util.isBlobLike(body)) { - if (typeof body.stream === 'function') { - writeIterable({ - client, - request, - contentLength, - h2stream: stream, - expectsPayload, - body: body.stream(), - socket: client[kSocket], - header: '' - }) - } else { - writeBlob({ - body, - client, - request, - contentLength, - expectsPayload, - h2stream: stream, - header: '', - socket: client[kSocket] - }) - } - } else if (util.isStream(body)) { - writeStream({ - body, - client, - request, - contentLength, - expectsPayload, - socket: client[kSocket], - h2stream: stream, - header: '' - }) - } else if (util.isIterable(body)) { - writeIterable({ - body, - client, - request, - contentLength, - expectsPayload, - header: '', - h2stream: stream, - socket: client[kSocket] - }) - } else { - assert(false) - } - } -} - -function writeStream ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { - assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') - - if (client[kHTTPConnVersion] === 'h2') { - // For HTTP/2, is enough to pipe the stream - const pipe = pipeline( - body, - h2stream, - (err) => { - if (err) { - util.destroy(body, err) - util.destroy(h2stream, err) - } else { - request.onRequestSent() - } - } - ) - - pipe.on('data', onPipeData) - pipe.once('end', () => { - pipe.removeListener('data', onPipeData) - util.destroy(pipe) - }) - - function onPipeData (chunk) { - request.onBodySent(chunk) - } - - return - } - - let finished = false - - const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) - - const onData = function (chunk) { - if (finished) { - return - } - - try { - if (!writer.write(chunk) && this.pause) { - this.pause() - } - } catch (err) { - util.destroy(this, err) - } - } - const onDrain = function () { - if (finished) { - return - } - - if (body.resume) { - body.resume() - } - } - const onAbort = function () { - if (finished) { - return - } - const err = new RequestAbortedError() - queueMicrotask(() => onFinished(err)) - } - const onFinished = function (err) { - if (finished) { - return - } - - finished = true +/** + * @see https://url.spec.whatwg.org/#concept-url-equals + * @param {URL} A + * @param {URL} B + * @param {boolean | undefined} excludeFragment + * @returns {boolean} + */ +function urlEquals (A, B, excludeFragment = false) { + const serializedA = URLSerializer(A, excludeFragment) - assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)) + const serializedB = URLSerializer(B, excludeFragment) - socket - .off('drain', onDrain) - .off('error', onFinished) + return serializedA === serializedB +} - body - .removeListener('data', onData) - .removeListener('end', onFinished) - .removeListener('error', onFinished) - .removeListener('close', onAbort) +/** + * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 + * @param {string} header + */ +function fieldValues (header) { + assert(header !== null) - if (!err) { - try { - writer.end() - } catch (er) { - err = er - } - } + const values = [] - writer.destroy(err) + for (let value of header.split(',')) { + value = value.trim() - if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { - util.destroy(body, err) - } else { - util.destroy(body) + if (!value.length) { + continue + } else if (!isValidHeaderName(value)) { + continue } - } - - body - .on('data', onData) - .on('end', onFinished) - .on('error', onFinished) - .on('close', onAbort) - if (body.resume) { - body.resume() + values.push(value) } - socket - .on('drain', onDrain) - .on('error', onFinished) + return values } -async function writeBlob ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { - assert(contentLength === body.size, 'blob body must have content length') - - const isH2 = client[kHTTPConnVersion] === 'h2' - try { - if (contentLength != null && contentLength !== body.size) { - throw new RequestContentLengthMismatchError() - } - - const buffer = Buffer.from(await body.arrayBuffer()) - - if (isH2) { - h2stream.cork() - h2stream.write(buffer) - h2stream.uncork() - } else { - socket.cork() - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - socket.write(buffer) - socket.uncork() - } +module.exports = { + urlEquals, + fieldValues +} - request.onBodySent(buffer) - request.onRequestSent() - if (!expectsPayload) { - socket[kReset] = true - } +/***/ }), - resume(client) - } catch (err) { - util.destroy(isH2 ? h2stream : socket, err) - } -} +/***/ 3598: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -async function writeIterable ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { - assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') +"use strict"; +// @ts-check - let callback = null - function onDrain () { - if (callback) { - const cb = callback - callback = null - cb() - } - } - const waitForDrain = () => new Promise((resolve, reject) => { - assert(callback === null) - if (socket[kError]) { - reject(socket[kError]) - } else { - callback = resolve - } - }) +/* global WebAssembly */ - if (client[kHTTPConnVersion] === 'h2') { - h2stream - .on('close', onDrain) - .on('drain', onDrain) - - try { - // It's up to the user to somehow abort the async iterable. - for await (const chunk of body) { - if (socket[kError]) { - throw socket[kError] - } +const assert = __nccwpck_require__(9491) +const net = __nccwpck_require__(1808) +const http = __nccwpck_require__(3685) +const { pipeline } = __nccwpck_require__(2781) +const util = __nccwpck_require__(3983) +const timers = __nccwpck_require__(9459) +const Request = __nccwpck_require__(2905) +const DispatcherBase = __nccwpck_require__(4839) +const { + RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, + InvalidArgumentError, + RequestAbortedError, + HeadersTimeoutError, + HeadersOverflowError, + SocketError, + InformationalError, + BodyTimeoutError, + HTTPParserError, + ResponseExceededMaxSizeError, + ClientDestroyedError +} = __nccwpck_require__(8045) +const buildConnector = __nccwpck_require__(2067) +const { + kUrl, + kReset, + kServerName, + kClient, + kBusy, + kParser, + kConnect, + kBlocking, + kResuming, + kRunning, + kPending, + kSize, + kWriting, + kQueue, + kConnected, + kConnecting, + kNeedDrain, + kNoRef, + kKeepAliveDefaultTimeout, + kHostHeader, + kPendingIdx, + kRunningIdx, + kError, + kPipelining, + kSocket, + kKeepAliveTimeoutValue, + kMaxHeadersSize, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kHeadersTimeout, + kBodyTimeout, + kStrictContentLength, + kConnector, + kMaxRedirections, + kMaxRequests, + kCounter, + kClose, + kDestroy, + kDispatch, + kInterceptors, + kLocalAddress, + kMaxResponseSize, + kHTTPConnVersion, + // HTTP2 + kHost, + kHTTP2Session, + kHTTP2SessionState, + kHTTP2BuildRequest, + kHTTP2CopyHeaders, + kHTTP1BuildRequest +} = __nccwpck_require__(2785) - const res = h2stream.write(chunk) - request.onBodySent(chunk) - if (!res) { - await waitForDrain() - } - } - } catch (err) { - h2stream.destroy(err) - } finally { - request.onRequestSent() - h2stream.end() - h2stream - .off('close', onDrain) - .off('drain', onDrain) - } +/** @type {import('http2')} */ +let http2 +try { + http2 = __nccwpck_require__(5158) +} catch { + // @ts-ignore + http2 = { constants: {} } +} - return +const { + constants: { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_SCHEME, + HTTP2_HEADER_CONTENT_LENGTH, + HTTP2_HEADER_EXPECT, + HTTP2_HEADER_STATUS } +} = http2 - socket - .on('close', onDrain) - .on('drain', onDrain) - - const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) - try { - // It's up to the user to somehow abort the async iterable. - for await (const chunk of body) { - if (socket[kError]) { - throw socket[kError] - } +// Experimental +let h2ExperimentalWarned = false - if (!writer.write(chunk)) { - await waitForDrain() - } - } +const FastBuffer = Buffer[Symbol.species] - writer.end() - } catch (err) { - writer.destroy(err) - } finally { - socket - .off('close', onDrain) - .off('drain', onDrain) - } -} +const kClosedResolve = Symbol('kClosedResolve') -class AsyncWriter { - constructor ({ socket, request, contentLength, client, expectsPayload, header }) { - this.socket = socket - this.request = request - this.contentLength = contentLength - this.client = client - this.bytesWritten = 0 - this.expectsPayload = expectsPayload - this.header = header +const channels = {} - socket[kWriting] = true - } +try { + const diagnosticsChannel = __nccwpck_require__(7643) + channels.sendHeaders = diagnosticsChannel.channel('undici:client:sendHeaders') + channels.beforeConnect = diagnosticsChannel.channel('undici:client:beforeConnect') + channels.connectError = diagnosticsChannel.channel('undici:client:connectError') + channels.connected = diagnosticsChannel.channel('undici:client:connected') +} catch { + channels.sendHeaders = { hasSubscribers: false } + channels.beforeConnect = { hasSubscribers: false } + channels.connectError = { hasSubscribers: false } + channels.connected = { hasSubscribers: false } +} - write (chunk) { - const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this +/** + * @type {import('../types/client').default} + */ +class Client extends DispatcherBase { + /** + * + * @param {string|URL} url + * @param {import('../types/client').Client.Options} options + */ + constructor (url, { + interceptors, + maxHeaderSize, + headersTimeout, + socketTimeout, + requestTimeout, + connectTimeout, + bodyTimeout, + idleTimeout, + keepAlive, + keepAliveTimeout, + maxKeepAliveTimeout, + keepAliveMaxTimeout, + keepAliveTimeoutThreshold, + socketPath, + pipelining, + tls, + strictContentLength, + maxCachedSessions, + maxRedirections, + connect, + maxRequestsPerClient, + localAddress, + maxResponseSize, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + // h2 + allowH2, + maxConcurrentStreams + } = {}) { + super() - if (socket[kError]) { - throw socket[kError] + if (keepAlive !== undefined) { + throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') } - if (socket.destroyed) { - return false + if (socketTimeout !== undefined) { + throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') } - const len = Buffer.byteLength(chunk) - if (!len) { - return true + if (requestTimeout !== undefined) { + throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') } - // We should defer writing chunks. - if (contentLength !== null && bytesWritten + len > contentLength) { - if (client[kStrictContentLength]) { - throw new RequestContentLengthMismatchError() - } + if (idleTimeout !== undefined) { + throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') + } - process.emitWarning(new RequestContentLengthMismatchError()) + if (maxKeepAliveTimeout !== undefined) { + throw new InvalidArgumentError('unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') } - socket.cork() + if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { + throw new InvalidArgumentError('invalid maxHeaderSize') + } - if (bytesWritten === 0) { - if (!expectsPayload) { - socket[kReset] = true - } + if (socketPath != null && typeof socketPath !== 'string') { + throw new InvalidArgumentError('invalid socketPath') + } - if (contentLength === null) { - socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1') - } else { - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - } + if (connectTimeout != null && (!Number.isFinite(connectTimeout) || connectTimeout < 0)) { + throw new InvalidArgumentError('invalid connectTimeout') } - if (contentLength === null) { - socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1') + if (keepAliveTimeout != null && (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveTimeout') } - this.bytesWritten += len - - const ret = socket.write(chunk) + if (keepAliveMaxTimeout != null && (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0)) { + throw new InvalidArgumentError('invalid keepAliveMaxTimeout') + } - socket.uncork() + if (keepAliveTimeoutThreshold != null && !Number.isFinite(keepAliveTimeoutThreshold)) { + throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') + } - request.onBodySent(chunk) + if (headersTimeout != null && (!Number.isInteger(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('headersTimeout must be a positive integer or zero') + } - if (!ret) { - if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { - // istanbul ignore else: only for jest - if (socket[kParser].timeout.refresh) { - socket[kParser].timeout.refresh() - } - } + if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('bodyTimeout must be a positive integer or zero') } - return ret - } + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') + } - end () { - const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this - request.onRequestSent() + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } - socket[kWriting] = false + if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) { + throw new InvalidArgumentError('maxRequestsPerClient must be a positive number') + } - if (socket[kError]) { - throw socket[kError] + if (localAddress != null && (typeof localAddress !== 'string' || net.isIP(localAddress) === 0)) { + throw new InvalidArgumentError('localAddress must be valid string IP address') } - if (socket.destroyed) { - return + if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) { + throw new InvalidArgumentError('maxResponseSize must be a positive number') } - if (bytesWritten === 0) { - if (expectsPayload) { - // https://tools.ietf.org/html/rfc7230#section-3.3.2 - // A user agent SHOULD send a Content-Length in a request message when - // no Transfer-Encoding is sent and the request method defines a meaning - // for an enclosed payload body. + if ( + autoSelectFamilyAttemptTimeout != null && + (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1) + ) { + throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') + } - socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') - } else { - socket.write(`${header}\r\n`, 'latin1') - } - } else if (contentLength === null) { - socket.write('\r\n0\r\n\r\n', 'latin1') + // h2 + if (allowH2 != null && typeof allowH2 !== 'boolean') { + throw new InvalidArgumentError('allowH2 must be a valid boolean value') } - if (contentLength !== null && bytesWritten !== contentLength) { - if (client[kStrictContentLength]) { - throw new RequestContentLengthMismatchError() - } else { - process.emitWarning(new RequestContentLengthMismatchError()) - } + if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { + throw new InvalidArgumentError('maxConcurrentStreams must be a possitive integer, greater than 0') } - if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { - // istanbul ignore else: only for jest - if (socket[kParser].timeout.refresh) { - socket[kParser].timeout.refresh() - } + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) } - resume(client) - } + this[kInterceptors] = interceptors && interceptors.Client && Array.isArray(interceptors.Client) + ? interceptors.Client + : [createRedirectInterceptor({ maxRedirections })] + this[kUrl] = util.parseOrigin(url) + this[kConnector] = connect + this[kSocket] = null + this[kPipelining] = pipelining != null ? pipelining : 1 + this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize + this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout + this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout + this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold + this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout] + this[kServerName] = null + this[kLocalAddress] = localAddress != null ? localAddress : null + this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kHostHeader] = `host: ${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}\r\n` + this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3 + this[kHeadersTimeout] = headersTimeout != null ? headersTimeout : 300e3 + this[kStrictContentLength] = strictContentLength == null ? true : strictContentLength + this[kMaxRedirections] = maxRedirections + this[kMaxRequests] = maxRequestsPerClient + this[kClosedResolve] = null + this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 + this[kHTTPConnVersion] = 'h1' - destroy (err) { - const { socket, client } = this + // HTTP/2 + this[kHTTP2Session] = null + this[kHTTP2SessionState] = !allowH2 + ? null + : { + // streams: null, // Fixed queue of streams - For future support of `push` + openStreams: 0, // Keep track of them to decide wether or not unref the session + maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server + } + this[kHost] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}` - socket[kWriting] = false + // kQueue is built up of 3 sections separated by + // the kRunningIdx and kPendingIdx indices. + // | complete | running | pending | + // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length + // kRunningIdx points to the first running element. + // kPendingIdx points to the first pending element. + // This implements a fast queue with an amortized + // time of O(1). - if (err) { - assert(client[kRunning] <= 1, 'pipeline should only contain this request') - util.destroy(socket, err) - } + this[kQueue] = [] + this[kRunningIdx] = 0 + this[kPendingIdx] = 0 } -} -function errorRequest (client, request, err) { - try { - request.onError(err) - assert(request.aborted) - } catch (err) { - client.emit('error', err) + get pipelining () { + return this[kPipelining] } -} - -module.exports = Client - - -/***/ }), -/***/ 6436: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -/* istanbul ignore file: only for Node 12 */ - -const { kConnected, kSize } = __nccwpck_require__(2785) - -class CompatWeakRef { - constructor (value) { - this.value = value + set pipelining (value) { + this[kPipelining] = value + resume(this, true) } - deref () { - return this.value[kConnected] === 0 && this.value[kSize] === 0 - ? undefined - : this.value + get [kPending] () { + return this[kQueue].length - this[kPendingIdx] } -} -class CompatFinalizer { - constructor (finalizer) { - this.finalizer = finalizer + get [kRunning] () { + return this[kPendingIdx] - this[kRunningIdx] } - register (dispatcher, key) { - if (dispatcher.on) { - dispatcher.on('disconnect', () => { - if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { - this.finalizer(key) - } - }) - } + get [kSize] () { + return this[kQueue].length - this[kRunningIdx] } -} -module.exports = function () { - // FIXME: remove workaround when the Node bug is fixed - // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 - if (process.env.NODE_V8_COVERAGE) { - return { - WeakRef: CompatWeakRef, - FinalizationRegistry: CompatFinalizer - } - } - return { - WeakRef: global.WeakRef || CompatWeakRef, - FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer + get [kConnected] () { + return !!this[kSocket] && !this[kConnecting] && !this[kSocket].destroyed } -} + get [kBusy] () { + const socket = this[kSocket] + return ( + (socket && (socket[kReset] || socket[kWriting] || socket[kBlocking])) || + (this[kSize] >= (this[kPipelining] || 1)) || + this[kPending] > 0 + ) + } -/***/ }), + /* istanbul ignore: only used for test */ + [kConnect] (cb) { + connect(this) + this.once('connect', cb) + } -/***/ 663: -/***/ ((module) => { + [kDispatch] (opts, handler) { + const origin = opts.origin || this[kUrl].origin -"use strict"; + const request = this[kHTTPConnVersion] === 'h2' + ? Request[kHTTP2BuildRequest](origin, opts, handler) + : Request[kHTTP1BuildRequest](origin, opts, handler) + this[kQueue].push(request) + if (this[kResuming]) { + // Do nothing. + } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { + // Wait a tick in case stream/iterator is ended in the same tick. + this[kResuming] = 1 + process.nextTick(resume, this) + } else { + resume(this, true) + } -// https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size -const maxAttributeValueSize = 1024 + if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { + this[kNeedDrain] = 2 + } -// https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size -const maxNameValuePairSize = 4096 - -module.exports = { - maxAttributeValueSize, - maxNameValuePairSize -} + return this[kNeedDrain] < 2 + } + async [kClose] () { + // TODO: for H2 we need to gracefully flush the remaining enqueued + // request and close each stream. + return new Promise((resolve) => { + if (!this[kSize]) { + resolve(null) + } else { + this[kClosedResolve] = resolve + } + }) + } -/***/ }), + async [kDestroy] (err) { + return new Promise((resolve) => { + const requests = this[kQueue].splice(this[kPendingIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) + } -/***/ 1724: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + const callback = () => { + if (this[kClosedResolve]) { + // TODO (fix): Should we error here with ClientDestroyedError? + this[kClosedResolve]() + this[kClosedResolve] = null + } + resolve() + } -"use strict"; + if (this[kHTTP2Session] != null) { + util.destroy(this[kHTTP2Session], err) + this[kHTTP2Session] = null + this[kHTTP2SessionState] = null + } + if (!this[kSocket]) { + queueMicrotask(callback) + } else { + util.destroy(this[kSocket].on('close', callback), err) + } -const { parseSetCookie } = __nccwpck_require__(4408) -const { stringify, getHeadersList } = __nccwpck_require__(3121) -const { webidl } = __nccwpck_require__(1744) -const { Headers } = __nccwpck_require__(554) + resume(this) + }) + } +} -/** - * @typedef {Object} Cookie - * @property {string} name - * @property {string} value - * @property {Date|number|undefined} expires - * @property {number|undefined} maxAge - * @property {string|undefined} domain - * @property {string|undefined} path - * @property {boolean|undefined} secure - * @property {boolean|undefined} httpOnly - * @property {'Strict'|'Lax'|'None'} sameSite - * @property {string[]} unparsed - */ +function onHttp2SessionError (err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') -/** - * @param {Headers} headers - * @returns {Record} - */ -function getCookies (headers) { - webidl.argumentLengthCheck(arguments, 1, { header: 'getCookies' }) + this[kSocket][kError] = err - webidl.brandCheck(headers, Headers, { strict: false }) + onError(this[kClient], err) +} - const cookie = headers.get('cookie') - const out = {} +function onHttp2FrameError (type, code, id) { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) - if (!cookie) { - return out + if (id === 0) { + this[kSocket][kError] = err + onError(this[kClient], err) } +} - for (const piece of cookie.split(';')) { - const [name, ...value] = piece.split('=') +function onHttp2SessionEnd () { + util.destroy(this, new SocketError('other side closed')) + util.destroy(this[kSocket], new SocketError('other side closed')) +} - out[name.trim()] = value.join('=') - } +function onHTTP2GoAway (code) { + const client = this[kClient] + const err = new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${code}`) + client[kSocket] = null + client[kHTTP2Session] = null - return out -} + if (client.destroyed) { + assert(this[kPending] === 0) -/** - * @param {Headers} headers - * @param {string} name - * @param {{ path?: string, domain?: string }|undefined} attributes - * @returns {void} - */ -function deleteCookie (headers, name, attributes) { - webidl.argumentLengthCheck(arguments, 2, { header: 'deleteCookie' }) + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) + } + } else if (client[kRunning] > 0) { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null - webidl.brandCheck(headers, Headers, { strict: false }) + errorRequest(client, request, err) + } - name = webidl.converters.DOMString(name) - attributes = webidl.converters.DeleteCookieAttributes(attributes) + client[kPendingIdx] = client[kRunningIdx] - // Matches behavior of - // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 - setCookie(headers, { - name, - value: '', - expires: new Date(0), - ...attributes - }) + assert(client[kRunning] === 0) + + client.emit('disconnect', + client[kUrl], + [client], + err + ) + + resume(client) } -/** - * @param {Headers} headers - * @returns {Cookie[]} - */ -function getSetCookies (headers) { - webidl.argumentLengthCheck(arguments, 1, { header: 'getSetCookies' }) +const constants = __nccwpck_require__(953) +const createRedirectInterceptor = __nccwpck_require__(8861) +const EMPTY_BUF = Buffer.alloc(0) - webidl.brandCheck(headers, Headers, { strict: false }) +async function lazyllhttp () { + const llhttpWasmData = process.env.JEST_WORKER_ID ? __nccwpck_require__(1145) : undefined - const cookies = getHeadersList(headers).cookies + let mod + try { + mod = await WebAssembly.compile(Buffer.from(__nccwpck_require__(5627), 'base64')) + } catch (e) { + /* istanbul ignore next */ - if (!cookies) { - return [] + // We could check if the error was caused by the simd option not + // being enabled, but the occurring of this other error + // * https://github.com/emscripten-core/emscripten/issues/11495 + // got me to remove that check to avoid breaking Node 12. + mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || __nccwpck_require__(1145), 'base64')) } - // In older versions of undici, cookies is a list of name:value. - return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair)) -} + return await WebAssembly.instantiate(mod, { + env: { + /* eslint-disable camelcase */ -/** - * @param {Headers} headers - * @param {Cookie} cookie - * @returns {void} - */ -function setCookie (headers, cookie) { - webidl.argumentLengthCheck(arguments, 2, { header: 'setCookie' }) + wasm_on_url: (p, at, len) => { + /* istanbul ignore next */ + return 0 + }, + wasm_on_status: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_message_begin: (p) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onMessageBegin() || 0 + }, + wasm_on_header_field: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_header_value: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0 + }, + wasm_on_body: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0 + }, + wasm_on_message_complete: (p) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onMessageComplete() || 0 + } - webidl.brandCheck(headers, Headers, { strict: false }) + /* eslint-enable camelcase */ + } + }) +} - cookie = webidl.converters.Cookie(cookie) +let llhttpInstance = null +let llhttpPromise = lazyllhttp() +llhttpPromise.catch() - const str = stringify(cookie) +let currentParser = null +let currentBufferRef = null +let currentBufferSize = 0 +let currentBufferPtr = null - if (str) { - headers.append('Set-Cookie', stringify(cookie)) - } -} +const TIMEOUT_HEADERS = 1 +const TIMEOUT_BODY = 2 +const TIMEOUT_IDLE = 3 -webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'path', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'domain', - defaultValue: null - } -]) +class Parser { + constructor (client, socket, { exports }) { + assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0) -webidl.converters.Cookie = webidl.dictionaryConverter([ - { - converter: webidl.converters.DOMString, - key: 'name' - }, - { - converter: webidl.converters.DOMString, - key: 'value' - }, - { - converter: webidl.nullableConverter((value) => { - if (typeof value === 'number') { - return webidl.converters['unsigned long long'](value) - } + this.llhttp = exports + this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE) + this.client = client + this.socket = socket + this.timeout = null + this.timeoutValue = null + this.timeoutType = null + this.statusCode = null + this.statusText = '' + this.upgrade = false + this.headers = [] + this.headersSize = 0 + this.headersMaxSize = client[kMaxHeadersSize] + this.shouldKeepAlive = false + this.paused = false + this.resume = this.resume.bind(this) - return new Date(value) - }), - key: 'expires', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters['long long']), - key: 'maxAge', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'domain', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.DOMString), - key: 'path', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.boolean), - key: 'secure', - defaultValue: null - }, - { - converter: webidl.nullableConverter(webidl.converters.boolean), - key: 'httpOnly', - defaultValue: null - }, - { - converter: webidl.converters.USVString, - key: 'sameSite', - allowedValues: ['Strict', 'Lax', 'None'] - }, - { - converter: webidl.sequenceConverter(webidl.converters.DOMString), - key: 'unparsed', - defaultValue: [] - } -]) + this.bytesRead = 0 -module.exports = { - getCookies, - deleteCookie, - getSetCookies, - setCookie -} + this.keepAlive = '' + this.contentLength = '' + this.connection = '' + this.maxResponseSize = client[kMaxResponseSize] + } + setTimeout (value, type) { + this.timeoutType = type + if (value !== this.timeoutValue) { + timers.clearTimeout(this.timeout) + if (value) { + this.timeout = timers.setTimeout(onParserTimeout, value, this) + // istanbul ignore else: only for jest + if (this.timeout.unref) { + this.timeout.unref() + } + } else { + this.timeout = null + } + this.timeoutValue = value + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + } -/***/ }), + resume () { + if (this.socket.destroyed || !this.paused) { + return + } -/***/ 4408: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + assert(this.ptr != null) + assert(currentParser == null) -"use strict"; + this.llhttp.llhttp_resume(this.ptr) + assert(this.timeoutType === TIMEOUT_BODY) + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } -const { maxNameValuePairSize, maxAttributeValueSize } = __nccwpck_require__(663) -const { isCTLExcludingHtab } = __nccwpck_require__(3121) -const { collectASequenceOfCodePointsFast } = __nccwpck_require__(685) -const assert = __nccwpck_require__(9491) + this.paused = false + this.execute(this.socket.read() || EMPTY_BUF) // Flush parser. + this.readMore() + } -/** - * @description Parses the field-value attributes of a set-cookie header string. - * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 - * @param {string} header - * @returns if the header is invalid, null will be returned - */ -function parseSetCookie (header) { - // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F - // character (CTL characters excluding HTAB): Abort these steps and - // ignore the set-cookie-string entirely. - if (isCTLExcludingHtab(header)) { - return null + readMore () { + while (!this.paused && this.ptr) { + const chunk = this.socket.read() + if (chunk === null) { + break + } + this.execute(chunk) + } } - let nameValuePair = '' - let unparsedAttributes = '' - let name = '' - let value = '' + execute (data) { + assert(this.ptr != null) + assert(currentParser == null) + assert(!this.paused) - // 2. If the set-cookie-string contains a %x3B (";") character: - if (header.includes(';')) { - // 1. The name-value-pair string consists of the characters up to, - // but not including, the first %x3B (";"), and the unparsed- - // attributes consist of the remainder of the set-cookie-string - // (including the %x3B (";") in question). - const position = { position: 0 } + const { socket, llhttp } = this - nameValuePair = collectASequenceOfCodePointsFast(';', header, position) - unparsedAttributes = header.slice(position.position) - } else { - // Otherwise: + if (data.length > currentBufferSize) { + if (currentBufferPtr) { + llhttp.free(currentBufferPtr) + } + currentBufferSize = Math.ceil(data.length / 4096) * 4096 + currentBufferPtr = llhttp.malloc(currentBufferSize) + } - // 1. The name-value-pair string consists of all the characters - // contained in the set-cookie-string, and the unparsed- - // attributes is the empty string. - nameValuePair = header - } + new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data) - // 3. If the name-value-pair string lacks a %x3D ("=") character, then - // the name string is empty, and the value string is the value of - // name-value-pair. - if (!nameValuePair.includes('=')) { - value = nameValuePair - } else { - // Otherwise, the name string consists of the characters up to, but - // not including, the first %x3D ("=") character, and the (possibly - // empty) value string consists of the characters after the first - // %x3D ("=") character. - const position = { position: 0 } - name = collectASequenceOfCodePointsFast( - '=', - nameValuePair, - position - ) - value = nameValuePair.slice(position.position + 1) - } + // Call `execute` on the wasm parser. + // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, + // and finally the length of bytes to parse. + // The return value is an error code or `constants.ERROR.OK`. + try { + let ret - // 4. Remove any leading or trailing WSP characters from the name - // string and the value string. - name = name.trim() - value = value.trim() + try { + currentBufferRef = data + currentParser = this + ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length) + /* eslint-disable-next-line no-useless-catch */ + } catch (err) { + /* istanbul ignore next: difficult to make a test case for */ + throw err + } finally { + currentParser = null + currentBufferRef = null + } - // 5. If the sum of the lengths of the name string and the value string - // is more than 4096 octets, abort these steps and ignore the set- - // cookie-string entirely. - if (name.length + value.length > maxNameValuePairSize) { - return null - } + const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr - // 6. The cookie-name is the name string, and the cookie-value is the - // value string. - return { - name, value, ...parseUnparsedAttributes(unparsedAttributes) + if (ret === constants.ERROR.PAUSED_UPGRADE) { + this.onUpgrade(data.slice(offset)) + } else if (ret === constants.ERROR.PAUSED) { + this.paused = true + socket.unshift(data.slice(offset)) + } else if (ret !== constants.ERROR.OK) { + const ptr = llhttp.llhttp_get_error_reason(this.ptr) + let message = '' + /* istanbul ignore else: difficult to make a test case for */ + if (ptr) { + const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0) + message = + 'Response does not match the HTTP/1.1 protocol (' + + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + + ')' + } + throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset)) + } + } catch (err) { + util.destroy(socket, err) + } } -} -/** - * Parses the remaining attributes of a set-cookie header - * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 - * @param {string} unparsedAttributes - * @param {[Object.]={}} cookieAttributeList - */ -function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) { - // 1. If the unparsed-attributes string is empty, skip the rest of - // these steps. - if (unparsedAttributes.length === 0) { - return cookieAttributeList - } + destroy () { + assert(this.ptr != null) + assert(currentParser == null) - // 2. Discard the first character of the unparsed-attributes (which - // will be a %x3B (";") character). - assert(unparsedAttributes[0] === ';') - unparsedAttributes = unparsedAttributes.slice(1) + this.llhttp.llhttp_free(this.ptr) + this.ptr = null - let cookieAv = '' + timers.clearTimeout(this.timeout) + this.timeout = null + this.timeoutValue = null + this.timeoutType = null - // 3. If the remaining unparsed-attributes contains a %x3B (";") - // character: - if (unparsedAttributes.includes(';')) { - // 1. Consume the characters of the unparsed-attributes up to, but - // not including, the first %x3B (";") character. - cookieAv = collectASequenceOfCodePointsFast( - ';', - unparsedAttributes, - { position: 0 } - ) - unparsedAttributes = unparsedAttributes.slice(cookieAv.length) - } else { - // Otherwise: + this.paused = false + } - // 1. Consume the remainder of the unparsed-attributes. - cookieAv = unparsedAttributes - unparsedAttributes = '' + onStatus (buf) { + this.statusText = buf.toString() } - // Let the cookie-av string be the characters consumed in this step. + onMessageBegin () { + const { socket, client } = this - let attributeName = '' - let attributeValue = '' + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 + } - // 4. If the cookie-av string contains a %x3D ("=") character: - if (cookieAv.includes('=')) { - // 1. The (possibly empty) attribute-name string consists of the - // characters up to, but not including, the first %x3D ("=") - // character, and the (possibly empty) attribute-value string - // consists of the characters after the first %x3D ("=") - // character. - const position = { position: 0 } + const request = client[kQueue][client[kRunningIdx]] + if (!request) { + return -1 + } + } - attributeName = collectASequenceOfCodePointsFast( - '=', - cookieAv, - position - ) - attributeValue = cookieAv.slice(position.position + 1) - } else { - // Otherwise: + onHeaderField (buf) { + const len = this.headers.length - // 1. The attribute-name string consists of the entire cookie-av - // string, and the attribute-value string is empty. - attributeName = cookieAv + if ((len & 1) === 0) { + this.headers.push(buf) + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + } + + this.trackHeader(buf.length) } - // 5. Remove any leading or trailing WSP characters from the attribute- - // name string and the attribute-value string. - attributeName = attributeName.trim() - attributeValue = attributeValue.trim() + onHeaderValue (buf) { + let len = this.headers.length - // 6. If the attribute-value is longer than 1024 octets, ignore the - // cookie-av string and return to Step 1 of this algorithm. - if (attributeValue.length > maxAttributeValueSize) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } + if ((len & 1) === 1) { + this.headers.push(buf) + len += 1 + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) + } - // 7. Process the attribute-name and attribute-value according to the - // requirements in the following subsections. (Notice that - // attributes with unrecognized attribute-names are ignored.) - const attributeNameLowercase = attributeName.toLowerCase() + const key = this.headers[len - 2] + if (key.length === 10 && key.toString().toLowerCase() === 'keep-alive') { + this.keepAlive += buf.toString() + } else if (key.length === 10 && key.toString().toLowerCase() === 'connection') { + this.connection += buf.toString() + } else if (key.length === 14 && key.toString().toLowerCase() === 'content-length') { + this.contentLength += buf.toString() + } - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 - // If the attribute-name case-insensitively matches the string - // "Expires", the user agent MUST process the cookie-av as follows. - if (attributeNameLowercase === 'expires') { - // 1. Let the expiry-time be the result of parsing the attribute-value - // as cookie-date (see Section 5.1.1). - const expiryTime = new Date(attributeValue) + this.trackHeader(buf.length) + } - // 2. If the attribute-value failed to parse as a cookie date, ignore - // the cookie-av. + trackHeader (len) { + this.headersSize += len + if (this.headersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) + } + } - cookieAttributeList.expires = expiryTime - } else if (attributeNameLowercase === 'max-age') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 - // If the attribute-name case-insensitively matches the string "Max- - // Age", the user agent MUST process the cookie-av as follows. + onUpgrade (head) { + const { upgrade, client, socket, headers, statusCode } = this - // 1. If the first character of the attribute-value is not a DIGIT or a - // "-" character, ignore the cookie-av. - const charCode = attributeValue.charCodeAt(0) + assert(upgrade) - if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } + const request = client[kQueue][client[kRunningIdx]] + assert(request) - // 2. If the remainder of attribute-value contains a non-DIGIT - // character, ignore the cookie-av. - if (!/^\d+$/.test(attributeValue)) { - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) - } + assert(!socket.destroyed) + assert(socket === client[kSocket]) + assert(!this.paused) + assert(request.upgrade || request.method === 'CONNECT') - // 3. Let delta-seconds be the attribute-value converted to an integer. - const deltaSeconds = Number(attributeValue) + this.statusCode = null + this.statusText = '' + this.shouldKeepAlive = null - // 4. Let cookie-age-limit be the maximum age of the cookie (which - // SHOULD be 400 days or less, see Section 4.1.2.2). + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 - // 5. Set delta-seconds to the smaller of its present value and cookie- - // age-limit. - // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) + socket.unshift(head) - // 6. If delta-seconds is less than or equal to zero (0), let expiry- - // time be the earliest representable date and time. Otherwise, let - // the expiry-time be the current date and time plus delta-seconds - // seconds. - // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds + socket[kParser].destroy() + socket[kParser] = null - // 7. Append an attribute to the cookie-attribute-list with an - // attribute-name of Max-Age and an attribute-value of expiry-time. - cookieAttributeList.maxAge = deltaSeconds - } else if (attributeNameLowercase === 'domain') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 - // If the attribute-name case-insensitively matches the string "Domain", - // the user agent MUST process the cookie-av as follows. + socket[kClient] = null + socket[kError] = null + socket + .removeListener('error', onSocketError) + .removeListener('readable', onSocketReadable) + .removeListener('end', onSocketEnd) + .removeListener('close', onSocketClose) - // 1. Let cookie-domain be the attribute-value. - let cookieDomain = attributeValue + client[kSocket] = null + client[kQueue][client[kRunningIdx]++] = null + client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade')) - // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be - // cookie-domain without its leading %x2E ("."). - if (cookieDomain[0] === '.') { - cookieDomain = cookieDomain.slice(1) + try { + request.onUpgrade(statusCode, headers, socket) + } catch (err) { + util.destroy(socket, err) } - // 3. Convert the cookie-domain to lower case. - cookieDomain = cookieDomain.toLowerCase() - - // 4. Append an attribute to the cookie-attribute-list with an - // attribute-name of Domain and an attribute-value of cookie-domain. - cookieAttributeList.domain = cookieDomain - } else if (attributeNameLowercase === 'path') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 - // If the attribute-name case-insensitively matches the string "Path", - // the user agent MUST process the cookie-av as follows. + resume(client) + } - // 1. If the attribute-value is empty or if the first character of the - // attribute-value is not %x2F ("/"): - let cookiePath = '' - if (attributeValue.length === 0 || attributeValue[0] !== '/') { - // 1. Let cookie-path be the default-path. - cookiePath = '/' - } else { - // Otherwise: + onHeadersComplete (statusCode, upgrade, shouldKeepAlive) { + const { client, socket, headers, statusText } = this - // 1. Let cookie-path be the attribute-value. - cookiePath = attributeValue + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 } - // 2. Append an attribute to the cookie-attribute-list with an - // attribute-name of Path and an attribute-value of cookie-path. - cookieAttributeList.path = cookiePath - } else if (attributeNameLowercase === 'secure') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 - // If the attribute-name case-insensitively matches the string "Secure", - // the user agent MUST append an attribute to the cookie-attribute-list - // with an attribute-name of Secure and an empty attribute-value. + const request = client[kQueue][client[kRunningIdx]] - cookieAttributeList.secure = true - } else if (attributeNameLowercase === 'httponly') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 - // If the attribute-name case-insensitively matches the string - // "HttpOnly", the user agent MUST append an attribute to the cookie- - // attribute-list with an attribute-name of HttpOnly and an empty - // attribute-value. + /* istanbul ignore next: difficult to make a test case for */ + if (!request) { + return -1 + } - cookieAttributeList.httpOnly = true - } else if (attributeNameLowercase === 'samesite') { - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 - // If the attribute-name case-insensitively matches the string - // "SameSite", the user agent MUST process the cookie-av as follows: - - // 1. Let enforcement be "Default". - let enforcement = 'Default' + assert(!this.upgrade) + assert(this.statusCode < 200) - const attributeValueLowercase = attributeValue.toLowerCase() - // 2. If cookie-av's attribute-value is a case-insensitive match for - // "None", set enforcement to "None". - if (attributeValueLowercase.includes('none')) { - enforcement = 'None' + if (statusCode === 100) { + util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket))) + return -1 } - // 3. If cookie-av's attribute-value is a case-insensitive match for - // "Strict", set enforcement to "Strict". - if (attributeValueLowercase.includes('strict')) { - enforcement = 'Strict' + /* this can only happen if server is misbehaving */ + if (upgrade && !request.upgrade) { + util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket))) + return -1 } - // 4. If cookie-av's attribute-value is a case-insensitive match for - // "Lax", set enforcement to "Lax". - if (attributeValueLowercase.includes('lax')) { - enforcement = 'Lax' + assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS) + + this.statusCode = statusCode + this.shouldKeepAlive = ( + shouldKeepAlive || + // Override llhttp value which does not allow keepAlive for HEAD. + (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive') + ) + + if (this.statusCode >= 200) { + const bodyTimeout = request.bodyTimeout != null + ? request.bodyTimeout + : client[kBodyTimeout] + this.setTimeout(bodyTimeout, TIMEOUT_BODY) + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } } - // 5. Append an attribute to the cookie-attribute-list with an - // attribute-name of "SameSite" and an attribute-value of - // enforcement. - cookieAttributeList.sameSite = enforcement - } else { - cookieAttributeList.unparsed ??= [] + if (request.method === 'CONNECT') { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } - cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`) - } + if (upgrade) { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } - // 8. Return to Step 1 of this algorithm. - return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) -} + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 -module.exports = { - parseSetCookie, - parseUnparsedAttributes -} + if (this.shouldKeepAlive && client[kPipelining]) { + const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null + if (keepAliveTimeout != null) { + const timeout = Math.min( + keepAliveTimeout - client[kKeepAliveTimeoutThreshold], + client[kKeepAliveMaxTimeout] + ) + if (timeout <= 0) { + socket[kReset] = true + } else { + client[kKeepAliveTimeoutValue] = timeout + } + } else { + client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] + } + } else { + // Stop more requests from being dispatched. + socket[kReset] = true + } -/***/ }), + const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false -/***/ 3121: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (request.aborted) { + return -1 + } -"use strict"; + if (request.method === 'HEAD') { + return 1 + } + if (statusCode < 200) { + return 1 + } -const assert = __nccwpck_require__(9491) -const { kHeadersList } = __nccwpck_require__(2785) + if (socket[kBlocking]) { + socket[kBlocking] = false + resume(client) + } -function isCTLExcludingHtab (value) { - if (value.length === 0) { - return false + return pause ? constants.ERROR.PAUSED : 0 } - for (const char of value) { - const code = char.charCodeAt(0) + onBody (buf) { + const { client, socket, statusCode, maxResponseSize } = this - if ( - (code >= 0x00 || code <= 0x08) || - (code >= 0x0A || code <= 0x1F) || - code === 0x7F - ) { - return false + if (socket.destroyed) { + return -1 } - } -} -/** - CHAR = - token = 1* - separators = "(" | ")" | "<" | ">" | "@" - | "," | ";" | ":" | "\" | <"> - | "/" | "[" | "]" | "?" | "=" - | "{" | "}" | SP | HT - * @param {string} name - */ -function validateCookieName (name) { - for (const char of name) { - const code = char.charCodeAt(0) + const request = client[kQueue][client[kRunningIdx]] + assert(request) - if ( - (code <= 0x20 || code > 0x7F) || - char === '(' || - char === ')' || - char === '>' || - char === '<' || - char === '@' || - char === ',' || - char === ';' || - char === ':' || - char === '\\' || - char === '"' || - char === '/' || - char === '[' || - char === ']' || - char === '?' || - char === '=' || - char === '{' || - char === '}' - ) { - throw new Error('Invalid cookie name') + assert.strictEqual(this.timeoutType, TIMEOUT_BODY) + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } } - } -} -/** - cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) - cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E - ; US-ASCII characters excluding CTLs, - ; whitespace DQUOTE, comma, semicolon, - ; and backslash - * @param {string} value - */ -function validateCookieValue (value) { - for (const char of value) { - const code = char.charCodeAt(0) + assert(statusCode >= 200) - if ( - code < 0x21 || // exclude CTLs (0-31) - code === 0x22 || - code === 0x2C || - code === 0x3B || - code === 0x5C || - code > 0x7E // non-ascii - ) { - throw new Error('Invalid header value') + if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) { + util.destroy(socket, new ResponseExceededMaxSizeError()) + return -1 } - } -} -/** - * path-value = - * @param {string} path - */ -function validateCookiePath (path) { - for (const char of path) { - const code = char.charCodeAt(0) + this.bytesRead += buf.length - if (code < 0x21 || char === ';') { - throw new Error('Invalid cookie path') + if (request.onData(buf) === false) { + return constants.ERROR.PAUSED } } -} -/** - * I have no idea why these values aren't allowed to be honest, - * but Deno tests these. - Khafra - * @param {string} domain - */ -function validateCookieDomain (domain) { - if ( - domain.startsWith('-') || - domain.endsWith('.') || - domain.endsWith('-') - ) { - throw new Error('Invalid cookie domain') - } -} + onMessageComplete () { + const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this -/** - * @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.1 - * @param {number|Date} date - IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT - ; fixed length/zone/capitalization subset of the format - ; see Section 3.3 of [RFC5322] + if (socket.destroyed && (!statusCode || shouldKeepAlive)) { + return -1 + } - day-name = %x4D.6F.6E ; "Mon", case-sensitive - / %x54.75.65 ; "Tue", case-sensitive - / %x57.65.64 ; "Wed", case-sensitive - / %x54.68.75 ; "Thu", case-sensitive - / %x46.72.69 ; "Fri", case-sensitive - / %x53.61.74 ; "Sat", case-sensitive - / %x53.75.6E ; "Sun", case-sensitive - date1 = day SP month SP year - ; e.g., 02 Jun 1982 + if (upgrade) { + return + } - day = 2DIGIT - month = %x4A.61.6E ; "Jan", case-sensitive - / %x46.65.62 ; "Feb", case-sensitive - / %x4D.61.72 ; "Mar", case-sensitive - / %x41.70.72 ; "Apr", case-sensitive - / %x4D.61.79 ; "May", case-sensitive - / %x4A.75.6E ; "Jun", case-sensitive - / %x4A.75.6C ; "Jul", case-sensitive - / %x41.75.67 ; "Aug", case-sensitive - / %x53.65.70 ; "Sep", case-sensitive - / %x4F.63.74 ; "Oct", case-sensitive - / %x4E.6F.76 ; "Nov", case-sensitive - / %x44.65.63 ; "Dec", case-sensitive - year = 4DIGIT + const request = client[kQueue][client[kRunningIdx]] + assert(request) - GMT = %x47.4D.54 ; "GMT", case-sensitive + assert(statusCode >= 100) - time-of-day = hour ":" minute ":" second - ; 00:00:00 - 23:59:60 (leap second) + this.statusCode = null + this.statusText = '' + this.bytesRead = 0 + this.contentLength = '' + this.keepAlive = '' + this.connection = '' - hour = 2DIGIT - minute = 2DIGIT - second = 2DIGIT - */ -function toIMFDate (date) { - if (typeof date === 'number') { - date = new Date(date) - } + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 - const days = [ - 'Sun', 'Mon', 'Tue', 'Wed', - 'Thu', 'Fri', 'Sat' - ] + if (statusCode < 200) { + return + } - const months = [ - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' - ] + /* istanbul ignore next: should be handled by llhttp? */ + if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) { + util.destroy(socket, new ResponseContentLengthMismatchError()) + return -1 + } - const dayName = days[date.getUTCDay()] - const day = date.getUTCDate().toString().padStart(2, '0') - const month = months[date.getUTCMonth()] - const year = date.getUTCFullYear() - const hour = date.getUTCHours().toString().padStart(2, '0') - const minute = date.getUTCMinutes().toString().padStart(2, '0') - const second = date.getUTCSeconds().toString().padStart(2, '0') + request.onComplete(headers) - return `${dayName}, ${day} ${month} ${year} ${hour}:${minute}:${second} GMT` + client[kQueue][client[kRunningIdx]++] = null + + if (socket[kWriting]) { + assert.strictEqual(client[kRunning], 0) + // Response completed before request. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (!shouldKeepAlive) { + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (socket[kReset] && client[kRunning] === 0) { + // Destroy socket once all requests have completed. + // The request at the tail of the pipeline is the one + // that requested reset and no further requests should + // have been queued since then. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (client[kPipelining] === 1) { + // We must wait a full event loop cycle to reuse this socket to make sure + // that non-spec compliant servers are not closing the connection even if they + // said they won't. + setImmediate(resume, client) + } else { + resume(client) + } + } } -/** - max-age-av = "Max-Age=" non-zero-digit *DIGIT - ; In practice, both expires-av and max-age-av - ; are limited to dates representable by the - ; user agent. - * @param {number} maxAge - */ -function validateCookieMaxAge (maxAge) { - if (maxAge < 0) { - throw new Error('Invalid cookie max-age') +function onParserTimeout (parser) { + const { socket, timeoutType, client } = parser + + /* istanbul ignore else */ + if (timeoutType === TIMEOUT_HEADERS) { + if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) { + assert(!parser.paused, 'cannot be paused while waiting for headers') + util.destroy(socket, new HeadersTimeoutError()) + } + } else if (timeoutType === TIMEOUT_BODY) { + if (!parser.paused) { + util.destroy(socket, new BodyTimeoutError()) + } + } else if (timeoutType === TIMEOUT_IDLE) { + assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) + util.destroy(socket, new InformationalError('socket idle timeout')) } } -/** - * @see https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1 - * @param {import('./index').Cookie} cookie - */ -function stringify (cookie) { - if (cookie.name.length === 0) { - return null +function onSocketReadable () { + const { [kParser]: parser } = this + if (parser) { + parser.readMore() } +} - validateCookieName(cookie.name) - validateCookieValue(cookie.value) +function onSocketError (err) { + const { [kClient]: client, [kParser]: parser } = this - const out = [`${cookie.name}=${cookie.value}`] + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1 - // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2 - if (cookie.name.startsWith('__Secure-')) { - cookie.secure = true + if (client[kHTTPConnVersion] !== 'h2') { + // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded + // to the user. + if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so for as a valid response. + parser.onMessageComplete() + return + } } - if (cookie.name.startsWith('__Host-')) { - cookie.secure = true - cookie.domain = null - cookie.path = '/' - } + this[kError] = err - if (cookie.secure) { - out.push('Secure') - } + onError(this[kClient], err) +} - if (cookie.httpOnly) { - out.push('HttpOnly') - } +function onError (client, err) { + if ( + client[kRunning] === 0 && + err.code !== 'UND_ERR_INFO' && + err.code !== 'UND_ERR_SOCKET' + ) { + // Error is not caused by running request and not a recoverable + // socket error. - if (typeof cookie.maxAge === 'number') { - validateCookieMaxAge(cookie.maxAge) - out.push(`Max-Age=${cookie.maxAge}`) - } + assert(client[kPendingIdx] === client[kRunningIdx]) - if (cookie.domain) { - validateCookieDomain(cookie.domain) - out.push(`Domain=${cookie.domain}`) + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(client, request, err) + } + assert(client[kSize] === 0) } +} - if (cookie.path) { - validateCookiePath(cookie.path) - out.push(`Path=${cookie.path}`) - } +function onSocketEnd () { + const { [kParser]: parser, [kClient]: client } = this - if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') { - out.push(`Expires=${toIMFDate(cookie.expires)}`) + if (client[kHTTPConnVersion] !== 'h2') { + if (parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + return + } } - if (cookie.sameSite) { - out.push(`SameSite=${cookie.sameSite}`) - } + util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) +} - for (const part of cookie.unparsed) { - if (!part.includes('=')) { - throw new Error('Invalid unparsed') - } +function onSocketClose () { + const { [kClient]: client, [kParser]: parser } = this - const [key, ...value] = part.split('=') + if (client[kHTTPConnVersion] === 'h1' && parser) { + if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + } - out.push(`${key.trim()}=${value.join('=')}`) + this[kParser].destroy() + this[kParser] = null } - return out.join('; ') -} + const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) -let kHeadersListNode + client[kSocket] = null -function getHeadersList (headers) { - if (headers[kHeadersList]) { - return headers[kHeadersList] - } + if (client.destroyed) { + assert(client[kPending] === 0) - if (!kHeadersListNode) { - kHeadersListNode = Object.getOwnPropertySymbols(headers).find( - (symbol) => symbol.description === 'headers list' - ) + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(client, request, err) + } + } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null - assert(kHeadersListNode, 'Headers cannot be parsed') + errorRequest(client, request, err) } - const headersList = headers[kHeadersListNode] - assert(headersList) + client[kPendingIdx] = client[kRunningIdx] - return headersList -} + assert(client[kRunning] === 0) -module.exports = { - isCTLExcludingHtab, - stringify, - getHeadersList + client.emit('disconnect', client[kUrl], [client], err) + + resume(client) } +async function connect (client) { + assert(!client[kConnecting]) + assert(!client[kSocket]) -/***/ }), - -/***/ 2067: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; + let { host, hostname, protocol, port } = client[kUrl] + // Resolve ipv6 + if (hostname[0] === '[') { + const idx = hostname.indexOf(']') -const net = __nccwpck_require__(1808) -const assert = __nccwpck_require__(9491) -const util = __nccwpck_require__(3983) -const { InvalidArgumentError, ConnectTimeoutError } = __nccwpck_require__(8045) + assert(idx !== -1) + const ip = hostname.substring(1, idx) -let tls // include tls conditionally since it is not always available + assert(net.isIP(ip)) + hostname = ip + } -// TODO: session re-use does not wait for the first -// connection to resolve the session and might therefore -// resolve the same servername multiple times even when -// re-use is enabled. + client[kConnecting] = true -let SessionCache -// FIXME: remove workaround when the Node bug is fixed -// https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 -if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) { - SessionCache = class WeakSessionCache { - constructor (maxCachedSessions) { - this._maxCachedSessions = maxCachedSessions - this._sessionCache = new Map() - this._sessionRegistry = new global.FinalizationRegistry((key) => { - if (this._sessionCache.size < this._maxCachedSessions) { - return - } + if (channels.beforeConnect.hasSubscribers) { + channels.beforeConnect.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector] + }) + } - const ref = this._sessionCache.get(key) - if (ref !== undefined && ref.deref() === undefined) { - this._sessionCache.delete(key) + try { + const socket = await new Promise((resolve, reject) => { + client[kConnector]({ + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, (err, socket) => { + if (err) { + reject(err) + } else { + resolve(socket) } }) - } - - get (sessionKey) { - const ref = this._sessionCache.get(sessionKey) - return ref ? ref.deref() : null - } - - set (sessionKey, session) { - if (this._maxCachedSessions === 0) { - return - } + }) - this._sessionCache.set(sessionKey, new WeakRef(session)) - this._sessionRegistry.register(session, sessionKey) - } - } -} else { - SessionCache = class SimpleSessionCache { - constructor (maxCachedSessions) { - this._maxCachedSessions = maxCachedSessions - this._sessionCache = new Map() + if (client.destroyed) { + util.destroy(socket.on('error', () => {}), new ClientDestroyedError()) + return } - get (sessionKey) { - return this._sessionCache.get(sessionKey) - } + client[kConnecting] = false - set (sessionKey, session) { - if (this._maxCachedSessions === 0) { - return - } + assert(socket) - if (this._sessionCache.size >= this._maxCachedSessions) { - // remove the oldest session - const { value: oldestKey } = this._sessionCache.keys().next() - this._sessionCache.delete(oldestKey) + const isH2 = socket.alpnProtocol === 'h2' + if (isH2) { + if (!h2ExperimentalWarned) { + h2ExperimentalWarned = true + process.emitWarning('H2 support is experimental, expect them to change at any time.', { + code: 'UNDICI-H2' + }) } - this._sessionCache.set(sessionKey, session) - } - } -} + const session = http2.connect(client[kUrl], { + createConnection: () => socket, + peerMaxConcurrentStreams: client[kHTTP2SessionState].maxConcurrentStreams + }) -function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, ...opts }) { - if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { - throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') - } + client[kHTTPConnVersion] = 'h2' + session[kClient] = client + session[kSocket] = socket + session.on('error', onHttp2SessionError) + session.on('frameError', onHttp2FrameError) + session.on('end', onHttp2SessionEnd) + session.on('goaway', onHTTP2GoAway) + session.on('close', onSocketClose) + session.unref() - const options = { path: socketPath, ...opts } - const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) - timeout = timeout == null ? 10e3 : timeout - allowH2 = allowH2 != null ? allowH2 : false - return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { - let socket - if (protocol === 'https:') { - if (!tls) { - tls = __nccwpck_require__(4404) + client[kHTTP2Session] = session + socket[kHTTP2Session] = session + } else { + if (!llhttpInstance) { + llhttpInstance = await llhttpPromise + llhttpPromise = null } - servername = servername || options.servername || util.getServerName(host) || null - const sessionKey = servername || hostname - const session = sessionCache.get(sessionKey) || null + socket[kNoRef] = false + socket[kWriting] = false + socket[kReset] = false + socket[kBlocking] = false + socket[kParser] = new Parser(client, socket, llhttpInstance) + } - assert(sessionKey) + socket[kCounter] = 0 + socket[kMaxRequests] = client[kMaxRequests] + socket[kClient] = client + socket[kError] = null - socket = tls.connect({ - highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... - ...options, - servername, - session, - localAddress, - // TODO(HTTP/2): Add support for h2c - ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], - socket: httpSocket, // upgrade socket connection - port: port || 443, - host: hostname - }) + socket + .on('error', onSocketError) + .on('readable', onSocketReadable) + .on('end', onSocketEnd) + .on('close', onSocketClose) - socket - .on('session', function (session) { - // TODO (fix): Can a session become invalid once established? Don't think so? - sessionCache.set(sessionKey, session) - }) - } else { - assert(!httpSocket, 'httpSocket can only be sent on TLS update') - socket = net.connect({ - highWaterMark: 64 * 1024, // Same as nodejs fs streams. - ...options, - localAddress, - port: port || 80, - host: hostname + client[kSocket] = socket + + if (channels.connected.hasSubscribers) { + channels.connected.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + socket }) } - - // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket - if (options.keepAlive == null || options.keepAlive) { - const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay - socket.setKeepAlive(true, keepAliveInitialDelay) + client.emit('connect', client[kUrl], [client]) + } catch (err) { + if (client.destroyed) { + return } - const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout) - - socket - .setNoDelay(true) - .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { - cancelTimeout() + client[kConnecting] = false - if (callback) { - const cb = callback - callback = null - cb(null, this) - } + if (channels.connectError.hasSubscribers) { + channels.connectError.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress] + }, + connector: client[kConnector], + error: err }) - .on('error', function (err) { - cancelTimeout() + } - if (callback) { - const cb = callback - callback = null - cb(err) - } - }) + if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + assert(client[kRunning] === 0) + while (client[kPending] > 0 && client[kQueue][client[kPendingIdx]].servername === client[kServerName]) { + const request = client[kQueue][client[kPendingIdx]++] + errorRequest(client, request, err) + } + } else { + onError(client, err) + } - return socket + client.emit('connectionError', client[kUrl], [client], err) } + + resume(client) } -function setupTimeout (onConnectTimeout, timeout) { - if (!timeout) { - return () => {} +function emitDrain (client) { + client[kNeedDrain] = 0 + client.emit('drain', client[kUrl], [client]) +} + +function resume (client, sync) { + if (client[kResuming] === 2) { + return } - let s1 = null - let s2 = null - const timeoutId = setTimeout(() => { - // setImmediate is added to make sure that we priotorise socket error events over timeouts - s1 = setImmediate(() => { - if (process.platform === 'win32') { - // Windows needs an extra setImmediate probably due to implementation differences in the socket logic - s2 = setImmediate(() => onConnectTimeout()) - } else { - onConnectTimeout() - } - }) - }, timeout) - return () => { - clearTimeout(timeoutId) - clearImmediate(s1) - clearImmediate(s2) + client[kResuming] = 2 + + _resume(client, sync) + client[kResuming] = 0 + + if (client[kRunningIdx] > 256) { + client[kQueue].splice(0, client[kRunningIdx]) + client[kPendingIdx] -= client[kRunningIdx] + client[kRunningIdx] = 0 } } -function onConnectTimeout (socket) { - util.destroy(socket, new ConnectTimeoutError()) -} +function _resume (client, sync) { + while (true) { + if (client.destroyed) { + assert(client[kPending] === 0) + return + } -module.exports = buildConnector + if (client[kClosedResolve] && !client[kSize]) { + client[kClosedResolve]() + client[kClosedResolve] = null + return + } + const socket = client[kSocket] -/***/ }), + if (socket && !socket.destroyed && socket.alpnProtocol !== 'h2') { + if (client[kSize] === 0) { + if (!socket[kNoRef] && socket.unref) { + socket.unref() + socket[kNoRef] = true + } + } else if (socket[kNoRef] && socket.ref) { + socket.ref() + socket[kNoRef] = false + } -/***/ 8045: -/***/ ((module) => { + if (client[kSize] === 0) { + if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { + socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_IDLE) + } + } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) { + if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { + const request = client[kQueue][client[kRunningIdx]] + const headersTimeout = request.headersTimeout != null + ? request.headersTimeout + : client[kHeadersTimeout] + socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) + } + } + } -"use strict"; + if (client[kBusy]) { + client[kNeedDrain] = 2 + } else if (client[kNeedDrain] === 2) { + if (sync) { + client[kNeedDrain] = 1 + process.nextTick(emitDrain, client) + } else { + emitDrain(client) + } + continue + } + if (client[kPending] === 0) { + return + } -class UndiciError extends Error { - constructor (message) { - super(message) - this.name = 'UndiciError' - this.code = 'UND_ERR' - } -} + if (client[kRunning] >= (client[kPipelining] || 1)) { + return + } -class ConnectTimeoutError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ConnectTimeoutError) - this.name = 'ConnectTimeoutError' - this.message = message || 'Connect Timeout Error' - this.code = 'UND_ERR_CONNECT_TIMEOUT' - } -} + const request = client[kQueue][client[kPendingIdx]] -class HeadersTimeoutError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, HeadersTimeoutError) - this.name = 'HeadersTimeoutError' - this.message = message || 'Headers Timeout Error' - this.code = 'UND_ERR_HEADERS_TIMEOUT' - } -} + if (client[kUrl].protocol === 'https:' && client[kServerName] !== request.servername) { + if (client[kRunning] > 0) { + return + } -class HeadersOverflowError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, HeadersOverflowError) - this.name = 'HeadersOverflowError' - this.message = message || 'Headers Overflow Error' - this.code = 'UND_ERR_HEADERS_OVERFLOW' - } -} + client[kServerName] = request.servername -class BodyTimeoutError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, BodyTimeoutError) - this.name = 'BodyTimeoutError' - this.message = message || 'Body Timeout Error' - this.code = 'UND_ERR_BODY_TIMEOUT' - } -} + if (socket && socket.servername !== request.servername) { + util.destroy(socket, new InformationalError('servername changed')) + return + } + } -class ResponseStatusCodeError extends UndiciError { - constructor (message, statusCode, headers, body) { - super(message) - Error.captureStackTrace(this, ResponseStatusCodeError) - this.name = 'ResponseStatusCodeError' - this.message = message || 'Response Status Code Error' - this.code = 'UND_ERR_RESPONSE_STATUS_CODE' - this.body = body - this.status = statusCode - this.statusCode = statusCode - this.headers = headers - } -} + if (client[kConnecting]) { + return + } -class InvalidArgumentError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, InvalidArgumentError) - this.name = 'InvalidArgumentError' - this.message = message || 'Invalid Argument Error' - this.code = 'UND_ERR_INVALID_ARG' - } -} + if (!socket && !client[kHTTP2Session]) { + connect(client) + return + } -class InvalidReturnValueError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, InvalidReturnValueError) - this.name = 'InvalidReturnValueError' - this.message = message || 'Invalid Return Value Error' - this.code = 'UND_ERR_INVALID_RETURN_VALUE' - } -} + if (socket.destroyed || socket[kWriting] || socket[kReset] || socket[kBlocking]) { + return + } -class RequestAbortedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, RequestAbortedError) - this.name = 'AbortError' - this.message = message || 'Request aborted' - this.code = 'UND_ERR_ABORTED' + if (client[kRunning] > 0 && !request.idempotent) { + // Non-idempotent request cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return + } + + if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) { + // Don't dispatch an upgrade until all preceding requests have completed. + // A misbehaving server might upgrade the connection before all pipelined + // request has completed. + return + } + + if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 && + (util.isStream(request.body) || util.isAsyncIterable(request.body))) { + // Request with stream or iterator body can error while other requests + // are inflight and indirectly error those as well. + // Ensure this doesn't happen by waiting for inflight + // to complete before dispatching. + + // Request with stream or iterator body cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return + } + + if (!request.aborted && write(client, request)) { + client[kPendingIdx]++ + } else { + client[kQueue].splice(client[kPendingIdx], 1) + } } } -class InformationalError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, InformationalError) - this.name = 'InformationalError' - this.message = message || 'Request information' - this.code = 'UND_ERR_INFO' - } +// https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 +function shouldSendContentLength (method) { + return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT' } -class RequestContentLengthMismatchError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, RequestContentLengthMismatchError) - this.name = 'RequestContentLengthMismatchError' - this.message = message || 'Request body length does not match content-length header' - this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' +function write (client, request) { + if (client[kHTTPConnVersion] === 'h2') { + writeH2(client, client[kHTTP2Session], request) + return } -} -class ResponseContentLengthMismatchError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ResponseContentLengthMismatchError) - this.name = 'ResponseContentLengthMismatchError' - this.message = message || 'Response body length does not match content-length header' - this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' - } -} + const { body, method, path, host, upgrade, headers, blocking, reset } = request -class ClientDestroyedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ClientDestroyedError) - this.name = 'ClientDestroyedError' - this.message = message || 'The client is destroyed' - this.code = 'UND_ERR_DESTROYED' - } -} + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 -class ClientClosedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ClientClosedError) - this.name = 'ClientClosedError' - this.message = message || 'The client is closed' - this.code = 'UND_ERR_CLOSED' - } -} + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. -class SocketError extends UndiciError { - constructor (message, socket) { - super(message) - Error.captureStackTrace(this, SocketError) - this.name = 'SocketError' - this.message = message || 'Socket error' - this.code = 'UND_ERR_SOCKET' - this.socket = socket - } -} + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ) -class NotSupportedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, NotSupportedError) - this.name = 'NotSupportedError' - this.message = message || 'Not supported error' - this.code = 'UND_ERR_NOT_SUPPORTED' + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) } -} -class BalancedPoolMissingUpstreamError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, NotSupportedError) - this.name = 'MissingUpstreamError' - this.message = message || 'No upstream has been added to the BalancedPool' - this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' - } -} + const bodyLength = util.bodyLength(body) -class HTTPParserError extends Error { - constructor (message, code, data) { - super(message) - Error.captureStackTrace(this, HTTPParserError) - this.name = 'HTTPParserError' - this.code = code ? `HPE_${code}` : undefined - this.data = data ? data.toString() : undefined - } -} + let contentLength = bodyLength -class ResponseExceededMaxSizeError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, ResponseExceededMaxSizeError) - this.name = 'ResponseExceededMaxSizeError' - this.message = message || 'Response content exceeded max size' - this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' + if (contentLength === null) { + contentLength = request.contentLength } -} -class RequestRetryError extends UndiciError { - constructor (message, code, { headers, data }) { - super(message) - Error.captureStackTrace(this, RequestRetryError) - this.name = 'RequestRetryError' - this.message = message || 'Request retry error' - this.code = 'UND_ERR_REQ_RETRY' - this.statusCode = code - this.data = data - this.headers = headers + if (contentLength === 0 && !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null } -} -module.exports = { - HTTPParserError, - UndiciError, - HeadersTimeoutError, - HeadersOverflowError, - BodyTimeoutError, - RequestContentLengthMismatchError, - ConnectTimeoutError, - ResponseStatusCodeError, - InvalidArgumentError, - InvalidReturnValueError, - RequestAbortedError, - ClientDestroyedError, - ClientClosedError, - InformationalError, - SocketError, - NotSupportedError, - ResponseContentLengthMismatchError, - BalancedPoolMissingUpstreamError, - ResponseExceededMaxSizeError, - RequestRetryError -} + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + errorRequest(client, request, new RequestContentLengthMismatchError()) + return false + } + process.emitWarning(new RequestContentLengthMismatchError()) + } -/***/ }), + const socket = client[kSocket] -/***/ 2905: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + try { + request.onConnect((err) => { + if (request.aborted || request.completed) { + return + } -"use strict"; + errorRequest(client, request, err || new RequestAbortedError()) + util.destroy(socket, new InformationalError('aborted')) + }) + } catch (err) { + errorRequest(client, request, err) + } -const { - InvalidArgumentError, - NotSupportedError -} = __nccwpck_require__(8045) -const assert = __nccwpck_require__(9491) -const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = __nccwpck_require__(2785) -const util = __nccwpck_require__(3983) + if (request.aborted) { + return false + } -// tokenRegExp and headerCharRegex have been lifted from -// https://github.com/nodejs/node/blob/main/lib/_http_common.js + if (method === 'HEAD') { + // https://github.com/mcollina/undici/issues/258 + // Close after a HEAD request to interop with misbehaving servers + // that may send a body in the response. -/** - * Verifies that the given val is a valid HTTP token - * per the rules defined in RFC 7230 - * See https://tools.ietf.org/html/rfc7230#section-3.2.6 - */ -const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/ + socket[kReset] = true + } -/** - * Matches if val contains an invalid field-vchar - * field-value = *( field-content / obs-fold ) - * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] - * field-vchar = VCHAR / obs-text - */ -const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/ + if (upgrade || method === 'CONNECT') { + // On CONNECT or upgrade, block pipeline from dispatching further + // requests on this connection. -// Verifies that a given path is valid does not contain control chars \x00 to \x20 -const invalidPathRegex = /[^\u0021-\u00ff]/ + socket[kReset] = true + } -const kHandler = Symbol('handler') + if (reset != null) { + socket[kReset] = reset + } -const channels = {} + if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) { + socket[kReset] = true + } -let extractBody + if (blocking) { + socket[kBlocking] = true + } -try { - const diagnosticsChannel = __nccwpck_require__(7643) - channels.create = diagnosticsChannel.channel('undici:request:create') - channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent') - channels.headers = diagnosticsChannel.channel('undici:request:headers') - channels.trailers = diagnosticsChannel.channel('undici:request:trailers') - channels.error = diagnosticsChannel.channel('undici:request:error') -} catch { - channels.create = { hasSubscribers: false } - channels.bodySent = { hasSubscribers: false } - channels.headers = { hasSubscribers: false } - channels.trailers = { hasSubscribers: false } - channels.error = { hasSubscribers: false } -} + let header = `${method} ${path} HTTP/1.1\r\n` -class Request { - constructor (origin, { - path, - method, - body, - headers, - query, - idempotent, - blocking, - upgrade, - headersTimeout, - bodyTimeout, - reset, - throwOnError, - expectContinue - }, handler) { - if (typeof path !== 'string') { - throw new InvalidArgumentError('path must be a string') - } else if ( - path[0] !== '/' && - !(path.startsWith('http://') || path.startsWith('https://')) && - method !== 'CONNECT' - ) { - throw new InvalidArgumentError('path must be an absolute URL or start with a slash') - } else if (invalidPathRegex.exec(path) !== null) { - throw new InvalidArgumentError('invalid request path') - } + if (typeof host === 'string') { + header += `host: ${host}\r\n` + } else { + header += client[kHostHeader] + } - if (typeof method !== 'string') { - throw new InvalidArgumentError('method must be a string') - } else if (tokenRegExp.exec(method) === null) { - throw new InvalidArgumentError('invalid request method') - } + if (upgrade) { + header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n` + } else if (client[kPipelining] && !socket[kReset]) { + header += 'connection: keep-alive\r\n' + } else { + header += 'connection: close\r\n' + } - if (upgrade && typeof upgrade !== 'string') { - throw new InvalidArgumentError('upgrade must be a string') - } + if (headers) { + header += headers + } - if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { - throw new InvalidArgumentError('invalid headersTimeout') - } + if (channels.sendHeaders.hasSubscribers) { + channels.sendHeaders.publish({ request, headers: header, socket }) + } - if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { - throw new InvalidArgumentError('invalid bodyTimeout') + /* istanbul ignore else: assertion */ + if (!body || bodyLength === 0) { + if (contentLength === 0) { + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + assert(contentLength === null, 'no body must not have content length') + socket.write(`${header}\r\n`, 'latin1') } + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') - if (reset != null && typeof reset !== 'boolean') { - throw new InvalidArgumentError('invalid reset') + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(body) + socket.uncork() + request.onBodySent(body) + request.onRequestSent() + if (!expectsPayload) { + socket[kReset] = true } - - if (expectContinue != null && typeof expectContinue !== 'boolean') { - throw new InvalidArgumentError('invalid expectContinue') + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ body: body.stream(), client, request, socket, contentLength, header, expectsPayload }) + } else { + writeBlob({ body, client, request, socket, contentLength, header, expectsPayload }) } + } else if (util.isStream(body)) { + writeStream({ body, client, request, socket, contentLength, header, expectsPayload }) + } else if (util.isIterable(body)) { + writeIterable({ body, client, request, socket, contentLength, header, expectsPayload }) + } else { + assert(false) + } - this.headersTimeout = headersTimeout - - this.bodyTimeout = bodyTimeout - - this.throwOnError = throwOnError === true - - this.method = method + return true +} - this.abort = null +function writeH2 (client, session, request) { + const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request - if (body == null) { - this.body = null - } else if (util.isStream(body)) { - this.body = body + let headers + if (typeof reqHeaders === 'string') headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()) + else headers = reqHeaders - const rState = this.body._readableState - if (!rState || !rState.autoDestroy) { - this.endHandler = function autoDestroy () { - util.destroy(this) - } - this.body.on('end', this.endHandler) - } + if (upgrade) { + errorRequest(client, request, new Error('Upgrade not supported for H2')) + return false + } - this.errorHandler = err => { - if (this.abort) { - this.abort(err) - } else { - this.error = err - } + try { + // TODO(HTTP/2): Should we call onConnect immediately or on stream ready event? + request.onConnect((err) => { + if (request.aborted || request.completed) { + return } - this.body.on('error', this.errorHandler) - } else if (util.isBuffer(body)) { - this.body = body.byteLength ? body : null - } else if (ArrayBuffer.isView(body)) { - this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null - } else if (body instanceof ArrayBuffer) { - this.body = body.byteLength ? Buffer.from(body) : null - } else if (typeof body === 'string') { - this.body = body.length ? Buffer.from(body) : null - } else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) { - this.body = body - } else { - throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') - } - this.completed = false - - this.aborted = false - - this.upgrade = upgrade || null + errorRequest(client, request, err || new RequestAbortedError()) + }) + } catch (err) { + errorRequest(client, request, err) + } - this.path = query ? util.buildURL(path, query) : path + if (request.aborted) { + return false + } - this.origin = origin + /** @type {import('node:http2').ClientHttp2Stream} */ + let stream + const h2State = client[kHTTP2SessionState] - this.idempotent = idempotent == null - ? method === 'HEAD' || method === 'GET' - : idempotent + headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost] + headers[HTTP2_HEADER_METHOD] = method - this.blocking = blocking == null ? false : blocking + if (method === 'CONNECT') { + session.ref() + // we are already connected, streams are pending, first request + // will create a new stream. We trigger a request to create the stream and wait until + // `ready` event is triggered + // We disabled endStream to allow the user to write to the stream + stream = session.request(headers, { endStream: false, signal }) - this.reset = reset == null ? null : reset + if (stream.id && !stream.pending) { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + } else { + stream.once('ready', () => { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + }) + } - this.host = null + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) session.unref() + }) - this.contentLength = null + return true + } - this.contentType = null + // https://tools.ietf.org/html/rfc7540#section-8.3 + // :path and :scheme headers must be omited when sending CONNECT - this.headers = '' + headers[HTTP2_HEADER_PATH] = path + headers[HTTP2_HEADER_SCHEME] = 'https' - // Only for H2 - this.expectContinue = expectContinue != null ? expectContinue : false + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 - if (Array.isArray(headers)) { - if (headers.length % 2 !== 0) { - throw new InvalidArgumentError('headers array must be even') - } - for (let i = 0; i < headers.length; i += 2) { - processHeader(this, headers[i], headers[i + 1]) - } - } else if (headers && typeof headers === 'object') { - const keys = Object.keys(headers) - for (let i = 0; i < keys.length; i++) { - const key = keys[i] - processHeader(this, key, headers[key]) - } - } else if (headers != null) { - throw new InvalidArgumentError('headers must be an object or an array') - } + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. - if (util.isFormDataLike(this.body)) { - if (util.nodeMajor < 16 || (util.nodeMajor === 16 && util.nodeMinor < 8)) { - throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.') - } + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ) - if (!extractBody) { - extractBody = (__nccwpck_require__(1472).extractBody) - } + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } - const [bodyStream, contentType] = extractBody(body) - if (this.contentType == null) { - this.contentType = contentType - this.headers += `content-type: ${contentType}\r\n` - } - this.body = bodyStream.stream - this.contentLength = bodyStream.length - } else if (util.isBlobLike(body) && this.contentType == null && body.type) { - this.contentType = body.type - this.headers += `content-type: ${body.type}\r\n` - } + let contentLength = util.bodyLength(body) - util.validateHandler(handler, method, upgrade) + if (contentLength == null) { + contentLength = request.contentLength + } - this.servername = util.getServerName(this.host) + if (contentLength === 0 || !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. - this[kHandler] = handler + contentLength = null + } - if (channels.create.hasSubscribers) { - channels.create.publish({ request: this }) + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength != null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + errorRequest(client, request, new RequestContentLengthMismatchError()) + return false } + + process.emitWarning(new RequestContentLengthMismatchError()) } - onBodySent (chunk) { - if (this[kHandler].onBodySent) { - try { - return this[kHandler].onBodySent(chunk) - } catch (err) { - this.abort(err) - } - } + if (contentLength != null) { + assert(body, 'no body must not have content length') + headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` } - onRequestSent () { - if (channels.bodySent.hasSubscribers) { - channels.bodySent.publish({ request: this }) - } + session.ref() - if (this[kHandler].onRequestSent) { - try { - return this[kHandler].onRequestSent() - } catch (err) { - this.abort(err) - } - } + const shouldEndStream = method === 'GET' || method === 'HEAD' + if (expectContinue) { + headers[HTTP2_HEADER_EXPECT] = '100-continue' + stream = session.request(headers, { endStream: shouldEndStream, signal }) + + stream.once('continue', writeBodyH2) + } else { + stream = session.request(headers, { + endStream: shouldEndStream, + signal + }) + writeBodyH2() } - onConnect (abort) { - assert(!this.aborted) - assert(!this.completed) + // Increment counter as we have new several streams open + ++h2State.openStreams - if (this.error) { - abort(this.error) - } else { - this.abort = abort - return this[kHandler].onConnect(abort) + stream.once('response', headers => { + const { [HTTP2_HEADER_STATUS]: statusCode, ...realHeaders } = headers + + if (request.onHeaders(Number(statusCode), realHeaders, stream.resume.bind(stream), '') === false) { + stream.pause() } - } + }) - onHeaders (statusCode, headers, resume, statusText) { - assert(!this.aborted) - assert(!this.completed) + stream.once('end', () => { + request.onComplete([]) + }) - if (channels.headers.hasSubscribers) { - channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) + stream.on('data', (chunk) => { + if (request.onData(chunk) === false) { + stream.pause() } + }) - try { - return this[kHandler].onHeaders(statusCode, headers, resume, statusText) - } catch (err) { - this.abort(err) + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) { + session.unref() } - } + }) - onData (chunk) { - assert(!this.aborted) - assert(!this.completed) + stream.once('error', function (err) { + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1 + util.destroy(stream, err) + } + }) - try { - return this[kHandler].onData(chunk) - } catch (err) { - this.abort(err) - return false + stream.once('frameError', (type, code) => { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) + errorRequest(client, request, err) + + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1 + util.destroy(stream, err) } - } + }) - onUpgrade (statusCode, headers, socket) { - assert(!this.aborted) - assert(!this.completed) + // stream.on('aborted', () => { + // // TODO(HTTP/2): Support aborted + // }) - return this[kHandler].onUpgrade(statusCode, headers, socket) - } + // stream.on('timeout', () => { + // // TODO(HTTP/2): Support timeout + // }) - onComplete (trailers) { - this.onFinally() + // stream.on('push', headers => { + // // TODO(HTTP/2): Suppor push + // }) - assert(!this.aborted) + // stream.on('trailers', headers => { + // // TODO(HTTP/2): Support trailers + // }) - this.completed = true - if (channels.trailers.hasSubscribers) { - channels.trailers.publish({ request: this, trailers }) - } + return true - try { - return this[kHandler].onComplete(trailers) - } catch (err) { - // TODO (fix): This might be a bad idea? - this.onError(err) + function writeBodyH2 () { + /* istanbul ignore else: assertion */ + if (!body) { + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') + stream.cork() + stream.write(body) + stream.uncork() + stream.end() + request.onBodySent(body) + request.onRequestSent() + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ + client, + request, + contentLength, + h2stream: stream, + expectsPayload, + body: body.stream(), + socket: client[kSocket], + header: '' + }) + } else { + writeBlob({ + body, + client, + request, + contentLength, + expectsPayload, + h2stream: stream, + header: '', + socket: client[kSocket] + }) + } + } else if (util.isStream(body)) { + writeStream({ + body, + client, + request, + contentLength, + expectsPayload, + socket: client[kSocket], + h2stream: stream, + header: '' + }) + } else if (util.isIterable(body)) { + writeIterable({ + body, + client, + request, + contentLength, + expectsPayload, + header: '', + h2stream: stream, + socket: client[kSocket] + }) + } else { + assert(false) } } +} - onError (error) { - this.onFinally() +function writeStream ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') - if (channels.error.hasSubscribers) { - channels.error.publish({ request: this, error }) - } + if (client[kHTTPConnVersion] === 'h2') { + // For HTTP/2, is enough to pipe the stream + const pipe = pipeline( + body, + h2stream, + (err) => { + if (err) { + util.destroy(body, err) + util.destroy(h2stream, err) + } else { + request.onRequestSent() + } + } + ) - if (this.aborted) { - return + pipe.on('data', onPipeData) + pipe.once('end', () => { + pipe.removeListener('data', onPipeData) + util.destroy(pipe) + }) + + function onPipeData (chunk) { + request.onBodySent(chunk) } - this.aborted = true - return this[kHandler].onError(error) + return } - onFinally () { - if (this.errorHandler) { - this.body.off('error', this.errorHandler) - this.errorHandler = null + let finished = false + + const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) + + const onData = function (chunk) { + if (finished) { + return } - if (this.endHandler) { - this.body.off('end', this.endHandler) - this.endHandler = null + try { + if (!writer.write(chunk) && this.pause) { + this.pause() + } + } catch (err) { + util.destroy(this, err) } } + const onDrain = function () { + if (finished) { + return + } - // TODO: adjust to support H2 - addHeader (key, value) { - processHeader(this, key, value) - return this + if (body.resume) { + body.resume() + } } - - static [kHTTP1BuildRequest] (origin, opts, handler) { - // TODO: Migrate header parsing here, to make Requests - // HTTP agnostic - return new Request(origin, opts, handler) + const onAbort = function () { + if (finished) { + return + } + const err = new RequestAbortedError() + queueMicrotask(() => onFinished(err)) } + const onFinished = function (err) { + if (finished) { + return + } - static [kHTTP2BuildRequest] (origin, opts, handler) { - const headers = opts.headers - opts = { ...opts, headers: null } - - const request = new Request(origin, opts, handler) + finished = true - request.headers = {} + assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1)) - if (Array.isArray(headers)) { - if (headers.length % 2 !== 0) { - throw new InvalidArgumentError('headers array must be even') - } - for (let i = 0; i < headers.length; i += 2) { - processHeader(request, headers[i], headers[i + 1], true) - } - } else if (headers && typeof headers === 'object') { - const keys = Object.keys(headers) - for (let i = 0; i < keys.length; i++) { - const key = keys[i] - processHeader(request, key, headers[key], true) + socket + .off('drain', onDrain) + .off('error', onFinished) + + body + .removeListener('data', onData) + .removeListener('end', onFinished) + .removeListener('error', onFinished) + .removeListener('close', onAbort) + + if (!err) { + try { + writer.end() + } catch (er) { + err = er } - } else if (headers != null) { - throw new InvalidArgumentError('headers must be an object or an array') } - return request + writer.destroy(err) + + if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { + util.destroy(body, err) + } else { + util.destroy(body) + } } - static [kHTTP2CopyHeaders] (raw) { - const rawHeaders = raw.split('\r\n') - const headers = {} + body + .on('data', onData) + .on('end', onFinished) + .on('error', onFinished) + .on('close', onAbort) - for (const header of rawHeaders) { - const [key, value] = header.split(': ') + if (body.resume) { + body.resume() + } - if (value == null || value.length === 0) continue + socket + .on('drain', onDrain) + .on('error', onFinished) +} - if (headers[key]) headers[key] += `,${value}` - else headers[key] = value +async function writeBlob ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength === body.size, 'blob body must have content length') + + const isH2 = client[kHTTPConnVersion] === 'h2' + try { + if (contentLength != null && contentLength !== body.size) { + throw new RequestContentLengthMismatchError() } - return headers - } -} + const buffer = Buffer.from(await body.arrayBuffer()) -function processHeaderValue (key, val, skipAppend) { - if (val && typeof val === 'object') { - throw new InvalidArgumentError(`invalid ${key} header`) - } + if (isH2) { + h2stream.cork() + h2stream.write(buffer) + h2stream.uncork() + } else { + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(buffer) + socket.uncork() + } - val = val != null ? `${val}` : '' + request.onBodySent(buffer) + request.onRequestSent() - if (headerCharRegex.exec(val) !== null) { - throw new InvalidArgumentError(`invalid ${key} header`) - } + if (!expectsPayload) { + socket[kReset] = true + } - return skipAppend ? val : `${key}: ${val}\r\n` + resume(client) + } catch (err) { + util.destroy(isH2 ? h2stream : socket, err) + } } -function processHeader (request, key, val, skipAppend = false) { - if (val && (typeof val === 'object' && !Array.isArray(val))) { - throw new InvalidArgumentError(`invalid ${key} header`) - } else if (val === undefined) { - return - } +async function writeIterable ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { + assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') - if ( - request.host === null && - key.length === 4 && - key.toLowerCase() === 'host' - ) { - if (headerCharRegex.exec(val) !== null) { - throw new InvalidArgumentError(`invalid ${key} header`) - } - // Consumed by Client - request.host = val - } else if ( - request.contentLength === null && - key.length === 14 && - key.toLowerCase() === 'content-length' - ) { - request.contentLength = parseInt(val, 10) - if (!Number.isFinite(request.contentLength)) { - throw new InvalidArgumentError('invalid content-length header') + let callback = null + function onDrain () { + if (callback) { + const cb = callback + callback = null + cb() } - } else if ( - request.contentType === null && - key.length === 12 && - key.toLowerCase() === 'content-type' - ) { - request.contentType = val - if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) - else request.headers += processHeaderValue(key, val) - } else if ( - key.length === 17 && - key.toLowerCase() === 'transfer-encoding' - ) { - throw new InvalidArgumentError('invalid transfer-encoding header') - } else if ( - key.length === 10 && - key.toLowerCase() === 'connection' - ) { - const value = typeof val === 'string' ? val.toLowerCase() : null - if (value !== 'close' && value !== 'keep-alive') { - throw new InvalidArgumentError('invalid connection header') - } else if (value === 'close') { - request.reset = true + } + + const waitForDrain = () => new Promise((resolve, reject) => { + assert(callback === null) + + if (socket[kError]) { + reject(socket[kError]) + } else { + callback = resolve } - } else if ( - key.length === 10 && - key.toLowerCase() === 'keep-alive' - ) { - throw new InvalidArgumentError('invalid keep-alive header') - } else if ( - key.length === 7 && - key.toLowerCase() === 'upgrade' - ) { - throw new InvalidArgumentError('invalid upgrade header') - } else if ( - key.length === 6 && - key.toLowerCase() === 'expect' - ) { - throw new NotSupportedError('expect header not supported') - } else if (tokenRegExp.exec(key) === null) { - throw new InvalidArgumentError('invalid header key') - } else { - if (Array.isArray(val)) { - for (let i = 0; i < val.length; i++) { - if (skipAppend) { - if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` - else request.headers[key] = processHeaderValue(key, val[i], skipAppend) - } else { - request.headers += processHeaderValue(key, val[i]) + }) + + if (client[kHTTPConnVersion] === 'h2') { + h2stream + .on('close', onDrain) + .on('drain', onDrain) + + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + const res = h2stream.write(chunk) + request.onBodySent(chunk) + if (!res) { + await waitForDrain() } } - } else { - if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) - else request.headers += processHeaderValue(key, val) + } catch (err) { + h2stream.destroy(err) + } finally { + request.onRequestSent() + h2stream.end() + h2stream + .off('close', onDrain) + .off('drain', onDrain) } + + return } -} -module.exports = Request + socket + .on('close', onDrain) + .on('drain', onDrain) + const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } -/***/ }), + if (!writer.write(chunk)) { + await waitForDrain() + } + } -/***/ 2785: -/***/ ((module) => { + writer.end() + } catch (err) { + writer.destroy(err) + } finally { + socket + .off('close', onDrain) + .off('drain', onDrain) + } +} -module.exports = { - kClose: Symbol('close'), - kDestroy: Symbol('destroy'), - kDispatch: Symbol('dispatch'), - kUrl: Symbol('url'), - kWriting: Symbol('writing'), - kResuming: Symbol('resuming'), - kQueue: Symbol('queue'), - kConnect: Symbol('connect'), - kConnecting: Symbol('connecting'), - kHeadersList: Symbol('headers list'), - kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), - kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), - kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), - kKeepAliveTimeoutValue: Symbol('keep alive timeout'), - kKeepAlive: Symbol('keep alive'), - kHeadersTimeout: Symbol('headers timeout'), - kBodyTimeout: Symbol('body timeout'), - kServerName: Symbol('server name'), - kLocalAddress: Symbol('local address'), - kHost: Symbol('host'), - kNoRef: Symbol('no ref'), - kBodyUsed: Symbol('used'), - kRunning: Symbol('running'), - kBlocking: Symbol('blocking'), - kPending: Symbol('pending'), - kSize: Symbol('size'), - kBusy: Symbol('busy'), - kQueued: Symbol('queued'), - kFree: Symbol('free'), - kConnected: Symbol('connected'), - kClosed: Symbol('closed'), - kNeedDrain: Symbol('need drain'), - kReset: Symbol('reset'), - kDestroyed: Symbol.for('nodejs.stream.destroyed'), - kMaxHeadersSize: Symbol('max headers size'), - kRunningIdx: Symbol('running index'), - kPendingIdx: Symbol('pending index'), - kError: Symbol('error'), - kClients: Symbol('clients'), - kClient: Symbol('client'), - kParser: Symbol('parser'), - kOnDestroyed: Symbol('destroy callbacks'), - kPipelining: Symbol('pipelining'), - kSocket: Symbol('socket'), - kHostHeader: Symbol('host header'), - kConnector: Symbol('connector'), - kStrictContentLength: Symbol('strict content length'), - kMaxRedirections: Symbol('maxRedirections'), - kMaxRequests: Symbol('maxRequestsPerClient'), - kProxy: Symbol('proxy agent options'), - kCounter: Symbol('socket request counter'), - kInterceptors: Symbol('dispatch interceptors'), - kMaxResponseSize: Symbol('max response size'), - kHTTP2Session: Symbol('http2Session'), - kHTTP2SessionState: Symbol('http2Session state'), - kHTTP2BuildRequest: Symbol('http2 build request'), - kHTTP1BuildRequest: Symbol('http1 build request'), - kHTTP2CopyHeaders: Symbol('http2 copy headers'), - kHTTPConnVersion: Symbol('http connection version'), - kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), - kConstruct: Symbol('constructable') -} +class AsyncWriter { + constructor ({ socket, request, contentLength, client, expectsPayload, header }) { + this.socket = socket + this.request = request + this.contentLength = contentLength + this.client = client + this.bytesWritten = 0 + this.expectsPayload = expectsPayload + this.header = header + socket[kWriting] = true + } -/***/ }), + write (chunk) { + const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this -/***/ 3983: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (socket[kError]) { + throw socket[kError] + } -"use strict"; + if (socket.destroyed) { + return false + } + const len = Buffer.byteLength(chunk) + if (!len) { + return true + } -const assert = __nccwpck_require__(9491) -const { kDestroyed, kBodyUsed } = __nccwpck_require__(2785) -const { IncomingMessage } = __nccwpck_require__(3685) -const stream = __nccwpck_require__(2781) -const net = __nccwpck_require__(1808) -const { InvalidArgumentError } = __nccwpck_require__(8045) -const { Blob } = __nccwpck_require__(4300) -const nodeUtil = __nccwpck_require__(3837) -const { stringify } = __nccwpck_require__(3477) + // We should defer writing chunks. + if (contentLength !== null && bytesWritten + len > contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } -const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)) + process.emitWarning(new RequestContentLengthMismatchError()) + } -function nop () {} + socket.cork() -function isStream (obj) { - return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' -} + if (bytesWritten === 0) { + if (!expectsPayload) { + socket[kReset] = true + } -// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) -function isBlobLike (object) { - return (Blob && object instanceof Blob) || ( - object && - typeof object === 'object' && - (typeof object.stream === 'function' || - typeof object.arrayBuffer === 'function') && - /^(Blob|File)$/.test(object[Symbol.toStringTag]) - ) -} + if (contentLength === null) { + socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1') + } else { + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + } + } -function buildURL (url, queryParams) { - if (url.includes('?') || url.includes('#')) { - throw new Error('Query params cannot be passed when url already contains "?" or "#".') - } + if (contentLength === null) { + socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1') + } - const stringified = stringify(queryParams) + this.bytesWritten += len - if (stringified) { - url += '?' + stringified - } + const ret = socket.write(chunk) - return url -} + socket.uncork() -function parseURL (url) { - if (typeof url === 'string') { - url = new URL(url) + request.onBodySent(chunk) - if (!/^https?:/.test(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + if (!ret) { + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } + } } - return url + return ret } - if (!url || typeof url !== 'object') { - throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') - } + end () { + const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this + request.onRequestSent() - if (!/^https?:/.test(url.origin || url.protocol)) { - throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') - } + socket[kWriting] = false - if (!(url instanceof URL)) { - if (url.port != null && url.port !== '' && !Number.isFinite(parseInt(url.port))) { - throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') + if (socket[kError]) { + throw socket[kError] } - if (url.path != null && typeof url.path !== 'string') { - throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') + if (socket.destroyed) { + return } - if (url.pathname != null && typeof url.pathname !== 'string') { - throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') - } + if (bytesWritten === 0) { + if (expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD send a Content-Length in a request message when + // no Transfer-Encoding is sent and the request method defines a meaning + // for an enclosed payload body. - if (url.hostname != null && typeof url.hostname !== 'string') { - throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + socket.write(`${header}\r\n`, 'latin1') + } + } else if (contentLength === null) { + socket.write('\r\n0\r\n\r\n', 'latin1') } - if (url.origin != null && typeof url.origin !== 'string') { - throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') + if (contentLength !== null && bytesWritten !== contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } else { + process.emitWarning(new RequestContentLengthMismatchError()) + } } - const port = url.port != null - ? url.port - : (url.protocol === 'https:' ? 443 : 80) - let origin = url.origin != null - ? url.origin - : `${url.protocol}//${url.hostname}:${port}` - let path = url.path != null - ? url.path - : `${url.pathname || ''}${url.search || ''}` - - if (origin.endsWith('/')) { - origin = origin.substring(0, origin.length - 1) + if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } } - if (path && !path.startsWith('/')) { - path = `/${path}` - } - // new URL(path, origin) is unsafe when `path` contains an absolute URL - // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: - // If first parameter is a relative URL, second param is required, and will be used as the base URL. - // If first parameter is an absolute URL, a given second param will be ignored. - url = new URL(origin + path) + resume(client) } - return url -} + destroy (err) { + const { socket, client } = this -function parseOrigin (url) { - url = parseURL(url) + socket[kWriting] = false - if (url.pathname !== '/' || url.search || url.hash) { - throw new InvalidArgumentError('invalid url') + if (err) { + assert(client[kRunning] <= 1, 'pipeline should only contain this request') + util.destroy(socket, err) + } } +} - return url +function errorRequest (client, request, err) { + try { + request.onError(err) + assert(request.aborted) + } catch (err) { + client.emit('error', err) + } } -function getHostname (host) { - if (host[0] === '[') { - const idx = host.indexOf(']') +module.exports = Client - assert(idx !== -1) - return host.substring(1, idx) - } - const idx = host.indexOf(':') - if (idx === -1) return host +/***/ }), - return host.substring(0, idx) -} +/***/ 6436: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -// IP addresses are not valid server names per RFC6066 -// > Currently, the only server names supported are DNS hostnames -function getServerName (host) { - if (!host) { - return null - } +"use strict"; - assert.strictEqual(typeof host, 'string') - const servername = getHostname(host) - if (net.isIP(servername)) { - return '' +/* istanbul ignore file: only for Node 12 */ + +const { kConnected, kSize } = __nccwpck_require__(2785) + +class CompatWeakRef { + constructor (value) { + this.value = value } - return servername + deref () { + return this.value[kConnected] === 0 && this.value[kSize] === 0 + ? undefined + : this.value + } } -function deepClone (obj) { - return JSON.parse(JSON.stringify(obj)) -} +class CompatFinalizer { + constructor (finalizer) { + this.finalizer = finalizer + } -function isAsyncIterable (obj) { - return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') + register (dispatcher, key) { + if (dispatcher.on) { + dispatcher.on('disconnect', () => { + if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { + this.finalizer(key) + } + }) + } + } } -function isIterable (obj) { - return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) +module.exports = function () { + // FIXME: remove workaround when the Node bug is fixed + // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 + if (process.env.NODE_V8_COVERAGE) { + return { + WeakRef: CompatWeakRef, + FinalizationRegistry: CompatFinalizer + } + } + return { + WeakRef: global.WeakRef || CompatWeakRef, + FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer + } } -function bodyLength (body) { - if (body == null) { - return 0 - } else if (isStream(body)) { - const state = body._readableState - return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) - ? state.length - : null - } else if (isBlobLike(body)) { - return body.size != null ? body.size : null - } else if (isBuffer(body)) { - return body.byteLength - } - return null -} +/***/ }), -function isDestroyed (stream) { - return !stream || !!(stream.destroyed || stream[kDestroyed]) -} +/***/ 663: +/***/ ((module) => { -function isReadableAborted (stream) { - const state = stream && stream._readableState - return isDestroyed(stream) && state && !state.endEmitted -} +"use strict"; -function destroy (stream, err) { - if (stream == null || !isStream(stream) || isDestroyed(stream)) { - return - } - if (typeof stream.destroy === 'function') { - if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { - // See: https://github.com/nodejs/node/pull/38505/files - stream.socket = null - } +// https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size +const maxAttributeValueSize = 1024 - stream.destroy(err) - } else if (err) { - process.nextTick((stream, err) => { - stream.emit('error', err) - }, stream, err) - } +// https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size +const maxNameValuePairSize = 4096 - if (stream.destroyed !== true) { - stream[kDestroyed] = true - } +module.exports = { + maxAttributeValueSize, + maxNameValuePairSize } -const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/ -function parseKeepAliveTimeout (val) { - const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR) - return m ? parseInt(m[1], 10) * 1000 : null -} -function parseHeaders (headers, obj = {}) { - // For H2 support - if (!Array.isArray(headers)) return headers +/***/ }), - for (let i = 0; i < headers.length; i += 2) { - const key = headers[i].toString().toLowerCase() - let val = obj[key] +/***/ 1724: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!val) { - if (Array.isArray(headers[i + 1])) { - obj[key] = headers[i + 1].map(x => x.toString('utf8')) - } else { - obj[key] = headers[i + 1].toString('utf8') - } - } else { - if (!Array.isArray(val)) { - val = [val] - obj[key] = val - } - val.push(headers[i + 1].toString('utf8')) - } - } +"use strict"; - // See https://github.com/nodejs/node/pull/46528 - if ('content-length' in obj && 'content-disposition' in obj) { - obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1') - } - return obj -} +const { parseSetCookie } = __nccwpck_require__(4408) +const { stringify, getHeadersList } = __nccwpck_require__(3121) +const { webidl } = __nccwpck_require__(1744) +const { Headers } = __nccwpck_require__(554) -function parseRawHeaders (headers) { - const ret = [] - let hasContentLength = false - let contentDispositionIdx = -1 +/** + * @typedef {Object} Cookie + * @property {string} name + * @property {string} value + * @property {Date|number|undefined} expires + * @property {number|undefined} maxAge + * @property {string|undefined} domain + * @property {string|undefined} path + * @property {boolean|undefined} secure + * @property {boolean|undefined} httpOnly + * @property {'Strict'|'Lax'|'None'} sameSite + * @property {string[]} unparsed + */ - for (let n = 0; n < headers.length; n += 2) { - const key = headers[n + 0].toString() - const val = headers[n + 1].toString('utf8') +/** + * @param {Headers} headers + * @returns {Record} + */ +function getCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, { header: 'getCookies' }) - if (key.length === 14 && (key === 'content-length' || key.toLowerCase() === 'content-length')) { - ret.push(key, val) - hasContentLength = true - } else if (key.length === 19 && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) { - contentDispositionIdx = ret.push(key, val) - 1 - } else { - ret.push(key, val) - } + webidl.brandCheck(headers, Headers, { strict: false }) + + const cookie = headers.get('cookie') + const out = {} + + if (!cookie) { + return out } - // See https://github.com/nodejs/node/pull/46528 - if (hasContentLength && contentDispositionIdx !== -1) { - ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1') + for (const piece of cookie.split(';')) { + const [name, ...value] = piece.split('=') + + out[name.trim()] = value.join('=') } - return ret + return out } -function isBuffer (buffer) { - // See, https://github.com/mcollina/undici/pull/319 - return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) +/** + * @param {Headers} headers + * @param {string} name + * @param {{ path?: string, domain?: string }|undefined} attributes + * @returns {void} + */ +function deleteCookie (headers, name, attributes) { + webidl.argumentLengthCheck(arguments, 2, { header: 'deleteCookie' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + name = webidl.converters.DOMString(name) + attributes = webidl.converters.DeleteCookieAttributes(attributes) + + // Matches behavior of + // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 + setCookie(headers, { + name, + value: '', + expires: new Date(0), + ...attributes + }) } -function validateHandler (handler, method, upgrade) { - if (!handler || typeof handler !== 'object') { - throw new InvalidArgumentError('handler must be an object') - } +/** + * @param {Headers} headers + * @returns {Cookie[]} + */ +function getSetCookies (headers) { + webidl.argumentLengthCheck(arguments, 1, { header: 'getSetCookies' }) - if (typeof handler.onConnect !== 'function') { - throw new InvalidArgumentError('invalid onConnect method') - } + webidl.brandCheck(headers, Headers, { strict: false }) - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') - } + const cookies = getHeadersList(headers).cookies - if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { - throw new InvalidArgumentError('invalid onBodySent method') + if (!cookies) { + return [] } - if (upgrade || method === 'CONNECT') { - if (typeof handler.onUpgrade !== 'function') { - throw new InvalidArgumentError('invalid onUpgrade method') - } - } else { - if (typeof handler.onHeaders !== 'function') { - throw new InvalidArgumentError('invalid onHeaders method') - } - - if (typeof handler.onData !== 'function') { - throw new InvalidArgumentError('invalid onData method') - } - - if (typeof handler.onComplete !== 'function') { - throw new InvalidArgumentError('invalid onComplete method') - } - } + // In older versions of undici, cookies is a list of name:value. + return cookies.map((pair) => parseSetCookie(Array.isArray(pair) ? pair[1] : pair)) } -// A body is disturbed if it has been read from and it cannot -// be re-used without losing state or data. -function isDisturbed (body) { - return !!(body && ( - stream.isDisturbed - ? stream.isDisturbed(body) || body[kBodyUsed] // TODO (fix): Why is body[kBodyUsed] needed? - : body[kBodyUsed] || - body.readableDidRead || - (body._readableState && body._readableState.dataEmitted) || - isReadableAborted(body) - )) -} +/** + * @param {Headers} headers + * @param {Cookie} cookie + * @returns {void} + */ +function setCookie (headers, cookie) { + webidl.argumentLengthCheck(arguments, 2, { header: 'setCookie' }) -function isErrored (body) { - return !!(body && ( - stream.isErrored - ? stream.isErrored(body) - : /state: 'errored'/.test(nodeUtil.inspect(body) - ))) -} + webidl.brandCheck(headers, Headers, { strict: false }) -function isReadable (body) { - return !!(body && ( - stream.isReadable - ? stream.isReadable(body) - : /state: 'readable'/.test(nodeUtil.inspect(body) - ))) -} + cookie = webidl.converters.Cookie(cookie) -function getSocketInfo (socket) { - return { - localAddress: socket.localAddress, - localPort: socket.localPort, - remoteAddress: socket.remoteAddress, - remotePort: socket.remotePort, - remoteFamily: socket.remoteFamily, - timeout: socket.timeout, - bytesWritten: socket.bytesWritten, - bytesRead: socket.bytesRead - } -} + const str = stringify(cookie) -async function * convertIterableToBuffer (iterable) { - for await (const chunk of iterable) { - yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) + if (str) { + headers.append('Set-Cookie', stringify(cookie)) } } -let ReadableStream -function ReadableStreamFrom (iterable) { - if (!ReadableStream) { - ReadableStream = (__nccwpck_require__(5356).ReadableStream) +webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: null } +]) - if (ReadableStream.from) { - return ReadableStream.from(convertIterableToBuffer(iterable)) +webidl.converters.Cookie = webidl.dictionaryConverter([ + { + converter: webidl.converters.DOMString, + key: 'name' + }, + { + converter: webidl.converters.DOMString, + key: 'value' + }, + { + converter: webidl.nullableConverter((value) => { + if (typeof value === 'number') { + return webidl.converters['unsigned long long'](value) + } + + return new Date(value) + }), + key: 'expires', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters['long long']), + key: 'maxAge', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'secure', + defaultValue: null + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'httpOnly', + defaultValue: null + }, + { + converter: webidl.converters.USVString, + key: 'sameSite', + allowedValues: ['Strict', 'Lax', 'None'] + }, + { + converter: webidl.sequenceConverter(webidl.converters.DOMString), + key: 'unparsed', + defaultValue: [] } +]) - let iterator - return new ReadableStream( - { - async start () { - iterator = iterable[Symbol.asyncIterator]() - }, - async pull (controller) { - const { done, value } = await iterator.next() - if (done) { - queueMicrotask(() => { - controller.close() - }) - } else { - const buf = Buffer.isBuffer(value) ? value : Buffer.from(value) - controller.enqueue(new Uint8Array(buf)) - } - return controller.desiredSize > 0 - }, - async cancel (reason) { - await iterator.return() - } - }, - 0 - ) +module.exports = { + getCookies, + deleteCookie, + getSetCookies, + setCookie } -// The chunk should be a FormData instance and contains -// all the required methods. -function isFormDataLike (object) { - return ( - object && - typeof object === 'object' && - typeof object.append === 'function' && - typeof object.delete === 'function' && - typeof object.get === 'function' && - typeof object.getAll === 'function' && - typeof object.has === 'function' && - typeof object.set === 'function' && - object[Symbol.toStringTag] === 'FormData' - ) -} -function throwIfAborted (signal) { - if (!signal) { return } - if (typeof signal.throwIfAborted === 'function') { - signal.throwIfAborted() - } else { - if (signal.aborted) { - // DOMException not available < v17.0.0 - const err = new Error('The operation was aborted') - err.name = 'AbortError' - throw err - } - } -} +/***/ }), -function addAbortListener (signal, listener) { - if ('addEventListener' in signal) { - signal.addEventListener('abort', listener, { once: true }) - return () => signal.removeEventListener('abort', listener) - } - signal.addListener('abort', listener) - return () => signal.removeListener('abort', listener) -} +/***/ 4408: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const hasToWellFormed = !!String.prototype.toWellFormed +"use strict"; + + +const { maxNameValuePairSize, maxAttributeValueSize } = __nccwpck_require__(663) +const { isCTLExcludingHtab } = __nccwpck_require__(3121) +const { collectASequenceOfCodePointsFast } = __nccwpck_require__(685) +const assert = __nccwpck_require__(9491) /** - * @param {string} val + * @description Parses the field-value attributes of a set-cookie header string. + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} header + * @returns if the header is invalid, null will be returned */ -function toUSVString (val) { - if (hasToWellFormed) { - return `${val}`.toWellFormed() - } else if (nodeUtil.toUSVString) { - return nodeUtil.toUSVString(val) +function parseSetCookie (header) { + // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F + // character (CTL characters excluding HTAB): Abort these steps and + // ignore the set-cookie-string entirely. + if (isCTLExcludingHtab(header)) { + return null } - return `${val}` -} + let nameValuePair = '' + let unparsedAttributes = '' + let name = '' + let value = '' -// Parsed accordingly to RFC 9110 -// https://www.rfc-editor.org/rfc/rfc9110#field.content-range -function parseRangeHeader (range) { - if (range == null || range === '') return { start: 0, end: null, size: null } + // 2. If the set-cookie-string contains a %x3B (";") character: + if (header.includes(';')) { + // 1. The name-value-pair string consists of the characters up to, + // but not including, the first %x3B (";"), and the unparsed- + // attributes consist of the remainder of the set-cookie-string + // (including the %x3B (";") in question). + const position = { position: 0 } - const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null - return m - ? { - start: parseInt(m[1]), - end: m[2] ? parseInt(m[2]) : null, - size: m[3] ? parseInt(m[3]) : null - } - : null -} + nameValuePair = collectASequenceOfCodePointsFast(';', header, position) + unparsedAttributes = header.slice(position.position) + } else { + // Otherwise: -const kEnumerableProperty = Object.create(null) -kEnumerableProperty.enumerable = true + // 1. The name-value-pair string consists of all the characters + // contained in the set-cookie-string, and the unparsed- + // attributes is the empty string. + nameValuePair = header + } -module.exports = { - kEnumerableProperty, - nop, - isDisturbed, - isErrored, - isReadable, - toUSVString, - isReadableAborted, - isBlobLike, - parseOrigin, - parseURL, - getServerName, - isStream, - isIterable, - isAsyncIterable, - isDestroyed, - parseRawHeaders, - parseHeaders, - parseKeepAliveTimeout, - destroy, - bodyLength, - deepClone, - ReadableStreamFrom, - isBuffer, - validateHandler, - getSocketInfo, - isFormDataLike, - buildURL, - throwIfAborted, - addAbortListener, - parseRangeHeader, - nodeMajor, - nodeMinor, - nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13), - safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'] + // 3. If the name-value-pair string lacks a %x3D ("=") character, then + // the name string is empty, and the value string is the value of + // name-value-pair. + if (!nameValuePair.includes('=')) { + value = nameValuePair + } else { + // Otherwise, the name string consists of the characters up to, but + // not including, the first %x3D ("=") character, and the (possibly + // empty) value string consists of the characters after the first + // %x3D ("=") character. + const position = { position: 0 } + name = collectASequenceOfCodePointsFast( + '=', + nameValuePair, + position + ) + value = nameValuePair.slice(position.position + 1) + } + + // 4. Remove any leading or trailing WSP characters from the name + // string and the value string. + name = name.trim() + value = value.trim() + + // 5. If the sum of the lengths of the name string and the value string + // is more than 4096 octets, abort these steps and ignore the set- + // cookie-string entirely. + if (name.length + value.length > maxNameValuePairSize) { + return null + } + + // 6. The cookie-name is the name string, and the cookie-value is the + // value string. + return { + name, value, ...parseUnparsedAttributes(unparsedAttributes) + } } +/** + * Parses the remaining attributes of a set-cookie header + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} unparsedAttributes + * @param {[Object.]={}} cookieAttributeList + */ +function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {}) { + // 1. If the unparsed-attributes string is empty, skip the rest of + // these steps. + if (unparsedAttributes.length === 0) { + return cookieAttributeList + } -/***/ }), + // 2. Discard the first character of the unparsed-attributes (which + // will be a %x3B (";") character). + assert(unparsedAttributes[0] === ';') + unparsedAttributes = unparsedAttributes.slice(1) -/***/ 4839: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + let cookieAv = '' -"use strict"; + // 3. If the remaining unparsed-attributes contains a %x3B (";") + // character: + if (unparsedAttributes.includes(';')) { + // 1. Consume the characters of the unparsed-attributes up to, but + // not including, the first %x3B (";") character. + cookieAv = collectASequenceOfCodePointsFast( + ';', + unparsedAttributes, + { position: 0 } + ) + unparsedAttributes = unparsedAttributes.slice(cookieAv.length) + } else { + // Otherwise: + // 1. Consume the remainder of the unparsed-attributes. + cookieAv = unparsedAttributes + unparsedAttributes = '' + } -const Dispatcher = __nccwpck_require__(412) -const { - ClientDestroyedError, - ClientClosedError, - InvalidArgumentError -} = __nccwpck_require__(8045) -const { kDestroy, kClose, kDispatch, kInterceptors } = __nccwpck_require__(2785) + // Let the cookie-av string be the characters consumed in this step. -const kDestroyed = Symbol('destroyed') -const kClosed = Symbol('closed') -const kOnDestroyed = Symbol('onDestroyed') -const kOnClosed = Symbol('onClosed') -const kInterceptedDispatch = Symbol('Intercepted Dispatch') + let attributeName = '' + let attributeValue = '' -class DispatcherBase extends Dispatcher { - constructor () { - super() + // 4. If the cookie-av string contains a %x3D ("=") character: + if (cookieAv.includes('=')) { + // 1. The (possibly empty) attribute-name string consists of the + // characters up to, but not including, the first %x3D ("=") + // character, and the (possibly empty) attribute-value string + // consists of the characters after the first %x3D ("=") + // character. + const position = { position: 0 } - this[kDestroyed] = false - this[kOnDestroyed] = null - this[kClosed] = false - this[kOnClosed] = [] - } + attributeName = collectASequenceOfCodePointsFast( + '=', + cookieAv, + position + ) + attributeValue = cookieAv.slice(position.position + 1) + } else { + // Otherwise: - get destroyed () { - return this[kDestroyed] + // 1. The attribute-name string consists of the entire cookie-av + // string, and the attribute-value string is empty. + attributeName = cookieAv } - get closed () { - return this[kClosed] - } + // 5. Remove any leading or trailing WSP characters from the attribute- + // name string and the attribute-value string. + attributeName = attributeName.trim() + attributeValue = attributeValue.trim() - get interceptors () { - return this[kInterceptors] + // 6. If the attribute-value is longer than 1024 octets, ignore the + // cookie-av string and return to Step 1 of this algorithm. + if (attributeValue.length > maxAttributeValueSize) { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) } - set interceptors (newInterceptors) { - if (newInterceptors) { - for (let i = newInterceptors.length - 1; i >= 0; i--) { - const interceptor = this[kInterceptors][i] - if (typeof interceptor !== 'function') { - throw new InvalidArgumentError('interceptor must be an function') - } - } - } + // 7. Process the attribute-name and attribute-value according to the + // requirements in the following subsections. (Notice that + // attributes with unrecognized attribute-names are ignored.) + const attributeNameLowercase = attributeName.toLowerCase() - this[kInterceptors] = newInterceptors - } + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 + // If the attribute-name case-insensitively matches the string + // "Expires", the user agent MUST process the cookie-av as follows. + if (attributeNameLowercase === 'expires') { + // 1. Let the expiry-time be the result of parsing the attribute-value + // as cookie-date (see Section 5.1.1). + const expiryTime = new Date(attributeValue) - close (callback) { - if (callback === undefined) { - return new Promise((resolve, reject) => { - this.close((err, data) => { - return err ? reject(err) : resolve(data) - }) - }) - } + // 2. If the attribute-value failed to parse as a cookie date, ignore + // the cookie-av. - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + cookieAttributeList.expires = expiryTime + } else if (attributeNameLowercase === 'max-age') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 + // If the attribute-name case-insensitively matches the string "Max- + // Age", the user agent MUST process the cookie-av as follows. - if (this[kDestroyed]) { - queueMicrotask(() => callback(new ClientDestroyedError(), null)) - return + // 1. If the first character of the attribute-value is not a DIGIT or a + // "-" character, ignore the cookie-av. + const charCode = attributeValue.charCodeAt(0) + + if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) } - if (this[kClosed]) { - if (this[kOnClosed]) { - this[kOnClosed].push(callback) - } else { - queueMicrotask(() => callback(null, null)) - } - return + // 2. If the remainder of attribute-value contains a non-DIGIT + // character, ignore the cookie-av. + if (!/^\d+$/.test(attributeValue)) { + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) } - this[kClosed] = true - this[kOnClosed].push(callback) + // 3. Let delta-seconds be the attribute-value converted to an integer. + const deltaSeconds = Number(attributeValue) - const onClosed = () => { - const callbacks = this[kOnClosed] - this[kOnClosed] = null - for (let i = 0; i < callbacks.length; i++) { - callbacks[i](null, null) - } - } + // 4. Let cookie-age-limit be the maximum age of the cookie (which + // SHOULD be 400 days or less, see Section 4.1.2.2). - // Should not error. - this[kClose]() - .then(() => this.destroy()) - .then(() => { - queueMicrotask(onClosed) - }) - } - - destroy (err, callback) { - if (typeof err === 'function') { - callback = err - err = null - } - - if (callback === undefined) { - return new Promise((resolve, reject) => { - this.destroy(err, (err, data) => { - return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) - }) - }) - } - - if (typeof callback !== 'function') { - throw new InvalidArgumentError('invalid callback') - } + // 5. Set delta-seconds to the smaller of its present value and cookie- + // age-limit. + // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) - if (this[kDestroyed]) { - if (this[kOnDestroyed]) { - this[kOnDestroyed].push(callback) - } else { - queueMicrotask(() => callback(null, null)) - } - return - } + // 6. If delta-seconds is less than or equal to zero (0), let expiry- + // time be the earliest representable date and time. Otherwise, let + // the expiry-time be the current date and time plus delta-seconds + // seconds. + // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds - if (!err) { - err = new ClientDestroyedError() - } + // 7. Append an attribute to the cookie-attribute-list with an + // attribute-name of Max-Age and an attribute-value of expiry-time. + cookieAttributeList.maxAge = deltaSeconds + } else if (attributeNameLowercase === 'domain') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 + // If the attribute-name case-insensitively matches the string "Domain", + // the user agent MUST process the cookie-av as follows. - this[kDestroyed] = true - this[kOnDestroyed] = this[kOnDestroyed] || [] - this[kOnDestroyed].push(callback) + // 1. Let cookie-domain be the attribute-value. + let cookieDomain = attributeValue - const onDestroyed = () => { - const callbacks = this[kOnDestroyed] - this[kOnDestroyed] = null - for (let i = 0; i < callbacks.length; i++) { - callbacks[i](null, null) - } + // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be + // cookie-domain without its leading %x2E ("."). + if (cookieDomain[0] === '.') { + cookieDomain = cookieDomain.slice(1) } - // Should not error. - this[kDestroy](err).then(() => { - queueMicrotask(onDestroyed) - }) - } + // 3. Convert the cookie-domain to lower case. + cookieDomain = cookieDomain.toLowerCase() - [kInterceptedDispatch] (opts, handler) { - if (!this[kInterceptors] || this[kInterceptors].length === 0) { - this[kInterceptedDispatch] = this[kDispatch] - return this[kDispatch](opts, handler) - } + // 4. Append an attribute to the cookie-attribute-list with an + // attribute-name of Domain and an attribute-value of cookie-domain. + cookieAttributeList.domain = cookieDomain + } else if (attributeNameLowercase === 'path') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 + // If the attribute-name case-insensitively matches the string "Path", + // the user agent MUST process the cookie-av as follows. - let dispatch = this[kDispatch].bind(this) - for (let i = this[kInterceptors].length - 1; i >= 0; i--) { - dispatch = this[kInterceptors][i](dispatch) - } - this[kInterceptedDispatch] = dispatch - return dispatch(opts, handler) - } + // 1. If the attribute-value is empty or if the first character of the + // attribute-value is not %x2F ("/"): + let cookiePath = '' + if (attributeValue.length === 0 || attributeValue[0] !== '/') { + // 1. Let cookie-path be the default-path. + cookiePath = '/' + } else { + // Otherwise: - dispatch (opts, handler) { - if (!handler || typeof handler !== 'object') { - throw new InvalidArgumentError('handler must be an object') + // 1. Let cookie-path be the attribute-value. + cookiePath = attributeValue } - try { - if (!opts || typeof opts !== 'object') { - throw new InvalidArgumentError('opts must be an object.') - } - - if (this[kDestroyed] || this[kOnDestroyed]) { - throw new ClientDestroyedError() - } + // 2. Append an attribute to the cookie-attribute-list with an + // attribute-name of Path and an attribute-value of cookie-path. + cookieAttributeList.path = cookiePath + } else if (attributeNameLowercase === 'secure') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 + // If the attribute-name case-insensitively matches the string "Secure", + // the user agent MUST append an attribute to the cookie-attribute-list + // with an attribute-name of Secure and an empty attribute-value. - if (this[kClosed]) { - throw new ClientClosedError() - } + cookieAttributeList.secure = true + } else if (attributeNameLowercase === 'httponly') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 + // If the attribute-name case-insensitively matches the string + // "HttpOnly", the user agent MUST append an attribute to the cookie- + // attribute-list with an attribute-name of HttpOnly and an empty + // attribute-value. - return this[kInterceptedDispatch](opts, handler) - } catch (err) { - if (typeof handler.onError !== 'function') { - throw new InvalidArgumentError('invalid onError method') - } + cookieAttributeList.httpOnly = true + } else if (attributeNameLowercase === 'samesite') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 + // If the attribute-name case-insensitively matches the string + // "SameSite", the user agent MUST process the cookie-av as follows: - handler.onError(err) + // 1. Let enforcement be "Default". + let enforcement = 'Default' - return false + const attributeValueLowercase = attributeValue.toLowerCase() + // 2. If cookie-av's attribute-value is a case-insensitive match for + // "None", set enforcement to "None". + if (attributeValueLowercase.includes('none')) { + enforcement = 'None' } - } -} - -module.exports = DispatcherBase - - -/***/ }), - -/***/ 412: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; + // 3. If cookie-av's attribute-value is a case-insensitive match for + // "Strict", set enforcement to "Strict". + if (attributeValueLowercase.includes('strict')) { + enforcement = 'Strict' + } -const EventEmitter = __nccwpck_require__(2361) + // 4. If cookie-av's attribute-value is a case-insensitive match for + // "Lax", set enforcement to "Lax". + if (attributeValueLowercase.includes('lax')) { + enforcement = 'Lax' + } -class Dispatcher extends EventEmitter { - dispatch () { - throw new Error('not implemented') - } + // 5. Append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of + // enforcement. + cookieAttributeList.sameSite = enforcement + } else { + cookieAttributeList.unparsed ??= [] - close () { - throw new Error('not implemented') + cookieAttributeList.unparsed.push(`${attributeName}=${attributeValue}`) } - destroy () { - throw new Error('not implemented') - } + // 8. Return to Step 1 of this algorithm. + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) } -module.exports = Dispatcher +module.exports = { + parseSetCookie, + parseUnparsedAttributes +} /***/ }), -/***/ 1472: +/***/ 3121: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const Busboy = __nccwpck_require__(727) -const util = __nccwpck_require__(3983) -const { - ReadableStreamFrom, - isBlobLike, - isReadableStreamLike, - readableStreamClose, - createDeferredPromise, - fullyReadBody -} = __nccwpck_require__(2538) -const { FormData } = __nccwpck_require__(2015) -const { kState } = __nccwpck_require__(5861) -const { webidl } = __nccwpck_require__(1744) -const { DOMException, structuredClone } = __nccwpck_require__(1037) -const { Blob, File: NativeFile } = __nccwpck_require__(4300) -const { kBodyUsed } = __nccwpck_require__(2785) const assert = __nccwpck_require__(9491) -const { isErrored } = __nccwpck_require__(3983) -const { isUint8Array, isArrayBuffer } = __nccwpck_require__(9830) -const { File: UndiciFile } = __nccwpck_require__(8511) -const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) +const { kHeadersList } = __nccwpck_require__(2785) -let ReadableStream = globalThis.ReadableStream +function isCTLExcludingHtab (value) { + if (value.length === 0) { + return false + } -/** @type {globalThis['File']} */ -const File = NativeFile ?? UndiciFile -const textEncoder = new TextEncoder() -const textDecoder = new TextDecoder() + for (const char of value) { + const code = char.charCodeAt(0) -// https://fetch.spec.whatwg.org/#concept-bodyinit-extract -function extractBody (object, keepalive = false) { - if (!ReadableStream) { - ReadableStream = (__nccwpck_require__(5356).ReadableStream) + if ( + (code >= 0x00 || code <= 0x08) || + (code >= 0x0A || code <= 0x1F) || + code === 0x7F + ) { + return false + } } +} - // 1. Let stream be null. - let stream = null +/** + CHAR = + token = 1* + separators = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + * @param {string} name + */ +function validateCookieName (name) { + for (const char of name) { + const code = char.charCodeAt(0) - // 2. If object is a ReadableStream object, then set stream to object. - if (object instanceof ReadableStream) { - stream = object - } else if (isBlobLike(object)) { - // 3. Otherwise, if object is a Blob object, set stream to the - // result of running object’s get stream. - stream = object.stream() - } else { - // 4. Otherwise, set stream to a new ReadableStream object, and set - // up stream. - stream = new ReadableStream({ - async pull (controller) { - controller.enqueue( - typeof source === 'string' ? textEncoder.encode(source) : source - ) - queueMicrotask(() => readableStreamClose(controller)) - }, - start () {}, - type: undefined - }) + if ( + (code <= 0x20 || code > 0x7F) || + char === '(' || + char === ')' || + char === '>' || + char === '<' || + char === '@' || + char === ',' || + char === ';' || + char === ':' || + char === '\\' || + char === '"' || + char === '/' || + char === '[' || + char === ']' || + char === '?' || + char === '=' || + char === '{' || + char === '}' + ) { + throw new Error('Invalid cookie name') + } } +} - // 5. Assert: stream is a ReadableStream object. - assert(isReadableStreamLike(stream)) +/** + cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) + cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + ; US-ASCII characters excluding CTLs, + ; whitespace DQUOTE, comma, semicolon, + ; and backslash + * @param {string} value + */ +function validateCookieValue (value) { + for (const char of value) { + const code = char.charCodeAt(0) - // 6. Let action be null. - let action = null + if ( + code < 0x21 || // exclude CTLs (0-31) + code === 0x22 || + code === 0x2C || + code === 0x3B || + code === 0x5C || + code > 0x7E // non-ascii + ) { + throw new Error('Invalid header value') + } + } +} - // 7. Let source be null. - let source = null +/** + * path-value = + * @param {string} path + */ +function validateCookiePath (path) { + for (const char of path) { + const code = char.charCodeAt(0) - // 8. Let length be null. - let length = null + if (code < 0x21 || char === ';') { + throw new Error('Invalid cookie path') + } + } +} - // 9. Let type be null. - let type = null +/** + * I have no idea why these values aren't allowed to be honest, + * but Deno tests these. - Khafra + * @param {string} domain + */ +function validateCookieDomain (domain) { + if ( + domain.startsWith('-') || + domain.endsWith('.') || + domain.endsWith('-') + ) { + throw new Error('Invalid cookie domain') + } +} - // 10. Switch on object: - if (typeof object === 'string') { - // Set source to the UTF-8 encoding of object. - // Note: setting source to a Uint8Array here breaks some mocking assumptions. - source = object +/** + * @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.1 + * @param {number|Date} date + IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT + ; fixed length/zone/capitalization subset of the format + ; see Section 3.3 of [RFC5322] - // Set type to `text/plain;charset=UTF-8`. - type = 'text/plain;charset=UTF-8' - } else if (object instanceof URLSearchParams) { - // URLSearchParams + day-name = %x4D.6F.6E ; "Mon", case-sensitive + / %x54.75.65 ; "Tue", case-sensitive + / %x57.65.64 ; "Wed", case-sensitive + / %x54.68.75 ; "Thu", case-sensitive + / %x46.72.69 ; "Fri", case-sensitive + / %x53.61.74 ; "Sat", case-sensitive + / %x53.75.6E ; "Sun", case-sensitive + date1 = day SP month SP year + ; e.g., 02 Jun 1982 - // spec says to run application/x-www-form-urlencoded on body.list - // this is implemented in Node.js as apart of an URLSearchParams instance toString method - // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490 - // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100 + day = 2DIGIT + month = %x4A.61.6E ; "Jan", case-sensitive + / %x46.65.62 ; "Feb", case-sensitive + / %x4D.61.72 ; "Mar", case-sensitive + / %x41.70.72 ; "Apr", case-sensitive + / %x4D.61.79 ; "May", case-sensitive + / %x4A.75.6E ; "Jun", case-sensitive + / %x4A.75.6C ; "Jul", case-sensitive + / %x41.75.67 ; "Aug", case-sensitive + / %x53.65.70 ; "Sep", case-sensitive + / %x4F.63.74 ; "Oct", case-sensitive + / %x4E.6F.76 ; "Nov", case-sensitive + / %x44.65.63 ; "Dec", case-sensitive + year = 4DIGIT - // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. - source = object.toString() + GMT = %x47.4D.54 ; "GMT", case-sensitive - // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. - type = 'application/x-www-form-urlencoded;charset=UTF-8' - } else if (isArrayBuffer(object)) { - // BufferSource/ArrayBuffer + time-of-day = hour ":" minute ":" second + ; 00:00:00 - 23:59:60 (leap second) - // Set source to a copy of the bytes held by object. - source = new Uint8Array(object.slice()) - } else if (ArrayBuffer.isView(object)) { - // BufferSource/ArrayBufferView + hour = 2DIGIT + minute = 2DIGIT + second = 2DIGIT + */ +function toIMFDate (date) { + if (typeof date === 'number') { + date = new Date(date) + } - // Set source to a copy of the bytes held by object. - source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) - } else if (util.isFormDataLike(object)) { - const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` - const prefix = `--${boundary}\r\nContent-Disposition: form-data` + const days = [ + 'Sun', 'Mon', 'Tue', 'Wed', + 'Thu', 'Fri', 'Sat' + ] - /*! formdata-polyfill. MIT License. Jimmy Wärting */ - const escape = (str) => - str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22') - const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n') + const months = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ] - // Set action to this step: run the multipart/form-data - // encoding algorithm, with object’s entry list and UTF-8. - // - This ensures that the body is immutable and can't be changed afterwords - // - That the content-length is calculated in advance. - // - And that all parts are pre-encoded and ready to be sent. + const dayName = days[date.getUTCDay()] + const day = date.getUTCDate().toString().padStart(2, '0') + const month = months[date.getUTCMonth()] + const year = date.getUTCFullYear() + const hour = date.getUTCHours().toString().padStart(2, '0') + const minute = date.getUTCMinutes().toString().padStart(2, '0') + const second = date.getUTCSeconds().toString().padStart(2, '0') - const blobParts = [] - const rn = new Uint8Array([13, 10]) // '\r\n' - length = 0 - let hasUnknownSizeValue = false + return `${dayName}, ${day} ${month} ${year} ${hour}:${minute}:${second} GMT` +} - for (const [name, value] of object) { - if (typeof value === 'string') { - const chunk = textEncoder.encode(prefix + - `; name="${escape(normalizeLinefeeds(name))}"` + - `\r\n\r\n${normalizeLinefeeds(value)}\r\n`) - blobParts.push(chunk) - length += chunk.byteLength - } else { - const chunk = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + - (value.name ? `; filename="${escape(value.name)}"` : '') + '\r\n' + - `Content-Type: ${ - value.type || 'application/octet-stream' - }\r\n\r\n`) - blobParts.push(chunk, value, rn) - if (typeof value.size === 'number') { - length += chunk.byteLength + value.size + rn.byteLength - } else { - hasUnknownSizeValue = true - } - } - } +/** + max-age-av = "Max-Age=" non-zero-digit *DIGIT + ; In practice, both expires-av and max-age-av + ; are limited to dates representable by the + ; user agent. + * @param {number} maxAge + */ +function validateCookieMaxAge (maxAge) { + if (maxAge < 0) { + throw new Error('Invalid cookie max-age') + } +} - const chunk = textEncoder.encode(`--${boundary}--`) - blobParts.push(chunk) - length += chunk.byteLength - if (hasUnknownSizeValue) { - length = null - } +/** + * @see https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1 + * @param {import('./index').Cookie} cookie + */ +function stringify (cookie) { + if (cookie.name.length === 0) { + return null + } - // Set source to object. - source = object + validateCookieName(cookie.name) + validateCookieValue(cookie.value) - action = async function * () { - for (const part of blobParts) { - if (part.stream) { - yield * part.stream() - } else { - yield part - } - } - } + const out = [`${cookie.name}=${cookie.value}`] - // Set type to `multipart/form-data; boundary=`, - // followed by the multipart/form-data boundary string generated - // by the multipart/form-data encoding algorithm. - type = 'multipart/form-data; boundary=' + boundary - } else if (isBlobLike(object)) { - // Blob + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1 + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2 + if (cookie.name.startsWith('__Secure-')) { + cookie.secure = true + } - // Set source to object. - source = object + if (cookie.name.startsWith('__Host-')) { + cookie.secure = true + cookie.domain = null + cookie.path = '/' + } - // Set length to object’s size. - length = object.size + if (cookie.secure) { + out.push('Secure') + } - // If object’s type attribute is not the empty byte sequence, set - // type to its value. - if (object.type) { - type = object.type - } - } else if (typeof object[Symbol.asyncIterator] === 'function') { - // If keepalive is true, then throw a TypeError. - if (keepalive) { - throw new TypeError('keepalive') - } + if (cookie.httpOnly) { + out.push('HttpOnly') + } - // If object is disturbed or locked, then throw a TypeError. - if (util.isDisturbed(object) || object.locked) { - throw new TypeError( - 'Response body object should not be disturbed or locked' - ) - } + if (typeof cookie.maxAge === 'number') { + validateCookieMaxAge(cookie.maxAge) + out.push(`Max-Age=${cookie.maxAge}`) + } - stream = - object instanceof ReadableStream ? object : ReadableStreamFrom(object) + if (cookie.domain) { + validateCookieDomain(cookie.domain) + out.push(`Domain=${cookie.domain}`) } - // 11. If source is a byte sequence, then set action to a - // step that returns source and length to source’s length. - if (typeof source === 'string' || util.isBuffer(source)) { - length = Buffer.byteLength(source) + if (cookie.path) { + validateCookiePath(cookie.path) + out.push(`Path=${cookie.path}`) } - // 12. If action is non-null, then run these steps in in parallel: - if (action != null) { - // Run action. - let iterator - stream = new ReadableStream({ - async start () { - iterator = action(object)[Symbol.asyncIterator]() - }, - async pull (controller) { - const { value, done } = await iterator.next() - if (done) { - // When running action is done, close stream. - queueMicrotask(() => { - controller.close() - }) - } else { - // Whenever one or more bytes are available and stream is not errored, - // enqueue a Uint8Array wrapping an ArrayBuffer containing the available - // bytes into stream. - if (!isErrored(stream)) { - controller.enqueue(new Uint8Array(value)) - } - } - return controller.desiredSize > 0 - }, - async cancel (reason) { - await iterator.return() - }, - type: undefined - }) + if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') { + out.push(`Expires=${toIMFDate(cookie.expires)}`) } - // 13. Let body be a body whose stream is stream, source is source, - // and length is length. - const body = { stream, source, length } + if (cookie.sameSite) { + out.push(`SameSite=${cookie.sameSite}`) + } - // 14. Return (body, type). - return [body, type] + for (const part of cookie.unparsed) { + if (!part.includes('=')) { + throw new Error('Invalid unparsed') + } + + const [key, ...value] = part.split('=') + + out.push(`${key.trim()}=${value.join('=')}`) + } + + return out.join('; ') } -// https://fetch.spec.whatwg.org/#bodyinit-safely-extract -function safelyExtractBody (object, keepalive = false) { - if (!ReadableStream) { - // istanbul ignore next - ReadableStream = (__nccwpck_require__(5356).ReadableStream) +let kHeadersListNode + +function getHeadersList (headers) { + if (headers[kHeadersList]) { + return headers[kHeadersList] } - // To safely extract a body and a `Content-Type` value from - // a byte sequence or BodyInit object object, run these steps: + if (!kHeadersListNode) { + kHeadersListNode = Object.getOwnPropertySymbols(headers).find( + (symbol) => symbol.description === 'headers list' + ) - // 1. If object is a ReadableStream object, then: - if (object instanceof ReadableStream) { - // Assert: object is neither disturbed nor locked. - // istanbul ignore next - assert(!util.isDisturbed(object), 'The body has already been consumed.') - // istanbul ignore next - assert(!object.locked, 'The stream is locked.') + assert(kHeadersListNode, 'Headers cannot be parsed') } - // 2. Return the results of extracting object. - return extractBody(object, keepalive) + const headersList = headers[kHeadersListNode] + assert(headersList) + + return headersList } -function cloneBody (body) { - // To clone a body body, run these steps: +module.exports = { + isCTLExcludingHtab, + stringify, + getHeadersList +} - // https://fetch.spec.whatwg.org/#concept-body-clone - // 1. Let « out1, out2 » be the result of teeing body’s stream. - const [out1, out2] = body.stream.tee() - const out2Clone = structuredClone(out2, { transfer: [out2] }) - // This, for whatever reasons, unrefs out2Clone which allows - // the process to exit by itself. - const [, finalClone] = out2Clone.tee() +/***/ }), - // 2. Set body’s stream to out1. - body.stream = out1 +/***/ 2067: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 3. Return a body whose stream is out2 and other members are copied from body. - return { - stream: finalClone, - length: body.length, - source: body.source - } -} +"use strict"; -async function * consumeBody (body) { - if (body) { - if (isUint8Array(body)) { - yield body - } else { - const stream = body.stream - if (util.isDisturbed(stream)) { - throw new TypeError('The body has already been consumed.') +const net = __nccwpck_require__(1808) +const assert = __nccwpck_require__(9491) +const util = __nccwpck_require__(3983) +const { InvalidArgumentError, ConnectTimeoutError } = __nccwpck_require__(8045) + +let tls // include tls conditionally since it is not always available + +// TODO: session re-use does not wait for the first +// connection to resolve the session and might therefore +// resolve the same servername multiple times even when +// re-use is enabled. + +let SessionCache +// FIXME: remove workaround when the Node bug is fixed +// https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 +if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) { + SessionCache = class WeakSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + this._sessionRegistry = new global.FinalizationRegistry((key) => { + if (this._sessionCache.size < this._maxCachedSessions) { + return + } + + const ref = this._sessionCache.get(key) + if (ref !== undefined && ref.deref() === undefined) { + this._sessionCache.delete(key) + } + }) + } + + get (sessionKey) { + const ref = this._sessionCache.get(sessionKey) + return ref ? ref.deref() : null + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return } - if (stream.locked) { - throw new TypeError('The stream is locked.') + this._sessionCache.set(sessionKey, new WeakRef(session)) + this._sessionRegistry.register(session, sessionKey) + } + } +} else { + SessionCache = class SimpleSessionCache { + constructor (maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + } + + get (sessionKey) { + return this._sessionCache.get(sessionKey) + } + + set (sessionKey, session) { + if (this._maxCachedSessions === 0) { + return } - // Compat. - stream[kBodyUsed] = true + if (this._sessionCache.size >= this._maxCachedSessions) { + // remove the oldest session + const { value: oldestKey } = this._sessionCache.keys().next() + this._sessionCache.delete(oldestKey) + } - yield * stream + this._sessionCache.set(sessionKey, session) } } } -function throwIfAborted (state) { - if (state.aborted) { - throw new DOMException('The operation was aborted.', 'AbortError') +function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, ...opts }) { + if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { + throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') } -} -function bodyMixinMethods (instance) { - const methods = { - blob () { - // The blob() method steps are to return the result of - // running consume body with this and the following step - // given a byte sequence bytes: return a Blob whose - // contents are bytes and whose type attribute is this’s - // MIME type. - return specConsumeBody(this, (bytes) => { - let mimeType = bodyMimeType(this) - - if (mimeType === 'failure') { - mimeType = '' - } else if (mimeType) { - mimeType = serializeAMimeType(mimeType) - } - - // Return a Blob whose contents are bytes and type attribute - // is mimeType. - return new Blob([bytes], { type: mimeType }) - }, instance) - }, - - arrayBuffer () { - // The arrayBuffer() method steps are to return the result - // of running consume body with this and the following step - // given a byte sequence bytes: return a new ArrayBuffer - // whose contents are bytes. - return specConsumeBody(this, (bytes) => { - return new Uint8Array(bytes).buffer - }, instance) - }, - - text () { - // The text() method steps are to return the result of running - // consume body with this and UTF-8 decode. - return specConsumeBody(this, utf8DecodeBytes, instance) - }, + const options = { path: socketPath, ...opts } + const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) + timeout = timeout == null ? 10e3 : timeout + allowH2 = allowH2 != null ? allowH2 : false + return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { + let socket + if (protocol === 'https:') { + if (!tls) { + tls = __nccwpck_require__(4404) + } + servername = servername || options.servername || util.getServerName(host) || null - json () { - // The json() method steps are to return the result of running - // consume body with this and parse JSON from bytes. - return specConsumeBody(this, parseJSONFromBytes, instance) - }, + const sessionKey = servername || hostname + const session = sessionCache.get(sessionKey) || null - async formData () { - webidl.brandCheck(this, instance) + assert(sessionKey) - throwIfAborted(this[kState]) + socket = tls.connect({ + highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... + ...options, + servername, + session, + localAddress, + // TODO(HTTP/2): Add support for h2c + ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], + socket: httpSocket, // upgrade socket connection + port: port || 443, + host: hostname + }) - const contentType = this.headers.get('Content-Type') + socket + .on('session', function (session) { + // TODO (fix): Can a session become invalid once established? Don't think so? + sessionCache.set(sessionKey, session) + }) + } else { + assert(!httpSocket, 'httpSocket can only be sent on TLS update') + socket = net.connect({ + highWaterMark: 64 * 1024, // Same as nodejs fs streams. + ...options, + localAddress, + port: port || 80, + host: hostname + }) + } - // If mimeType’s essence is "multipart/form-data", then: - if (/multipart\/form-data/.test(contentType)) { - const headers = {} - for (const [key, value] of this.headers) headers[key.toLowerCase()] = value + // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket + if (options.keepAlive == null || options.keepAlive) { + const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay + socket.setKeepAlive(true, keepAliveInitialDelay) + } - const responseFormData = new FormData() + const cancelTimeout = setupTimeout(() => onConnectTimeout(socket), timeout) - let busboy + socket + .setNoDelay(true) + .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () { + cancelTimeout() - try { - busboy = new Busboy({ - headers, - preservePath: true - }) - } catch (err) { - throw new DOMException(`${err}`, 'AbortError') + if (callback) { + const cb = callback + callback = null + cb(null, this) } + }) + .on('error', function (err) { + cancelTimeout() - busboy.on('field', (name, value) => { - responseFormData.append(name, value) - }) - busboy.on('file', (name, value, filename, encoding, mimeType) => { - const chunks = [] - - if (encoding === 'base64' || encoding.toLowerCase() === 'base64') { - let base64chunk = '' + if (callback) { + const cb = callback + callback = null + cb(err) + } + }) - value.on('data', (chunk) => { - base64chunk += chunk.toString().replace(/[\r\n]/gm, '') + return socket + } +} - const end = base64chunk.length - base64chunk.length % 4 - chunks.push(Buffer.from(base64chunk.slice(0, end), 'base64')) +function setupTimeout (onConnectTimeout, timeout) { + if (!timeout) { + return () => {} + } - base64chunk = base64chunk.slice(end) - }) - value.on('end', () => { - chunks.push(Buffer.from(base64chunk, 'base64')) - responseFormData.append(name, new File(chunks, filename, { type: mimeType })) - }) - } else { - value.on('data', (chunk) => { - chunks.push(chunk) - }) - value.on('end', () => { - responseFormData.append(name, new File(chunks, filename, { type: mimeType })) - }) - } - }) + let s1 = null + let s2 = null + const timeoutId = setTimeout(() => { + // setImmediate is added to make sure that we priotorise socket error events over timeouts + s1 = setImmediate(() => { + if (process.platform === 'win32') { + // Windows needs an extra setImmediate probably due to implementation differences in the socket logic + s2 = setImmediate(() => onConnectTimeout()) + } else { + onConnectTimeout() + } + }) + }, timeout) + return () => { + clearTimeout(timeoutId) + clearImmediate(s1) + clearImmediate(s2) + } +} - const busboyResolve = new Promise((resolve, reject) => { - busboy.on('finish', resolve) - busboy.on('error', (err) => reject(new TypeError(err))) - }) +function onConnectTimeout (socket) { + util.destroy(socket, new ConnectTimeoutError()) +} - if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk) - busboy.end() - await busboyResolve +module.exports = buildConnector - return responseFormData - } else if (/application\/x-www-form-urlencoded/.test(contentType)) { - // Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then: - // 1. Let entries be the result of parsing bytes. - let entries - try { - let text = '' - // application/x-www-form-urlencoded parser will keep the BOM. - // https://url.spec.whatwg.org/#concept-urlencoded-parser - // Note that streaming decoder is stateful and cannot be reused - const streamingDecoder = new TextDecoder('utf-8', { ignoreBOM: true }) +/***/ }), - for await (const chunk of consumeBody(this[kState].body)) { - if (!isUint8Array(chunk)) { - throw new TypeError('Expected Uint8Array chunk') - } - text += streamingDecoder.decode(chunk, { stream: true }) - } - text += streamingDecoder.decode() - entries = new URLSearchParams(text) - } catch (err) { - // istanbul ignore next: Unclear when new URLSearchParams can fail on a string. - // 2. If entries is failure, then throw a TypeError. - throw Object.assign(new TypeError(), { cause: err }) - } +/***/ 8045: +/***/ ((module) => { - // 3. Return a new FormData object whose entries are entries. - const formData = new FormData() - for (const [name, value] of entries) { - formData.append(name, value) - } - return formData - } else { - // Wait a tick before checking if the request has been aborted. - // Otherwise, a TypeError can be thrown when an AbortError should. - await Promise.resolve() +"use strict"; - throwIfAborted(this[kState]) - // Otherwise, throw a TypeError. - throw webidl.errors.exception({ - header: `${instance.name}.formData`, - message: 'Could not parse content as FormData.' - }) - } - } +class UndiciError extends Error { + constructor (message) { + super(message) + this.name = 'UndiciError' + this.code = 'UND_ERR' } +} - return methods +class ConnectTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ConnectTimeoutError) + this.name = 'ConnectTimeoutError' + this.message = message || 'Connect Timeout Error' + this.code = 'UND_ERR_CONNECT_TIMEOUT' + } } -function mixinBody (prototype) { - Object.assign(prototype.prototype, bodyMixinMethods(prototype)) +class HeadersTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, HeadersTimeoutError) + this.name = 'HeadersTimeoutError' + this.message = message || 'Headers Timeout Error' + this.code = 'UND_ERR_HEADERS_TIMEOUT' + } } -/** - * @see https://fetch.spec.whatwg.org/#concept-body-consume-body - * @param {Response|Request} object - * @param {(value: unknown) => unknown} convertBytesToJSValue - * @param {Response|Request} instance - */ -async function specConsumeBody (object, convertBytesToJSValue, instance) { - webidl.brandCheck(object, instance) - - throwIfAborted(object[kState]) - - // 1. If object is unusable, then return a promise rejected - // with a TypeError. - if (bodyUnusable(object[kState].body)) { - throw new TypeError('Body is unusable') +class HeadersOverflowError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, HeadersOverflowError) + this.name = 'HeadersOverflowError' + this.message = message || 'Headers Overflow Error' + this.code = 'UND_ERR_HEADERS_OVERFLOW' } +} - // 2. Let promise be a new promise. - const promise = createDeferredPromise() +class BodyTimeoutError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, BodyTimeoutError) + this.name = 'BodyTimeoutError' + this.message = message || 'Body Timeout Error' + this.code = 'UND_ERR_BODY_TIMEOUT' + } +} - // 3. Let errorSteps given error be to reject promise with error. - const errorSteps = (error) => promise.reject(error) +class ResponseStatusCodeError extends UndiciError { + constructor (message, statusCode, headers, body) { + super(message) + Error.captureStackTrace(this, ResponseStatusCodeError) + this.name = 'ResponseStatusCodeError' + this.message = message || 'Response Status Code Error' + this.code = 'UND_ERR_RESPONSE_STATUS_CODE' + this.body = body + this.status = statusCode + this.statusCode = statusCode + this.headers = headers + } +} - // 4. Let successSteps given a byte sequence data be to resolve - // promise with the result of running convertBytesToJSValue - // with data. If that threw an exception, then run errorSteps - // with that exception. - const successSteps = (data) => { - try { - promise.resolve(convertBytesToJSValue(data)) - } catch (e) { - errorSteps(e) - } +class InvalidArgumentError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InvalidArgumentError) + this.name = 'InvalidArgumentError' + this.message = message || 'Invalid Argument Error' + this.code = 'UND_ERR_INVALID_ARG' } +} - // 5. If object’s body is null, then run successSteps with an - // empty byte sequence. - if (object[kState].body == null) { - successSteps(new Uint8Array()) - return promise.promise +class InvalidReturnValueError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InvalidReturnValueError) + this.name = 'InvalidReturnValueError' + this.message = message || 'Invalid Return Value Error' + this.code = 'UND_ERR_INVALID_RETURN_VALUE' } +} - // 6. Otherwise, fully read object’s body given successSteps, - // errorSteps, and object’s relevant global object. - await fullyReadBody(object[kState].body, successSteps, errorSteps) +class RequestAbortedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, RequestAbortedError) + this.name = 'AbortError' + this.message = message || 'Request aborted' + this.code = 'UND_ERR_ABORTED' + } +} - // 7. Return promise. - return promise.promise +class InformationalError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, InformationalError) + this.name = 'InformationalError' + this.message = message || 'Request information' + this.code = 'UND_ERR_INFO' + } } -// https://fetch.spec.whatwg.org/#body-unusable -function bodyUnusable (body) { - // An object including the Body interface mixin is - // said to be unusable if its body is non-null and - // its body’s stream is disturbed or locked. - return body != null && (body.stream.locked || util.isDisturbed(body.stream)) +class RequestContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, RequestContentLengthMismatchError) + this.name = 'RequestContentLengthMismatchError' + this.message = message || 'Request body length does not match content-length header' + this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' + } } -/** - * @see https://encoding.spec.whatwg.org/#utf-8-decode - * @param {Buffer} buffer - */ -function utf8DecodeBytes (buffer) { - if (buffer.length === 0) { - return '' +class ResponseContentLengthMismatchError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ResponseContentLengthMismatchError) + this.name = 'ResponseContentLengthMismatchError' + this.message = message || 'Response body length does not match content-length header' + this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' } +} - // 1. Let buffer be the result of peeking three bytes from - // ioQueue, converted to a byte sequence. +class ClientDestroyedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ClientDestroyedError) + this.name = 'ClientDestroyedError' + this.message = message || 'The client is destroyed' + this.code = 'UND_ERR_DESTROYED' + } +} - // 2. If buffer is 0xEF 0xBB 0xBF, then read three - // bytes from ioQueue. (Do nothing with those bytes.) - if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { - buffer = buffer.subarray(3) +class ClientClosedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ClientClosedError) + this.name = 'ClientClosedError' + this.message = message || 'The client is closed' + this.code = 'UND_ERR_CLOSED' } +} - // 3. Process a queue with an instance of UTF-8’s - // decoder, ioQueue, output, and "replacement". - const output = textDecoder.decode(buffer) +class SocketError extends UndiciError { + constructor (message, socket) { + super(message) + Error.captureStackTrace(this, SocketError) + this.name = 'SocketError' + this.message = message || 'Socket error' + this.code = 'UND_ERR_SOCKET' + this.socket = socket + } +} - // 4. Return output. - return output +class NotSupportedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, NotSupportedError) + this.name = 'NotSupportedError' + this.message = message || 'Not supported error' + this.code = 'UND_ERR_NOT_SUPPORTED' + } } -/** - * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value - * @param {Uint8Array} bytes - */ -function parseJSONFromBytes (bytes) { - return JSON.parse(utf8DecodeBytes(bytes)) +class BalancedPoolMissingUpstreamError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, NotSupportedError) + this.name = 'MissingUpstreamError' + this.message = message || 'No upstream has been added to the BalancedPool' + this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' + } } -/** - * @see https://fetch.spec.whatwg.org/#concept-body-mime-type - * @param {import('./response').Response|import('./request').Request} object - */ -function bodyMimeType (object) { - const { headersList } = object[kState] - const contentType = headersList.get('content-type') +class HTTPParserError extends Error { + constructor (message, code, data) { + super(message) + Error.captureStackTrace(this, HTTPParserError) + this.name = 'HTTPParserError' + this.code = code ? `HPE_${code}` : undefined + this.data = data ? data.toString() : undefined + } +} - if (contentType === null) { - return 'failure' +class ResponseExceededMaxSizeError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, ResponseExceededMaxSizeError) + this.name = 'ResponseExceededMaxSizeError' + this.message = message || 'Response content exceeded max size' + this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' } +} - return parseMIMEType(contentType) +class RequestRetryError extends UndiciError { + constructor (message, code, { headers, data }) { + super(message) + Error.captureStackTrace(this, RequestRetryError) + this.name = 'RequestRetryError' + this.message = message || 'Request retry error' + this.code = 'UND_ERR_REQ_RETRY' + this.statusCode = code + this.data = data + this.headers = headers + } } module.exports = { - extractBody, - safelyExtractBody, - cloneBody, - mixinBody + HTTPParserError, + UndiciError, + HeadersTimeoutError, + HeadersOverflowError, + BodyTimeoutError, + RequestContentLengthMismatchError, + ConnectTimeoutError, + ResponseStatusCodeError, + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError, + ClientDestroyedError, + ClientClosedError, + InformationalError, + SocketError, + NotSupportedError, + ResponseContentLengthMismatchError, + BalancedPoolMissingUpstreamError, + ResponseExceededMaxSizeError, + RequestRetryError } /***/ }), -/***/ 1037: +/***/ 2905: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { MessageChannel, receiveMessageOnPort } = __nccwpck_require__(1267) - -const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] -const corsSafeListedMethodsSet = new Set(corsSafeListedMethods) - -const nullBodyStatus = [101, 204, 205, 304] - -const redirectStatus = [301, 302, 303, 307, 308] -const redirectStatusSet = new Set(redirectStatus) - -// https://fetch.spec.whatwg.org/#block-bad-port -const badPorts = [ - '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79', - '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137', - '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532', - '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723', - '2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6697', - '10080' -] - -const badPortsSet = new Set(badPorts) +const { + InvalidArgumentError, + NotSupportedError +} = __nccwpck_require__(8045) +const assert = __nccwpck_require__(9491) +const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = __nccwpck_require__(2785) +const util = __nccwpck_require__(3983) -// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies -const referrerPolicy = [ - '', - 'no-referrer', - 'no-referrer-when-downgrade', - 'same-origin', - 'origin', - 'strict-origin', - 'origin-when-cross-origin', - 'strict-origin-when-cross-origin', - 'unsafe-url' -] -const referrerPolicySet = new Set(referrerPolicy) +// tokenRegExp and headerCharRegex have been lifted from +// https://github.com/nodejs/node/blob/main/lib/_http_common.js -const requestRedirect = ['follow', 'manual', 'error'] +/** + * Verifies that the given val is a valid HTTP token + * per the rules defined in RFC 7230 + * See https://tools.ietf.org/html/rfc7230#section-3.2.6 + */ +const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/ -const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE'] -const safeMethodsSet = new Set(safeMethods) +/** + * Matches if val contains an invalid field-vchar + * field-value = *( field-content / obs-fold ) + * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + * field-vchar = VCHAR / obs-text + */ +const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/ -const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors'] +// Verifies that a given path is valid does not contain control chars \x00 to \x20 +const invalidPathRegex = /[^\u0021-\u00ff]/ -const requestCredentials = ['omit', 'same-origin', 'include'] +const kHandler = Symbol('handler') -const requestCache = [ - 'default', - 'no-store', - 'reload', - 'no-cache', - 'force-cache', - 'only-if-cached' -] +const channels = {} -// https://fetch.spec.whatwg.org/#request-body-header-name -const requestBodyHeader = [ - 'content-encoding', - 'content-language', - 'content-location', - 'content-type', - // See https://github.com/nodejs/undici/issues/2021 - // 'Content-Length' is a forbidden header name, which is typically - // removed in the Headers implementation. However, undici doesn't - // filter out headers, so we add it here. - 'content-length' -] +let extractBody -// https://fetch.spec.whatwg.org/#enumdef-requestduplex -const requestDuplex = [ - 'half' -] +try { + const diagnosticsChannel = __nccwpck_require__(7643) + channels.create = diagnosticsChannel.channel('undici:request:create') + channels.bodySent = diagnosticsChannel.channel('undici:request:bodySent') + channels.headers = diagnosticsChannel.channel('undici:request:headers') + channels.trailers = diagnosticsChannel.channel('undici:request:trailers') + channels.error = diagnosticsChannel.channel('undici:request:error') +} catch { + channels.create = { hasSubscribers: false } + channels.bodySent = { hasSubscribers: false } + channels.headers = { hasSubscribers: false } + channels.trailers = { hasSubscribers: false } + channels.error = { hasSubscribers: false } +} -// http://fetch.spec.whatwg.org/#forbidden-method -const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK'] -const forbiddenMethodsSet = new Set(forbiddenMethods) +class Request { + constructor (origin, { + path, + method, + body, + headers, + query, + idempotent, + blocking, + upgrade, + headersTimeout, + bodyTimeout, + reset, + throwOnError, + expectContinue + }, handler) { + if (typeof path !== 'string') { + throw new InvalidArgumentError('path must be a string') + } else if ( + path[0] !== '/' && + !(path.startsWith('http://') || path.startsWith('https://')) && + method !== 'CONNECT' + ) { + throw new InvalidArgumentError('path must be an absolute URL or start with a slash') + } else if (invalidPathRegex.exec(path) !== null) { + throw new InvalidArgumentError('invalid request path') + } -const subresource = [ - 'audio', - 'audioworklet', - 'font', - 'image', - 'manifest', - 'paintworklet', - 'script', - 'style', - 'track', - 'video', - 'xslt', - '' -] -const subresourceSet = new Set(subresource) + if (typeof method !== 'string') { + throw new InvalidArgumentError('method must be a string') + } else if (tokenRegExp.exec(method) === null) { + throw new InvalidArgumentError('invalid request method') + } -/** @type {globalThis['DOMException']} */ -const DOMException = globalThis.DOMException ?? (() => { - // DOMException was only made a global in Node v17.0.0, - // but fetch supports >= v16.8. - try { - atob('~') - } catch (err) { - return Object.getPrototypeOf(err).constructor - } -})() + if (upgrade && typeof upgrade !== 'string') { + throw new InvalidArgumentError('upgrade must be a string') + } -let channel + if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) { + throw new InvalidArgumentError('invalid headersTimeout') + } -/** @type {globalThis['structuredClone']} */ -const structuredClone = - globalThis.structuredClone ?? - // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js - // structuredClone was added in v17.0.0, but fetch supports v16.8 - function structuredClone (value, options = undefined) { - if (arguments.length === 0) { - throw new TypeError('missing argument') + if (bodyTimeout != null && (!Number.isFinite(bodyTimeout) || bodyTimeout < 0)) { + throw new InvalidArgumentError('invalid bodyTimeout') } - if (!channel) { - channel = new MessageChannel() + if (reset != null && typeof reset !== 'boolean') { + throw new InvalidArgumentError('invalid reset') } - channel.port1.unref() - channel.port2.unref() - channel.port1.postMessage(value, options?.transfer) - return receiveMessageOnPort(channel.port2).message - } -module.exports = { - DOMException, - structuredClone, - subresource, - forbiddenMethods, - requestBodyHeader, - referrerPolicy, - requestRedirect, - requestMode, - requestCredentials, - requestCache, - redirectStatus, - corsSafeListedMethods, - nullBodyStatus, - safeMethods, - badPorts, - requestDuplex, - subresourceSet, - badPortsSet, - redirectStatusSet, - corsSafeListedMethodsSet, - safeMethodsSet, - forbiddenMethodsSet, - referrerPolicySet -} + if (expectContinue != null && typeof expectContinue !== 'boolean') { + throw new InvalidArgumentError('invalid expectContinue') + } + this.headersTimeout = headersTimeout -/***/ }), + this.bodyTimeout = bodyTimeout -/***/ 685: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.throwOnError = throwOnError === true -const assert = __nccwpck_require__(9491) -const { atob } = __nccwpck_require__(4300) -const { isomorphicDecode } = __nccwpck_require__(2538) + this.method = method -const encoder = new TextEncoder() + this.abort = null -/** - * @see https://mimesniff.spec.whatwg.org/#http-token-code-point - */ -const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ -const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line -/** - * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point - */ -const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line + if (body == null) { + this.body = null + } else if (util.isStream(body)) { + this.body = body -// https://fetch.spec.whatwg.org/#data-url-processor -/** @param {URL} dataURL */ -function dataURLProcessor (dataURL) { - // 1. Assert: dataURL’s scheme is "data". - assert(dataURL.protocol === 'data:') + const rState = this.body._readableState + if (!rState || !rState.autoDestroy) { + this.endHandler = function autoDestroy () { + util.destroy(this) + } + this.body.on('end', this.endHandler) + } - // 2. Let input be the result of running the URL - // serializer on dataURL with exclude fragment - // set to true. - let input = URLSerializer(dataURL, true) + this.errorHandler = err => { + if (this.abort) { + this.abort(err) + } else { + this.error = err + } + } + this.body.on('error', this.errorHandler) + } else if (util.isBuffer(body)) { + this.body = body.byteLength ? body : null + } else if (ArrayBuffer.isView(body)) { + this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null + } else if (body instanceof ArrayBuffer) { + this.body = body.byteLength ? Buffer.from(body) : null + } else if (typeof body === 'string') { + this.body = body.length ? Buffer.from(body) : null + } else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) { + this.body = body + } else { + throw new InvalidArgumentError('body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable') + } - // 3. Remove the leading "data:" string from input. - input = input.slice(5) + this.completed = false - // 4. Let position point at the start of input. - const position = { position: 0 } + this.aborted = false - // 5. Let mimeType be the result of collecting a - // sequence of code points that are not equal - // to U+002C (,), given position. - let mimeType = collectASequenceOfCodePointsFast( - ',', - input, - position - ) + this.upgrade = upgrade || null - // 6. Strip leading and trailing ASCII whitespace - // from mimeType. - // Undici implementation note: we need to store the - // length because if the mimetype has spaces removed, - // the wrong amount will be sliced from the input in - // step #9 - const mimeTypeLength = mimeType.length - mimeType = removeASCIIWhitespace(mimeType, true, true) + this.path = query ? util.buildURL(path, query) : path - // 7. If position is past the end of input, then - // return failure - if (position.position >= input.length) { - return 'failure' - } + this.origin = origin - // 8. Advance position by 1. - position.position++ + this.idempotent = idempotent == null + ? method === 'HEAD' || method === 'GET' + : idempotent - // 9. Let encodedBody be the remainder of input. - const encodedBody = input.slice(mimeTypeLength + 1) + this.blocking = blocking == null ? false : blocking - // 10. Let body be the percent-decoding of encodedBody. - let body = stringPercentDecode(encodedBody) + this.reset = reset == null ? null : reset - // 11. If mimeType ends with U+003B (;), followed by - // zero or more U+0020 SPACE, followed by an ASCII - // case-insensitive match for "base64", then: - if (/;(\u0020){0,}base64$/i.test(mimeType)) { - // 1. Let stringBody be the isomorphic decode of body. - const stringBody = isomorphicDecode(body) + this.host = null - // 2. Set body to the forgiving-base64 decode of - // stringBody. - body = forgivingBase64(stringBody) + this.contentLength = null - // 3. If body is failure, then return failure. - if (body === 'failure') { - return 'failure' + this.contentType = null + + this.headers = '' + + // Only for H2 + this.expectContinue = expectContinue != null ? expectContinue : false + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(this, headers[i], headers[i + 1]) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(this, key, headers[key]) + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') } - // 4. Remove the last 6 code points from mimeType. - mimeType = mimeType.slice(0, -6) + if (util.isFormDataLike(this.body)) { + if (util.nodeMajor < 16 || (util.nodeMajor === 16 && util.nodeMinor < 8)) { + throw new InvalidArgumentError('Form-Data bodies are only supported in node v16.8 and newer.') + } - // 5. Remove trailing U+0020 SPACE code points from mimeType, - // if any. - mimeType = mimeType.replace(/(\u0020)+$/, '') + if (!extractBody) { + extractBody = (__nccwpck_require__(1472).extractBody) + } - // 6. Remove the last U+003B (;) code point from mimeType. - mimeType = mimeType.slice(0, -1) + const [bodyStream, contentType] = extractBody(body) + if (this.contentType == null) { + this.contentType = contentType + this.headers += `content-type: ${contentType}\r\n` + } + this.body = bodyStream.stream + this.contentLength = bodyStream.length + } else if (util.isBlobLike(body) && this.contentType == null && body.type) { + this.contentType = body.type + this.headers += `content-type: ${body.type}\r\n` + } + + util.validateHandler(handler, method, upgrade) + + this.servername = util.getServerName(this.host) + + this[kHandler] = handler + + if (channels.create.hasSubscribers) { + channels.create.publish({ request: this }) + } } - // 12. If mimeType starts with U+003B (;), then prepend - // "text/plain" to mimeType. - if (mimeType.startsWith(';')) { - mimeType = 'text/plain' + mimeType + onBodySent (chunk) { + if (this[kHandler].onBodySent) { + try { + return this[kHandler].onBodySent(chunk) + } catch (err) { + this.abort(err) + } + } } - // 13. Let mimeTypeRecord be the result of parsing - // mimeType. - let mimeTypeRecord = parseMIMEType(mimeType) + onRequestSent () { + if (channels.bodySent.hasSubscribers) { + channels.bodySent.publish({ request: this }) + } - // 14. If mimeTypeRecord is failure, then set - // mimeTypeRecord to text/plain;charset=US-ASCII. - if (mimeTypeRecord === 'failure') { - mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII') + if (this[kHandler].onRequestSent) { + try { + return this[kHandler].onRequestSent() + } catch (err) { + this.abort(err) + } + } } - // 15. Return a new data: URL struct whose MIME - // type is mimeTypeRecord and body is body. - // https://fetch.spec.whatwg.org/#data-url-struct - return { mimeType: mimeTypeRecord, body } -} + onConnect (abort) { + assert(!this.aborted) + assert(!this.completed) -// https://url.spec.whatwg.org/#concept-url-serializer -/** - * @param {URL} url - * @param {boolean} excludeFragment - */ -function URLSerializer (url, excludeFragment = false) { - if (!excludeFragment) { - return url.href + if (this.error) { + abort(this.error) + } else { + this.abort = abort + return this[kHandler].onConnect(abort) + } } - const href = url.href - const hashLength = url.hash.length + onHeaders (statusCode, headers, resume, statusText) { + assert(!this.aborted) + assert(!this.completed) - return hashLength === 0 ? href : href.substring(0, href.length - hashLength) -} + if (channels.headers.hasSubscribers) { + channels.headers.publish({ request: this, response: { statusCode, headers, statusText } }) + } -// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points -/** - * @param {(char: string) => boolean} condition - * @param {string} input - * @param {{ position: number }} position - */ -function collectASequenceOfCodePoints (condition, input, position) { - // 1. Let result be the empty string. - let result = '' + try { + return this[kHandler].onHeaders(statusCode, headers, resume, statusText) + } catch (err) { + this.abort(err) + } + } - // 2. While position doesn’t point past the end of input and the - // code point at position within input meets the condition condition: - while (position.position < input.length && condition(input[position.position])) { - // 1. Append that code point to the end of result. - result += input[position.position] + onData (chunk) { + assert(!this.aborted) + assert(!this.completed) - // 2. Advance position by 1. - position.position++ + try { + return this[kHandler].onData(chunk) + } catch (err) { + this.abort(err) + return false + } } - // 3. Return result. - return result -} - -/** - * A faster collectASequenceOfCodePoints that only works when comparing a single character. - * @param {string} char - * @param {string} input - * @param {{ position: number }} position - */ -function collectASequenceOfCodePointsFast (char, input, position) { - const idx = input.indexOf(char, position.position) - const start = position.position + onUpgrade (statusCode, headers, socket) { + assert(!this.aborted) + assert(!this.completed) - if (idx === -1) { - position.position = input.length - return input.slice(start) + return this[kHandler].onUpgrade(statusCode, headers, socket) } - position.position = idx - return input.slice(start, position.position) -} + onComplete (trailers) { + this.onFinally() -// https://url.spec.whatwg.org/#string-percent-decode -/** @param {string} input */ -function stringPercentDecode (input) { - // 1. Let bytes be the UTF-8 encoding of input. - const bytes = encoder.encode(input) + assert(!this.aborted) - // 2. Return the percent-decoding of bytes. - return percentDecode(bytes) -} + this.completed = true + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers }) + } -// https://url.spec.whatwg.org/#percent-decode -/** @param {Uint8Array} input */ -function percentDecode (input) { - // 1. Let output be an empty byte sequence. - /** @type {number[]} */ - const output = [] + try { + return this[kHandler].onComplete(trailers) + } catch (err) { + // TODO (fix): This might be a bad idea? + this.onError(err) + } + } - // 2. For each byte byte in input: - for (let i = 0; i < input.length; i++) { - const byte = input[i] + onError (error) { + this.onFinally() - // 1. If byte is not 0x25 (%), then append byte to output. - if (byte !== 0x25) { - output.push(byte) + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error }) + } - // 2. Otherwise, if byte is 0x25 (%) and the next two bytes - // after byte in input are not in the ranges - // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F), - // and 0x61 (a) to 0x66 (f), all inclusive, append byte - // to output. - } else if ( - byte === 0x25 && - !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2])) - ) { - output.push(0x25) + if (this.aborted) { + return + } + this.aborted = true - // 3. Otherwise: - } else { - // 1. Let bytePoint be the two bytes after byte in input, - // decoded, and then interpreted as hexadecimal number. - const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2]) - const bytePoint = Number.parseInt(nextTwoBytes, 16) + return this[kHandler].onError(error) + } - // 2. Append a byte whose value is bytePoint to output. - output.push(bytePoint) + onFinally () { + if (this.errorHandler) { + this.body.off('error', this.errorHandler) + this.errorHandler = null + } - // 3. Skip the next two bytes in input. - i += 2 + if (this.endHandler) { + this.body.off('end', this.endHandler) + this.endHandler = null } } - // 3. Return output. - return Uint8Array.from(output) -} - -// https://mimesniff.spec.whatwg.org/#parse-a-mime-type -/** @param {string} input */ -function parseMIMEType (input) { - // 1. Remove any leading and trailing HTTP whitespace - // from input. - input = removeHTTPWhitespace(input, true, true) - - // 2. Let position be a position variable for input, - // initially pointing at the start of input. - const position = { position: 0 } - - // 3. Let type be the result of collecting a sequence - // of code points that are not U+002F (/) from - // input, given position. - const type = collectASequenceOfCodePointsFast( - '/', - input, - position - ) - - // 4. If type is the empty string or does not solely - // contain HTTP token code points, then return failure. - // https://mimesniff.spec.whatwg.org/#http-token-code-point - if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { - return 'failure' + // TODO: adjust to support H2 + addHeader (key, value) { + processHeader(this, key, value) + return this } - // 5. If position is past the end of input, then return - // failure - if (position.position > input.length) { - return 'failure' + static [kHTTP1BuildRequest] (origin, opts, handler) { + // TODO: Migrate header parsing here, to make Requests + // HTTP agnostic + return new Request(origin, opts, handler) } - // 6. Advance position by 1. (This skips past U+002F (/).) - position.position++ - - // 7. Let subtype be the result of collecting a sequence of - // code points that are not U+003B (;) from input, given - // position. - let subtype = collectASequenceOfCodePointsFast( - ';', - input, - position - ) + static [kHTTP2BuildRequest] (origin, opts, handler) { + const headers = opts.headers + opts = { ...opts, headers: null } - // 8. Remove any trailing HTTP whitespace from subtype. - subtype = removeHTTPWhitespace(subtype, false, true) + const request = new Request(origin, opts, handler) - // 9. If subtype is the empty string or does not solely - // contain HTTP token code points, then return failure. - if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { - return 'failure' - } + request.headers = {} - const typeLowercase = type.toLowerCase() - const subtypeLowercase = subtype.toLowerCase() + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(request, headers[i], headers[i + 1], true) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(request, key, headers[key], true) + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') + } - // 10. Let mimeType be a new MIME type record whose type - // is type, in ASCII lowercase, and subtype is subtype, - // in ASCII lowercase. - // https://mimesniff.spec.whatwg.org/#mime-type - const mimeType = { - type: typeLowercase, - subtype: subtypeLowercase, - /** @type {Map} */ - parameters: new Map(), - // https://mimesniff.spec.whatwg.org/#mime-type-essence - essence: `${typeLowercase}/${subtypeLowercase}` + return request } - // 11. While position is not past the end of input: - while (position.position < input.length) { - // 1. Advance position by 1. (This skips past U+003B (;).) - position.position++ - - // 2. Collect a sequence of code points that are HTTP - // whitespace from input given position. - collectASequenceOfCodePoints( - // https://fetch.spec.whatwg.org/#http-whitespace - char => HTTP_WHITESPACE_REGEX.test(char), - input, - position - ) - - // 3. Let parameterName be the result of collecting a - // sequence of code points that are not U+003B (;) - // or U+003D (=) from input, given position. - let parameterName = collectASequenceOfCodePoints( - (char) => char !== ';' && char !== '=', - input, - position - ) + static [kHTTP2CopyHeaders] (raw) { + const rawHeaders = raw.split('\r\n') + const headers = {} - // 4. Set parameterName to parameterName, in ASCII - // lowercase. - parameterName = parameterName.toLowerCase() + for (const header of rawHeaders) { + const [key, value] = header.split(': ') - // 5. If position is not past the end of input, then: - if (position.position < input.length) { - // 1. If the code point at position within input is - // U+003B (;), then continue. - if (input[position.position] === ';') { - continue - } + if (value == null || value.length === 0) continue - // 2. Advance position by 1. (This skips past U+003D (=).) - position.position++ + if (headers[key]) headers[key] += `,${value}` + else headers[key] = value } - // 6. If position is past the end of input, then break. - if (position.position > input.length) { - break - } + return headers + } +} - // 7. Let parameterValue be null. - let parameterValue = null +function processHeaderValue (key, val, skipAppend) { + if (val && typeof val === 'object') { + throw new InvalidArgumentError(`invalid ${key} header`) + } - // 8. If the code point at position within input is - // U+0022 ("), then: - if (input[position.position] === '"') { - // 1. Set parameterValue to the result of collecting - // an HTTP quoted string from input, given position - // and the extract-value flag. - parameterValue = collectAnHTTPQuotedString(input, position, true) + val = val != null ? `${val}` : '' - // 2. Collect a sequence of code points that are not - // U+003B (;) from input, given position. - collectASequenceOfCodePointsFast( - ';', - input, - position - ) + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) + } - // 9. Otherwise: - } else { - // 1. Set parameterValue to the result of collecting - // a sequence of code points that are not U+003B (;) - // from input, given position. - parameterValue = collectASequenceOfCodePointsFast( - ';', - input, - position - ) + return skipAppend ? val : `${key}: ${val}\r\n` +} - // 2. Remove any trailing HTTP whitespace from parameterValue. - parameterValue = removeHTTPWhitespace(parameterValue, false, true) +function processHeader (request, key, val, skipAppend = false) { + if (val && (typeof val === 'object' && !Array.isArray(val))) { + throw new InvalidArgumentError(`invalid ${key} header`) + } else if (val === undefined) { + return + } - // 3. If parameterValue is the empty string, then continue. - if (parameterValue.length === 0) { - continue - } + if ( + request.host === null && + key.length === 4 && + key.toLowerCase() === 'host' + ) { + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) } - - // 10. If all of the following are true - // - parameterName is not the empty string - // - parameterName solely contains HTTP token code points - // - parameterValue solely contains HTTP quoted-string token code points - // - mimeType’s parameters[parameterName] does not exist - // then set mimeType’s parameters[parameterName] to parameterValue. - if ( - parameterName.length !== 0 && - HTTP_TOKEN_CODEPOINTS.test(parameterName) && - (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && - !mimeType.parameters.has(parameterName) - ) { - mimeType.parameters.set(parameterName, parameterValue) + // Consumed by Client + request.host = val + } else if ( + request.contentLength === null && + key.length === 14 && + key.toLowerCase() === 'content-length' + ) { + request.contentLength = parseInt(val, 10) + if (!Number.isFinite(request.contentLength)) { + throw new InvalidArgumentError('invalid content-length header') + } + } else if ( + request.contentType === null && + key.length === 12 && + key.toLowerCase() === 'content-type' + ) { + request.contentType = val + if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) + } else if ( + key.length === 17 && + key.toLowerCase() === 'transfer-encoding' + ) { + throw new InvalidArgumentError('invalid transfer-encoding header') + } else if ( + key.length === 10 && + key.toLowerCase() === 'connection' + ) { + const value = typeof val === 'string' ? val.toLowerCase() : null + if (value !== 'close' && value !== 'keep-alive') { + throw new InvalidArgumentError('invalid connection header') + } else if (value === 'close') { + request.reset = true + } + } else if ( + key.length === 10 && + key.toLowerCase() === 'keep-alive' + ) { + throw new InvalidArgumentError('invalid keep-alive header') + } else if ( + key.length === 7 && + key.toLowerCase() === 'upgrade' + ) { + throw new InvalidArgumentError('invalid upgrade header') + } else if ( + key.length === 6 && + key.toLowerCase() === 'expect' + ) { + throw new NotSupportedError('expect header not supported') + } else if (tokenRegExp.exec(key) === null) { + throw new InvalidArgumentError('invalid header key') + } else { + if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + if (skipAppend) { + if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` + else request.headers[key] = processHeaderValue(key, val[i], skipAppend) + } else { + request.headers += processHeaderValue(key, val[i]) + } + } + } else { + if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) } } - - // 12. Return mimeType. - return mimeType } -// https://infra.spec.whatwg.org/#forgiving-base64-decode -/** @param {string} data */ -function forgivingBase64 (data) { - // 1. Remove all ASCII whitespace from data. - data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line - - // 2. If data’s code point length divides by 4 leaving - // no remainder, then: - if (data.length % 4 === 0) { - // 1. If data ends with one or two U+003D (=) code points, - // then remove them from data. - data = data.replace(/=?=$/, '') - } - - // 3. If data’s code point length divides by 4 leaving - // a remainder of 1, then return failure. - if (data.length % 4 === 1) { - return 'failure' - } +module.exports = Request - // 4. If data contains a code point that is not one of - // U+002B (+) - // U+002F (/) - // ASCII alphanumeric - // then return failure. - if (/[^+/0-9A-Za-z]/.test(data)) { - return 'failure' - } - const binary = atob(data) - const bytes = new Uint8Array(binary.length) +/***/ }), - for (let byte = 0; byte < binary.length; byte++) { - bytes[byte] = binary.charCodeAt(byte) - } +/***/ 2785: +/***/ ((module) => { - return bytes +module.exports = { + kClose: Symbol('close'), + kDestroy: Symbol('destroy'), + kDispatch: Symbol('dispatch'), + kUrl: Symbol('url'), + kWriting: Symbol('writing'), + kResuming: Symbol('resuming'), + kQueue: Symbol('queue'), + kConnect: Symbol('connect'), + kConnecting: Symbol('connecting'), + kHeadersList: Symbol('headers list'), + kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), + kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), + kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), + kKeepAliveTimeoutValue: Symbol('keep alive timeout'), + kKeepAlive: Symbol('keep alive'), + kHeadersTimeout: Symbol('headers timeout'), + kBodyTimeout: Symbol('body timeout'), + kServerName: Symbol('server name'), + kLocalAddress: Symbol('local address'), + kHost: Symbol('host'), + kNoRef: Symbol('no ref'), + kBodyUsed: Symbol('used'), + kRunning: Symbol('running'), + kBlocking: Symbol('blocking'), + kPending: Symbol('pending'), + kSize: Symbol('size'), + kBusy: Symbol('busy'), + kQueued: Symbol('queued'), + kFree: Symbol('free'), + kConnected: Symbol('connected'), + kClosed: Symbol('closed'), + kNeedDrain: Symbol('need drain'), + kReset: Symbol('reset'), + kDestroyed: Symbol.for('nodejs.stream.destroyed'), + kMaxHeadersSize: Symbol('max headers size'), + kRunningIdx: Symbol('running index'), + kPendingIdx: Symbol('pending index'), + kError: Symbol('error'), + kClients: Symbol('clients'), + kClient: Symbol('client'), + kParser: Symbol('parser'), + kOnDestroyed: Symbol('destroy callbacks'), + kPipelining: Symbol('pipelining'), + kSocket: Symbol('socket'), + kHostHeader: Symbol('host header'), + kConnector: Symbol('connector'), + kStrictContentLength: Symbol('strict content length'), + kMaxRedirections: Symbol('maxRedirections'), + kMaxRequests: Symbol('maxRequestsPerClient'), + kProxy: Symbol('proxy agent options'), + kCounter: Symbol('socket request counter'), + kInterceptors: Symbol('dispatch interceptors'), + kMaxResponseSize: Symbol('max response size'), + kHTTP2Session: Symbol('http2Session'), + kHTTP2SessionState: Symbol('http2Session state'), + kHTTP2BuildRequest: Symbol('http2 build request'), + kHTTP1BuildRequest: Symbol('http1 build request'), + kHTTP2CopyHeaders: Symbol('http2 copy headers'), + kHTTPConnVersion: Symbol('http connection version'), + kRetryHandlerDefaultRetry: Symbol('retry agent default retry'), + kConstruct: Symbol('constructable') } -// https://fetch.spec.whatwg.org/#collect-an-http-quoted-string -// tests: https://fetch.spec.whatwg.org/#example-http-quoted-string -/** - * @param {string} input - * @param {{ position: number }} position - * @param {boolean?} extractValue - */ -function collectAnHTTPQuotedString (input, position, extractValue) { - // 1. Let positionStart be position. - const positionStart = position.position - - // 2. Let value be the empty string. - let value = '' - // 3. Assert: the code point at position within input - // is U+0022 ("). - assert(input[position.position] === '"') +/***/ }), - // 4. Advance position by 1. - position.position++ +/***/ 3983: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 5. While true: - while (true) { - // 1. Append the result of collecting a sequence of code points - // that are not U+0022 (") or U+005C (\) from input, given - // position, to value. - value += collectASequenceOfCodePoints( - (char) => char !== '"' && char !== '\\', - input, - position - ) +"use strict"; - // 2. If position is past the end of input, then break. - if (position.position >= input.length) { - break - } - // 3. Let quoteOrBackslash be the code point at position within - // input. - const quoteOrBackslash = input[position.position] +const assert = __nccwpck_require__(9491) +const { kDestroyed, kBodyUsed } = __nccwpck_require__(2785) +const { IncomingMessage } = __nccwpck_require__(3685) +const stream = __nccwpck_require__(2781) +const net = __nccwpck_require__(1808) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { Blob } = __nccwpck_require__(4300) +const nodeUtil = __nccwpck_require__(3837) +const { stringify } = __nccwpck_require__(3477) - // 4. Advance position by 1. - position.position++ +const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)) - // 5. If quoteOrBackslash is U+005C (\), then: - if (quoteOrBackslash === '\\') { - // 1. If position is past the end of input, then append - // U+005C (\) to value and break. - if (position.position >= input.length) { - value += '\\' - break - } +function nop () {} - // 2. Append the code point at position within input to value. - value += input[position.position] +function isStream (obj) { + return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function' +} - // 3. Advance position by 1. - position.position++ - - // 6. Otherwise: - } else { - // 1. Assert: quoteOrBackslash is U+0022 ("). - assert(quoteOrBackslash === '"') +// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) +function isBlobLike (object) { + return (Blob && object instanceof Blob) || ( + object && + typeof object === 'object' && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + /^(Blob|File)$/.test(object[Symbol.toStringTag]) + ) +} - // 2. Break. - break - } +function buildURL (url, queryParams) { + if (url.includes('?') || url.includes('#')) { + throw new Error('Query params cannot be passed when url already contains "?" or "#".') } - // 6. If the extract-value flag is set, then return value. - if (extractValue) { - return value + const stringified = stringify(queryParams) + + if (stringified) { + url += '?' + stringified } - // 7. Return the code points from positionStart to position, - // inclusive, within input. - return input.slice(positionStart, position.position) + return url } -/** - * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type - */ -function serializeAMimeType (mimeType) { - assert(mimeType !== 'failure') - const { parameters, essence } = mimeType - - // 1. Let serialization be the concatenation of mimeType’s - // type, U+002F (/), and mimeType’s subtype. - let serialization = essence +function parseURL (url) { + if (typeof url === 'string') { + url = new URL(url) - // 2. For each name → value of mimeType’s parameters: - for (let [name, value] of parameters.entries()) { - // 1. Append U+003B (;) to serialization. - serialization += ';' + if (!/^https?:/.test(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } - // 2. Append name to serialization. - serialization += name + return url + } - // 3. Append U+003D (=) to serialization. - serialization += '=' + if (!url || typeof url !== 'object') { + throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.') + } - // 4. If value does not solely contain HTTP token code - // points or value is the empty string, then: - if (!HTTP_TOKEN_CODEPOINTS.test(value)) { - // 1. Precede each occurence of U+0022 (") or - // U+005C (\) in value with U+005C (\). - value = value.replace(/(\\|")/g, '\\$1') + if (!/^https?:/.test(url.origin || url.protocol)) { + throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.') + } - // 2. Prepend U+0022 (") to value. - value = '"' + value + if (!(url instanceof URL)) { + if (url.port != null && url.port !== '' && !Number.isFinite(parseInt(url.port))) { + throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.') + } - // 3. Append U+0022 (") to value. - value += '"' + if (url.path != null && typeof url.path !== 'string') { + throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.') } - // 5. Append value to serialization. - serialization += value - } + if (url.pathname != null && typeof url.pathname !== 'string') { + throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.') + } - // 3. Return serialization. - return serialization -} + if (url.hostname != null && typeof url.hostname !== 'string') { + throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.') + } -/** - * @see https://fetch.spec.whatwg.org/#http-whitespace - * @param {string} char - */ -function isHTTPWhiteSpace (char) { - return char === '\r' || char === '\n' || char === '\t' || char === ' ' -} + if (url.origin != null && typeof url.origin !== 'string') { + throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.') + } -/** - * @see https://fetch.spec.whatwg.org/#http-whitespace - * @param {string} str - */ -function removeHTTPWhitespace (str, leading = true, trailing = true) { - let lead = 0 - let trail = str.length - 1 + const port = url.port != null + ? url.port + : (url.protocol === 'https:' ? 443 : 80) + let origin = url.origin != null + ? url.origin + : `${url.protocol}//${url.hostname}:${port}` + let path = url.path != null + ? url.path + : `${url.pathname || ''}${url.search || ''}` - if (leading) { - for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++); - } + if (origin.endsWith('/')) { + origin = origin.substring(0, origin.length - 1) + } - if (trailing) { - for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--); + if (path && !path.startsWith('/')) { + path = `/${path}` + } + // new URL(path, origin) is unsafe when `path` contains an absolute URL + // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: + // If first parameter is a relative URL, second param is required, and will be used as the base URL. + // If first parameter is an absolute URL, a given second param will be ignored. + url = new URL(origin + path) } - return str.slice(lead, trail + 1) + return url } -/** - * @see https://infra.spec.whatwg.org/#ascii-whitespace - * @param {string} char - */ -function isASCIIWhitespace (char) { - return char === '\r' || char === '\n' || char === '\t' || char === '\f' || char === ' ' +function parseOrigin (url) { + url = parseURL(url) + + if (url.pathname !== '/' || url.search || url.hash) { + throw new InvalidArgumentError('invalid url') + } + + return url } -/** - * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace - */ -function removeASCIIWhitespace (str, leading = true, trailing = true) { - let lead = 0 - let trail = str.length - 1 +function getHostname (host) { + if (host[0] === '[') { + const idx = host.indexOf(']') - if (leading) { - for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++); + assert(idx !== -1) + return host.substring(1, idx) } - if (trailing) { - for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--); - } + const idx = host.indexOf(':') + if (idx === -1) return host - return str.slice(lead, trail + 1) + return host.substring(0, idx) } -module.exports = { - dataURLProcessor, - URLSerializer, - collectASequenceOfCodePoints, - collectASequenceOfCodePointsFast, - stringPercentDecode, - parseMIMEType, - collectAnHTTPQuotedString, - serializeAMimeType -} +// IP addresses are not valid server names per RFC6066 +// > Currently, the only server names supported are DNS hostnames +function getServerName (host) { + if (!host) { + return null + } + assert.strictEqual(typeof host, 'string') -/***/ }), + const servername = getHostname(host) + if (net.isIP(servername)) { + return '' + } -/***/ 8511: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return servername +} -"use strict"; +function deepClone (obj) { + return JSON.parse(JSON.stringify(obj)) +} +function isAsyncIterable (obj) { + return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function') +} -const { Blob, File: NativeFile } = __nccwpck_require__(4300) -const { types } = __nccwpck_require__(3837) -const { kState } = __nccwpck_require__(5861) -const { isBlobLike } = __nccwpck_require__(2538) -const { webidl } = __nccwpck_require__(1744) -const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) -const { kEnumerableProperty } = __nccwpck_require__(3983) -const encoder = new TextEncoder() +function isIterable (obj) { + return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function')) +} -class File extends Blob { - constructor (fileBits, fileName, options = {}) { - // The File constructor is invoked with two or three parameters, depending - // on whether the optional dictionary parameter is used. When the File() - // constructor is invoked, user agents must run the following steps: - webidl.argumentLengthCheck(arguments, 2, { header: 'File constructor' }) +function bodyLength (body) { + if (body == null) { + return 0 + } else if (isStream(body)) { + const state = body._readableState + return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) + ? state.length + : null + } else if (isBlobLike(body)) { + return body.size != null ? body.size : null + } else if (isBuffer(body)) { + return body.byteLength + } - fileBits = webidl.converters['sequence'](fileBits) - fileName = webidl.converters.USVString(fileName) - options = webidl.converters.FilePropertyBag(options) + return null +} - // 1. Let bytes be the result of processing blob parts given fileBits and - // options. - // Note: Blob handles this for us +function isDestroyed (stream) { + return !stream || !!(stream.destroyed || stream[kDestroyed]) +} - // 2. Let n be the fileName argument to the constructor. - const n = fileName +function isReadableAborted (stream) { + const state = stream && stream._readableState + return isDestroyed(stream) && state && !state.endEmitted +} - // 3. Process FilePropertyBag dictionary argument by running the following - // substeps: +function destroy (stream, err) { + if (stream == null || !isStream(stream) || isDestroyed(stream)) { + return + } - // 1. If the type member is provided and is not the empty string, let t - // be set to the type dictionary member. If t contains any characters - // outside the range U+0020 to U+007E, then set t to the empty string - // and return from these substeps. - // 2. Convert every character in t to ASCII lowercase. - let t = options.type - let d - - // eslint-disable-next-line no-labels - substep: { - if (t) { - t = parseMIMEType(t) - - if (t === 'failure') { - t = '' - // eslint-disable-next-line no-labels - break substep - } - - t = serializeAMimeType(t).toLowerCase() - } - - // 3. If the lastModified member is provided, let d be set to the - // lastModified dictionary member. If it is not provided, set d to the - // current date and time represented as the number of milliseconds since - // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). - d = options.lastModified - } - - // 4. Return a new File object F such that: - // F refers to the bytes byte sequence. - // F.size is set to the number of total bytes in bytes. - // F.name is set to n. - // F.type is set to t. - // F.lastModified is set to d. - - super(processBlobParts(fileBits, options), { type: t }) - this[kState] = { - name: n, - lastModified: d, - type: t + if (typeof stream.destroy === 'function') { + if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { + // See: https://github.com/nodejs/node/pull/38505/files + stream.socket = null } - } - - get name () { - webidl.brandCheck(this, File) - - return this[kState].name - } - get lastModified () { - webidl.brandCheck(this, File) - - return this[kState].lastModified + stream.destroy(err) + } else if (err) { + process.nextTick((stream, err) => { + stream.emit('error', err) + }, stream, err) } - get type () { - webidl.brandCheck(this, File) - - return this[kState].type + if (stream.destroyed !== true) { + stream[kDestroyed] = true } } -class FileLike { - constructor (blobLike, fileName, options = {}) { - // TODO: argument idl type check - - // The File constructor is invoked with two or three parameters, depending - // on whether the optional dictionary parameter is used. When the File() - // constructor is invoked, user agents must run the following steps: - - // 1. Let bytes be the result of processing blob parts given fileBits and - // options. - - // 2. Let n be the fileName argument to the constructor. - const n = fileName - - // 3. Process FilePropertyBag dictionary argument by running the following - // substeps: - - // 1. If the type member is provided and is not the empty string, let t - // be set to the type dictionary member. If t contains any characters - // outside the range U+0020 to U+007E, then set t to the empty string - // and return from these substeps. - // TODO - const t = options.type - - // 2. Convert every character in t to ASCII lowercase. - // TODO +const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/ +function parseKeepAliveTimeout (val) { + const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR) + return m ? parseInt(m[1], 10) * 1000 : null +} - // 3. If the lastModified member is provided, let d be set to the - // lastModified dictionary member. If it is not provided, set d to the - // current date and time represented as the number of milliseconds since - // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). - const d = options.lastModified ?? Date.now() +function parseHeaders (headers, obj = {}) { + // For H2 support + if (!Array.isArray(headers)) return headers - // 4. Return a new File object F such that: - // F refers to the bytes byte sequence. - // F.size is set to the number of total bytes in bytes. - // F.name is set to n. - // F.type is set to t. - // F.lastModified is set to d. + for (let i = 0; i < headers.length; i += 2) { + const key = headers[i].toString().toLowerCase() + let val = obj[key] - this[kState] = { - blobLike, - name: n, - type: t, - lastModified: d + if (!val) { + if (Array.isArray(headers[i + 1])) { + obj[key] = headers[i + 1].map(x => x.toString('utf8')) + } else { + obj[key] = headers[i + 1].toString('utf8') + } + } else { + if (!Array.isArray(val)) { + val = [val] + obj[key] = val + } + val.push(headers[i + 1].toString('utf8')) } } - stream (...args) { - webidl.brandCheck(this, FileLike) - - return this[kState].blobLike.stream(...args) + // See https://github.com/nodejs/node/pull/46528 + if ('content-length' in obj && 'content-disposition' in obj) { + obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1') } - arrayBuffer (...args) { - webidl.brandCheck(this, FileLike) + return obj +} - return this[kState].blobLike.arrayBuffer(...args) - } +function parseRawHeaders (headers) { + const ret = [] + let hasContentLength = false + let contentDispositionIdx = -1 - slice (...args) { - webidl.brandCheck(this, FileLike) + for (let n = 0; n < headers.length; n += 2) { + const key = headers[n + 0].toString() + const val = headers[n + 1].toString('utf8') - return this[kState].blobLike.slice(...args) + if (key.length === 14 && (key === 'content-length' || key.toLowerCase() === 'content-length')) { + ret.push(key, val) + hasContentLength = true + } else if (key.length === 19 && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) { + contentDispositionIdx = ret.push(key, val) - 1 + } else { + ret.push(key, val) + } } - text (...args) { - webidl.brandCheck(this, FileLike) - - return this[kState].blobLike.text(...args) + // See https://github.com/nodejs/node/pull/46528 + if (hasContentLength && contentDispositionIdx !== -1) { + ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1') } - get size () { - webidl.brandCheck(this, FileLike) - - return this[kState].blobLike.size - } + return ret +} - get type () { - webidl.brandCheck(this, FileLike) +function isBuffer (buffer) { + // See, https://github.com/mcollina/undici/pull/319 + return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) +} - return this[kState].blobLike.type +function validateHandler (handler, method, upgrade) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') } - get name () { - webidl.brandCheck(this, FileLike) - - return this[kState].name + if (typeof handler.onConnect !== 'function') { + throw new InvalidArgumentError('invalid onConnect method') } - get lastModified () { - webidl.brandCheck(this, FileLike) - - return this[kState].lastModified + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') } - get [Symbol.toStringTag] () { - return 'File' + if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) { + throw new InvalidArgumentError('invalid onBodySent method') } -} - -Object.defineProperties(File.prototype, { - [Symbol.toStringTag]: { - value: 'File', - configurable: true - }, - name: kEnumerableProperty, - lastModified: kEnumerableProperty -}) -webidl.converters.Blob = webidl.interfaceConverter(Blob) + if (upgrade || method === 'CONNECT') { + if (typeof handler.onUpgrade !== 'function') { + throw new InvalidArgumentError('invalid onUpgrade method') + } + } else { + if (typeof handler.onHeaders !== 'function') { + throw new InvalidArgumentError('invalid onHeaders method') + } -webidl.converters.BlobPart = function (V, opts) { - if (webidl.util.Type(V) === 'Object') { - if (isBlobLike(V)) { - return webidl.converters.Blob(V, { strict: false }) + if (typeof handler.onData !== 'function') { + throw new InvalidArgumentError('invalid onData method') } - if ( - ArrayBuffer.isView(V) || - types.isAnyArrayBuffer(V) - ) { - return webidl.converters.BufferSource(V, opts) + if (typeof handler.onComplete !== 'function') { + throw new InvalidArgumentError('invalid onComplete method') } } - - return webidl.converters.USVString(V, opts) } -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.BlobPart -) +// A body is disturbed if it has been read from and it cannot +// be re-used without losing state or data. +function isDisturbed (body) { + return !!(body && ( + stream.isDisturbed + ? stream.isDisturbed(body) || body[kBodyUsed] // TODO (fix): Why is body[kBodyUsed] needed? + : body[kBodyUsed] || + body.readableDidRead || + (body._readableState && body._readableState.dataEmitted) || + isReadableAborted(body) + )) +} -// https://www.w3.org/TR/FileAPI/#dfn-FilePropertyBag -webidl.converters.FilePropertyBag = webidl.dictionaryConverter([ - { - key: 'lastModified', - converter: webidl.converters['long long'], - get defaultValue () { - return Date.now() - } - }, - { - key: 'type', - converter: webidl.converters.DOMString, - defaultValue: '' - }, - { - key: 'endings', - converter: (value) => { - value = webidl.converters.DOMString(value) - value = value.toLowerCase() +function isErrored (body) { + return !!(body && ( + stream.isErrored + ? stream.isErrored(body) + : /state: 'errored'/.test(nodeUtil.inspect(body) + ))) +} - if (value !== 'native') { - value = 'transparent' - } +function isReadable (body) { + return !!(body && ( + stream.isReadable + ? stream.isReadable(body) + : /state: 'readable'/.test(nodeUtil.inspect(body) + ))) +} - return value - }, - defaultValue: 'transparent' +function getSocketInfo (socket) { + return { + localAddress: socket.localAddress, + localPort: socket.localPort, + remoteAddress: socket.remoteAddress, + remotePort: socket.remotePort, + remoteFamily: socket.remoteFamily, + timeout: socket.timeout, + bytesWritten: socket.bytesWritten, + bytesRead: socket.bytesRead } -]) +} -/** - * @see https://www.w3.org/TR/FileAPI/#process-blob-parts - * @param {(NodeJS.TypedArray|Blob|string)[]} parts - * @param {{ type: string, endings: string }} options - */ -function processBlobParts (parts, options) { - // 1. Let bytes be an empty sequence of bytes. - /** @type {NodeJS.TypedArray[]} */ - const bytes = [] +async function * convertIterableToBuffer (iterable) { + for await (const chunk of iterable) { + yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) + } +} - // 2. For each element in parts: - for (const element of parts) { - // 1. If element is a USVString, run the following substeps: - if (typeof element === 'string') { - // 1. Let s be element. - let s = element +let ReadableStream +function ReadableStreamFrom (iterable) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } - // 2. If the endings member of options is "native", set s - // to the result of converting line endings to native - // of element. - if (options.endings === 'native') { - s = convertLineEndingsNative(s) - } + if (ReadableStream.from) { + return ReadableStream.from(convertIterableToBuffer(iterable)) + } - // 3. Append the result of UTF-8 encoding s to bytes. - bytes.push(encoder.encode(s)) - } else if ( - types.isAnyArrayBuffer(element) || - types.isTypedArray(element) - ) { - // 2. If element is a BufferSource, get a copy of the - // bytes held by the buffer source, and append those - // bytes to bytes. - if (!element.buffer) { // ArrayBuffer - bytes.push(new Uint8Array(element)) - } else { - bytes.push( - new Uint8Array(element.buffer, element.byteOffset, element.byteLength) - ) + let iterator + return new ReadableStream( + { + async start () { + iterator = iterable[Symbol.asyncIterator]() + }, + async pull (controller) { + const { done, value } = await iterator.next() + if (done) { + queueMicrotask(() => { + controller.close() + }) + } else { + const buf = Buffer.isBuffer(value) ? value : Buffer.from(value) + controller.enqueue(new Uint8Array(buf)) + } + return controller.desiredSize > 0 + }, + async cancel (reason) { + await iterator.return() } - } else if (isBlobLike(element)) { - // 3. If element is a Blob, append the bytes it represents - // to bytes. - bytes.push(element) + }, + 0 + ) +} + +// The chunk should be a FormData instance and contains +// all the required methods. +function isFormDataLike (object) { + return ( + object && + typeof object === 'object' && + typeof object.append === 'function' && + typeof object.delete === 'function' && + typeof object.get === 'function' && + typeof object.getAll === 'function' && + typeof object.has === 'function' && + typeof object.set === 'function' && + object[Symbol.toStringTag] === 'FormData' + ) +} + +function throwIfAborted (signal) { + if (!signal) { return } + if (typeof signal.throwIfAborted === 'function') { + signal.throwIfAborted() + } else { + if (signal.aborted) { + // DOMException not available < v17.0.0 + const err = new Error('The operation was aborted') + err.name = 'AbortError' + throw err } } +} - // 3. Return bytes. - return bytes +function addAbortListener (signal, listener) { + if ('addEventListener' in signal) { + signal.addEventListener('abort', listener, { once: true }) + return () => signal.removeEventListener('abort', listener) + } + signal.addListener('abort', listener) + return () => signal.removeListener('abort', listener) } +const hasToWellFormed = !!String.prototype.toWellFormed + /** - * @see https://www.w3.org/TR/FileAPI/#convert-line-endings-to-native - * @param {string} s + * @param {string} val */ -function convertLineEndingsNative (s) { - // 1. Let native line ending be be the code point U+000A LF. - let nativeLineEnding = '\n' - - // 2. If the underlying platform’s conventions are to - // represent newlines as a carriage return and line feed - // sequence, set native line ending to the code point - // U+000D CR followed by the code point U+000A LF. - if (process.platform === 'win32') { - nativeLineEnding = '\r\n' +function toUSVString (val) { + if (hasToWellFormed) { + return `${val}`.toWellFormed() + } else if (nodeUtil.toUSVString) { + return nodeUtil.toUSVString(val) } - return s.replace(/\r?\n/g, nativeLineEnding) + return `${val}` } -// If this function is moved to ./util.js, some tools (such as -// rollup) will warn about circular dependencies. See: -// https://github.com/nodejs/undici/issues/1629 -function isFileLike (object) { - return ( - (NativeFile && object instanceof NativeFile) || - object instanceof File || ( - object && - (typeof object.stream === 'function' || - typeof object.arrayBuffer === 'function') && - object[Symbol.toStringTag] === 'File' - ) - ) +// Parsed accordingly to RFC 9110 +// https://www.rfc-editor.org/rfc/rfc9110#field.content-range +function parseRangeHeader (range) { + if (range == null || range === '') return { start: 0, end: null, size: null } + + const m = range ? range.match(/^bytes (\d+)-(\d+)\/(\d+)?$/) : null + return m + ? { + start: parseInt(m[1]), + end: m[2] ? parseInt(m[2]) : null, + size: m[3] ? parseInt(m[3]) : null + } + : null } -module.exports = { File, FileLike, isFileLike } +const kEnumerableProperty = Object.create(null) +kEnumerableProperty.enumerable = true + +module.exports = { + kEnumerableProperty, + nop, + isDisturbed, + isErrored, + isReadable, + toUSVString, + isReadableAborted, + isBlobLike, + parseOrigin, + parseURL, + getServerName, + isStream, + isIterable, + isAsyncIterable, + isDestroyed, + parseRawHeaders, + parseHeaders, + parseKeepAliveTimeout, + destroy, + bodyLength, + deepClone, + ReadableStreamFrom, + isBuffer, + validateHandler, + getSocketInfo, + isFormDataLike, + buildURL, + throwIfAborted, + addAbortListener, + parseRangeHeader, + nodeMajor, + nodeMinor, + nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13), + safeHTTPMethods: ['GET', 'HEAD', 'OPTIONS', 'TRACE'] +} /***/ }), -/***/ 2015: +/***/ 4839: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { isBlobLike, toUSVString, makeIterator } = __nccwpck_require__(2538) -const { kState } = __nccwpck_require__(5861) -const { File: UndiciFile, FileLike, isFileLike } = __nccwpck_require__(8511) -const { webidl } = __nccwpck_require__(1744) -const { Blob, File: NativeFile } = __nccwpck_require__(4300) +const Dispatcher = __nccwpck_require__(412) +const { + ClientDestroyedError, + ClientClosedError, + InvalidArgumentError +} = __nccwpck_require__(8045) +const { kDestroy, kClose, kDispatch, kInterceptors } = __nccwpck_require__(2785) -/** @type {globalThis['File']} */ -const File = NativeFile ?? UndiciFile +const kDestroyed = Symbol('destroyed') +const kClosed = Symbol('closed') +const kOnDestroyed = Symbol('onDestroyed') +const kOnClosed = Symbol('onClosed') +const kInterceptedDispatch = Symbol('Intercepted Dispatch') -// https://xhr.spec.whatwg.org/#formdata -class FormData { - constructor (form) { - if (form !== undefined) { - throw webidl.errors.conversionFailed({ - prefix: 'FormData constructor', - argument: 'Argument 1', - types: ['undefined'] - }) - } +class DispatcherBase extends Dispatcher { + constructor () { + super() - this[kState] = [] + this[kDestroyed] = false + this[kOnDestroyed] = null + this[kClosed] = false + this[kOnClosed] = [] } - append (name, value, filename = undefined) { - webidl.brandCheck(this, FormData) + get destroyed () { + return this[kDestroyed] + } - webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.append' }) + get closed () { + return this[kClosed] + } - if (arguments.length === 3 && !isBlobLike(value)) { - throw new TypeError( - "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" - ) + get interceptors () { + return this[kInterceptors] + } + + set interceptors (newInterceptors) { + if (newInterceptors) { + for (let i = newInterceptors.length - 1; i >= 0; i--) { + const interceptor = this[kInterceptors][i] + if (typeof interceptor !== 'function') { + throw new InvalidArgumentError('interceptor must be an function') + } + } } - // 1. Let value be value if given; otherwise blobValue. + this[kInterceptors] = newInterceptors + } - name = webidl.converters.USVString(name) - value = isBlobLike(value) - ? webidl.converters.Blob(value, { strict: false }) - : webidl.converters.USVString(value) - filename = arguments.length === 3 - ? webidl.converters.USVString(filename) - : undefined + close (callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.close((err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } - // 2. Let entry be the result of creating an entry with - // name, value, and filename if given. - const entry = makeEntry(name, value, filename) + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - // 3. Append entry to this’s entry list. - this[kState].push(entry) - } + if (this[kDestroyed]) { + queueMicrotask(() => callback(new ClientDestroyedError(), null)) + return + } - delete (name) { - webidl.brandCheck(this, FormData) + if (this[kClosed]) { + if (this[kOnClosed]) { + this[kOnClosed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return + } - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.delete' }) + this[kClosed] = true + this[kOnClosed].push(callback) - name = webidl.converters.USVString(name) + const onClosed = () => { + const callbacks = this[kOnClosed] + this[kOnClosed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } - // The delete(name) method steps are to remove all entries whose name - // is name from this’s entry list. - this[kState] = this[kState].filter(entry => entry.name !== name) + // Should not error. + this[kClose]() + .then(() => this.destroy()) + .then(() => { + queueMicrotask(onClosed) + }) } - get (name) { - webidl.brandCheck(this, FormData) + destroy (err, callback) { + if (typeof err === 'function') { + callback = err + err = null + } - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.get' }) + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.destroy(err, (err, data) => { + return err ? /* istanbul ignore next: should never error */ reject(err) : resolve(data) + }) + }) + } - name = webidl.converters.USVString(name) + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - // 1. If there is no entry whose name is name in this’s entry list, - // then return null. - const idx = this[kState].findIndex((entry) => entry.name === name) - if (idx === -1) { - return null + if (this[kDestroyed]) { + if (this[kOnDestroyed]) { + this[kOnDestroyed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return } - // 2. Return the value of the first entry whose name is name from - // this’s entry list. - return this[kState][idx].value - } + if (!err) { + err = new ClientDestroyedError() + } - getAll (name) { - webidl.brandCheck(this, FormData) + this[kDestroyed] = true + this[kOnDestroyed] = this[kOnDestroyed] || [] + this[kOnDestroyed].push(callback) - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.getAll' }) + const onDestroyed = () => { + const callbacks = this[kOnDestroyed] + this[kOnDestroyed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } - name = webidl.converters.USVString(name) + // Should not error. + this[kDestroy](err).then(() => { + queueMicrotask(onDestroyed) + }) + } - // 1. If there is no entry whose name is name in this’s entry list, - // then return the empty list. - // 2. Return the values of all entries whose name is name, in order, - // from this’s entry list. - return this[kState] - .filter((entry) => entry.name === name) - .map((entry) => entry.value) + [kInterceptedDispatch] (opts, handler) { + if (!this[kInterceptors] || this[kInterceptors].length === 0) { + this[kInterceptedDispatch] = this[kDispatch] + return this[kDispatch](opts, handler) + } + + let dispatch = this[kDispatch].bind(this) + for (let i = this[kInterceptors].length - 1; i >= 0; i--) { + dispatch = this[kInterceptors][i](dispatch) + } + this[kInterceptedDispatch] = dispatch + return dispatch(opts, handler) } - has (name) { - webidl.brandCheck(this, FormData) + dispatch (opts, handler) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.has' }) + try { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object.') + } - name = webidl.converters.USVString(name) + if (this[kDestroyed] || this[kOnDestroyed]) { + throw new ClientDestroyedError() + } - // The has(name) method steps are to return true if there is an entry - // whose name is name in this’s entry list; otherwise false. - return this[kState].findIndex((entry) => entry.name === name) !== -1 - } + if (this[kClosed]) { + throw new ClientClosedError() + } - set (name, value, filename = undefined) { - webidl.brandCheck(this, FormData) + return this[kInterceptedDispatch](opts, handler) + } catch (err) { + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') + } - webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.set' }) + handler.onError(err) - if (arguments.length === 3 && !isBlobLike(value)) { - throw new TypeError( - "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" - ) + return false } + } +} - // The set(name, value) and set(name, blobValue, filename) method steps - // are: +module.exports = DispatcherBase - // 1. Let value be value if given; otherwise blobValue. - name = webidl.converters.USVString(name) - value = isBlobLike(value) - ? webidl.converters.Blob(value, { strict: false }) - : webidl.converters.USVString(value) - filename = arguments.length === 3 - ? toUSVString(filename) - : undefined +/***/ }), - // 2. Let entry be the result of creating an entry with name, value, and - // filename if given. - const entry = makeEntry(name, value, filename) +/***/ 412: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 3. If there are entries in this’s entry list whose name is name, then - // replace the first such entry with entry and remove the others. - const idx = this[kState].findIndex((entry) => entry.name === name) - if (idx !== -1) { - this[kState] = [ - ...this[kState].slice(0, idx), - entry, - ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name) - ] - } else { - // 4. Otherwise, append entry to this’s entry list. - this[kState].push(entry) - } - } - - entries () { - webidl.brandCheck(this, FormData) - - return makeIterator( - () => this[kState].map(pair => [pair.name, pair.value]), - 'FormData', - 'key+value' - ) - } - - keys () { - webidl.brandCheck(this, FormData) - - return makeIterator( - () => this[kState].map(pair => [pair.name, pair.value]), - 'FormData', - 'key' - ) - } - - values () { - webidl.brandCheck(this, FormData) - - return makeIterator( - () => this[kState].map(pair => [pair.name, pair.value]), - 'FormData', - 'value' - ) - } - - /** - * @param {(value: string, key: string, self: FormData) => void} callbackFn - * @param {unknown} thisArg - */ - forEach (callbackFn, thisArg = globalThis) { - webidl.brandCheck(this, FormData) +"use strict"; - webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.forEach' }) - if (typeof callbackFn !== 'function') { - throw new TypeError( - "Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'." - ) - } +const EventEmitter = __nccwpck_require__(2361) - for (const [key, value] of this) { - callbackFn.apply(thisArg, [value, key, this]) - } +class Dispatcher extends EventEmitter { + dispatch () { + throw new Error('not implemented') } -} - -FormData.prototype[Symbol.iterator] = FormData.prototype.entries -Object.defineProperties(FormData.prototype, { - [Symbol.toStringTag]: { - value: 'FormData', - configurable: true + close () { + throw new Error('not implemented') } -}) - -/** - * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry - * @param {string} name - * @param {string|Blob} value - * @param {?string} filename - * @returns - */ -function makeEntry (name, value, filename) { - // 1. Set name to the result of converting name into a scalar value string. - // "To convert a string into a scalar value string, replace any surrogates - // with U+FFFD." - // see: https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#buftostringencoding-start-end - name = Buffer.from(name).toString('utf8') - - // 2. If value is a string, then set value to the result of converting - // value into a scalar value string. - if (typeof value === 'string') { - value = Buffer.from(value).toString('utf8') - } else { - // 3. Otherwise: - - // 1. If value is not a File object, then set value to a new File object, - // representing the same bytes, whose name attribute value is "blob" - if (!isFileLike(value)) { - value = value instanceof Blob - ? new File([value], 'blob', { type: value.type }) - : new FileLike(value, 'blob', { type: value.type }) - } - - // 2. If filename is given, then set value to a new File object, - // representing the same bytes, whose name attribute is filename. - if (filename !== undefined) { - /** @type {FilePropertyBag} */ - const options = { - type: value.type, - lastModified: value.lastModified - } - value = (NativeFile && value instanceof NativeFile) || value instanceof UndiciFile - ? new File([value], filename, options) - : new FileLike(value, filename, options) - } + destroy () { + throw new Error('not implemented') } - - // 4. Return an entry whose name is name and whose value is value. - return { name, value } } -module.exports = { FormData } +module.exports = Dispatcher /***/ }), -/***/ 1246: -/***/ ((module) => { +/***/ 1472: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -// In case of breaking changes, increase the version -// number to avoid conflicts. -const globalOrigin = Symbol.for('undici.globalOrigin.1') +const Busboy = __nccwpck_require__(727) +const util = __nccwpck_require__(3983) +const { + ReadableStreamFrom, + isBlobLike, + isReadableStreamLike, + readableStreamClose, + createDeferredPromise, + fullyReadBody +} = __nccwpck_require__(2538) +const { FormData } = __nccwpck_require__(2015) +const { kState } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { DOMException, structuredClone } = __nccwpck_require__(1037) +const { Blob, File: NativeFile } = __nccwpck_require__(4300) +const { kBodyUsed } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { isErrored } = __nccwpck_require__(3983) +const { isUint8Array, isArrayBuffer } = __nccwpck_require__(9830) +const { File: UndiciFile } = __nccwpck_require__(8511) +const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) -function getGlobalOrigin () { - return globalThis[globalOrigin] -} +let ReadableStream = globalThis.ReadableStream -function setGlobalOrigin (newOrigin) { - if (newOrigin === undefined) { - Object.defineProperty(globalThis, globalOrigin, { - value: undefined, - writable: true, - enumerable: false, - configurable: false - }) +/** @type {globalThis['File']} */ +const File = NativeFile ?? UndiciFile +const textEncoder = new TextEncoder() +const textDecoder = new TextDecoder() - return +// https://fetch.spec.whatwg.org/#concept-bodyinit-extract +function extractBody (object, keepalive = false) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) } - const parsedURL = new URL(newOrigin) + // 1. Let stream be null. + let stream = null - if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') { - throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`) + // 2. If object is a ReadableStream object, then set stream to object. + if (object instanceof ReadableStream) { + stream = object + } else if (isBlobLike(object)) { + // 3. Otherwise, if object is a Blob object, set stream to the + // result of running object’s get stream. + stream = object.stream() + } else { + // 4. Otherwise, set stream to a new ReadableStream object, and set + // up stream. + stream = new ReadableStream({ + async pull (controller) { + controller.enqueue( + typeof source === 'string' ? textEncoder.encode(source) : source + ) + queueMicrotask(() => readableStreamClose(controller)) + }, + start () {}, + type: undefined + }) } - Object.defineProperty(globalThis, globalOrigin, { - value: parsedURL, - writable: true, - enumerable: false, - configurable: false - }) -} - -module.exports = { - getGlobalOrigin, - setGlobalOrigin -} + // 5. Assert: stream is a ReadableStream object. + assert(isReadableStreamLike(stream)) + // 6. Let action be null. + let action = null -/***/ }), + // 7. Let source be null. + let source = null -/***/ 554: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 8. Let length be null. + let length = null -"use strict"; -// https://github.com/Ethan-Arrowood/undici-fetch + // 9. Let type be null. + let type = null + // 10. Switch on object: + if (typeof object === 'string') { + // Set source to the UTF-8 encoding of object. + // Note: setting source to a Uint8Array here breaks some mocking assumptions. + source = object + // Set type to `text/plain;charset=UTF-8`. + type = 'text/plain;charset=UTF-8' + } else if (object instanceof URLSearchParams) { + // URLSearchParams -const { kHeadersList, kConstruct } = __nccwpck_require__(2785) -const { kGuard } = __nccwpck_require__(5861) -const { kEnumerableProperty } = __nccwpck_require__(3983) -const { - makeIterator, - isValidHeaderName, - isValidHeaderValue -} = __nccwpck_require__(2538) -const { webidl } = __nccwpck_require__(1744) -const assert = __nccwpck_require__(9491) + // spec says to run application/x-www-form-urlencoded on body.list + // this is implemented in Node.js as apart of an URLSearchParams instance toString method + // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490 + // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100 -const kHeadersMap = Symbol('headers map') -const kHeadersSortedMap = Symbol('headers map sorted') + // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. + source = object.toString() -/** - * @param {number} code - */ -function isHTTPWhiteSpaceCharCode (code) { - return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020 -} + // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. + type = 'application/x-www-form-urlencoded;charset=UTF-8' + } else if (isArrayBuffer(object)) { + // BufferSource/ArrayBuffer -/** - * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize - * @param {string} potentialValue - */ -function headerValueNormalize (potentialValue) { - // To normalize a byte sequence potentialValue, remove - // any leading and trailing HTTP whitespace bytes from - // potentialValue. - let i = 0; let j = potentialValue.length + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.slice()) + } else if (ArrayBuffer.isView(object)) { + // BufferSource/ArrayBufferView - while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j - while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) + } else if (util.isFormDataLike(object)) { + const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` + const prefix = `--${boundary}\r\nContent-Disposition: form-data` - return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j) -} + /*! formdata-polyfill. MIT License. Jimmy Wärting */ + const escape = (str) => + str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22') + const normalizeLinefeeds = (value) => value.replace(/\r?\n|\r/g, '\r\n') -function fill (headers, object) { - // To fill a Headers object headers with a given object object, run these steps: + // Set action to this step: run the multipart/form-data + // encoding algorithm, with object’s entry list and UTF-8. + // - This ensures that the body is immutable and can't be changed afterwords + // - That the content-length is calculated in advance. + // - And that all parts are pre-encoded and ready to be sent. - // 1. If object is a sequence, then for each header in object: - // Note: webidl conversion to array has already been done. - if (Array.isArray(object)) { - for (let i = 0; i < object.length; ++i) { - const header = object[i] - // 1. If header does not contain exactly two items, then throw a TypeError. - if (header.length !== 2) { - throw webidl.errors.exception({ - header: 'Headers constructor', - message: `expected name/value pair to be length 2, found ${header.length}.` - }) + const blobParts = [] + const rn = new Uint8Array([13, 10]) // '\r\n' + length = 0 + let hasUnknownSizeValue = false + + for (const [name, value] of object) { + if (typeof value === 'string') { + const chunk = textEncoder.encode(prefix + + `; name="${escape(normalizeLinefeeds(name))}"` + + `\r\n\r\n${normalizeLinefeeds(value)}\r\n`) + blobParts.push(chunk) + length += chunk.byteLength + } else { + const chunk = textEncoder.encode(`${prefix}; name="${escape(normalizeLinefeeds(name))}"` + + (value.name ? `; filename="${escape(value.name)}"` : '') + '\r\n' + + `Content-Type: ${ + value.type || 'application/octet-stream' + }\r\n\r\n`) + blobParts.push(chunk, value, rn) + if (typeof value.size === 'number') { + length += chunk.byteLength + value.size + rn.byteLength + } else { + hasUnknownSizeValue = true + } } + } - // 2. Append (header’s first item, header’s second item) to headers. - appendHeader(headers, header[0], header[1]) + const chunk = textEncoder.encode(`--${boundary}--`) + blobParts.push(chunk) + length += chunk.byteLength + if (hasUnknownSizeValue) { + length = null } - } else if (typeof object === 'object' && object !== null) { - // Note: null should throw - // 2. Otherwise, object is a record, then for each key → value in object, - // append (key, value) to headers - const keys = Object.keys(object) - for (let i = 0; i < keys.length; ++i) { - appendHeader(headers, keys[i], object[keys[i]]) + // Set source to object. + source = object + + action = async function * () { + for (const part of blobParts) { + if (part.stream) { + yield * part.stream() + } else { + yield part + } + } } - } else { - throw webidl.errors.conversionFailed({ - prefix: 'Headers constructor', - argument: 'Argument 1', - types: ['sequence>', 'record'] - }) - } -} -/** - * @see https://fetch.spec.whatwg.org/#concept-headers-append - */ -function appendHeader (headers, name, value) { - // 1. Normalize value. - value = headerValueNormalize(value) + // Set type to `multipart/form-data; boundary=`, + // followed by the multipart/form-data boundary string generated + // by the multipart/form-data encoding algorithm. + type = 'multipart/form-data; boundary=' + boundary + } else if (isBlobLike(object)) { + // Blob - // 2. If name is not a header name or value is not a - // header value, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.append', - value: name, - type: 'header name' - }) - } else if (!isValidHeaderValue(value)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.append', - value, - type: 'header value' - }) + // Set source to object. + source = object + + // Set length to object’s size. + length = object.size + + // If object’s type attribute is not the empty byte sequence, set + // type to its value. + if (object.type) { + type = object.type + } + } else if (typeof object[Symbol.asyncIterator] === 'function') { + // If keepalive is true, then throw a TypeError. + if (keepalive) { + throw new TypeError('keepalive') + } + + // If object is disturbed or locked, then throw a TypeError. + if (util.isDisturbed(object) || object.locked) { + throw new TypeError( + 'Response body object should not be disturbed or locked' + ) + } + + stream = + object instanceof ReadableStream ? object : ReadableStreamFrom(object) } - // 3. If headers’s guard is "immutable", then throw a TypeError. - // 4. Otherwise, if headers’s guard is "request" and name is a - // forbidden header name, return. - // Note: undici does not implement forbidden header names - if (headers[kGuard] === 'immutable') { - throw new TypeError('immutable') - } else if (headers[kGuard] === 'request-no-cors') { - // 5. Otherwise, if headers’s guard is "request-no-cors": - // TODO + // 11. If source is a byte sequence, then set action to a + // step that returns source and length to source’s length. + if (typeof source === 'string' || util.isBuffer(source)) { + length = Buffer.byteLength(source) } - // 6. Otherwise, if headers’s guard is "response" and name is a - // forbidden response-header name, return. + // 12. If action is non-null, then run these steps in in parallel: + if (action != null) { + // Run action. + let iterator + stream = new ReadableStream({ + async start () { + iterator = action(object)[Symbol.asyncIterator]() + }, + async pull (controller) { + const { value, done } = await iterator.next() + if (done) { + // When running action is done, close stream. + queueMicrotask(() => { + controller.close() + }) + } else { + // Whenever one or more bytes are available and stream is not errored, + // enqueue a Uint8Array wrapping an ArrayBuffer containing the available + // bytes into stream. + if (!isErrored(stream)) { + controller.enqueue(new Uint8Array(value)) + } + } + return controller.desiredSize > 0 + }, + async cancel (reason) { + await iterator.return() + }, + type: undefined + }) + } - // 7. Append (name, value) to headers’s header list. - return headers[kHeadersList].append(name, value) + // 13. Let body be a body whose stream is stream, source is source, + // and length is length. + const body = { stream, source, length } - // 8. If headers’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from headers + // 14. Return (body, type). + return [body, type] } -class HeadersList { - /** @type {[string, string][]|null} */ - cookies = null - - constructor (init) { - if (init instanceof HeadersList) { - this[kHeadersMap] = new Map(init[kHeadersMap]) - this[kHeadersSortedMap] = init[kHeadersSortedMap] - this.cookies = init.cookies === null ? null : [...init.cookies] - } else { - this[kHeadersMap] = new Map(init) - this[kHeadersSortedMap] = null - } +// https://fetch.spec.whatwg.org/#bodyinit-safely-extract +function safelyExtractBody (object, keepalive = false) { + if (!ReadableStream) { + // istanbul ignore next + ReadableStream = (__nccwpck_require__(5356).ReadableStream) } - // https://fetch.spec.whatwg.org/#header-list-contains - contains (name) { - // A header list list contains a header name name if list - // contains a header whose name is a byte-case-insensitive - // match for name. - name = name.toLowerCase() + // To safely extract a body and a `Content-Type` value from + // a byte sequence or BodyInit object object, run these steps: - return this[kHeadersMap].has(name) + // 1. If object is a ReadableStream object, then: + if (object instanceof ReadableStream) { + // Assert: object is neither disturbed nor locked. + // istanbul ignore next + assert(!util.isDisturbed(object), 'The body has already been consumed.') + // istanbul ignore next + assert(!object.locked, 'The stream is locked.') } - clear () { - this[kHeadersMap].clear() - this[kHeadersSortedMap] = null - this.cookies = null - } + // 2. Return the results of extracting object. + return extractBody(object, keepalive) +} - // https://fetch.spec.whatwg.org/#concept-header-list-append - append (name, value) { - this[kHeadersSortedMap] = null +function cloneBody (body) { + // To clone a body body, run these steps: - // 1. If list contains name, then set name to the first such - // header’s name. - const lowercaseName = name.toLowerCase() - const exists = this[kHeadersMap].get(lowercaseName) - - // 2. Append (name, value) to list. - if (exists) { - const delimiter = lowercaseName === 'cookie' ? '; ' : ', ' - this[kHeadersMap].set(lowercaseName, { - name: exists.name, - value: `${exists.value}${delimiter}${value}` - }) - } else { - this[kHeadersMap].set(lowercaseName, { name, value }) - } - - if (lowercaseName === 'set-cookie') { - this.cookies ??= [] - this.cookies.push(value) - } - } + // https://fetch.spec.whatwg.org/#concept-body-clone - // https://fetch.spec.whatwg.org/#concept-header-list-set - set (name, value) { - this[kHeadersSortedMap] = null - const lowercaseName = name.toLowerCase() + // 1. Let « out1, out2 » be the result of teeing body’s stream. + const [out1, out2] = body.stream.tee() + const out2Clone = structuredClone(out2, { transfer: [out2] }) + // This, for whatever reasons, unrefs out2Clone which allows + // the process to exit by itself. + const [, finalClone] = out2Clone.tee() - if (lowercaseName === 'set-cookie') { - this.cookies = [value] - } + // 2. Set body’s stream to out1. + body.stream = out1 - // 1. If list contains name, then set the value of - // the first such header to value and remove the - // others. - // 2. Otherwise, append header (name, value) to list. - this[kHeadersMap].set(lowercaseName, { name, value }) + // 3. Return a body whose stream is out2 and other members are copied from body. + return { + stream: finalClone, + length: body.length, + source: body.source } +} - // https://fetch.spec.whatwg.org/#concept-header-list-delete - delete (name) { - this[kHeadersSortedMap] = null - - name = name.toLowerCase() - - if (name === 'set-cookie') { - this.cookies = null - } +async function * consumeBody (body) { + if (body) { + if (isUint8Array(body)) { + yield body + } else { + const stream = body.stream - this[kHeadersMap].delete(name) - } + if (util.isDisturbed(stream)) { + throw new TypeError('The body has already been consumed.') + } - // https://fetch.spec.whatwg.org/#concept-header-list-get - get (name) { - const value = this[kHeadersMap].get(name.toLowerCase()) + if (stream.locked) { + throw new TypeError('The stream is locked.') + } - // 1. If list does not contain name, then return null. - // 2. Return the values of all headers in list whose name - // is a byte-case-insensitive match for name, - // separated from each other by 0x2C 0x20, in order. - return value === undefined ? null : value.value - } + // Compat. + stream[kBodyUsed] = true - * [Symbol.iterator] () { - // use the lowercased name - for (const [name, { value }] of this[kHeadersMap]) { - yield [name, value] + yield * stream } } +} - get entries () { - const headers = {} - - if (this[kHeadersMap].size) { - for (const { name, value } of this[kHeadersMap].values()) { - headers[name] = value - } - } - - return headers +function throwIfAborted (state) { + if (state.aborted) { + throw new DOMException('The operation was aborted.', 'AbortError') } } -// https://fetch.spec.whatwg.org/#headers-class -class Headers { - constructor (init = undefined) { - if (init === kConstruct) { - return - } - this[kHeadersList] = new HeadersList() +function bodyMixinMethods (instance) { + const methods = { + blob () { + // The blob() method steps are to return the result of + // running consume body with this and the following step + // given a byte sequence bytes: return a Blob whose + // contents are bytes and whose type attribute is this’s + // MIME type. + return specConsumeBody(this, (bytes) => { + let mimeType = bodyMimeType(this) - // The new Headers(init) constructor steps are: + if (mimeType === 'failure') { + mimeType = '' + } else if (mimeType) { + mimeType = serializeAMimeType(mimeType) + } - // 1. Set this’s guard to "none". - this[kGuard] = 'none' + // Return a Blob whose contents are bytes and type attribute + // is mimeType. + return new Blob([bytes], { type: mimeType }) + }, instance) + }, - // 2. If init is given, then fill this with init. - if (init !== undefined) { - init = webidl.converters.HeadersInit(init) - fill(this, init) - } - } + arrayBuffer () { + // The arrayBuffer() method steps are to return the result + // of running consume body with this and the following step + // given a byte sequence bytes: return a new ArrayBuffer + // whose contents are bytes. + return specConsumeBody(this, (bytes) => { + return new Uint8Array(bytes).buffer + }, instance) + }, - // https://fetch.spec.whatwg.org/#dom-headers-append - append (name, value) { - webidl.brandCheck(this, Headers) + text () { + // The text() method steps are to return the result of running + // consume body with this and UTF-8 decode. + return specConsumeBody(this, utf8DecodeBytes, instance) + }, - webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.append' }) + json () { + // The json() method steps are to return the result of running + // consume body with this and parse JSON from bytes. + return specConsumeBody(this, parseJSONFromBytes, instance) + }, - name = webidl.converters.ByteString(name) - value = webidl.converters.ByteString(value) + async formData () { + webidl.brandCheck(this, instance) - return appendHeader(this, name, value) - } + throwIfAborted(this[kState]) - // https://fetch.spec.whatwg.org/#dom-headers-delete - delete (name) { - webidl.brandCheck(this, Headers) + const contentType = this.headers.get('Content-Type') - webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.delete' }) + // If mimeType’s essence is "multipart/form-data", then: + if (/multipart\/form-data/.test(contentType)) { + const headers = {} + for (const [key, value] of this.headers) headers[key.toLowerCase()] = value - name = webidl.converters.ByteString(name) + const responseFormData = new FormData() - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.delete', - value: name, - type: 'header name' - }) - } + let busboy - // 2. If this’s guard is "immutable", then throw a TypeError. - // 3. Otherwise, if this’s guard is "request" and name is a - // forbidden header name, return. - // 4. Otherwise, if this’s guard is "request-no-cors", name - // is not a no-CORS-safelisted request-header name, and - // name is not a privileged no-CORS request-header name, - // return. - // 5. Otherwise, if this’s guard is "response" and name is - // a forbidden response-header name, return. - // Note: undici does not implement forbidden header names - if (this[kGuard] === 'immutable') { - throw new TypeError('immutable') - } else if (this[kGuard] === 'request-no-cors') { - // TODO - } + try { + busboy = new Busboy({ + headers, + preservePath: true + }) + } catch (err) { + throw new DOMException(`${err}`, 'AbortError') + } - // 6. If this’s header list does not contain name, then - // return. - if (!this[kHeadersList].contains(name)) { - return - } + busboy.on('field', (name, value) => { + responseFormData.append(name, value) + }) + busboy.on('file', (name, value, filename, encoding, mimeType) => { + const chunks = [] - // 7. Delete name from this’s header list. - // 8. If this’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from this. - this[kHeadersList].delete(name) - } + if (encoding === 'base64' || encoding.toLowerCase() === 'base64') { + let base64chunk = '' - // https://fetch.spec.whatwg.org/#dom-headers-get - get (name) { - webidl.brandCheck(this, Headers) + value.on('data', (chunk) => { + base64chunk += chunk.toString().replace(/[\r\n]/gm, '') - webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.get' }) + const end = base64chunk.length - base64chunk.length % 4 + chunks.push(Buffer.from(base64chunk.slice(0, end), 'base64')) - name = webidl.converters.ByteString(name) + base64chunk = base64chunk.slice(end) + }) + value.on('end', () => { + chunks.push(Buffer.from(base64chunk, 'base64')) + responseFormData.append(name, new File(chunks, filename, { type: mimeType })) + }) + } else { + value.on('data', (chunk) => { + chunks.push(chunk) + }) + value.on('end', () => { + responseFormData.append(name, new File(chunks, filename, { type: mimeType })) + }) + } + }) - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.get', - value: name, - type: 'header name' - }) - } - - // 2. Return the result of getting name from this’s header - // list. - return this[kHeadersList].get(name) - } + const busboyResolve = new Promise((resolve, reject) => { + busboy.on('finish', resolve) + busboy.on('error', (err) => reject(new TypeError(err))) + }) - // https://fetch.spec.whatwg.org/#dom-headers-has - has (name) { - webidl.brandCheck(this, Headers) + if (this.body !== null) for await (const chunk of consumeBody(this[kState].body)) busboy.write(chunk) + busboy.end() + await busboyResolve - webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.has' }) + return responseFormData + } else if (/application\/x-www-form-urlencoded/.test(contentType)) { + // Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then: - name = webidl.converters.ByteString(name) + // 1. Let entries be the result of parsing bytes. + let entries + try { + let text = '' + // application/x-www-form-urlencoded parser will keep the BOM. + // https://url.spec.whatwg.org/#concept-urlencoded-parser + // Note that streaming decoder is stateful and cannot be reused + const streamingDecoder = new TextDecoder('utf-8', { ignoreBOM: true }) - // 1. If name is not a header name, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.has', - value: name, - type: 'header name' - }) - } + for await (const chunk of consumeBody(this[kState].body)) { + if (!isUint8Array(chunk)) { + throw new TypeError('Expected Uint8Array chunk') + } + text += streamingDecoder.decode(chunk, { stream: true }) + } + text += streamingDecoder.decode() + entries = new URLSearchParams(text) + } catch (err) { + // istanbul ignore next: Unclear when new URLSearchParams can fail on a string. + // 2. If entries is failure, then throw a TypeError. + throw Object.assign(new TypeError(), { cause: err }) + } - // 2. Return true if this’s header list contains name; - // otherwise false. - return this[kHeadersList].contains(name) - } + // 3. Return a new FormData object whose entries are entries. + const formData = new FormData() + for (const [name, value] of entries) { + formData.append(name, value) + } + return formData + } else { + // Wait a tick before checking if the request has been aborted. + // Otherwise, a TypeError can be thrown when an AbortError should. + await Promise.resolve() - // https://fetch.spec.whatwg.org/#dom-headers-set - set (name, value) { - webidl.brandCheck(this, Headers) + throwIfAborted(this[kState]) - webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.set' }) + // Otherwise, throw a TypeError. + throw webidl.errors.exception({ + header: `${instance.name}.formData`, + message: 'Could not parse content as FormData.' + }) + } + } + } - name = webidl.converters.ByteString(name) - value = webidl.converters.ByteString(value) + return methods +} - // 1. Normalize value. - value = headerValueNormalize(value) +function mixinBody (prototype) { + Object.assign(prototype.prototype, bodyMixinMethods(prototype)) +} - // 2. If name is not a header name or value is not a - // header value, then throw a TypeError. - if (!isValidHeaderName(name)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.set', - value: name, - type: 'header name' - }) - } else if (!isValidHeaderValue(value)) { - throw webidl.errors.invalidArgument({ - prefix: 'Headers.set', - value, - type: 'header value' - }) - } +/** + * @see https://fetch.spec.whatwg.org/#concept-body-consume-body + * @param {Response|Request} object + * @param {(value: unknown) => unknown} convertBytesToJSValue + * @param {Response|Request} instance + */ +async function specConsumeBody (object, convertBytesToJSValue, instance) { + webidl.brandCheck(object, instance) - // 3. If this’s guard is "immutable", then throw a TypeError. - // 4. Otherwise, if this’s guard is "request" and name is a - // forbidden header name, return. - // 5. Otherwise, if this’s guard is "request-no-cors" and - // name/value is not a no-CORS-safelisted request-header, - // return. - // 6. Otherwise, if this’s guard is "response" and name is a - // forbidden response-header name, return. - // Note: undici does not implement forbidden header names - if (this[kGuard] === 'immutable') { - throw new TypeError('immutable') - } else if (this[kGuard] === 'request-no-cors') { - // TODO - } + throwIfAborted(object[kState]) - // 7. Set (name, value) in this’s header list. - // 8. If this’s guard is "request-no-cors", then remove - // privileged no-CORS request headers from this - this[kHeadersList].set(name, value) + // 1. If object is unusable, then return a promise rejected + // with a TypeError. + if (bodyUnusable(object[kState].body)) { + throw new TypeError('Body is unusable') } - // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie - getSetCookie () { - webidl.brandCheck(this, Headers) - - // 1. If this’s header list does not contain `Set-Cookie`, then return « ». - // 2. Return the values of all headers in this’s header list whose name is - // a byte-case-insensitive match for `Set-Cookie`, in order. + // 2. Let promise be a new promise. + const promise = createDeferredPromise() - const list = this[kHeadersList].cookies + // 3. Let errorSteps given error be to reject promise with error. + const errorSteps = (error) => promise.reject(error) - if (list) { - return [...list] + // 4. Let successSteps given a byte sequence data be to resolve + // promise with the result of running convertBytesToJSValue + // with data. If that threw an exception, then run errorSteps + // with that exception. + const successSteps = (data) => { + try { + promise.resolve(convertBytesToJSValue(data)) + } catch (e) { + errorSteps(e) } + } - return [] + // 5. If object’s body is null, then run successSteps with an + // empty byte sequence. + if (object[kState].body == null) { + successSteps(new Uint8Array()) + return promise.promise } - // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine - get [kHeadersSortedMap] () { - if (this[kHeadersList][kHeadersSortedMap]) { - return this[kHeadersList][kHeadersSortedMap] - } + // 6. Otherwise, fully read object’s body given successSteps, + // errorSteps, and object’s relevant global object. + await fullyReadBody(object[kState].body, successSteps, errorSteps) - // 1. Let headers be an empty list of headers with the key being the name - // and value the value. - const headers = [] + // 7. Return promise. + return promise.promise +} - // 2. Let names be the result of convert header names to a sorted-lowercase - // set with all the names of the headers in list. - const names = [...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1) - const cookies = this[kHeadersList].cookies +// https://fetch.spec.whatwg.org/#body-unusable +function bodyUnusable (body) { + // An object including the Body interface mixin is + // said to be unusable if its body is non-null and + // its body’s stream is disturbed or locked. + return body != null && (body.stream.locked || util.isDisturbed(body.stream)) +} - // 3. For each name of names: - for (let i = 0; i < names.length; ++i) { - const [name, value] = names[i] - // 1. If name is `set-cookie`, then: - if (name === 'set-cookie') { - // 1. Let values be a list of all values of headers in list whose name - // is a byte-case-insensitive match for name, in order. +/** + * @see https://encoding.spec.whatwg.org/#utf-8-decode + * @param {Buffer} buffer + */ +function utf8DecodeBytes (buffer) { + if (buffer.length === 0) { + return '' + } - // 2. For each value of values: - // 1. Append (name, value) to headers. - for (let j = 0; j < cookies.length; ++j) { - headers.push([name, cookies[j]]) - } - } else { - // 2. Otherwise: + // 1. Let buffer be the result of peeking three bytes from + // ioQueue, converted to a byte sequence. - // 1. Let value be the result of getting name from list. + // 2. If buffer is 0xEF 0xBB 0xBF, then read three + // bytes from ioQueue. (Do nothing with those bytes.) + if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { + buffer = buffer.subarray(3) + } - // 2. Assert: value is non-null. - assert(value !== null) + // 3. Process a queue with an instance of UTF-8’s + // decoder, ioQueue, output, and "replacement". + const output = textDecoder.decode(buffer) - // 3. Append (name, value) to headers. - headers.push([name, value]) - } - } + // 4. Return output. + return output +} - this[kHeadersList][kHeadersSortedMap] = headers +/** + * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value + * @param {Uint8Array} bytes + */ +function parseJSONFromBytes (bytes) { + return JSON.parse(utf8DecodeBytes(bytes)) +} - // 4. Return headers. - return headers +/** + * @see https://fetch.spec.whatwg.org/#concept-body-mime-type + * @param {import('./response').Response|import('./request').Request} object + */ +function bodyMimeType (object) { + const { headersList } = object[kState] + const contentType = headersList.get('content-type') + + if (contentType === null) { + return 'failure' } - keys () { - webidl.brandCheck(this, Headers) + return parseMIMEType(contentType) +} - if (this[kGuard] === 'immutable') { - const value = this[kHeadersSortedMap] - return makeIterator(() => value, 'Headers', - 'key') - } +module.exports = { + extractBody, + safelyExtractBody, + cloneBody, + mixinBody +} - return makeIterator( - () => [...this[kHeadersSortedMap].values()], - 'Headers', - 'key' - ) - } - values () { - webidl.brandCheck(this, Headers) +/***/ }), - if (this[kGuard] === 'immutable') { - const value = this[kHeadersSortedMap] - return makeIterator(() => value, 'Headers', - 'value') - } +/***/ 1037: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return makeIterator( - () => [...this[kHeadersSortedMap].values()], - 'Headers', - 'value' - ) - } +"use strict"; - entries () { - webidl.brandCheck(this, Headers) - if (this[kGuard] === 'immutable') { - const value = this[kHeadersSortedMap] - return makeIterator(() => value, 'Headers', - 'key+value') - } +const { MessageChannel, receiveMessageOnPort } = __nccwpck_require__(1267) - return makeIterator( - () => [...this[kHeadersSortedMap].values()], - 'Headers', - 'key+value' - ) - } +const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] +const corsSafeListedMethodsSet = new Set(corsSafeListedMethods) - /** - * @param {(value: string, key: string, self: Headers) => void} callbackFn - * @param {unknown} thisArg - */ - forEach (callbackFn, thisArg = globalThis) { - webidl.brandCheck(this, Headers) +const nullBodyStatus = [101, 204, 205, 304] - webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.forEach' }) +const redirectStatus = [301, 302, 303, 307, 308] +const redirectStatusSet = new Set(redirectStatus) - if (typeof callbackFn !== 'function') { - throw new TypeError( - "Failed to execute 'forEach' on 'Headers': parameter 1 is not of type 'Function'." - ) - } +// https://fetch.spec.whatwg.org/#block-bad-port +const badPorts = [ + '1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79', + '87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137', + '139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532', + '540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723', + '2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6697', + '10080' +] - for (const [key, value] of this) { - callbackFn.apply(thisArg, [value, key, this]) - } - } +const badPortsSet = new Set(badPorts) - [Symbol.for('nodejs.util.inspect.custom')] () { - webidl.brandCheck(this, Headers) +// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies +const referrerPolicy = [ + '', + 'no-referrer', + 'no-referrer-when-downgrade', + 'same-origin', + 'origin', + 'strict-origin', + 'origin-when-cross-origin', + 'strict-origin-when-cross-origin', + 'unsafe-url' +] +const referrerPolicySet = new Set(referrerPolicy) - return this[kHeadersList] - } -} +const requestRedirect = ['follow', 'manual', 'error'] -Headers.prototype[Symbol.iterator] = Headers.prototype.entries +const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE'] +const safeMethodsSet = new Set(safeMethods) -Object.defineProperties(Headers.prototype, { - append: kEnumerableProperty, - delete: kEnumerableProperty, - get: kEnumerableProperty, - has: kEnumerableProperty, - set: kEnumerableProperty, - getSetCookie: kEnumerableProperty, - keys: kEnumerableProperty, - values: kEnumerableProperty, - entries: kEnumerableProperty, - forEach: kEnumerableProperty, - [Symbol.iterator]: { enumerable: false }, - [Symbol.toStringTag]: { - value: 'Headers', - configurable: true +const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors'] + +const requestCredentials = ['omit', 'same-origin', 'include'] + +const requestCache = [ + 'default', + 'no-store', + 'reload', + 'no-cache', + 'force-cache', + 'only-if-cached' +] + +// https://fetch.spec.whatwg.org/#request-body-header-name +const requestBodyHeader = [ + 'content-encoding', + 'content-language', + 'content-location', + 'content-type', + // See https://github.com/nodejs/undici/issues/2021 + // 'Content-Length' is a forbidden header name, which is typically + // removed in the Headers implementation. However, undici doesn't + // filter out headers, so we add it here. + 'content-length' +] + +// https://fetch.spec.whatwg.org/#enumdef-requestduplex +const requestDuplex = [ + 'half' +] + +// http://fetch.spec.whatwg.org/#forbidden-method +const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK'] +const forbiddenMethodsSet = new Set(forbiddenMethods) + +const subresource = [ + 'audio', + 'audioworklet', + 'font', + 'image', + 'manifest', + 'paintworklet', + 'script', + 'style', + 'track', + 'video', + 'xslt', + '' +] +const subresourceSet = new Set(subresource) + +/** @type {globalThis['DOMException']} */ +const DOMException = globalThis.DOMException ?? (() => { + // DOMException was only made a global in Node v17.0.0, + // but fetch supports >= v16.8. + try { + atob('~') + } catch (err) { + return Object.getPrototypeOf(err).constructor } -}) +})() -webidl.converters.HeadersInit = function (V) { - if (webidl.util.Type(V) === 'Object') { - if (V[Symbol.iterator]) { - return webidl.converters['sequence>'](V) +let channel + +/** @type {globalThis['structuredClone']} */ +const structuredClone = + globalThis.structuredClone ?? + // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js + // structuredClone was added in v17.0.0, but fetch supports v16.8 + function structuredClone (value, options = undefined) { + if (arguments.length === 0) { + throw new TypeError('missing argument') } - return webidl.converters['record'](V) + if (!channel) { + channel = new MessageChannel() + } + channel.port1.unref() + channel.port2.unref() + channel.port1.postMessage(value, options?.transfer) + return receiveMessageOnPort(channel.port2).message } - throw webidl.errors.conversionFailed({ - prefix: 'Headers constructor', - argument: 'Argument 1', - types: ['sequence>', 'record'] - }) -} - module.exports = { - fill, - Headers, - HeadersList + DOMException, + structuredClone, + subresource, + forbiddenMethods, + requestBodyHeader, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + redirectStatus, + corsSafeListedMethods, + nullBodyStatus, + safeMethods, + badPorts, + requestDuplex, + subresourceSet, + badPortsSet, + redirectStatusSet, + corsSafeListedMethodsSet, + safeMethodsSet, + forbiddenMethodsSet, + referrerPolicySet } /***/ }), -/***/ 4881: +/***/ 685: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; -// https://github.com/Ethan-Arrowood/undici-fetch +const assert = __nccwpck_require__(9491) +const { atob } = __nccwpck_require__(4300) +const { isomorphicDecode } = __nccwpck_require__(2538) +const encoder = new TextEncoder() +/** + * @see https://mimesniff.spec.whatwg.org/#http-token-code-point + */ +const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ +const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line +/** + * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point + */ +const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line -const { - Response, - makeNetworkError, - makeAppropriateNetworkError, - filterResponse, - makeResponse -} = __nccwpck_require__(7823) -const { Headers } = __nccwpck_require__(554) -const { Request, makeRequest } = __nccwpck_require__(8359) -const zlib = __nccwpck_require__(9796) -const { - bytesMatch, - makePolicyContainer, - clonePolicyContainer, - requestBadPort, - TAOCheck, - appendRequestOriginHeader, - responseLocationURL, - requestCurrentURL, - setRequestReferrerPolicyOnRedirect, - tryUpgradeRequestToAPotentiallyTrustworthyURL, - createOpaqueTimingInfo, - appendFetchMetadata, - corsCheck, - crossOriginResourcePolicyCheck, - determineRequestsReferrer, - coarsenedSharedCurrentTime, - createDeferredPromise, - isBlobLike, - sameOrigin, - isCancelled, - isAborted, - isErrorLike, - fullyReadBody, - readableStreamClose, - isomorphicEncode, - urlIsLocal, - urlIsHttpHttpsScheme, - urlHasHttpsScheme -} = __nccwpck_require__(2538) -const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) -const assert = __nccwpck_require__(9491) -const { safelyExtractBody } = __nccwpck_require__(1472) -const { - redirectStatusSet, - nullBodyStatus, - safeMethodsSet, - requestBodyHeader, - subresourceSet, - DOMException -} = __nccwpck_require__(1037) -const { kHeadersList } = __nccwpck_require__(2785) -const EE = __nccwpck_require__(2361) -const { Readable, pipeline } = __nccwpck_require__(2781) -const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = __nccwpck_require__(3983) -const { dataURLProcessor, serializeAMimeType } = __nccwpck_require__(685) -const { TransformStream } = __nccwpck_require__(5356) -const { getGlobalDispatcher } = __nccwpck_require__(1892) -const { webidl } = __nccwpck_require__(1744) -const { STATUS_CODES } = __nccwpck_require__(3685) -const GET_OR_HEAD = ['GET', 'HEAD'] +// https://fetch.spec.whatwg.org/#data-url-processor +/** @param {URL} dataURL */ +function dataURLProcessor (dataURL) { + // 1. Assert: dataURL’s scheme is "data". + assert(dataURL.protocol === 'data:') -/** @type {import('buffer').resolveObjectURL} */ -let resolveObjectURL -let ReadableStream = globalThis.ReadableStream + // 2. Let input be the result of running the URL + // serializer on dataURL with exclude fragment + // set to true. + let input = URLSerializer(dataURL, true) -class Fetch extends EE { - constructor (dispatcher) { - super() + // 3. Remove the leading "data:" string from input. + input = input.slice(5) - this.dispatcher = dispatcher - this.connection = null - this.dump = false - this.state = 'ongoing' - // 2 terminated listeners get added per request, - // but only 1 gets removed. If there are 20 redirects, - // 21 listeners will be added. - // See https://github.com/nodejs/undici/issues/1711 - // TODO (fix): Find and fix root cause for leaked listener. - this.setMaxListeners(21) - } + // 4. Let position point at the start of input. + const position = { position: 0 } - terminate (reason) { - if (this.state !== 'ongoing') { - return - } + // 5. Let mimeType be the result of collecting a + // sequence of code points that are not equal + // to U+002C (,), given position. + let mimeType = collectASequenceOfCodePointsFast( + ',', + input, + position + ) - this.state = 'terminated' - this.connection?.destroy(reason) - this.emit('terminated', reason) - } + // 6. Strip leading and trailing ASCII whitespace + // from mimeType. + // Undici implementation note: we need to store the + // length because if the mimetype has spaces removed, + // the wrong amount will be sliced from the input in + // step #9 + const mimeTypeLength = mimeType.length + mimeType = removeASCIIWhitespace(mimeType, true, true) - // https://fetch.spec.whatwg.org/#fetch-controller-abort - abort (error) { - if (this.state !== 'ongoing') { - return - } + // 7. If position is past the end of input, then + // return failure + if (position.position >= input.length) { + return 'failure' + } - // 1. Set controller’s state to "aborted". - this.state = 'aborted' + // 8. Advance position by 1. + position.position++ - // 2. Let fallbackError be an "AbortError" DOMException. - // 3. Set error to fallbackError if it is not given. - if (!error) { - error = new DOMException('The operation was aborted.', 'AbortError') - } + // 9. Let encodedBody be the remainder of input. + const encodedBody = input.slice(mimeTypeLength + 1) - // 4. Let serializedError be StructuredSerialize(error). - // If that threw an exception, catch it, and let - // serializedError be StructuredSerialize(fallbackError). + // 10. Let body be the percent-decoding of encodedBody. + let body = stringPercentDecode(encodedBody) - // 5. Set controller’s serialized abort reason to serializedError. - this.serializedAbortReason = error + // 11. If mimeType ends with U+003B (;), followed by + // zero or more U+0020 SPACE, followed by an ASCII + // case-insensitive match for "base64", then: + if (/;(\u0020){0,}base64$/i.test(mimeType)) { + // 1. Let stringBody be the isomorphic decode of body. + const stringBody = isomorphicDecode(body) - this.connection?.destroy(error) - this.emit('terminated', error) - } -} + // 2. Set body to the forgiving-base64 decode of + // stringBody. + body = forgivingBase64(stringBody) -// https://fetch.spec.whatwg.org/#fetch-method -function fetch (input, init = {}) { - webidl.argumentLengthCheck(arguments, 1, { header: 'globalThis.fetch' }) + // 3. If body is failure, then return failure. + if (body === 'failure') { + return 'failure' + } - // 1. Let p be a new promise. - const p = createDeferredPromise() + // 4. Remove the last 6 code points from mimeType. + mimeType = mimeType.slice(0, -6) - // 2. Let requestObject be the result of invoking the initial value of - // Request as constructor with input and init as arguments. If this throws - // an exception, reject p with it and return p. - let requestObject + // 5. Remove trailing U+0020 SPACE code points from mimeType, + // if any. + mimeType = mimeType.replace(/(\u0020)+$/, '') - try { - requestObject = new Request(input, init) - } catch (e) { - p.reject(e) - return p.promise + // 6. Remove the last U+003B (;) code point from mimeType. + mimeType = mimeType.slice(0, -1) } - // 3. Let request be requestObject’s request. - const request = requestObject[kState] + // 12. If mimeType starts with U+003B (;), then prepend + // "text/plain" to mimeType. + if (mimeType.startsWith(';')) { + mimeType = 'text/plain' + mimeType + } - // 4. If requestObject’s signal’s aborted flag is set, then: - if (requestObject.signal.aborted) { - // 1. Abort the fetch() call with p, request, null, and - // requestObject’s signal’s abort reason. - abortFetch(p, request, null, requestObject.signal.reason) + // 13. Let mimeTypeRecord be the result of parsing + // mimeType. + let mimeTypeRecord = parseMIMEType(mimeType) - // 2. Return p. - return p.promise + // 14. If mimeTypeRecord is failure, then set + // mimeTypeRecord to text/plain;charset=US-ASCII. + if (mimeTypeRecord === 'failure') { + mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII') } - // 5. Let globalObject be request’s client’s global object. - const globalObject = request.client.globalObject + // 15. Return a new data: URL struct whose MIME + // type is mimeTypeRecord and body is body. + // https://fetch.spec.whatwg.org/#data-url-struct + return { mimeType: mimeTypeRecord, body } +} - // 6. If globalObject is a ServiceWorkerGlobalScope object, then set - // request’s service-workers mode to "none". - if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') { - request.serviceWorkers = 'none' +// https://url.spec.whatwg.org/#concept-url-serializer +/** + * @param {URL} url + * @param {boolean} excludeFragment + */ +function URLSerializer (url, excludeFragment = false) { + if (!excludeFragment) { + return url.href } - // 7. Let responseObject be null. - let responseObject = null - - // 8. Let relevantRealm be this’s relevant Realm. - const relevantRealm = null + const href = url.href + const hashLength = url.hash.length - // 9. Let locallyAborted be false. - let locallyAborted = false + return hashLength === 0 ? href : href.substring(0, href.length - hashLength) +} - // 10. Let controller be null. - let controller = null +// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points +/** + * @param {(char: string) => boolean} condition + * @param {string} input + * @param {{ position: number }} position + */ +function collectASequenceOfCodePoints (condition, input, position) { + // 1. Let result be the empty string. + let result = '' - // 11. Add the following abort steps to requestObject’s signal: - addAbortListener( - requestObject.signal, - () => { - // 1. Set locallyAborted to true. - locallyAborted = true + // 2. While position doesn’t point past the end of input and the + // code point at position within input meets the condition condition: + while (position.position < input.length && condition(input[position.position])) { + // 1. Append that code point to the end of result. + result += input[position.position] - // 2. Assert: controller is non-null. - assert(controller != null) + // 2. Advance position by 1. + position.position++ + } - // 3. Abort controller with requestObject’s signal’s abort reason. - controller.abort(requestObject.signal.reason) + // 3. Return result. + return result +} - // 4. Abort the fetch() call with p, request, responseObject, - // and requestObject’s signal’s abort reason. - abortFetch(p, request, responseObject, requestObject.signal.reason) - } - ) - - // 12. Let handleFetchDone given response response be to finalize and - // report timing with response, globalObject, and "fetch". - const handleFetchDone = (response) => - finalizeAndReportTiming(response, 'fetch') - - // 13. Set controller to the result of calling fetch given request, - // with processResponseEndOfBody set to handleFetchDone, and processResponse - // given response being these substeps: +/** + * A faster collectASequenceOfCodePoints that only works when comparing a single character. + * @param {string} char + * @param {string} input + * @param {{ position: number }} position + */ +function collectASequenceOfCodePointsFast (char, input, position) { + const idx = input.indexOf(char, position.position) + const start = position.position - const processResponse = (response) => { - // 1. If locallyAborted is true, terminate these substeps. - if (locallyAborted) { - return Promise.resolve() - } + if (idx === -1) { + position.position = input.length + return input.slice(start) + } - // 2. If response’s aborted flag is set, then: - if (response.aborted) { - // 1. Let deserializedError be the result of deserialize a serialized - // abort reason given controller’s serialized abort reason and - // relevantRealm. + position.position = idx + return input.slice(start, position.position) +} - // 2. Abort the fetch() call with p, request, responseObject, and - // deserializedError. +// https://url.spec.whatwg.org/#string-percent-decode +/** @param {string} input */ +function stringPercentDecode (input) { + // 1. Let bytes be the UTF-8 encoding of input. + const bytes = encoder.encode(input) - abortFetch(p, request, responseObject, controller.serializedAbortReason) - return Promise.resolve() - } + // 2. Return the percent-decoding of bytes. + return percentDecode(bytes) +} - // 3. If response is a network error, then reject p with a TypeError - // and terminate these substeps. - if (response.type === 'error') { - p.reject( - Object.assign(new TypeError('fetch failed'), { cause: response.error }) - ) - return Promise.resolve() - } +// https://url.spec.whatwg.org/#percent-decode +/** @param {Uint8Array} input */ +function percentDecode (input) { + // 1. Let output be an empty byte sequence. + /** @type {number[]} */ + const output = [] - // 4. Set responseObject to the result of creating a Response object, - // given response, "immutable", and relevantRealm. - responseObject = new Response() - responseObject[kState] = response - responseObject[kRealm] = relevantRealm - responseObject[kHeaders][kHeadersList] = response.headersList - responseObject[kHeaders][kGuard] = 'immutable' - responseObject[kHeaders][kRealm] = relevantRealm + // 2. For each byte byte in input: + for (let i = 0; i < input.length; i++) { + const byte = input[i] - // 5. Resolve p with responseObject. - p.resolve(responseObject) - } + // 1. If byte is not 0x25 (%), then append byte to output. + if (byte !== 0x25) { + output.push(byte) - controller = fetching({ - request, - processResponseEndOfBody: handleFetchDone, - processResponse, - dispatcher: init.dispatcher ?? getGlobalDispatcher() // undici - }) + // 2. Otherwise, if byte is 0x25 (%) and the next two bytes + // after byte in input are not in the ranges + // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F), + // and 0x61 (a) to 0x66 (f), all inclusive, append byte + // to output. + } else if ( + byte === 0x25 && + !/^[0-9A-Fa-f]{2}$/i.test(String.fromCharCode(input[i + 1], input[i + 2])) + ) { + output.push(0x25) - // 14. Return p. - return p.promise -} + // 3. Otherwise: + } else { + // 1. Let bytePoint be the two bytes after byte in input, + // decoded, and then interpreted as hexadecimal number. + const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2]) + const bytePoint = Number.parseInt(nextTwoBytes, 16) -// https://fetch.spec.whatwg.org/#finalize-and-report-timing -function finalizeAndReportTiming (response, initiatorType = 'other') { - // 1. If response is an aborted network error, then return. - if (response.type === 'error' && response.aborted) { - return - } + // 2. Append a byte whose value is bytePoint to output. + output.push(bytePoint) - // 2. If response’s URL list is null or empty, then return. - if (!response.urlList?.length) { - return + // 3. Skip the next two bytes in input. + i += 2 + } } - // 3. Let originalURL be response’s URL list[0]. - const originalURL = response.urlList[0] + // 3. Return output. + return Uint8Array.from(output) +} - // 4. Let timingInfo be response’s timing info. - let timingInfo = response.timingInfo +// https://mimesniff.spec.whatwg.org/#parse-a-mime-type +/** @param {string} input */ +function parseMIMEType (input) { + // 1. Remove any leading and trailing HTTP whitespace + // from input. + input = removeHTTPWhitespace(input, true, true) - // 5. Let cacheState be response’s cache state. - let cacheState = response.cacheState + // 2. Let position be a position variable for input, + // initially pointing at the start of input. + const position = { position: 0 } - // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return. - if (!urlIsHttpHttpsScheme(originalURL)) { - return - } + // 3. Let type be the result of collecting a sequence + // of code points that are not U+002F (/) from + // input, given position. + const type = collectASequenceOfCodePointsFast( + '/', + input, + position + ) - // 7. If timingInfo is null, then return. - if (timingInfo === null) { - return + // 4. If type is the empty string or does not solely + // contain HTTP token code points, then return failure. + // https://mimesniff.spec.whatwg.org/#http-token-code-point + if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { + return 'failure' } - // 8. If response’s timing allow passed flag is not set, then: - if (!response.timingAllowPassed) { - // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo. - timingInfo = createOpaqueTimingInfo({ - startTime: timingInfo.startTime - }) - - // 2. Set cacheState to the empty string. - cacheState = '' + // 5. If position is past the end of input, then return + // failure + if (position.position > input.length) { + return 'failure' } - // 9. Set timingInfo’s end time to the coarsened shared current time - // given global’s relevant settings object’s cross-origin isolated - // capability. - // TODO: given global’s relevant settings object’s cross-origin isolated - // capability? - timingInfo.endTime = coarsenedSharedCurrentTime() - - // 10. Set response’s timing info to timingInfo. - response.timingInfo = timingInfo + // 6. Advance position by 1. (This skips past U+002F (/).) + position.position++ - // 11. Mark resource timing for timingInfo, originalURL, initiatorType, - // global, and cacheState. - markResourceTiming( - timingInfo, - originalURL, - initiatorType, - globalThis, - cacheState + // 7. Let subtype be the result of collecting a sequence of + // code points that are not U+003B (;) from input, given + // position. + let subtype = collectASequenceOfCodePointsFast( + ';', + input, + position ) -} -// https://w3c.github.io/resource-timing/#dfn-mark-resource-timing -function markResourceTiming (timingInfo, originalURL, initiatorType, globalThis, cacheState) { - if (nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 2)) { - performance.markResourceTiming(timingInfo, originalURL.href, initiatorType, globalThis, cacheState) - } -} + // 8. Remove any trailing HTTP whitespace from subtype. + subtype = removeHTTPWhitespace(subtype, false, true) -// https://fetch.spec.whatwg.org/#abort-fetch -function abortFetch (p, request, responseObject, error) { - // Note: AbortSignal.reason was added in node v17.2.0 - // which would give us an undefined error to reject with. - // Remove this once node v16 is no longer supported. - if (!error) { - error = new DOMException('The operation was aborted.', 'AbortError') + // 9. If subtype is the empty string or does not solely + // contain HTTP token code points, then return failure. + if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { + return 'failure' } - // 1. Reject promise with error. - p.reject(error) - - // 2. If request’s body is not null and is readable, then cancel request’s - // body with error. - if (request.body != null && isReadable(request.body?.stream)) { - request.body.stream.cancel(error).catch((err) => { - if (err.code === 'ERR_INVALID_STATE') { - // Node bug? - return - } - throw err - }) - } + const typeLowercase = type.toLowerCase() + const subtypeLowercase = subtype.toLowerCase() - // 3. If responseObject is null, then return. - if (responseObject == null) { - return + // 10. Let mimeType be a new MIME type record whose type + // is type, in ASCII lowercase, and subtype is subtype, + // in ASCII lowercase. + // https://mimesniff.spec.whatwg.org/#mime-type + const mimeType = { + type: typeLowercase, + subtype: subtypeLowercase, + /** @type {Map} */ + parameters: new Map(), + // https://mimesniff.spec.whatwg.org/#mime-type-essence + essence: `${typeLowercase}/${subtypeLowercase}` } - // 4. Let response be responseObject’s response. - const response = responseObject[kState] + // 11. While position is not past the end of input: + while (position.position < input.length) { + // 1. Advance position by 1. (This skips past U+003B (;).) + position.position++ - // 5. If response’s body is not null and is readable, then error response’s - // body with error. - if (response.body != null && isReadable(response.body?.stream)) { - response.body.stream.cancel(error).catch((err) => { - if (err.code === 'ERR_INVALID_STATE') { - // Node bug? - return - } - throw err - }) - } -} + // 2. Collect a sequence of code points that are HTTP + // whitespace from input given position. + collectASequenceOfCodePoints( + // https://fetch.spec.whatwg.org/#http-whitespace + char => HTTP_WHITESPACE_REGEX.test(char), + input, + position + ) -// https://fetch.spec.whatwg.org/#fetching -function fetching ({ - request, - processRequestBodyChunkLength, - processRequestEndOfBody, - processResponse, - processResponseEndOfBody, - processResponseConsumeBody, - useParallelQueue = false, - dispatcher // undici -}) { - // 1. Let taskDestination be null. - let taskDestination = null + // 3. Let parameterName be the result of collecting a + // sequence of code points that are not U+003B (;) + // or U+003D (=) from input, given position. + let parameterName = collectASequenceOfCodePoints( + (char) => char !== ';' && char !== '=', + input, + position + ) - // 2. Let crossOriginIsolatedCapability be false. - let crossOriginIsolatedCapability = false + // 4. Set parameterName to parameterName, in ASCII + // lowercase. + parameterName = parameterName.toLowerCase() - // 3. If request’s client is non-null, then: - if (request.client != null) { - // 1. Set taskDestination to request’s client’s global object. - taskDestination = request.client.globalObject + // 5. If position is not past the end of input, then: + if (position.position < input.length) { + // 1. If the code point at position within input is + // U+003B (;), then continue. + if (input[position.position] === ';') { + continue + } - // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin - // isolated capability. - crossOriginIsolatedCapability = - request.client.crossOriginIsolatedCapability - } + // 2. Advance position by 1. (This skips past U+003D (=).) + position.position++ + } - // 4. If useParallelQueue is true, then set taskDestination to the result of - // starting a new parallel queue. - // TODO + // 6. If position is past the end of input, then break. + if (position.position > input.length) { + break + } - // 5. Let timingInfo be a new fetch timing info whose start time and - // post-redirect start time are the coarsened shared current time given - // crossOriginIsolatedCapability. - const currenTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability) - const timingInfo = createOpaqueTimingInfo({ - startTime: currenTime - }) + // 7. Let parameterValue be null. + let parameterValue = null - // 6. Let fetchParams be a new fetch params whose - // request is request, - // timing info is timingInfo, - // process request body chunk length is processRequestBodyChunkLength, - // process request end-of-body is processRequestEndOfBody, - // process response is processResponse, - // process response consume body is processResponseConsumeBody, - // process response end-of-body is processResponseEndOfBody, - // task destination is taskDestination, - // and cross-origin isolated capability is crossOriginIsolatedCapability. - const fetchParams = { - controller: new Fetch(dispatcher), - request, - timingInfo, - processRequestBodyChunkLength, - processRequestEndOfBody, - processResponse, - processResponseConsumeBody, - processResponseEndOfBody, - taskDestination, - crossOriginIsolatedCapability - } + // 8. If the code point at position within input is + // U+0022 ("), then: + if (input[position.position] === '"') { + // 1. Set parameterValue to the result of collecting + // an HTTP quoted string from input, given position + // and the extract-value flag. + parameterValue = collectAnHTTPQuotedString(input, position, true) - // 7. If request’s body is a byte sequence, then set request’s body to - // request’s body as a body. - // NOTE: Since fetching is only called from fetch, body should already be - // extracted. - assert(!request.body || request.body.stream) + // 2. Collect a sequence of code points that are not + // U+003B (;) from input, given position. + collectASequenceOfCodePointsFast( + ';', + input, + position + ) - // 8. If request’s window is "client", then set request’s window to request’s - // client, if request’s client’s global object is a Window object; otherwise - // "no-window". - if (request.window === 'client') { - // TODO: What if request.client is null? - request.window = - request.client?.globalObject?.constructor?.name === 'Window' - ? request.client - : 'no-window' - } + // 9. Otherwise: + } else { + // 1. Set parameterValue to the result of collecting + // a sequence of code points that are not U+003B (;) + // from input, given position. + parameterValue = collectASequenceOfCodePointsFast( + ';', + input, + position + ) - // 9. If request’s origin is "client", then set request’s origin to request’s - // client’s origin. - if (request.origin === 'client') { - // TODO: What if request.client is null? - request.origin = request.client?.origin - } + // 2. Remove any trailing HTTP whitespace from parameterValue. + parameterValue = removeHTTPWhitespace(parameterValue, false, true) - // 10. If all of the following conditions are true: - // TODO + // 3. If parameterValue is the empty string, then continue. + if (parameterValue.length === 0) { + continue + } + } - // 11. If request’s policy container is "client", then: - if (request.policyContainer === 'client') { - // 1. If request’s client is non-null, then set request’s policy - // container to a clone of request’s client’s policy container. [HTML] - if (request.client != null) { - request.policyContainer = clonePolicyContainer( - request.client.policyContainer - ) - } else { - // 2. Otherwise, set request’s policy container to a new policy - // container. - request.policyContainer = makePolicyContainer() + // 10. If all of the following are true + // - parameterName is not the empty string + // - parameterName solely contains HTTP token code points + // - parameterValue solely contains HTTP quoted-string token code points + // - mimeType’s parameters[parameterName] does not exist + // then set mimeType’s parameters[parameterName] to parameterValue. + if ( + parameterName.length !== 0 && + HTTP_TOKEN_CODEPOINTS.test(parameterName) && + (parameterValue.length === 0 || HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && + !mimeType.parameters.has(parameterName) + ) { + mimeType.parameters.set(parameterName, parameterValue) } } - // 12. If request’s header list does not contain `Accept`, then: - if (!request.headersList.contains('accept')) { - // 1. Let value be `*/*`. - const value = '*/*' + // 12. Return mimeType. + return mimeType +} - // 2. A user agent should set value to the first matching statement, if - // any, switching on request’s destination: - // "document" - // "frame" - // "iframe" - // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` - // "image" - // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5` - // "style" - // `text/css,*/*;q=0.1` - // TODO +// https://infra.spec.whatwg.org/#forgiving-base64-decode +/** @param {string} data */ +function forgivingBase64 (data) { + // 1. Remove all ASCII whitespace from data. + data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line - // 3. Append `Accept`/value to request’s header list. - request.headersList.append('accept', value) + // 2. If data’s code point length divides by 4 leaving + // no remainder, then: + if (data.length % 4 === 0) { + // 1. If data ends with one or two U+003D (=) code points, + // then remove them from data. + data = data.replace(/=?=$/, '') } - // 13. If request’s header list does not contain `Accept-Language`, then - // user agents should append `Accept-Language`/an appropriate value to - // request’s header list. - if (!request.headersList.contains('accept-language')) { - request.headersList.append('accept-language', '*') + // 3. If data’s code point length divides by 4 leaving + // a remainder of 1, then return failure. + if (data.length % 4 === 1) { + return 'failure' } - // 14. If request’s priority is null, then use request’s initiator and - // destination appropriately in setting request’s priority to a - // user-agent-defined object. - if (request.priority === null) { - // TODO + // 4. If data contains a code point that is not one of + // U+002B (+) + // U+002F (/) + // ASCII alphanumeric + // then return failure. + if (/[^+/0-9A-Za-z]/.test(data)) { + return 'failure' } - // 15. If request is a subresource request, then: - if (subresourceSet.has(request.destination)) { - // TODO - } + const binary = atob(data) + const bytes = new Uint8Array(binary.length) - // 16. Run main fetch given fetchParams. - mainFetch(fetchParams) - .catch(err => { - fetchParams.controller.terminate(err) - }) + for (let byte = 0; byte < binary.length; byte++) { + bytes[byte] = binary.charCodeAt(byte) + } - // 17. Return fetchParam's controller - return fetchParams.controller + return bytes } -// https://fetch.spec.whatwg.org/#concept-main-fetch -async function mainFetch (fetchParams, recursive = false) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request - - // 2. Let response be null. - let response = null +// https://fetch.spec.whatwg.org/#collect-an-http-quoted-string +// tests: https://fetch.spec.whatwg.org/#example-http-quoted-string +/** + * @param {string} input + * @param {{ position: number }} position + * @param {boolean?} extractValue + */ +function collectAnHTTPQuotedString (input, position, extractValue) { + // 1. Let positionStart be position. + const positionStart = position.position - // 3. If request’s local-URLs-only flag is set and request’s current URL is - // not local, then set response to a network error. - if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { - response = makeNetworkError('local URLs only') - } + // 2. Let value be the empty string. + let value = '' - // 4. Run report Content Security Policy violations for request. - // TODO + // 3. Assert: the code point at position within input + // is U+0022 ("). + assert(input[position.position] === '"') - // 5. Upgrade request to a potentially trustworthy URL, if appropriate. - tryUpgradeRequestToAPotentiallyTrustworthyURL(request) + // 4. Advance position by 1. + position.position++ - // 6. If should request be blocked due to a bad port, should fetching request - // be blocked as mixed content, or should request be blocked by Content - // Security Policy returns blocked, then set response to a network error. - if (requestBadPort(request) === 'blocked') { - response = makeNetworkError('bad port') - } - // TODO: should fetching request be blocked as mixed content? - // TODO: should request be blocked by Content Security Policy? + // 5. While true: + while (true) { + // 1. Append the result of collecting a sequence of code points + // that are not U+0022 (") or U+005C (\) from input, given + // position, to value. + value += collectASequenceOfCodePoints( + (char) => char !== '"' && char !== '\\', + input, + position + ) - // 7. If request’s referrer policy is the empty string, then set request’s - // referrer policy to request’s policy container’s referrer policy. - if (request.referrerPolicy === '') { - request.referrerPolicy = request.policyContainer.referrerPolicy - } + // 2. If position is past the end of input, then break. + if (position.position >= input.length) { + break + } - // 8. If request’s referrer is not "no-referrer", then set request’s - // referrer to the result of invoking determine request’s referrer. - if (request.referrer !== 'no-referrer') { - request.referrer = determineRequestsReferrer(request) - } + // 3. Let quoteOrBackslash be the code point at position within + // input. + const quoteOrBackslash = input[position.position] - // 9. Set request’s current URL’s scheme to "https" if all of the following - // conditions are true: - // - request’s current URL’s scheme is "http" - // - request’s current URL’s host is a domain - // - Matching request’s current URL’s host per Known HSTS Host Domain Name - // Matching results in either a superdomain match with an asserted - // includeSubDomains directive or a congruent match (with or without an - // asserted includeSubDomains directive). [HSTS] - // TODO + // 4. Advance position by 1. + position.position++ - // 10. If recursive is false, then run the remaining steps in parallel. - // TODO + // 5. If quoteOrBackslash is U+005C (\), then: + if (quoteOrBackslash === '\\') { + // 1. If position is past the end of input, then append + // U+005C (\) to value and break. + if (position.position >= input.length) { + value += '\\' + break + } - // 11. If response is null, then set response to the result of running - // the steps corresponding to the first matching statement: - if (response === null) { - response = await (async () => { - const currentURL = requestCurrentURL(request) + // 2. Append the code point at position within input to value. + value += input[position.position] - if ( - // - request’s current URL’s origin is same origin with request’s origin, - // and request’s response tainting is "basic" - (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') || - // request’s current URL’s scheme is "data" - (currentURL.protocol === 'data:') || - // - request’s mode is "navigate" or "websocket" - (request.mode === 'navigate' || request.mode === 'websocket') - ) { - // 1. Set request’s response tainting to "basic". - request.responseTainting = 'basic' + // 3. Advance position by 1. + position.position++ - // 2. Return the result of running scheme fetch given fetchParams. - return await schemeFetch(fetchParams) - } + // 6. Otherwise: + } else { + // 1. Assert: quoteOrBackslash is U+0022 ("). + assert(quoteOrBackslash === '"') - // request’s mode is "same-origin" - if (request.mode === 'same-origin') { - // 1. Return a network error. - return makeNetworkError('request mode cannot be "same-origin"') - } + // 2. Break. + break + } + } - // request’s mode is "no-cors" - if (request.mode === 'no-cors') { - // 1. If request’s redirect mode is not "follow", then return a network - // error. - if (request.redirect !== 'follow') { - return makeNetworkError( - 'redirect mode cannot be "follow" for "no-cors" request' - ) - } + // 6. If the extract-value flag is set, then return value. + if (extractValue) { + return value + } - // 2. Set request’s response tainting to "opaque". - request.responseTainting = 'opaque' + // 7. Return the code points from positionStart to position, + // inclusive, within input. + return input.slice(positionStart, position.position) +} - // 3. Return the result of running scheme fetch given fetchParams. - return await schemeFetch(fetchParams) - } +/** + * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type + */ +function serializeAMimeType (mimeType) { + assert(mimeType !== 'failure') + const { parameters, essence } = mimeType - // request’s current URL’s scheme is not an HTTP(S) scheme - if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { - // Return a network error. - return makeNetworkError('URL scheme must be a HTTP(S) scheme') - } + // 1. Let serialization be the concatenation of mimeType’s + // type, U+002F (/), and mimeType’s subtype. + let serialization = essence - // - request’s use-CORS-preflight flag is set - // - request’s unsafe-request flag is set and either request’s method is - // not a CORS-safelisted method or CORS-unsafe request-header names with - // request’s header list is not empty - // 1. Set request’s response tainting to "cors". - // 2. Let corsWithPreflightResponse be the result of running HTTP fetch - // given fetchParams and true. - // 3. If corsWithPreflightResponse is a network error, then clear cache - // entries using request. - // 4. Return corsWithPreflightResponse. - // TODO + // 2. For each name → value of mimeType’s parameters: + for (let [name, value] of parameters.entries()) { + // 1. Append U+003B (;) to serialization. + serialization += ';' - // Otherwise - // 1. Set request’s response tainting to "cors". - request.responseTainting = 'cors' + // 2. Append name to serialization. + serialization += name - // 2. Return the result of running HTTP fetch given fetchParams. - return await httpFetch(fetchParams) - })() - } + // 3. Append U+003D (=) to serialization. + serialization += '=' - // 12. If recursive is true, then return response. - if (recursive) { - return response - } + // 4. If value does not solely contain HTTP token code + // points or value is the empty string, then: + if (!HTTP_TOKEN_CODEPOINTS.test(value)) { + // 1. Precede each occurence of U+0022 (") or + // U+005C (\) in value with U+005C (\). + value = value.replace(/(\\|")/g, '\\$1') - // 13. If response is not a network error and response is not a filtered - // response, then: - if (response.status !== 0 && !response.internalResponse) { - // If request’s response tainting is "cors", then: - if (request.responseTainting === 'cors') { - // 1. Let headerNames be the result of extracting header list values - // given `Access-Control-Expose-Headers` and response’s header list. - // TODO - // 2. If request’s credentials mode is not "include" and headerNames - // contains `*`, then set response’s CORS-exposed header-name list to - // all unique header names in response’s header list. - // TODO - // 3. Otherwise, if headerNames is not null or failure, then set - // response’s CORS-exposed header-name list to headerNames. - // TODO - } + // 2. Prepend U+0022 (") to value. + value = '"' + value - // Set response to the following filtered response with response as its - // internal response, depending on request’s response tainting: - if (request.responseTainting === 'basic') { - response = filterResponse(response, 'basic') - } else if (request.responseTainting === 'cors') { - response = filterResponse(response, 'cors') - } else if (request.responseTainting === 'opaque') { - response = filterResponse(response, 'opaque') - } else { - assert(false) + // 3. Append U+0022 (") to value. + value += '"' } - } - - // 14. Let internalResponse be response, if response is a network error, - // and response’s internal response otherwise. - let internalResponse = - response.status === 0 ? response : response.internalResponse - // 15. If internalResponse’s URL list is empty, then set it to a clone of - // request’s URL list. - if (internalResponse.urlList.length === 0) { - internalResponse.urlList.push(...request.urlList) + // 5. Append value to serialization. + serialization += value } - // 16. If request’s timing allow failed flag is unset, then set - // internalResponse’s timing allow passed flag. - if (!request.timingAllowFailed) { - response.timingAllowPassed = true - } + // 3. Return serialization. + return serialization +} - // 17. If response is not a network error and any of the following returns - // blocked - // - should internalResponse to request be blocked as mixed content - // - should internalResponse to request be blocked by Content Security Policy - // - should internalResponse to request be blocked due to its MIME type - // - should internalResponse to request be blocked due to nosniff - // TODO +/** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} char + */ +function isHTTPWhiteSpace (char) { + return char === '\r' || char === '\n' || char === '\t' || char === ' ' +} - // 18. If response’s type is "opaque", internalResponse’s status is 206, - // internalResponse’s range-requested flag is set, and request’s header - // list does not contain `Range`, then set response and internalResponse - // to a network error. - if ( - response.type === 'opaque' && - internalResponse.status === 206 && - internalResponse.rangeRequested && - !request.headers.contains('range') - ) { - response = internalResponse = makeNetworkError() - } +/** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} str + */ +function removeHTTPWhitespace (str, leading = true, trailing = true) { + let lead = 0 + let trail = str.length - 1 - // 19. If response is not a network error and either request’s method is - // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, - // set internalResponse’s body to null and disregard any enqueuing toward - // it (if any). - if ( - response.status !== 0 && - (request.method === 'HEAD' || - request.method === 'CONNECT' || - nullBodyStatus.includes(internalResponse.status)) - ) { - internalResponse.body = null - fetchParams.controller.dump = true + if (leading) { + for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++); } - // 20. If request’s integrity metadata is not the empty string, then: - if (request.integrity) { - // 1. Let processBodyError be this step: run fetch finale given fetchParams - // and a network error. - const processBodyError = (reason) => - fetchFinale(fetchParams, makeNetworkError(reason)) - - // 2. If request’s response tainting is "opaque", or response’s body is null, - // then run processBodyError and abort these steps. - if (request.responseTainting === 'opaque' || response.body == null) { - processBodyError(response.error) - return - } + if (trailing) { + for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--); + } - // 3. Let processBody given bytes be these steps: - const processBody = (bytes) => { - // 1. If bytes do not match request’s integrity metadata, - // then run processBodyError and abort these steps. [SRI] - if (!bytesMatch(bytes, request.integrity)) { - processBodyError('integrity mismatch') - return - } + return str.slice(lead, trail + 1) +} - // 2. Set response’s body to bytes as a body. - response.body = safelyExtractBody(bytes)[0] +/** + * @see https://infra.spec.whatwg.org/#ascii-whitespace + * @param {string} char + */ +function isASCIIWhitespace (char) { + return char === '\r' || char === '\n' || char === '\t' || char === '\f' || char === ' ' +} - // 3. Run fetch finale given fetchParams and response. - fetchFinale(fetchParams, response) - } +/** + * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace + */ +function removeASCIIWhitespace (str, leading = true, trailing = true) { + let lead = 0 + let trail = str.length - 1 - // 4. Fully read response’s body given processBody and processBodyError. - await fullyReadBody(response.body, processBody, processBodyError) - } else { - // 21. Otherwise, run fetch finale given fetchParams and response. - fetchFinale(fetchParams, response) + if (leading) { + for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++); } -} -// https://fetch.spec.whatwg.org/#concept-scheme-fetch -// given a fetch params fetchParams -function schemeFetch (fetchParams) { - // Note: since the connection is destroyed on redirect, which sets fetchParams to a - // cancelled state, we do not want this condition to trigger *unless* there have been - // no redirects. See https://github.com/nodejs/undici/issues/1776 - // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { - return Promise.resolve(makeAppropriateNetworkError(fetchParams)) + if (trailing) { + for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--); } - // 2. Let request be fetchParams’s request. - const { request } = fetchParams + return str.slice(lead, trail + 1) +} - const { protocol: scheme } = requestCurrentURL(request) +module.exports = { + dataURLProcessor, + URLSerializer, + collectASequenceOfCodePoints, + collectASequenceOfCodePointsFast, + stringPercentDecode, + parseMIMEType, + collectAnHTTPQuotedString, + serializeAMimeType +} - // 3. Switch on request’s current URL’s scheme and run the associated steps: - switch (scheme) { - case 'about:': { - // If request’s current URL’s path is the string "blank", then return a new response - // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) », - // and body is the empty byte sequence as a body. - // Otherwise, return a network error. - return Promise.resolve(makeNetworkError('about scheme is not supported')) - } - case 'blob:': { - if (!resolveObjectURL) { - resolveObjectURL = (__nccwpck_require__(4300).resolveObjectURL) - } +/***/ }), - // 1. Let blobURLEntry be request’s current URL’s blob URL entry. - const blobURLEntry = requestCurrentURL(request) +/***/ 8511: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 - // Buffer.resolveObjectURL does not ignore URL queries. - if (blobURLEntry.search.length !== 0) { - return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) - } +"use strict"; - const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()) - // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s - // object is not a Blob object, then return a network error. - if (request.method !== 'GET' || !isBlobLike(blobURLEntryObject)) { - return Promise.resolve(makeNetworkError('invalid method')) - } +const { Blob, File: NativeFile } = __nccwpck_require__(4300) +const { types } = __nccwpck_require__(3837) +const { kState } = __nccwpck_require__(5861) +const { isBlobLike } = __nccwpck_require__(2538) +const { webidl } = __nccwpck_require__(1744) +const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const encoder = new TextEncoder() - // 3. Let bodyWithType be the result of safely extracting blobURLEntry’s object. - const bodyWithType = safelyExtractBody(blobURLEntryObject) +class File extends Blob { + constructor (fileBits, fileName, options = {}) { + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: + webidl.argumentLengthCheck(arguments, 2, { header: 'File constructor' }) - // 4. Let body be bodyWithType’s body. - const body = bodyWithType[0] + fileBits = webidl.converters['sequence'](fileBits) + fileName = webidl.converters.USVString(fileName) + options = webidl.converters.FilePropertyBag(options) - // 5. Let length be body’s length, serialized and isomorphic encoded. - const length = isomorphicEncode(`${body.length}`) + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. + // Note: Blob handles this for us - // 6. Let type be bodyWithType’s type if it is non-null; otherwise the empty byte sequence. - const type = bodyWithType[1] ?? '' + // 2. Let n be the fileName argument to the constructor. + const n = fileName - // 7. Return a new response whose status message is `OK`, header list is - // « (`Content-Length`, length), (`Content-Type`, type) », and body is body. - const response = makeResponse({ - statusText: 'OK', - headersList: [ - ['content-length', { name: 'Content-Length', value: length }], - ['content-type', { name: 'Content-Type', value: type }] - ] - }) + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: - response.body = body + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // 2. Convert every character in t to ASCII lowercase. + let t = options.type + let d - return Promise.resolve(response) - } - case 'data:': { - // 1. Let dataURLStruct be the result of running the - // data: URL processor on request’s current URL. - const currentURL = requestCurrentURL(request) - const dataURLStruct = dataURLProcessor(currentURL) + // eslint-disable-next-line no-labels + substep: { + if (t) { + t = parseMIMEType(t) - // 2. If dataURLStruct is failure, then return a - // network error. - if (dataURLStruct === 'failure') { - return Promise.resolve(makeNetworkError('failed to fetch the data URL')) - } + if (t === 'failure') { + t = '' + // eslint-disable-next-line no-labels + break substep + } - // 3. Let mimeType be dataURLStruct’s MIME type, serialized. - const mimeType = serializeAMimeType(dataURLStruct.mimeType) + t = serializeAMimeType(t).toLowerCase() + } - // 4. Return a response whose status message is `OK`, - // header list is « (`Content-Type`, mimeType) », - // and body is dataURLStruct’s body as a body. - return Promise.resolve(makeResponse({ - statusText: 'OK', - headersList: [ - ['content-type', { name: 'Content-Type', value: mimeType }] - ], - body: safelyExtractBody(dataURLStruct.body)[0] - })) - } - case 'file:': { - // For now, unfortunate as it is, file URLs are left as an exercise for the reader. - // When in doubt, return a network error. - return Promise.resolve(makeNetworkError('not implemented... yet...')) + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + d = options.lastModified } - case 'http:': - case 'https:': { - // Return the result of running HTTP fetch given fetchParams. - return httpFetch(fetchParams) - .catch((err) => makeNetworkError(err)) - } - default: { - return Promise.resolve(makeNetworkError('unknown scheme')) + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + super(processBlobParts(fileBits, options), { type: t }) + this[kState] = { + name: n, + lastModified: d, + type: t } } -} -// https://fetch.spec.whatwg.org/#finalize-response -function finalizeResponse (fetchParams, response) { - // 1. Set fetchParams’s request’s done flag. - fetchParams.request.done = true + get name () { + webidl.brandCheck(this, File) - // 2, If fetchParams’s process response done is not null, then queue a fetch - // task to run fetchParams’s process response done given response, with - // fetchParams’s task destination. - if (fetchParams.processResponseDone != null) { - queueMicrotask(() => fetchParams.processResponseDone(response)) + return this[kState].name } -} -// https://fetch.spec.whatwg.org/#fetch-finale -function fetchFinale (fetchParams, response) { - // 1. If response is a network error, then: - if (response.type === 'error') { - // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ». - response.urlList = [fetchParams.request.urlList[0]] + get lastModified () { + webidl.brandCheck(this, File) - // 2. Set response’s timing info to the result of creating an opaque timing - // info for fetchParams’s timing info. - response.timingInfo = createOpaqueTimingInfo({ - startTime: fetchParams.timingInfo.startTime - }) + return this[kState].lastModified } - // 2. Let processResponseEndOfBody be the following steps: - const processResponseEndOfBody = () => { - // 1. Set fetchParams’s request’s done flag. - fetchParams.request.done = true + get type () { + webidl.brandCheck(this, File) - // If fetchParams’s process response end-of-body is not null, - // then queue a fetch task to run fetchParams’s process response - // end-of-body given response with fetchParams’s task destination. - if (fetchParams.processResponseEndOfBody != null) { - queueMicrotask(() => fetchParams.processResponseEndOfBody(response)) - } + return this[kState].type } +} - // 3. If fetchParams’s process response is non-null, then queue a fetch task - // to run fetchParams’s process response given response, with fetchParams’s - // task destination. - if (fetchParams.processResponse != null) { - queueMicrotask(() => fetchParams.processResponse(response)) - } +class FileLike { + constructor (blobLike, fileName, options = {}) { + // TODO: argument idl type check - // 4. If response’s body is null, then run processResponseEndOfBody. - if (response.body == null) { - processResponseEndOfBody() - } else { - // 5. Otherwise: + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: - // 1. Let transformStream be a new a TransformStream. + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. - // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, - // enqueues chunk in transformStream. - const identityTransformAlgorithm = (chunk, controller) => { - controller.enqueue(chunk) - } + // 2. Let n be the fileName argument to the constructor. + const n = fileName - // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm - // and flushAlgorithm set to processResponseEndOfBody. - const transformStream = new TransformStream({ - start () {}, - transform: identityTransformAlgorithm, - flush: processResponseEndOfBody - }, { - size () { - return 1 - } - }, { - size () { - return 1 - } - }) + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: - // 4. Set response’s body to the result of piping response’s body through transformStream. - response.body = { stream: response.body.stream.pipeThrough(transformStream) } - } + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // TODO + const t = options.type - // 6. If fetchParams’s process response consume body is non-null, then: - if (fetchParams.processResponseConsumeBody != null) { - // 1. Let processBody given nullOrBytes be this step: run fetchParams’s - // process response consume body given response and nullOrBytes. - const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes) + // 2. Convert every character in t to ASCII lowercase. + // TODO - // 2. Let processBodyError be this step: run fetchParams’s process - // response consume body given response and failure. - const processBodyError = (failure) => fetchParams.processResponseConsumeBody(response, failure) + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + const d = options.lastModified ?? Date.now() - // 3. If response’s body is null, then queue a fetch task to run processBody - // given null, with fetchParams’s task destination. - if (response.body == null) { - queueMicrotask(() => processBody(null)) - } else { - // 4. Otherwise, fully read response’s body given processBody, processBodyError, - // and fetchParams’s task destination. - return fullyReadBody(response.body, processBody, processBodyError) + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + this[kState] = { + blobLike, + name: n, + type: t, + lastModified: d } - return Promise.resolve() } -} - -// https://fetch.spec.whatwg.org/#http-fetch -async function httpFetch (fetchParams) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request - // 2. Let response be null. - let response = null + stream (...args) { + webidl.brandCheck(this, FileLike) - // 3. Let actualResponse be null. - let actualResponse = null + return this[kState].blobLike.stream(...args) + } - // 4. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo + arrayBuffer (...args) { + webidl.brandCheck(this, FileLike) - // 5. If request’s service-workers mode is "all", then: - if (request.serviceWorkers === 'all') { - // TODO + return this[kState].blobLike.arrayBuffer(...args) } - // 6. If response is null, then: - if (response === null) { - // 1. If makeCORSPreflight is true and one of these conditions is true: - // TODO - - // 2. If request’s redirect mode is "follow", then set request’s - // service-workers mode to "none". - if (request.redirect === 'follow') { - request.serviceWorkers = 'none' - } + slice (...args) { + webidl.brandCheck(this, FileLike) - // 3. Set response and actualResponse to the result of running - // HTTP-network-or-cache fetch given fetchParams. - actualResponse = response = await httpNetworkOrCacheFetch(fetchParams) + return this[kState].blobLike.slice(...args) + } - // 4. If request’s response tainting is "cors" and a CORS check - // for request and response returns failure, then return a network error. - if ( - request.responseTainting === 'cors' && - corsCheck(request, response) === 'failure' - ) { - return makeNetworkError('cors failure') - } + text (...args) { + webidl.brandCheck(this, FileLike) - // 5. If the TAO check for request and response returns failure, then set - // request’s timing allow failed flag. - if (TAOCheck(request, response) === 'failure') { - request.timingAllowFailed = true - } + return this[kState].blobLike.text(...args) } - // 7. If either request’s response tainting or response’s type - // is "opaque", and the cross-origin resource policy check with - // request’s origin, request’s client, request’s destination, - // and actualResponse returns blocked, then return a network error. - if ( - (request.responseTainting === 'opaque' || response.type === 'opaque') && - crossOriginResourcePolicyCheck( - request.origin, - request.client, - request.destination, - actualResponse - ) === 'blocked' - ) { - return makeNetworkError('blocked') + get size () { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.size } - // 8. If actualResponse’s status is a redirect status, then: - if (redirectStatusSet.has(actualResponse.status)) { - // 1. If actualResponse’s status is not 303, request’s body is not null, - // and the connection uses HTTP/2, then user agents may, and are even - // encouraged to, transmit an RST_STREAM frame. - // See, https://github.com/whatwg/fetch/issues/1288 - if (request.redirect !== 'manual') { - fetchParams.controller.connection.destroy() - } + get type () { + webidl.brandCheck(this, FileLike) - // 2. Switch on request’s redirect mode: - if (request.redirect === 'error') { - // Set response to a network error. - response = makeNetworkError('unexpected redirect') - } else if (request.redirect === 'manual') { - // Set response to an opaque-redirect filtered response whose internal - // response is actualResponse. - // NOTE(spec): On the web this would return an `opaqueredirect` response, - // but that doesn't make sense server side. - // See https://github.com/nodejs/undici/issues/1193. - response = actualResponse - } else if (request.redirect === 'follow') { - // Set response to the result of running HTTP-redirect fetch given - // fetchParams and response. - response = await httpRedirectFetch(fetchParams, response) - } else { - assert(false) - } + return this[kState].blobLike.type } - // 9. Set response’s timing info to timingInfo. - response.timingInfo = timingInfo + get name () { + webidl.brandCheck(this, FileLike) - // 10. Return response. - return response -} + return this[kState].name + } -// https://fetch.spec.whatwg.org/#http-redirect-fetch -function httpRedirectFetch (fetchParams, response) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request + get lastModified () { + webidl.brandCheck(this, FileLike) - // 2. Let actualResponse be response, if response is not a filtered response, - // and response’s internal response otherwise. - const actualResponse = response.internalResponse - ? response.internalResponse - : response + return this[kState].lastModified + } - // 3. Let locationURL be actualResponse’s location URL given request’s current - // URL’s fragment. - let locationURL + get [Symbol.toStringTag] () { + return 'File' + } +} - try { - locationURL = responseLocationURL( - actualResponse, - requestCurrentURL(request).hash - ) +Object.defineProperties(File.prototype, { + [Symbol.toStringTag]: { + value: 'File', + configurable: true + }, + name: kEnumerableProperty, + lastModified: kEnumerableProperty +}) - // 4. If locationURL is null, then return response. - if (locationURL == null) { - return response +webidl.converters.Blob = webidl.interfaceConverter(Blob) + +webidl.converters.BlobPart = function (V, opts) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) } - } catch (err) { - // 5. If locationURL is failure, then return a network error. - return Promise.resolve(makeNetworkError(err)) - } - // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network - // error. - if (!urlIsHttpHttpsScheme(locationURL)) { - return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme')) + if ( + ArrayBuffer.isView(V) || + types.isAnyArrayBuffer(V) + ) { + return webidl.converters.BufferSource(V, opts) + } } - // 7. If request’s redirect count is 20, then return a network error. - if (request.redirectCount === 20) { - return Promise.resolve(makeNetworkError('redirect count exceeded')) - } + return webidl.converters.USVString(V, opts) +} - // 8. Increase request’s redirect count by 1. - request.redirectCount += 1 +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.BlobPart +) - // 9. If request’s mode is "cors", locationURL includes credentials, and - // request’s origin is not same origin with locationURL’s origin, then return - // a network error. - if ( - request.mode === 'cors' && - (locationURL.username || locationURL.password) && - !sameOrigin(request, locationURL) - ) { - return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')) - } +// https://www.w3.org/TR/FileAPI/#dfn-FilePropertyBag +webidl.converters.FilePropertyBag = webidl.dictionaryConverter([ + { + key: 'lastModified', + converter: webidl.converters['long long'], + get defaultValue () { + return Date.now() + } + }, + { + key: 'type', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'endings', + converter: (value) => { + value = webidl.converters.DOMString(value) + value = value.toLowerCase() - // 10. If request’s response tainting is "cors" and locationURL includes - // credentials, then return a network error. - if ( - request.responseTainting === 'cors' && - (locationURL.username || locationURL.password) - ) { - return Promise.resolve(makeNetworkError( - 'URL cannot contain credentials for request mode "cors"' - )) - } + if (value !== 'native') { + value = 'transparent' + } - // 11. If actualResponse’s status is not 303, request’s body is non-null, - // and request’s body’s source is null, then return a network error. - if ( - actualResponse.status !== 303 && - request.body != null && - request.body.source == null - ) { - return Promise.resolve(makeNetworkError()) + return value + }, + defaultValue: 'transparent' } +]) - // 12. If one of the following is true - // - actualResponse’s status is 301 or 302 and request’s method is `POST` - // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD` - if ( - ([301, 302].includes(actualResponse.status) && request.method === 'POST') || - (actualResponse.status === 303 && - !GET_OR_HEAD.includes(request.method)) - ) { - // then: - // 1. Set request’s method to `GET` and request’s body to null. - request.method = 'GET' - request.body = null - - // 2. For each headerName of request-body-header name, delete headerName from - // request’s header list. - for (const headerName of requestBodyHeader) { - request.headersList.delete(headerName) - } - } +/** + * @see https://www.w3.org/TR/FileAPI/#process-blob-parts + * @param {(NodeJS.TypedArray|Blob|string)[]} parts + * @param {{ type: string, endings: string }} options + */ +function processBlobParts (parts, options) { + // 1. Let bytes be an empty sequence of bytes. + /** @type {NodeJS.TypedArray[]} */ + const bytes = [] - // 13. If request’s current URL’s origin is not same origin with locationURL’s - // origin, then for each headerName of CORS non-wildcard request-header name, - // delete headerName from request’s header list. - if (!sameOrigin(requestCurrentURL(request), locationURL)) { - // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name - request.headersList.delete('authorization') + // 2. For each element in parts: + for (const element of parts) { + // 1. If element is a USVString, run the following substeps: + if (typeof element === 'string') { + // 1. Let s be element. + let s = element - // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. - request.headersList.delete('cookie') - request.headersList.delete('host') - } + // 2. If the endings member of options is "native", set s + // to the result of converting line endings to native + // of element. + if (options.endings === 'native') { + s = convertLineEndingsNative(s) + } - // 14. If request’s body is non-null, then set request’s body to the first return - // value of safely extracting request’s body’s source. - if (request.body != null) { - assert(request.body.source != null) - request.body = safelyExtractBody(request.body.source)[0] + // 3. Append the result of UTF-8 encoding s to bytes. + bytes.push(encoder.encode(s)) + } else if ( + types.isAnyArrayBuffer(element) || + types.isTypedArray(element) + ) { + // 2. If element is a BufferSource, get a copy of the + // bytes held by the buffer source, and append those + // bytes to bytes. + if (!element.buffer) { // ArrayBuffer + bytes.push(new Uint8Array(element)) + } else { + bytes.push( + new Uint8Array(element.buffer, element.byteOffset, element.byteLength) + ) + } + } else if (isBlobLike(element)) { + // 3. If element is a Blob, append the bytes it represents + // to bytes. + bytes.push(element) + } } - // 15. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo + // 3. Return bytes. + return bytes +} - // 16. Set timingInfo’s redirect end time and post-redirect start time to the - // coarsened shared current time given fetchParams’s cross-origin isolated - // capability. - timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = - coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) +/** + * @see https://www.w3.org/TR/FileAPI/#convert-line-endings-to-native + * @param {string} s + */ +function convertLineEndingsNative (s) { + // 1. Let native line ending be be the code point U+000A LF. + let nativeLineEnding = '\n' - // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s - // redirect start time to timingInfo’s start time. - if (timingInfo.redirectStartTime === 0) { - timingInfo.redirectStartTime = timingInfo.startTime + // 2. If the underlying platform’s conventions are to + // represent newlines as a carriage return and line feed + // sequence, set native line ending to the code point + // U+000D CR followed by the code point U+000A LF. + if (process.platform === 'win32') { + nativeLineEnding = '\r\n' } - // 18. Append locationURL to request’s URL list. - request.urlList.push(locationURL) - - // 19. Invoke set request’s referrer policy on redirect on request and - // actualResponse. - setRequestReferrerPolicyOnRedirect(request, actualResponse) + return s.replace(/\r?\n/g, nativeLineEnding) +} - // 20. Return the result of running main fetch given fetchParams and true. - return mainFetch(fetchParams, true) +// If this function is moved to ./util.js, some tools (such as +// rollup) will warn about circular dependencies. See: +// https://github.com/nodejs/undici/issues/1629 +function isFileLike (object) { + return ( + (NativeFile && object instanceof NativeFile) || + object instanceof File || ( + object && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + object[Symbol.toStringTag] === 'File' + ) + ) } -// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch -async function httpNetworkOrCacheFetch ( - fetchParams, - isAuthenticationFetch = false, - isNewConnectionFetch = false -) { - // 1. Let request be fetchParams’s request. - const request = fetchParams.request +module.exports = { File, FileLike, isFileLike } - // 2. Let httpFetchParams be null. - let httpFetchParams = null - // 3. Let httpRequest be null. - let httpRequest = null +/***/ }), - // 4. Let response be null. - let response = null +/***/ 2015: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 5. Let storedResponse be null. - // TODO: cache +"use strict"; - // 6. Let httpCache be null. - const httpCache = null - // 7. Let the revalidatingFlag be unset. - const revalidatingFlag = false - - // 8. Run these steps, but abort when the ongoing fetch is terminated: - - // 1. If request’s window is "no-window" and request’s redirect mode is - // "error", then set httpFetchParams to fetchParams and httpRequest to - // request. - if (request.window === 'no-window' && request.redirect === 'error') { - httpFetchParams = fetchParams - httpRequest = request - } else { - // Otherwise: +const { isBlobLike, toUSVString, makeIterator } = __nccwpck_require__(2538) +const { kState } = __nccwpck_require__(5861) +const { File: UndiciFile, FileLike, isFileLike } = __nccwpck_require__(8511) +const { webidl } = __nccwpck_require__(1744) +const { Blob, File: NativeFile } = __nccwpck_require__(4300) - // 1. Set httpRequest to a clone of request. - httpRequest = makeRequest(request) +/** @type {globalThis['File']} */ +const File = NativeFile ?? UndiciFile - // 2. Set httpFetchParams to a copy of fetchParams. - httpFetchParams = { ...fetchParams } +// https://xhr.spec.whatwg.org/#formdata +class FormData { + constructor (form) { + if (form !== undefined) { + throw webidl.errors.conversionFailed({ + prefix: 'FormData constructor', + argument: 'Argument 1', + types: ['undefined'] + }) + } - // 3. Set httpFetchParams’s request to httpRequest. - httpFetchParams.request = httpRequest + this[kState] = [] } - // 3. Let includeCredentials be true if one of - const includeCredentials = - request.credentials === 'include' || - (request.credentials === 'same-origin' && - request.responseTainting === 'basic') - - // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s - // body is non-null; otherwise null. - const contentLength = httpRequest.body ? httpRequest.body.length : null + append (name, value, filename = undefined) { + webidl.brandCheck(this, FormData) - // 5. Let contentLengthHeaderValue be null. - let contentLengthHeaderValue = null + webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.append' }) - // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or - // `PUT`, then set contentLengthHeaderValue to `0`. - if ( - httpRequest.body == null && - ['POST', 'PUT'].includes(httpRequest.method) - ) { - contentLengthHeaderValue = '0' - } + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" + ) + } - // 7. If contentLength is non-null, then set contentLengthHeaderValue to - // contentLength, serialized and isomorphic encoded. - if (contentLength != null) { - contentLengthHeaderValue = isomorphicEncode(`${contentLength}`) - } + // 1. Let value be value if given; otherwise blobValue. - // 8. If contentLengthHeaderValue is non-null, then append - // `Content-Length`/contentLengthHeaderValue to httpRequest’s header - // list. - if (contentLengthHeaderValue != null) { - httpRequest.headersList.append('content-length', contentLengthHeaderValue) - } + name = webidl.converters.USVString(name) + value = isBlobLike(value) + ? webidl.converters.Blob(value, { strict: false }) + : webidl.converters.USVString(value) + filename = arguments.length === 3 + ? webidl.converters.USVString(filename) + : undefined - // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, - // contentLengthHeaderValue) to httpRequest’s header list. + // 2. Let entry be the result of creating an entry with + // name, value, and filename if given. + const entry = makeEntry(name, value, filename) - // 10. If contentLength is non-null and httpRequest’s keepalive is true, - // then: - if (contentLength != null && httpRequest.keepalive) { - // NOTE: keepalive is a noop outside of browser context. + // 3. Append entry to this’s entry list. + this[kState].push(entry) } - // 11. If httpRequest’s referrer is a URL, then append - // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, - // to httpRequest’s header list. - if (httpRequest.referrer instanceof URL) { - httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href)) - } + delete (name) { + webidl.brandCheck(this, FormData) - // 12. Append a request `Origin` header for httpRequest. - appendRequestOriginHeader(httpRequest) + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.delete' }) - // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA] - appendFetchMetadata(httpRequest) + name = webidl.converters.USVString(name) - // 14. If httpRequest’s header list does not contain `User-Agent`, then - // user agents should append `User-Agent`/default `User-Agent` value to - // httpRequest’s header list. - if (!httpRequest.headersList.contains('user-agent')) { - httpRequest.headersList.append('user-agent', typeof esbuildDetection === 'undefined' ? 'undici' : 'node') + // The delete(name) method steps are to remove all entries whose name + // is name from this’s entry list. + this[kState] = this[kState].filter(entry => entry.name !== name) } - // 15. If httpRequest’s cache mode is "default" and httpRequest’s header - // list contains `If-Modified-Since`, `If-None-Match`, - // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set - // httpRequest’s cache mode to "no-store". - if ( - httpRequest.cache === 'default' && - (httpRequest.headersList.contains('if-modified-since') || - httpRequest.headersList.contains('if-none-match') || - httpRequest.headersList.contains('if-unmodified-since') || - httpRequest.headersList.contains('if-match') || - httpRequest.headersList.contains('if-range')) - ) { - httpRequest.cache = 'no-store' - } + get (name) { + webidl.brandCheck(this, FormData) - // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent - // no-cache cache-control header modification flag is unset, and - // httpRequest’s header list does not contain `Cache-Control`, then append - // `Cache-Control`/`max-age=0` to httpRequest’s header list. - if ( - httpRequest.cache === 'no-cache' && - !httpRequest.preventNoCacheCacheControlHeaderModification && - !httpRequest.headersList.contains('cache-control') - ) { - httpRequest.headersList.append('cache-control', 'max-age=0') - } + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.get' }) - // 17. If httpRequest’s cache mode is "no-store" or "reload", then: - if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') { - // 1. If httpRequest’s header list does not contain `Pragma`, then append - // `Pragma`/`no-cache` to httpRequest’s header list. - if (!httpRequest.headersList.contains('pragma')) { - httpRequest.headersList.append('pragma', 'no-cache') - } + name = webidl.converters.USVString(name) - // 2. If httpRequest’s header list does not contain `Cache-Control`, - // then append `Cache-Control`/`no-cache` to httpRequest’s header list. - if (!httpRequest.headersList.contains('cache-control')) { - httpRequest.headersList.append('cache-control', 'no-cache') + // 1. If there is no entry whose name is name in this’s entry list, + // then return null. + const idx = this[kState].findIndex((entry) => entry.name === name) + if (idx === -1) { + return null } - } - // 18. If httpRequest’s header list contains `Range`, then append - // `Accept-Encoding`/`identity` to httpRequest’s header list. - if (httpRequest.headersList.contains('range')) { - httpRequest.headersList.append('accept-encoding', 'identity') + // 2. Return the value of the first entry whose name is name from + // this’s entry list. + return this[kState][idx].value } - // 19. Modify httpRequest’s header list per HTTP. Do not append a given - // header if httpRequest’s header list contains that header’s name. - // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 - if (!httpRequest.headersList.contains('accept-encoding')) { - if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { - httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate') - } else { - httpRequest.headersList.append('accept-encoding', 'gzip, deflate') - } - } + getAll (name) { + webidl.brandCheck(this, FormData) - httpRequest.headersList.delete('host') + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.getAll' }) - // 20. If includeCredentials is true, then: - if (includeCredentials) { - // 1. If the user agent is not configured to block cookies for httpRequest - // (see section 7 of [COOKIES]), then: - // TODO: credentials - // 2. If httpRequest’s header list does not contain `Authorization`, then: - // TODO: credentials + name = webidl.converters.USVString(name) + + // 1. If there is no entry whose name is name in this’s entry list, + // then return the empty list. + // 2. Return the values of all entries whose name is name, in order, + // from this’s entry list. + return this[kState] + .filter((entry) => entry.name === name) + .map((entry) => entry.value) } - // 21. If there’s a proxy-authentication entry, use it as appropriate. - // TODO: proxy-authentication + has (name) { + webidl.brandCheck(this, FormData) - // 22. Set httpCache to the result of determining the HTTP cache - // partition, given httpRequest. - // TODO: cache + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.has' }) - // 23. If httpCache is null, then set httpRequest’s cache mode to - // "no-store". - if (httpCache == null) { - httpRequest.cache = 'no-store' - } + name = webidl.converters.USVString(name) - // 24. If httpRequest’s cache mode is neither "no-store" nor "reload", - // then: - if (httpRequest.mode !== 'no-store' && httpRequest.mode !== 'reload') { - // TODO: cache + // The has(name) method steps are to return true if there is an entry + // whose name is name in this’s entry list; otherwise false. + return this[kState].findIndex((entry) => entry.name === name) !== -1 } - // 9. If aborted, then return the appropriate network error for fetchParams. - // TODO + set (name, value, filename = undefined) { + webidl.brandCheck(this, FormData) - // 10. If response is null, then: - if (response == null) { - // 1. If httpRequest’s cache mode is "only-if-cached", then return a - // network error. - if (httpRequest.mode === 'only-if-cached') { - return makeNetworkError('only if cached') + webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.set' }) + + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" + ) } - // 2. Let forwardResponse be the result of running HTTP-network fetch - // given httpFetchParams, includeCredentials, and isNewConnectionFetch. - const forwardResponse = await httpNetworkFetch( - httpFetchParams, - includeCredentials, - isNewConnectionFetch - ) + // The set(name, value) and set(name, blobValue, filename) method steps + // are: - // 3. If httpRequest’s method is unsafe and forwardResponse’s status is - // in the range 200 to 399, inclusive, invalidate appropriate stored - // responses in httpCache, as per the "Invalidation" chapter of HTTP - // Caching, and set storedResponse to null. [HTTP-CACHING] - if ( - !safeMethodsSet.has(httpRequest.method) && - forwardResponse.status >= 200 && - forwardResponse.status <= 399 - ) { - // TODO: cache - } + // 1. Let value be value if given; otherwise blobValue. - // 4. If the revalidatingFlag is set and forwardResponse’s status is 304, - // then: - if (revalidatingFlag && forwardResponse.status === 304) { - // TODO: cache - } + name = webidl.converters.USVString(name) + value = isBlobLike(value) + ? webidl.converters.Blob(value, { strict: false }) + : webidl.converters.USVString(value) + filename = arguments.length === 3 + ? toUSVString(filename) + : undefined - // 5. If response is null, then: - if (response == null) { - // 1. Set response to forwardResponse. - response = forwardResponse + // 2. Let entry be the result of creating an entry with name, value, and + // filename if given. + const entry = makeEntry(name, value, filename) - // 2. Store httpRequest and forwardResponse in httpCache, as per the - // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING] - // TODO: cache + // 3. If there are entries in this’s entry list whose name is name, then + // replace the first such entry with entry and remove the others. + const idx = this[kState].findIndex((entry) => entry.name === name) + if (idx !== -1) { + this[kState] = [ + ...this[kState].slice(0, idx), + entry, + ...this[kState].slice(idx + 1).filter((entry) => entry.name !== name) + ] + } else { + // 4. Otherwise, append entry to this’s entry list. + this[kState].push(entry) } } - // 11. Set response’s URL list to a clone of httpRequest’s URL list. - response.urlList = [...httpRequest.urlList] + entries () { + webidl.brandCheck(this, FormData) - // 12. If httpRequest’s header list contains `Range`, then set response’s - // range-requested flag. - if (httpRequest.headersList.contains('range')) { - response.rangeRequested = true + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'key+value' + ) } - // 13. Set response’s request-includes-credentials to includeCredentials. - response.requestIncludesCredentials = includeCredentials - - // 14. If response’s status is 401, httpRequest’s response tainting is not - // "cors", includeCredentials is true, and request’s window is an environment - // settings object, then: - // TODO - - // 15. If response’s status is 407, then: - if (response.status === 407) { - // 1. If request’s window is "no-window", then return a network error. - if (request.window === 'no-window') { - return makeNetworkError() - } - - // 2. ??? + keys () { + webidl.brandCheck(this, FormData) - // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams)) { - return makeAppropriateNetworkError(fetchParams) - } + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'key' + ) + } - // 4. Prompt the end user as appropriate in request’s window and store - // the result as a proxy-authentication entry. [HTTP-AUTH] - // TODO: Invoke some kind of callback? + values () { + webidl.brandCheck(this, FormData) - // 5. Set response to the result of running HTTP-network-or-cache fetch given - // fetchParams. - // TODO - return makeNetworkError('proxy authentication required') + return makeIterator( + () => this[kState].map(pair => [pair.name, pair.value]), + 'FormData', + 'value' + ) } - // 16. If all of the following are true - if ( - // response’s status is 421 - response.status === 421 && - // isNewConnectionFetch is false - !isNewConnectionFetch && - // request’s body is null, or request’s body is non-null and request’s body’s source is non-null - (request.body == null || request.body.source != null) - ) { - // then: + /** + * @param {(value: string, key: string, self: FormData) => void} callbackFn + * @param {unknown} thisArg + */ + forEach (callbackFn, thisArg = globalThis) { + webidl.brandCheck(this, FormData) - // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. - if (isCancelled(fetchParams)) { - return makeAppropriateNetworkError(fetchParams) + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.forEach' }) + + if (typeof callbackFn !== 'function') { + throw new TypeError( + "Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'." + ) } - // 2. Set response to the result of running HTTP-network-or-cache - // fetch given fetchParams, isAuthenticationFetch, and true. + for (const [key, value] of this) { + callbackFn.apply(thisArg, [value, key, this]) + } + } +} - // TODO (spec): The spec doesn't specify this but we need to cancel - // the active response before we can start a new one. - // https://github.com/whatwg/fetch/issues/1293 - fetchParams.controller.connection.destroy() +FormData.prototype[Symbol.iterator] = FormData.prototype.entries - response = await httpNetworkOrCacheFetch( - fetchParams, - isAuthenticationFetch, - true - ) +Object.defineProperties(FormData.prototype, { + [Symbol.toStringTag]: { + value: 'FormData', + configurable: true } +}) - // 17. If isAuthenticationFetch is true, then create an authentication entry - if (isAuthenticationFetch) { - // TODO - } +/** + * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry + * @param {string} name + * @param {string|Blob} value + * @param {?string} filename + * @returns + */ +function makeEntry (name, value, filename) { + // 1. Set name to the result of converting name into a scalar value string. + // "To convert a string into a scalar value string, replace any surrogates + // with U+FFFD." + // see: https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#buftostringencoding-start-end + name = Buffer.from(name).toString('utf8') - // 18. Return response. - return response -} + // 2. If value is a string, then set value to the result of converting + // value into a scalar value string. + if (typeof value === 'string') { + value = Buffer.from(value).toString('utf8') + } else { + // 3. Otherwise: -// https://fetch.spec.whatwg.org/#http-network-fetch -async function httpNetworkFetch ( - fetchParams, - includeCredentials = false, - forceNewConnection = false -) { - assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed) + // 1. If value is not a File object, then set value to a new File object, + // representing the same bytes, whose name attribute value is "blob" + if (!isFileLike(value)) { + value = value instanceof Blob + ? new File([value], 'blob', { type: value.type }) + : new FileLike(value, 'blob', { type: value.type }) + } - fetchParams.controller.connection = { - abort: null, - destroyed: false, - destroy (err) { - if (!this.destroyed) { - this.destroyed = true - this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')) + // 2. If filename is given, then set value to a new File object, + // representing the same bytes, whose name attribute is filename. + if (filename !== undefined) { + /** @type {FilePropertyBag} */ + const options = { + type: value.type, + lastModified: value.lastModified } + + value = (NativeFile && value instanceof NativeFile) || value instanceof UndiciFile + ? new File([value], filename, options) + : new FileLike(value, filename, options) } } - // 1. Let request be fetchParams’s request. - const request = fetchParams.request + // 4. Return an entry whose name is name and whose value is value. + return { name, value } +} - // 2. Let response be null. - let response = null +module.exports = { FormData } - // 3. Let timingInfo be fetchParams’s timing info. - const timingInfo = fetchParams.timingInfo - // 4. Let httpCache be the result of determining the HTTP cache partition, - // given request. - // TODO: cache - const httpCache = null +/***/ }), - // 5. If httpCache is null, then set request’s cache mode to "no-store". - if (httpCache == null) { - request.cache = 'no-store' - } +/***/ 1246: +/***/ ((module) => { - // 6. Let networkPartitionKey be the result of determining the network - // partition key given request. - // TODO +"use strict"; - // 7. Let newConnection be "yes" if forceNewConnection is true; otherwise - // "no". - const newConnection = forceNewConnection ? 'yes' : 'no' // eslint-disable-line no-unused-vars - // 8. Switch on request’s mode: - if (request.mode === 'websocket') { - // Let connection be the result of obtaining a WebSocket connection, - // given request’s current URL. - // TODO - } else { - // Let connection be the result of obtaining a connection, given - // networkPartitionKey, request’s current URL’s origin, - // includeCredentials, and forceNewConnection. - // TODO - } +// In case of breaking changes, increase the version +// number to avoid conflicts. +const globalOrigin = Symbol.for('undici.globalOrigin.1') - // 9. Run these steps, but abort when the ongoing fetch is terminated: +function getGlobalOrigin () { + return globalThis[globalOrigin] +} - // 1. If connection is failure, then return a network error. +function setGlobalOrigin (newOrigin) { + if (newOrigin === undefined) { + Object.defineProperty(globalThis, globalOrigin, { + value: undefined, + writable: true, + enumerable: false, + configurable: false + }) - // 2. Set timingInfo’s final connection timing info to the result of - // calling clamp and coarsen connection timing info with connection’s - // timing info, timingInfo’s post-redirect start time, and fetchParams’s - // cross-origin isolated capability. + return + } - // 3. If connection is not an HTTP/2 connection, request’s body is non-null, - // and request’s body’s source is null, then append (`Transfer-Encoding`, - // `chunked`) to request’s header list. + const parsedURL = new URL(newOrigin) - // 4. Set timingInfo’s final network-request start time to the coarsened - // shared current time given fetchParams’s cross-origin isolated - // capability. + if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') { + throw new TypeError(`Only http & https urls are allowed, received ${parsedURL.protocol}`) + } - // 5. Set response to the result of making an HTTP request over connection - // using request with the following caveats: + Object.defineProperty(globalThis, globalOrigin, { + value: parsedURL, + writable: true, + enumerable: false, + configurable: false + }) +} - // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] - // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] +module.exports = { + getGlobalOrigin, + setGlobalOrigin +} - // - If request’s body is non-null, and request’s body’s source is null, - // then the user agent may have a buffer of up to 64 kibibytes and store - // a part of request’s body in that buffer. If the user agent reads from - // request’s body beyond that buffer’s size and the user agent needs to - // resend request, then instead return a network error. - // - Set timingInfo’s final network-response start time to the coarsened - // shared current time given fetchParams’s cross-origin isolated capability, - // immediately after the user agent’s HTTP parser receives the first byte - // of the response (e.g., frame header bytes for HTTP/2 or response status - // line for HTTP/1.x). +/***/ }), - // - Wait until all the headers are transmitted. +/***/ 554: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // - Any responses whose status is in the range 100 to 199, inclusive, - // and is not 101, are to be ignored, except for the purposes of setting - // timingInfo’s final network-response start time above. +"use strict"; +// https://github.com/Ethan-Arrowood/undici-fetch - // - If request’s header list contains `Transfer-Encoding`/`chunked` and - // response is transferred via HTTP/1.0 or older, then return a network - // error. - // - If the HTTP request results in a TLS client certificate dialog, then: - // 1. If request’s window is an environment settings object, make the - // dialog available in request’s window. +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const { kGuard } = __nccwpck_require__(5861) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const { + makeIterator, + isValidHeaderName, + isValidHeaderValue +} = __nccwpck_require__(2538) +const { webidl } = __nccwpck_require__(1744) +const assert = __nccwpck_require__(9491) - // 2. Otherwise, return a network error. +const kHeadersMap = Symbol('headers map') +const kHeadersSortedMap = Symbol('headers map sorted') - // To transmit request’s body body, run these steps: - let requestBody = null - // 1. If body is null and fetchParams’s process request end-of-body is - // non-null, then queue a fetch task given fetchParams’s process request - // end-of-body and fetchParams’s task destination. - if (request.body == null && fetchParams.processRequestEndOfBody) { - queueMicrotask(() => fetchParams.processRequestEndOfBody()) - } else if (request.body != null) { - // 2. Otherwise, if body is non-null: +/** + * @param {number} code + */ +function isHTTPWhiteSpaceCharCode (code) { + return code === 0x00a || code === 0x00d || code === 0x009 || code === 0x020 +} - // 1. Let processBodyChunk given bytes be these steps: - const processBodyChunk = async function * (bytes) { - // 1. If the ongoing fetch is terminated, then abort these steps. - if (isCancelled(fetchParams)) { - return - } +/** + * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize + * @param {string} potentialValue + */ +function headerValueNormalize (potentialValue) { + // To normalize a byte sequence potentialValue, remove + // any leading and trailing HTTP whitespace bytes from + // potentialValue. + let i = 0; let j = potentialValue.length - // 2. Run this step in parallel: transmit bytes. - yield bytes + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(j - 1))) --j + while (j > i && isHTTPWhiteSpaceCharCode(potentialValue.charCodeAt(i))) ++i - // 3. If fetchParams’s process request body is non-null, then run - // fetchParams’s process request body given bytes’s length. - fetchParams.processRequestBodyChunkLength?.(bytes.byteLength) - } + return i === 0 && j === potentialValue.length ? potentialValue : potentialValue.substring(i, j) +} - // 2. Let processEndOfBody be these steps: - const processEndOfBody = () => { - // 1. If fetchParams is canceled, then abort these steps. - if (isCancelled(fetchParams)) { - return - } +function fill (headers, object) { + // To fill a Headers object headers with a given object object, run these steps: - // 2. If fetchParams’s process request end-of-body is non-null, - // then run fetchParams’s process request end-of-body. - if (fetchParams.processRequestEndOfBody) { - fetchParams.processRequestEndOfBody() + // 1. If object is a sequence, then for each header in object: + // Note: webidl conversion to array has already been done. + if (Array.isArray(object)) { + for (let i = 0; i < object.length; ++i) { + const header = object[i] + // 1. If header does not contain exactly two items, then throw a TypeError. + if (header.length !== 2) { + throw webidl.errors.exception({ + header: 'Headers constructor', + message: `expected name/value pair to be length 2, found ${header.length}.` + }) } - } - // 3. Let processBodyError given e be these steps: - const processBodyError = (e) => { - // 1. If fetchParams is canceled, then abort these steps. - if (isCancelled(fetchParams)) { - return - } + // 2. Append (header’s first item, header’s second item) to headers. + appendHeader(headers, header[0], header[1]) + } + } else if (typeof object === 'object' && object !== null) { + // Note: null should throw - // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller. - if (e.name === 'AbortError') { - fetchParams.controller.abort() - } else { - fetchParams.controller.terminate(e) - } + // 2. Otherwise, object is a record, then for each key → value in object, + // append (key, value) to headers + const keys = Object.keys(object) + for (let i = 0; i < keys.length; ++i) { + appendHeader(headers, keys[i], object[keys[i]]) } + } else { + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: ['sequence>', 'record'] + }) + } +} - // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody, - // processBodyError, and fetchParams’s task destination. - requestBody = (async function * () { - try { - for await (const bytes of request.body.stream) { - yield * processBodyChunk(bytes) - } - processEndOfBody() - } catch (err) { - processBodyError(err) - } - })() +/** + * @see https://fetch.spec.whatwg.org/#concept-headers-append + */ +function appendHeader (headers, name, value) { + // 1. Normalize value. + value = headerValueNormalize(value) + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value, + type: 'header value' + }) } - try { - // socket is only provided for websockets - const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody }) + // 3. If headers’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if headers’s guard is "request" and name is a + // forbidden header name, return. + // Note: undici does not implement forbidden header names + if (headers[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (headers[kGuard] === 'request-no-cors') { + // 5. Otherwise, if headers’s guard is "request-no-cors": + // TODO + } - if (socket) { - response = makeResponse({ status, statusText, headersList, socket }) - } else { - const iterator = body[Symbol.asyncIterator]() - fetchParams.controller.next = () => iterator.next() + // 6. Otherwise, if headers’s guard is "response" and name is a + // forbidden response-header name, return. - response = makeResponse({ status, statusText, headersList }) - } - } catch (err) { - // 10. If aborted, then: - if (err.name === 'AbortError') { - // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame. - fetchParams.controller.connection.destroy() + // 7. Append (name, value) to headers’s header list. + return headers[kHeadersList].append(name, value) - // 2. Return the appropriate network error for fetchParams. - return makeAppropriateNetworkError(fetchParams, err) - } + // 8. If headers’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from headers +} - return makeNetworkError(err) - } +class HeadersList { + /** @type {[string, string][]|null} */ + cookies = null - // 11. Let pullAlgorithm be an action that resumes the ongoing fetch - // if it is suspended. - const pullAlgorithm = () => { - fetchParams.controller.resume() + constructor (init) { + if (init instanceof HeadersList) { + this[kHeadersMap] = new Map(init[kHeadersMap]) + this[kHeadersSortedMap] = init[kHeadersSortedMap] + this.cookies = init.cookies === null ? null : [...init.cookies] + } else { + this[kHeadersMap] = new Map(init) + this[kHeadersSortedMap] = null + } } - // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s - // controller with reason, given reason. - const cancelAlgorithm = (reason) => { - fetchParams.controller.abort(reason) + // https://fetch.spec.whatwg.org/#header-list-contains + contains (name) { + // A header list list contains a header name name if list + // contains a header whose name is a byte-case-insensitive + // match for name. + name = name.toLowerCase() + + return this[kHeadersMap].has(name) } - // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by - // the user agent. - // TODO + clear () { + this[kHeadersMap].clear() + this[kHeadersSortedMap] = null + this.cookies = null + } - // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object - // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent. - // TODO + // https://fetch.spec.whatwg.org/#concept-header-list-append + append (name, value) { + this[kHeadersSortedMap] = null - // 15. Let stream be a new ReadableStream. - // 16. Set up stream with pullAlgorithm set to pullAlgorithm, - // cancelAlgorithm set to cancelAlgorithm, highWaterMark set to - // highWaterMark, and sizeAlgorithm set to sizeAlgorithm. - if (!ReadableStream) { - ReadableStream = (__nccwpck_require__(5356).ReadableStream) - } + // 1. If list contains name, then set name to the first such + // header’s name. + const lowercaseName = name.toLowerCase() + const exists = this[kHeadersMap].get(lowercaseName) - const stream = new ReadableStream( - { - async start (controller) { - fetchParams.controller.controller = controller - }, - async pull (controller) { - await pullAlgorithm(controller) - }, - async cancel (reason) { - await cancelAlgorithm(reason) - } - }, - { - highWaterMark: 0, - size () { - return 1 - } + // 2. Append (name, value) to list. + if (exists) { + const delimiter = lowercaseName === 'cookie' ? '; ' : ', ' + this[kHeadersMap].set(lowercaseName, { + name: exists.name, + value: `${exists.value}${delimiter}${value}` + }) + } else { + this[kHeadersMap].set(lowercaseName, { name, value }) } - ) - - // 17. Run these steps, but abort when the ongoing fetch is terminated: - // 1. Set response’s body to a new body whose stream is stream. - response.body = { stream } + if (lowercaseName === 'set-cookie') { + this.cookies ??= [] + this.cookies.push(value) + } + } - // 2. If response is not a network error and request’s cache mode is - // not "no-store", then update response in httpCache for request. - // TODO + // https://fetch.spec.whatwg.org/#concept-header-list-set + set (name, value) { + this[kHeadersSortedMap] = null + const lowercaseName = name.toLowerCase() - // 3. If includeCredentials is true and the user agent is not configured - // to block cookies for request (see section 7 of [COOKIES]), then run the - // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on - // the value of each header whose name is a byte-case-insensitive match for - // `Set-Cookie` in response’s header list, if any, and request’s current URL. - // TODO + if (lowercaseName === 'set-cookie') { + this.cookies = [value] + } - // 18. If aborted, then: - // TODO + // 1. If list contains name, then set the value of + // the first such header to value and remove the + // others. + // 2. Otherwise, append header (name, value) to list. + this[kHeadersMap].set(lowercaseName, { name, value }) + } - // 19. Run these steps in parallel: + // https://fetch.spec.whatwg.org/#concept-header-list-delete + delete (name) { + this[kHeadersSortedMap] = null - // 1. Run these steps, but abort when fetchParams is canceled: - fetchParams.controller.on('terminated', onAborted) - fetchParams.controller.resume = async () => { - // 1. While true - while (true) { - // 1-3. See onData... + name = name.toLowerCase() - // 4. Set bytes to the result of handling content codings given - // codings and bytes. - let bytes - let isFailure - try { - const { done, value } = await fetchParams.controller.next() + if (name === 'set-cookie') { + this.cookies = null + } - if (isAborted(fetchParams)) { - break - } + this[kHeadersMap].delete(name) + } - bytes = done ? undefined : value - } catch (err) { - if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { - // zlib doesn't like empty streams. - bytes = undefined - } else { - bytes = err + // https://fetch.spec.whatwg.org/#concept-header-list-get + get (name) { + const value = this[kHeadersMap].get(name.toLowerCase()) - // err may be propagated from the result of calling readablestream.cancel, - // which might not be an error. https://github.com/nodejs/undici/issues/2009 - isFailure = true - } - } + // 1. If list does not contain name, then return null. + // 2. Return the values of all headers in list whose name + // is a byte-case-insensitive match for name, + // separated from each other by 0x2C 0x20, in order. + return value === undefined ? null : value.value + } - if (bytes === undefined) { - // 2. Otherwise, if the bytes transmission for response’s message - // body is done normally and stream is readable, then close - // stream, finalize response for fetchParams and response, and - // abort these in-parallel steps. - readableStreamClose(fetchParams.controller.controller) + * [Symbol.iterator] () { + // use the lowercased name + for (const [name, { value }] of this[kHeadersMap]) { + yield [name, value] + } + } - finalizeResponse(fetchParams, response) + get entries () { + const headers = {} - return + if (this[kHeadersMap].size) { + for (const { name, value } of this[kHeadersMap].values()) { + headers[name] = value } + } - // 5. Increase timingInfo’s decoded body size by bytes’s length. - timingInfo.decodedBodySize += bytes?.byteLength ?? 0 + return headers + } +} - // 6. If bytes is failure, then terminate fetchParams’s controller. - if (isFailure) { - fetchParams.controller.terminate(bytes) - return - } +// https://fetch.spec.whatwg.org/#headers-class +class Headers { + constructor (init = undefined) { + if (init === kConstruct) { + return + } + this[kHeadersList] = new HeadersList() - // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes - // into stream. - fetchParams.controller.controller.enqueue(new Uint8Array(bytes)) + // The new Headers(init) constructor steps are: - // 8. If stream is errored, then terminate the ongoing fetch. - if (isErrored(stream)) { - fetchParams.controller.terminate() - return - } + // 1. Set this’s guard to "none". + this[kGuard] = 'none' - // 9. If stream doesn’t need more data ask the user agent to suspend - // the ongoing fetch. - if (!fetchParams.controller.controller.desiredSize) { - return - } + // 2. If init is given, then fill this with init. + if (init !== undefined) { + init = webidl.converters.HeadersInit(init) + fill(this, init) } } - // 2. If aborted, then: - function onAborted (reason) { - // 2. If fetchParams is aborted, then: - if (isAborted(fetchParams)) { - // 1. Set response’s aborted flag. - response.aborted = true + // https://fetch.spec.whatwg.org/#dom-headers-append + append (name, value) { + webidl.brandCheck(this, Headers) - // 2. If stream is readable, then error stream with the result of - // deserialize a serialized abort reason given fetchParams’s - // controller’s serialized abort reason and an - // implementation-defined realm. - if (isReadable(stream)) { - fetchParams.controller.controller.error( - fetchParams.controller.serializedAbortReason - ) - } - } else { - // 3. Otherwise, if stream is readable, error stream with a TypeError. - if (isReadable(stream)) { - fetchParams.controller.controller.error(new TypeError('terminated', { - cause: isErrorLike(reason) ? reason : undefined - })) - } - } + webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.append' }) - // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame. - // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so. - fetchParams.controller.connection.destroy() + name = webidl.converters.ByteString(name) + value = webidl.converters.ByteString(value) + + return appendHeader(this, name, value) } - // 20. Return response. - return response + // https://fetch.spec.whatwg.org/#dom-headers-delete + delete (name) { + webidl.brandCheck(this, Headers) - async function dispatch ({ body }) { - const url = requestCurrentURL(request) - /** @type {import('../..').Agent} */ - const agent = fetchParams.controller.dispatcher + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.delete' }) - return new Promise((resolve, reject) => agent.dispatch( - { - path: url.pathname + url.search, - origin: url.origin, - method: request.method, - body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, - headers: request.headersList.entries, - maxRedirections: 0, - upgrade: request.mode === 'websocket' ? 'websocket' : undefined - }, - { - body: null, - abort: null, + name = webidl.converters.ByteString(name) - onConnect (abort) { - // TODO (fix): Do we need connection here? - const { connection } = fetchParams.controller + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.delete', + value: name, + type: 'header name' + }) + } - if (connection.destroyed) { - abort(new DOMException('The operation was aborted.', 'AbortError')) - } else { - fetchParams.controller.on('terminated', abort) - this.abort = connection.abort = abort - } - }, - - onHeaders (status, headersList, resume, statusText) { - if (status < 200) { - return - } - - let codings = [] - let location = '' + // 2. If this’s guard is "immutable", then throw a TypeError. + // 3. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 4. Otherwise, if this’s guard is "request-no-cors", name + // is not a no-CORS-safelisted request-header name, and + // name is not a privileged no-CORS request-header name, + // return. + // 5. Otherwise, if this’s guard is "response" and name is + // a forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // TODO + } - const headers = new Headers() + // 6. If this’s header list does not contain name, then + // return. + if (!this[kHeadersList].contains(name)) { + return + } - // For H2, the headers are a plain JS object - // We distinguish between them and iterate accordingly - if (Array.isArray(headersList)) { - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString('latin1') - const val = headersList[n + 1].toString('latin1') - if (key.toLowerCase() === 'content-encoding') { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = val.toLowerCase().split(',').map((x) => x.trim()) - } else if (key.toLowerCase() === 'location') { - location = val - } + // 7. Delete name from this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this. + this[kHeadersList].delete(name) + } - headers[kHeadersList].append(key, val) - } - } else { - const keys = Object.keys(headersList) - for (const key of keys) { - const val = headersList[key] - if (key.toLowerCase() === 'content-encoding') { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = val.toLowerCase().split(',').map((x) => x.trim()).reverse() - } else if (key.toLowerCase() === 'location') { - location = val - } + // https://fetch.spec.whatwg.org/#dom-headers-get + get (name) { + webidl.brandCheck(this, Headers) - headers[kHeadersList].append(key, val) - } - } + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.get' }) - this.body = new Readable({ read: resume }) + name = webidl.converters.ByteString(name) - const decoders = [] + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.get', + value: name, + type: 'header name' + }) + } - const willFollow = request.redirect === 'follow' && - location && - redirectStatusSet.has(status) + // 2. Return the result of getting name from this’s header + // list. + return this[kHeadersList].get(name) + } - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding - if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { - for (const coding of codings) { - // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 - if (coding === 'x-gzip' || coding === 'gzip') { - decoders.push(zlib.createGunzip({ - // Be less strict when decoding compressed responses, since sometimes - // servers send slightly invalid responses that are still accepted - // by common browsers. - // Always using Z_SYNC_FLUSH is what cURL does. - flush: zlib.constants.Z_SYNC_FLUSH, - finishFlush: zlib.constants.Z_SYNC_FLUSH - })) - } else if (coding === 'deflate') { - decoders.push(zlib.createInflate()) - } else if (coding === 'br') { - decoders.push(zlib.createBrotliDecompress()) - } else { - decoders.length = 0 - break - } - } - } + // https://fetch.spec.whatwg.org/#dom-headers-has + has (name) { + webidl.brandCheck(this, Headers) - resolve({ - status, - statusText, - headersList: headers[kHeadersList], - body: decoders.length - ? pipeline(this.body, ...decoders, () => { }) - : this.body.on('error', () => {}) - }) + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.has' }) - return true - }, + name = webidl.converters.ByteString(name) - onData (chunk) { - if (fetchParams.controller.dump) { - return - } + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.has', + value: name, + type: 'header name' + }) + } - // 1. If one or more bytes have been transmitted from response’s - // message body, then: + // 2. Return true if this’s header list contains name; + // otherwise false. + return this[kHeadersList].contains(name) + } - // 1. Let bytes be the transmitted bytes. - const bytes = chunk + // https://fetch.spec.whatwg.org/#dom-headers-set + set (name, value) { + webidl.brandCheck(this, Headers) - // 2. Let codings be the result of extracting header list values - // given `Content-Encoding` and response’s header list. - // See pullAlgorithm. + webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.set' }) - // 3. Increase timingInfo’s encoded body size by bytes’s length. - timingInfo.encodedBodySize += bytes.byteLength + name = webidl.converters.ByteString(name) + value = webidl.converters.ByteString(value) - // 4. See pullAlgorithm... + // 1. Normalize value. + value = headerValueNormalize(value) - return this.body.push(bytes) - }, + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.set', + value: name, + type: 'header name' + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.set', + value, + type: 'header value' + }) + } - onComplete () { - if (this.abort) { - fetchParams.controller.off('terminated', this.abort) - } + // 3. If this’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 5. Otherwise, if this’s guard is "request-no-cors" and + // name/value is not a no-CORS-safelisted request-header, + // return. + // 6. Otherwise, if this’s guard is "response" and name is a + // forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // TODO + } - fetchParams.controller.ended = true + // 7. Set (name, value) in this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this + this[kHeadersList].set(name, value) + } - this.body.push(null) - }, + // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie + getSetCookie () { + webidl.brandCheck(this, Headers) - onError (error) { - if (this.abort) { - fetchParams.controller.off('terminated', this.abort) - } + // 1. If this’s header list does not contain `Set-Cookie`, then return « ». + // 2. Return the values of all headers in this’s header list whose name is + // a byte-case-insensitive match for `Set-Cookie`, in order. - this.body?.destroy(error) + const list = this[kHeadersList].cookies - fetchParams.controller.terminate(error) + if (list) { + return [...list] + } - reject(error) - }, + return [] + } - onUpgrade (status, headersList, socket) { - if (status !== 101) { - return - } + // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine + get [kHeadersSortedMap] () { + if (this[kHeadersList][kHeadersSortedMap]) { + return this[kHeadersList][kHeadersSortedMap] + } - const headers = new Headers() + // 1. Let headers be an empty list of headers with the key being the name + // and value the value. + const headers = [] - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString('latin1') - const val = headersList[n + 1].toString('latin1') + // 2. Let names be the result of convert header names to a sorted-lowercase + // set with all the names of the headers in list. + const names = [...this[kHeadersList]].sort((a, b) => a[0] < b[0] ? -1 : 1) + const cookies = this[kHeadersList].cookies - headers[kHeadersList].append(key, val) - } + // 3. For each name of names: + for (let i = 0; i < names.length; ++i) { + const [name, value] = names[i] + // 1. If name is `set-cookie`, then: + if (name === 'set-cookie') { + // 1. Let values be a list of all values of headers in list whose name + // is a byte-case-insensitive match for name, in order. - resolve({ - status, - statusText: STATUS_CODES[status], - headersList: headers[kHeadersList], - socket - }) - - return true + // 2. For each value of values: + // 1. Append (name, value) to headers. + for (let j = 0; j < cookies.length; ++j) { + headers.push([name, cookies[j]]) } - } - )) - } -} + } else { + // 2. Otherwise: -module.exports = { - fetch, - Fetch, - fetching, - finalizeAndReportTiming -} + // 1. Let value be the result of getting name from list. + // 2. Assert: value is non-null. + assert(value !== null) -/***/ }), + // 3. Append (name, value) to headers. + headers.push([name, value]) + } + } -/***/ 8359: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[kHeadersList][kHeadersSortedMap] = headers -"use strict"; -/* globals AbortController */ + // 4. Return headers. + return headers + } + keys () { + webidl.brandCheck(this, Headers) + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'key') + } -const { extractBody, mixinBody, cloneBody } = __nccwpck_require__(1472) -const { Headers, fill: fillHeaders, HeadersList } = __nccwpck_require__(554) -const { FinalizationRegistry } = __nccwpck_require__(6436)() -const util = __nccwpck_require__(3983) -const { - isValidHTTPToken, - sameOrigin, - normalizeMethod, - makePolicyContainer, - normalizeMethodRecord -} = __nccwpck_require__(2538) -const { - forbiddenMethodsSet, - corsSafeListedMethodsSet, - referrerPolicy, - requestRedirect, - requestMode, - requestCredentials, - requestCache, - requestDuplex -} = __nccwpck_require__(1037) -const { kEnumerableProperty } = util -const { kHeaders, kSignal, kState, kGuard, kRealm } = __nccwpck_require__(5861) -const { webidl } = __nccwpck_require__(1744) -const { getGlobalOrigin } = __nccwpck_require__(1246) -const { URLSerializer } = __nccwpck_require__(685) -const { kHeadersList, kConstruct } = __nccwpck_require__(2785) -const assert = __nccwpck_require__(9491) -const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = __nccwpck_require__(2361) + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'key' + ) + } -let TransformStream = globalThis.TransformStream + values () { + webidl.brandCheck(this, Headers) -const kAbortController = Symbol('abortController') + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'value') + } -const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { - signal.removeEventListener('abort', abort) -}) + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'value' + ) + } -// https://fetch.spec.whatwg.org/#request-class -class Request { - // https://fetch.spec.whatwg.org/#dom-request - constructor (input, init = {}) { - if (input === kConstruct) { - return + entries () { + webidl.brandCheck(this, Headers) + + if (this[kGuard] === 'immutable') { + const value = this[kHeadersSortedMap] + return makeIterator(() => value, 'Headers', + 'key+value') } - webidl.argumentLengthCheck(arguments, 1, { header: 'Request constructor' }) + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'key+value' + ) + } - input = webidl.converters.RequestInfo(input) - init = webidl.converters.RequestInit(init) + /** + * @param {(value: string, key: string, self: Headers) => void} callbackFn + * @param {unknown} thisArg + */ + forEach (callbackFn, thisArg = globalThis) { + webidl.brandCheck(this, Headers) - // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object - this[kRealm] = { - settingsObject: { - baseUrl: getGlobalOrigin(), - get origin () { - return this.baseUrl?.origin - }, - policyContainer: makePolicyContainer() - } - } + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.forEach' }) - // 1. Let request be null. - let request = null + if (typeof callbackFn !== 'function') { + throw new TypeError( + "Failed to execute 'forEach' on 'Headers': parameter 1 is not of type 'Function'." + ) + } - // 2. Let fallbackMode be null. - let fallbackMode = null + for (const [key, value] of this) { + callbackFn.apply(thisArg, [value, key, this]) + } + } - // 3. Let baseURL be this’s relevant settings object’s API base URL. - const baseUrl = this[kRealm].settingsObject.baseUrl + [Symbol.for('nodejs.util.inspect.custom')] () { + webidl.brandCheck(this, Headers) - // 4. Let signal be null. - let signal = null + return this[kHeadersList] + } +} - // 5. If input is a string, then: - if (typeof input === 'string') { - // 1. Let parsedURL be the result of parsing input with baseURL. - // 2. If parsedURL is failure, then throw a TypeError. - let parsedURL - try { - parsedURL = new URL(input, baseUrl) - } catch (err) { - throw new TypeError('Failed to parse URL from ' + input, { cause: err }) - } +Headers.prototype[Symbol.iterator] = Headers.prototype.entries - // 3. If parsedURL includes credentials, then throw a TypeError. - if (parsedURL.username || parsedURL.password) { - throw new TypeError( - 'Request cannot be constructed from a URL that includes credentials: ' + - input - ) - } +Object.defineProperties(Headers.prototype, { + append: kEnumerableProperty, + delete: kEnumerableProperty, + get: kEnumerableProperty, + has: kEnumerableProperty, + set: kEnumerableProperty, + getSetCookie: kEnumerableProperty, + keys: kEnumerableProperty, + values: kEnumerableProperty, + entries: kEnumerableProperty, + forEach: kEnumerableProperty, + [Symbol.iterator]: { enumerable: false }, + [Symbol.toStringTag]: { + value: 'Headers', + configurable: true + } +}) - // 4. Set request to a new request whose URL is parsedURL. - request = makeRequest({ urlList: [parsedURL] }) +webidl.converters.HeadersInit = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (V[Symbol.iterator]) { + return webidl.converters['sequence>'](V) + } - // 5. Set fallbackMode to "cors". - fallbackMode = 'cors' - } else { - // 6. Otherwise: + return webidl.converters['record'](V) + } - // 7. Assert: input is a Request object. - assert(input instanceof Request) + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: ['sequence>', 'record'] + }) +} - // 8. Set request to input’s request. - request = input[kState] +module.exports = { + fill, + Headers, + HeadersList +} - // 9. Set signal to input’s signal. - signal = input[kSignal] - } - // 7. Let origin be this’s relevant settings object’s origin. - const origin = this[kRealm].settingsObject.origin +/***/ }), - // 8. Let window be "client". - let window = 'client' +/***/ 4881: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // 9. If request’s window is an environment settings object and its origin - // is same origin with origin, then set window to request’s window. - if ( - request.window?.constructor?.name === 'EnvironmentSettingsObject' && - sameOrigin(request.window, origin) - ) { - window = request.window - } +"use strict"; +// https://github.com/Ethan-Arrowood/undici-fetch - // 10. If init["window"] exists and is non-null, then throw a TypeError. - if (init.window != null) { - throw new TypeError(`'window' option '${window}' must be null`) - } - // 11. If init["window"] exists, then set window to "no-window". - if ('window' in init) { - window = 'no-window' - } - // 12. Set request to a new request with the following properties: - request = makeRequest({ - // URL request’s URL. - // undici implementation note: this is set as the first item in request's urlList in makeRequest - // method request’s method. - method: request.method, - // header list A copy of request’s header list. - // undici implementation note: headersList is cloned in makeRequest - headersList: request.headersList, - // unsafe-request flag Set. - unsafeRequest: request.unsafeRequest, - // client This’s relevant settings object. - client: this[kRealm].settingsObject, - // window window. - window, - // priority request’s priority. - priority: request.priority, - // origin request’s origin. The propagation of the origin is only significant for navigation requests - // being handled by a service worker. In this scenario a request can have an origin that is different - // from the current client. - origin: request.origin, - // referrer request’s referrer. - referrer: request.referrer, - // referrer policy request’s referrer policy. - referrerPolicy: request.referrerPolicy, - // mode request’s mode. - mode: request.mode, - // credentials mode request’s credentials mode. - credentials: request.credentials, - // cache mode request’s cache mode. - cache: request.cache, - // redirect mode request’s redirect mode. - redirect: request.redirect, - // integrity metadata request’s integrity metadata. - integrity: request.integrity, - // keepalive request’s keepalive. - keepalive: request.keepalive, - // reload-navigation flag request’s reload-navigation flag. - reloadNavigation: request.reloadNavigation, - // history-navigation flag request’s history-navigation flag. - historyNavigation: request.historyNavigation, - // URL list A clone of request’s URL list. - urlList: [...request.urlList] - }) - - const initHasKey = Object.keys(init).length !== 0 +const { + Response, + makeNetworkError, + makeAppropriateNetworkError, + filterResponse, + makeResponse +} = __nccwpck_require__(7823) +const { Headers } = __nccwpck_require__(554) +const { Request, makeRequest } = __nccwpck_require__(8359) +const zlib = __nccwpck_require__(9796) +const { + bytesMatch, + makePolicyContainer, + clonePolicyContainer, + requestBadPort, + TAOCheck, + appendRequestOriginHeader, + responseLocationURL, + requestCurrentURL, + setRequestReferrerPolicyOnRedirect, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + createOpaqueTimingInfo, + appendFetchMetadata, + corsCheck, + crossOriginResourcePolicyCheck, + determineRequestsReferrer, + coarsenedSharedCurrentTime, + createDeferredPromise, + isBlobLike, + sameOrigin, + isCancelled, + isAborted, + isErrorLike, + fullyReadBody, + readableStreamClose, + isomorphicEncode, + urlIsLocal, + urlIsHttpHttpsScheme, + urlHasHttpsScheme +} = __nccwpck_require__(2538) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const assert = __nccwpck_require__(9491) +const { safelyExtractBody } = __nccwpck_require__(1472) +const { + redirectStatusSet, + nullBodyStatus, + safeMethodsSet, + requestBodyHeader, + subresourceSet, + DOMException +} = __nccwpck_require__(1037) +const { kHeadersList } = __nccwpck_require__(2785) +const EE = __nccwpck_require__(2361) +const { Readable, pipeline } = __nccwpck_require__(2781) +const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = __nccwpck_require__(3983) +const { dataURLProcessor, serializeAMimeType } = __nccwpck_require__(685) +const { TransformStream } = __nccwpck_require__(5356) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { webidl } = __nccwpck_require__(1744) +const { STATUS_CODES } = __nccwpck_require__(3685) +const GET_OR_HEAD = ['GET', 'HEAD'] - // 13. If init is not empty, then: - if (initHasKey) { - // 1. If request’s mode is "navigate", then set it to "same-origin". - if (request.mode === 'navigate') { - request.mode = 'same-origin' - } +/** @type {import('buffer').resolveObjectURL} */ +let resolveObjectURL +let ReadableStream = globalThis.ReadableStream - // 2. Unset request’s reload-navigation flag. - request.reloadNavigation = false +class Fetch extends EE { + constructor (dispatcher) { + super() - // 3. Unset request’s history-navigation flag. - request.historyNavigation = false + this.dispatcher = dispatcher + this.connection = null + this.dump = false + this.state = 'ongoing' + // 2 terminated listeners get added per request, + // but only 1 gets removed. If there are 20 redirects, + // 21 listeners will be added. + // See https://github.com/nodejs/undici/issues/1711 + // TODO (fix): Find and fix root cause for leaked listener. + this.setMaxListeners(21) + } - // 4. Set request’s origin to "client". - request.origin = 'client' + terminate (reason) { + if (this.state !== 'ongoing') { + return + } - // 5. Set request’s referrer to "client" - request.referrer = 'client' + this.state = 'terminated' + this.connection?.destroy(reason) + this.emit('terminated', reason) + } - // 6. Set request’s referrer policy to the empty string. - request.referrerPolicy = '' + // https://fetch.spec.whatwg.org/#fetch-controller-abort + abort (error) { + if (this.state !== 'ongoing') { + return + } - // 7. Set request’s URL to request’s current URL. - request.url = request.urlList[request.urlList.length - 1] + // 1. Set controller’s state to "aborted". + this.state = 'aborted' - // 8. Set request’s URL list to « request’s URL ». - request.urlList = [request.url] + // 2. Let fallbackError be an "AbortError" DOMException. + // 3. Set error to fallbackError if it is not given. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError') } - // 14. If init["referrer"] exists, then: - if (init.referrer !== undefined) { - // 1. Let referrer be init["referrer"]. - const referrer = init.referrer + // 4. Let serializedError be StructuredSerialize(error). + // If that threw an exception, catch it, and let + // serializedError be StructuredSerialize(fallbackError). - // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". - if (referrer === '') { - request.referrer = 'no-referrer' - } else { - // 1. Let parsedReferrer be the result of parsing referrer with - // baseURL. - // 2. If parsedReferrer is failure, then throw a TypeError. - let parsedReferrer - try { - parsedReferrer = new URL(referrer, baseUrl) - } catch (err) { - throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }) - } + // 5. Set controller’s serialized abort reason to serializedError. + this.serializedAbortReason = error - // 3. If one of the following is true - // - parsedReferrer’s scheme is "about" and path is the string "client" - // - parsedReferrer’s origin is not same origin with origin - // then set request’s referrer to "client". - if ( - (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || - (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl)) - ) { - request.referrer = 'client' - } else { - // 4. Otherwise, set request’s referrer to parsedReferrer. - request.referrer = parsedReferrer - } - } - } + this.connection?.destroy(error) + this.emit('terminated', error) + } +} - // 15. If init["referrerPolicy"] exists, then set request’s referrer policy - // to it. - if (init.referrerPolicy !== undefined) { - request.referrerPolicy = init.referrerPolicy - } +// https://fetch.spec.whatwg.org/#fetch-method +function fetch (input, init = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'globalThis.fetch' }) - // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. - let mode - if (init.mode !== undefined) { - mode = init.mode - } else { - mode = fallbackMode - } + // 1. Let p be a new promise. + const p = createDeferredPromise() - // 17. If mode is "navigate", then throw a TypeError. - if (mode === 'navigate') { - throw webidl.errors.exception({ - header: 'Request constructor', - message: 'invalid request mode navigate.' - }) - } + // 2. Let requestObject be the result of invoking the initial value of + // Request as constructor with input and init as arguments. If this throws + // an exception, reject p with it and return p. + let requestObject - // 18. If mode is non-null, set request’s mode to mode. - if (mode != null) { - request.mode = mode - } + try { + requestObject = new Request(input, init) + } catch (e) { + p.reject(e) + return p.promise + } - // 19. If init["credentials"] exists, then set request’s credentials mode - // to it. - if (init.credentials !== undefined) { - request.credentials = init.credentials - } + // 3. Let request be requestObject’s request. + const request = requestObject[kState] - // 18. If init["cache"] exists, then set request’s cache mode to it. - if (init.cache !== undefined) { - request.cache = init.cache - } + // 4. If requestObject’s signal’s aborted flag is set, then: + if (requestObject.signal.aborted) { + // 1. Abort the fetch() call with p, request, null, and + // requestObject’s signal’s abort reason. + abortFetch(p, request, null, requestObject.signal.reason) - // 21. If request’s cache mode is "only-if-cached" and request’s mode is - // not "same-origin", then throw a TypeError. - if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { - throw new TypeError( - "'only-if-cached' can be set only with 'same-origin' mode" - ) - } + // 2. Return p. + return p.promise + } - // 22. If init["redirect"] exists, then set request’s redirect mode to it. - if (init.redirect !== undefined) { - request.redirect = init.redirect - } + // 5. Let globalObject be request’s client’s global object. + const globalObject = request.client.globalObject - // 23. If init["integrity"] exists, then set request’s integrity metadata to it. - if (init.integrity != null) { - request.integrity = String(init.integrity) - } + // 6. If globalObject is a ServiceWorkerGlobalScope object, then set + // request’s service-workers mode to "none". + if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') { + request.serviceWorkers = 'none' + } - // 24. If init["keepalive"] exists, then set request’s keepalive to it. - if (init.keepalive !== undefined) { - request.keepalive = Boolean(init.keepalive) - } + // 7. Let responseObject be null. + let responseObject = null - // 25. If init["method"] exists, then: - if (init.method !== undefined) { - // 1. Let method be init["method"]. - let method = init.method + // 8. Let relevantRealm be this’s relevant Realm. + const relevantRealm = null - // 2. If method is not a method or method is a forbidden method, then - // throw a TypeError. - if (!isValidHTTPToken(method)) { - throw new TypeError(`'${method}' is not a valid HTTP method.`) - } + // 9. Let locallyAborted be false. + let locallyAborted = false - if (forbiddenMethodsSet.has(method.toUpperCase())) { - throw new TypeError(`'${method}' HTTP method is unsupported.`) - } + // 10. Let controller be null. + let controller = null - // 3. Normalize method. - method = normalizeMethodRecord[method] ?? normalizeMethod(method) + // 11. Add the following abort steps to requestObject’s signal: + addAbortListener( + requestObject.signal, + () => { + // 1. Set locallyAborted to true. + locallyAborted = true - // 4. Set request’s method to method. - request.method = method - } + // 2. Assert: controller is non-null. + assert(controller != null) - // 26. If init["signal"] exists, then set signal to it. - if (init.signal !== undefined) { - signal = init.signal + // 3. Abort controller with requestObject’s signal’s abort reason. + controller.abort(requestObject.signal.reason) + + // 4. Abort the fetch() call with p, request, responseObject, + // and requestObject’s signal’s abort reason. + abortFetch(p, request, responseObject, requestObject.signal.reason) } + ) - // 27. Set this’s request to request. - this[kState] = request + // 12. Let handleFetchDone given response response be to finalize and + // report timing with response, globalObject, and "fetch". + const handleFetchDone = (response) => + finalizeAndReportTiming(response, 'fetch') - // 28. Set this’s signal to a new AbortSignal object with this’s relevant - // Realm. - // TODO: could this be simplified with AbortSignal.any - // (https://dom.spec.whatwg.org/#dom-abortsignal-any) - const ac = new AbortController() - this[kSignal] = ac.signal - this[kSignal][kRealm] = this[kRealm] + // 13. Set controller to the result of calling fetch given request, + // with processResponseEndOfBody set to handleFetchDone, and processResponse + // given response being these substeps: - // 29. If signal is not null, then make this’s signal follow signal. - if (signal != null) { - if ( - !signal || - typeof signal.aborted !== 'boolean' || - typeof signal.addEventListener !== 'function' - ) { - throw new TypeError( - "Failed to construct 'Request': member signal is not of type AbortSignal." - ) - } + const processResponse = (response) => { + // 1. If locallyAborted is true, terminate these substeps. + if (locallyAborted) { + return Promise.resolve() + } - if (signal.aborted) { - ac.abort(signal.reason) - } else { - // Keep a strong ref to ac while request object - // is alive. This is needed to prevent AbortController - // from being prematurely garbage collected. - // See, https://github.com/nodejs/undici/issues/1926. - this[kAbortController] = ac + // 2. If response’s aborted flag is set, then: + if (response.aborted) { + // 1. Let deserializedError be the result of deserialize a serialized + // abort reason given controller’s serialized abort reason and + // relevantRealm. - const acRef = new WeakRef(ac) - const abort = function () { - const ac = acRef.deref() - if (ac !== undefined) { - ac.abort(this.reason) - } - } + // 2. Abort the fetch() call with p, request, responseObject, and + // deserializedError. - // Third-party AbortControllers may not work with these. - // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. - try { - // If the max amount of listeners is equal to the default, increase it - // This is only available in node >= v19.9.0 - if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) { - setMaxListeners(100, signal) - } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) { - setMaxListeners(100, signal) - } - } catch {} + abortFetch(p, request, responseObject, controller.serializedAbortReason) + return Promise.resolve() + } - util.addAbortListener(signal, abort) - requestFinalizer.register(ac, { signal, abort }) - } + // 3. If response is a network error, then reject p with a TypeError + // and terminate these substeps. + if (response.type === 'error') { + p.reject( + Object.assign(new TypeError('fetch failed'), { cause: response.error }) + ) + return Promise.resolve() } - // 30. Set this’s headers to a new Headers object with this’s relevant - // Realm, whose header list is request’s header list and guard is - // "request". - this[kHeaders] = new Headers(kConstruct) - this[kHeaders][kHeadersList] = request.headersList - this[kHeaders][kGuard] = 'request' - this[kHeaders][kRealm] = this[kRealm] + // 4. Set responseObject to the result of creating a Response object, + // given response, "immutable", and relevantRealm. + responseObject = new Response() + responseObject[kState] = response + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kHeadersList] = response.headersList + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm - // 31. If this’s request’s mode is "no-cors", then: - if (mode === 'no-cors') { - // 1. If this’s request’s method is not a CORS-safelisted method, - // then throw a TypeError. - if (!corsSafeListedMethodsSet.has(request.method)) { - throw new TypeError( - `'${request.method} is unsupported in no-cors mode.` - ) - } + // 5. Resolve p with responseObject. + p.resolve(responseObject) + } - // 2. Set this’s headers’s guard to "request-no-cors". - this[kHeaders][kGuard] = 'request-no-cors' - } + controller = fetching({ + request, + processResponseEndOfBody: handleFetchDone, + processResponse, + dispatcher: init.dispatcher ?? getGlobalDispatcher() // undici + }) - // 32. If init is not empty, then: - if (initHasKey) { - /** @type {HeadersList} */ - const headersList = this[kHeaders][kHeadersList] - // 1. Let headers be a copy of this’s headers and its associated header - // list. - // 2. If init["headers"] exists, then set headers to init["headers"]. - const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList) + // 14. Return p. + return p.promise +} - // 3. Empty this’s headers’s header list. - headersList.clear() +// https://fetch.spec.whatwg.org/#finalize-and-report-timing +function finalizeAndReportTiming (response, initiatorType = 'other') { + // 1. If response is an aborted network error, then return. + if (response.type === 'error' && response.aborted) { + return + } - // 4. If headers is a Headers object, then for each header in its header - // list, append header’s name/header’s value to this’s headers. - if (headers instanceof HeadersList) { - for (const [key, val] of headers) { - headersList.append(key, val) - } - // Note: Copy the `set-cookie` meta-data. - headersList.cookies = headers.cookies - } else { - // 5. Otherwise, fill this’s headers with headers. - fillHeaders(this[kHeaders], headers) - } - } + // 2. If response’s URL list is null or empty, then return. + if (!response.urlList?.length) { + return + } - // 33. Let inputBody be input’s request’s body if input is a Request - // object; otherwise null. - const inputBody = input instanceof Request ? input[kState].body : null + // 3. Let originalURL be response’s URL list[0]. + const originalURL = response.urlList[0] - // 34. If either init["body"] exists and is non-null or inputBody is - // non-null, and request’s method is `GET` or `HEAD`, then throw a - // TypeError. - if ( - (init.body != null || inputBody != null) && - (request.method === 'GET' || request.method === 'HEAD') - ) { - throw new TypeError('Request with GET/HEAD method cannot have body.') - } + // 4. Let timingInfo be response’s timing info. + let timingInfo = response.timingInfo - // 35. Let initBody be null. - let initBody = null + // 5. Let cacheState be response’s cache state. + let cacheState = response.cacheState - // 36. If init["body"] exists and is non-null, then: - if (init.body != null) { - // 1. Let Content-Type be null. - // 2. Set initBody and Content-Type to the result of extracting - // init["body"], with keepalive set to request’s keepalive. - const [extractedBody, contentType] = extractBody( - init.body, - request.keepalive - ) - initBody = extractedBody + // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return. + if (!urlIsHttpHttpsScheme(originalURL)) { + return + } - // 3, If Content-Type is non-null and this’s headers’s header list does - // not contain `Content-Type`, then append `Content-Type`/Content-Type to - // this’s headers. - if (contentType && !this[kHeaders][kHeadersList].contains('content-type')) { - this[kHeaders].append('content-type', contentType) - } - } + // 7. If timingInfo is null, then return. + if (timingInfo === null) { + return + } - // 37. Let inputOrInitBody be initBody if it is non-null; otherwise - // inputBody. - const inputOrInitBody = initBody ?? inputBody + // 8. If response’s timing allow passed flag is not set, then: + if (!response.timingAllowPassed) { + // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo. + timingInfo = createOpaqueTimingInfo({ + startTime: timingInfo.startTime + }) - // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is - // null, then: - if (inputOrInitBody != null && inputOrInitBody.source == null) { - // 1. If initBody is non-null and init["duplex"] does not exist, - // then throw a TypeError. - if (initBody != null && init.duplex == null) { - throw new TypeError('RequestInit: duplex option is required when sending a body.') - } + // 2. Set cacheState to the empty string. + cacheState = '' + } - // 2. If this’s request’s mode is neither "same-origin" nor "cors", - // then throw a TypeError. - if (request.mode !== 'same-origin' && request.mode !== 'cors') { - throw new TypeError( - 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' - ) - } + // 9. Set timingInfo’s end time to the coarsened shared current time + // given global’s relevant settings object’s cross-origin isolated + // capability. + // TODO: given global’s relevant settings object’s cross-origin isolated + // capability? + timingInfo.endTime = coarsenedSharedCurrentTime() - // 3. Set this’s request’s use-CORS-preflight flag. - request.useCORSPreflightFlag = true - } + // 10. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo - // 39. Let finalBody be inputOrInitBody. - let finalBody = inputOrInitBody + // 11. Mark resource timing for timingInfo, originalURL, initiatorType, + // global, and cacheState. + markResourceTiming( + timingInfo, + originalURL, + initiatorType, + globalThis, + cacheState + ) +} - // 40. If initBody is null and inputBody is non-null, then: - if (initBody == null && inputBody != null) { - // 1. If input is unusable, then throw a TypeError. - if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { - throw new TypeError( - 'Cannot construct a Request with a Request object that has already been used.' - ) - } +// https://w3c.github.io/resource-timing/#dfn-mark-resource-timing +function markResourceTiming (timingInfo, originalURL, initiatorType, globalThis, cacheState) { + if (nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 2)) { + performance.markResourceTiming(timingInfo, originalURL.href, initiatorType, globalThis, cacheState) + } +} - // 2. Set finalBody to the result of creating a proxy for inputBody. - if (!TransformStream) { - TransformStream = (__nccwpck_require__(5356).TransformStream) - } +// https://fetch.spec.whatwg.org/#abort-fetch +function abortFetch (p, request, responseObject, error) { + // Note: AbortSignal.reason was added in node v17.2.0 + // which would give us an undefined error to reject with. + // Remove this once node v16 is no longer supported. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError') + } - // https://streams.spec.whatwg.org/#readablestream-create-a-proxy - const identityTransform = new TransformStream() - inputBody.stream.pipeThrough(identityTransform) - finalBody = { - source: inputBody.source, - length: inputBody.length, - stream: identityTransform.readable - } - } + // 1. Reject promise with error. + p.reject(error) - // 41. Set this’s request’s body to finalBody. - this[kState].body = finalBody + // 2. If request’s body is not null and is readable, then cancel request’s + // body with error. + if (request.body != null && isReadable(request.body?.stream)) { + request.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }) } - // Returns request’s HTTP method, which is "GET" by default. - get method () { - webidl.brandCheck(this, Request) - - // The method getter steps are to return this’s request’s method. - return this[kState].method + // 3. If responseObject is null, then return. + if (responseObject == null) { + return } - // Returns the URL of request as a string. - get url () { - webidl.brandCheck(this, Request) + // 4. Let response be responseObject’s response. + const response = responseObject[kState] - // The url getter steps are to return this’s request’s URL, serialized. - return URLSerializer(this[kState].url) + // 5. If response’s body is not null and is readable, then error response’s + // body with error. + if (response.body != null && isReadable(response.body?.stream)) { + response.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }) } +} - // Returns a Headers object consisting of the headers associated with request. - // Note that headers added in the network layer by the user agent will not - // be accounted for in this object, e.g., the "Host" header. - get headers () { - webidl.brandCheck(this, Request) +// https://fetch.spec.whatwg.org/#fetching +function fetching ({ + request, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseEndOfBody, + processResponseConsumeBody, + useParallelQueue = false, + dispatcher // undici +}) { + // 1. Let taskDestination be null. + let taskDestination = null - // The headers getter steps are to return this’s headers. - return this[kHeaders] - } + // 2. Let crossOriginIsolatedCapability be false. + let crossOriginIsolatedCapability = false - // Returns the kind of resource requested by request, e.g., "document" - // or "script". - get destination () { - webidl.brandCheck(this, Request) + // 3. If request’s client is non-null, then: + if (request.client != null) { + // 1. Set taskDestination to request’s client’s global object. + taskDestination = request.client.globalObject - // The destination getter are to return this’s request’s destination. - return this[kState].destination + // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin + // isolated capability. + crossOriginIsolatedCapability = + request.client.crossOriginIsolatedCapability } - // Returns the referrer of request. Its value can be a same-origin URL if - // explicitly set in init, the empty string to indicate no referrer, and - // "about:client" when defaulting to the global’s default. This is used - // during fetching to determine the value of the `Referer` header of the - // request being made. - get referrer () { - webidl.brandCheck(this, Request) - - // 1. If this’s request’s referrer is "no-referrer", then return the - // empty string. - if (this[kState].referrer === 'no-referrer') { - return '' - } + // 4. If useParallelQueue is true, then set taskDestination to the result of + // starting a new parallel queue. + // TODO - // 2. If this’s request’s referrer is "client", then return - // "about:client". - if (this[kState].referrer === 'client') { - return 'about:client' - } + // 5. Let timingInfo be a new fetch timing info whose start time and + // post-redirect start time are the coarsened shared current time given + // crossOriginIsolatedCapability. + const currenTime = coarsenedSharedCurrentTime(crossOriginIsolatedCapability) + const timingInfo = createOpaqueTimingInfo({ + startTime: currenTime + }) - // Return this’s request’s referrer, serialized. - return this[kState].referrer.toString() + // 6. Let fetchParams be a new fetch params whose + // request is request, + // timing info is timingInfo, + // process request body chunk length is processRequestBodyChunkLength, + // process request end-of-body is processRequestEndOfBody, + // process response is processResponse, + // process response consume body is processResponseConsumeBody, + // process response end-of-body is processResponseEndOfBody, + // task destination is taskDestination, + // and cross-origin isolated capability is crossOriginIsolatedCapability. + const fetchParams = { + controller: new Fetch(dispatcher), + request, + timingInfo, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseConsumeBody, + processResponseEndOfBody, + taskDestination, + crossOriginIsolatedCapability } - // Returns the referrer policy associated with request. - // This is used during fetching to compute the value of the request’s - // referrer. - get referrerPolicy () { - webidl.brandCheck(this, Request) + // 7. If request’s body is a byte sequence, then set request’s body to + // request’s body as a body. + // NOTE: Since fetching is only called from fetch, body should already be + // extracted. + assert(!request.body || request.body.stream) - // The referrerPolicy getter steps are to return this’s request’s referrer policy. - return this[kState].referrerPolicy + // 8. If request’s window is "client", then set request’s window to request’s + // client, if request’s client’s global object is a Window object; otherwise + // "no-window". + if (request.window === 'client') { + // TODO: What if request.client is null? + request.window = + request.client?.globalObject?.constructor?.name === 'Window' + ? request.client + : 'no-window' } - // Returns the mode associated with request, which is a string indicating - // whether the request will use CORS, or will be restricted to same-origin - // URLs. - get mode () { - webidl.brandCheck(this, Request) - - // The mode getter steps are to return this’s request’s mode. - return this[kState].mode + // 9. If request’s origin is "client", then set request’s origin to request’s + // client’s origin. + if (request.origin === 'client') { + // TODO: What if request.client is null? + request.origin = request.client?.origin } - // Returns the credentials mode associated with request, - // which is a string indicating whether credentials will be sent with the - // request always, never, or only when sent to a same-origin URL. - get credentials () { - // The credentials getter steps are to return this’s request’s credentials mode. - return this[kState].credentials - } - - // Returns the cache mode associated with request, - // which is a string indicating how the request will - // interact with the browser’s cache when fetching. - get cache () { - webidl.brandCheck(this, Request) + // 10. If all of the following conditions are true: + // TODO - // The cache getter steps are to return this’s request’s cache mode. - return this[kState].cache + // 11. If request’s policy container is "client", then: + if (request.policyContainer === 'client') { + // 1. If request’s client is non-null, then set request’s policy + // container to a clone of request’s client’s policy container. [HTML] + if (request.client != null) { + request.policyContainer = clonePolicyContainer( + request.client.policyContainer + ) + } else { + // 2. Otherwise, set request’s policy container to a new policy + // container. + request.policyContainer = makePolicyContainer() + } } - // Returns the redirect mode associated with request, - // which is a string indicating how redirects for the - // request will be handled during fetching. A request - // will follow redirects by default. - get redirect () { - webidl.brandCheck(this, Request) - - // The redirect getter steps are to return this’s request’s redirect mode. - return this[kState].redirect - } + // 12. If request’s header list does not contain `Accept`, then: + if (!request.headersList.contains('accept')) { + // 1. Let value be `*/*`. + const value = '*/*' - // Returns request’s subresource integrity metadata, which is a - // cryptographic hash of the resource being fetched. Its value - // consists of multiple hashes separated by whitespace. [SRI] - get integrity () { - webidl.brandCheck(this, Request) + // 2. A user agent should set value to the first matching statement, if + // any, switching on request’s destination: + // "document" + // "frame" + // "iframe" + // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` + // "image" + // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5` + // "style" + // `text/css,*/*;q=0.1` + // TODO - // The integrity getter steps are to return this’s request’s integrity - // metadata. - return this[kState].integrity + // 3. Append `Accept`/value to request’s header list. + request.headersList.append('accept', value) } - // Returns a boolean indicating whether or not request can outlive the - // global in which it was created. - get keepalive () { - webidl.brandCheck(this, Request) - - // The keepalive getter steps are to return this’s request’s keepalive. - return this[kState].keepalive + // 13. If request’s header list does not contain `Accept-Language`, then + // user agents should append `Accept-Language`/an appropriate value to + // request’s header list. + if (!request.headersList.contains('accept-language')) { + request.headersList.append('accept-language', '*') } - // Returns a boolean indicating whether or not request is for a reload - // navigation. - get isReloadNavigation () { - webidl.brandCheck(this, Request) + // 14. If request’s priority is null, then use request’s initiator and + // destination appropriately in setting request’s priority to a + // user-agent-defined object. + if (request.priority === null) { + // TODO + } - // The isReloadNavigation getter steps are to return true if this’s - // request’s reload-navigation flag is set; otherwise false. - return this[kState].reloadNavigation + // 15. If request is a subresource request, then: + if (subresourceSet.has(request.destination)) { + // TODO } - // Returns a boolean indicating whether or not request is for a history - // navigation (a.k.a. back-foward navigation). - get isHistoryNavigation () { - webidl.brandCheck(this, Request) + // 16. Run main fetch given fetchParams. + mainFetch(fetchParams) + .catch(err => { + fetchParams.controller.terminate(err) + }) - // The isHistoryNavigation getter steps are to return true if this’s request’s - // history-navigation flag is set; otherwise false. - return this[kState].historyNavigation - } + // 17. Return fetchParam's controller + return fetchParams.controller +} - // Returns the signal associated with request, which is an AbortSignal - // object indicating whether or not request has been aborted, and its - // abort event handler. - get signal () { - webidl.brandCheck(this, Request) +// https://fetch.spec.whatwg.org/#concept-main-fetch +async function mainFetch (fetchParams, recursive = false) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request - // The signal getter steps are to return this’s signal. - return this[kSignal] + // 2. Let response be null. + let response = null + + // 3. If request’s local-URLs-only flag is set and request’s current URL is + // not local, then set response to a network error. + if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { + response = makeNetworkError('local URLs only') } - get body () { - webidl.brandCheck(this, Request) + // 4. Run report Content Security Policy violations for request. + // TODO - return this[kState].body ? this[kState].body.stream : null + // 5. Upgrade request to a potentially trustworthy URL, if appropriate. + tryUpgradeRequestToAPotentiallyTrustworthyURL(request) + + // 6. If should request be blocked due to a bad port, should fetching request + // be blocked as mixed content, or should request be blocked by Content + // Security Policy returns blocked, then set response to a network error. + if (requestBadPort(request) === 'blocked') { + response = makeNetworkError('bad port') } + // TODO: should fetching request be blocked as mixed content? + // TODO: should request be blocked by Content Security Policy? - get bodyUsed () { - webidl.brandCheck(this, Request) + // 7. If request’s referrer policy is the empty string, then set request’s + // referrer policy to request’s policy container’s referrer policy. + if (request.referrerPolicy === '') { + request.referrerPolicy = request.policyContainer.referrerPolicy + } - return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + // 8. If request’s referrer is not "no-referrer", then set request’s + // referrer to the result of invoking determine request’s referrer. + if (request.referrer !== 'no-referrer') { + request.referrer = determineRequestsReferrer(request) } - get duplex () { - webidl.brandCheck(this, Request) + // 9. Set request’s current URL’s scheme to "https" if all of the following + // conditions are true: + // - request’s current URL’s scheme is "http" + // - request’s current URL’s host is a domain + // - Matching request’s current URL’s host per Known HSTS Host Domain Name + // Matching results in either a superdomain match with an asserted + // includeSubDomains directive or a congruent match (with or without an + // asserted includeSubDomains directive). [HSTS] + // TODO - return 'half' - } + // 10. If recursive is false, then run the remaining steps in parallel. + // TODO - // Returns a clone of request. - clone () { - webidl.brandCheck(this, Request) + // 11. If response is null, then set response to the result of running + // the steps corresponding to the first matching statement: + if (response === null) { + response = await (async () => { + const currentURL = requestCurrentURL(request) - // 1. If this is unusable, then throw a TypeError. - if (this.bodyUsed || this.body?.locked) { - throw new TypeError('unusable') - } + if ( + // - request’s current URL’s origin is same origin with request’s origin, + // and request’s response tainting is "basic" + (sameOrigin(currentURL, request.url) && request.responseTainting === 'basic') || + // request’s current URL’s scheme is "data" + (currentURL.protocol === 'data:') || + // - request’s mode is "navigate" or "websocket" + (request.mode === 'navigate' || request.mode === 'websocket') + ) { + // 1. Set request’s response tainting to "basic". + request.responseTainting = 'basic' - // 2. Let clonedRequest be the result of cloning this’s request. - const clonedRequest = cloneRequest(this[kState]) + // 2. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } - // 3. Let clonedRequestObject be the result of creating a Request object, - // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. - const clonedRequestObject = new Request(kConstruct) - clonedRequestObject[kState] = clonedRequest - clonedRequestObject[kRealm] = this[kRealm] - clonedRequestObject[kHeaders] = new Headers(kConstruct) - clonedRequestObject[kHeaders][kHeadersList] = clonedRequest.headersList - clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard] - clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm] + // request’s mode is "same-origin" + if (request.mode === 'same-origin') { + // 1. Return a network error. + return makeNetworkError('request mode cannot be "same-origin"') + } - // 4. Make clonedRequestObject’s signal follow this’s signal. - const ac = new AbortController() - if (this.signal.aborted) { - ac.abort(this.signal.reason) - } else { - util.addAbortListener( - this.signal, - () => { - ac.abort(this.signal.reason) + // request’s mode is "no-cors" + if (request.mode === 'no-cors') { + // 1. If request’s redirect mode is not "follow", then return a network + // error. + if (request.redirect !== 'follow') { + return makeNetworkError( + 'redirect mode cannot be "follow" for "no-cors" request' + ) } - ) - } - clonedRequestObject[kSignal] = ac.signal - // 4. Return clonedRequestObject. - return clonedRequestObject - } -} + // 2. Set request’s response tainting to "opaque". + request.responseTainting = 'opaque' -mixinBody(Request) + // 3. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } -function makeRequest (init) { - // https://fetch.spec.whatwg.org/#requests - const request = { - method: 'GET', - localURLsOnly: false, - unsafeRequest: false, - body: null, - client: null, - reservedClient: null, - replacesClientId: '', - window: 'client', - keepalive: false, - serviceWorkers: 'all', - initiator: '', - destination: '', - priority: null, - origin: 'client', - policyContainer: 'client', - referrer: 'client', - referrerPolicy: '', - mode: 'no-cors', - useCORSPreflightFlag: false, - credentials: 'same-origin', - useCredentials: false, - cache: 'default', - redirect: 'follow', - integrity: '', - cryptoGraphicsNonceMetadata: '', - parserMetadata: '', - reloadNavigation: false, - historyNavigation: false, - userActivation: false, - taintedOrigin: false, - redirectCount: 0, - responseTainting: 'basic', - preventNoCacheCacheControlHeaderModification: false, - done: false, - timingAllowFailed: false, - ...init, - headersList: init.headersList - ? new HeadersList(init.headersList) - : new HeadersList() - } - request.url = request.urlList[0] - return request -} + // request’s current URL’s scheme is not an HTTP(S) scheme + if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { + // Return a network error. + return makeNetworkError('URL scheme must be a HTTP(S) scheme') + } -// https://fetch.spec.whatwg.org/#concept-request-clone -function cloneRequest (request) { - // To clone a request request, run these steps: + // - request’s use-CORS-preflight flag is set + // - request’s unsafe-request flag is set and either request’s method is + // not a CORS-safelisted method or CORS-unsafe request-header names with + // request’s header list is not empty + // 1. Set request’s response tainting to "cors". + // 2. Let corsWithPreflightResponse be the result of running HTTP fetch + // given fetchParams and true. + // 3. If corsWithPreflightResponse is a network error, then clear cache + // entries using request. + // 4. Return corsWithPreflightResponse. + // TODO - // 1. Let newRequest be a copy of request, except for its body. - const newRequest = makeRequest({ ...request, body: null }) + // Otherwise + // 1. Set request’s response tainting to "cors". + request.responseTainting = 'cors' - // 2. If request’s body is non-null, set newRequest’s body to the - // result of cloning request’s body. - if (request.body != null) { - newRequest.body = cloneBody(request.body) + // 2. Return the result of running HTTP fetch given fetchParams. + return await httpFetch(fetchParams) + })() } - // 3. Return newRequest. - return newRequest -} + // 12. If recursive is true, then return response. + if (recursive) { + return response + } -Object.defineProperties(Request.prototype, { - method: kEnumerableProperty, - url: kEnumerableProperty, - headers: kEnumerableProperty, - redirect: kEnumerableProperty, - clone: kEnumerableProperty, - signal: kEnumerableProperty, - duplex: kEnumerableProperty, - destination: kEnumerableProperty, - body: kEnumerableProperty, - bodyUsed: kEnumerableProperty, - isHistoryNavigation: kEnumerableProperty, - isReloadNavigation: kEnumerableProperty, - keepalive: kEnumerableProperty, - integrity: kEnumerableProperty, - cache: kEnumerableProperty, - credentials: kEnumerableProperty, - attribute: kEnumerableProperty, - referrerPolicy: kEnumerableProperty, - referrer: kEnumerableProperty, - mode: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'Request', - configurable: true + // 13. If response is not a network error and response is not a filtered + // response, then: + if (response.status !== 0 && !response.internalResponse) { + // If request’s response tainting is "cors", then: + if (request.responseTainting === 'cors') { + // 1. Let headerNames be the result of extracting header list values + // given `Access-Control-Expose-Headers` and response’s header list. + // TODO + // 2. If request’s credentials mode is not "include" and headerNames + // contains `*`, then set response’s CORS-exposed header-name list to + // all unique header names in response’s header list. + // TODO + // 3. Otherwise, if headerNames is not null or failure, then set + // response’s CORS-exposed header-name list to headerNames. + // TODO + } + + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (request.responseTainting === 'basic') { + response = filterResponse(response, 'basic') + } else if (request.responseTainting === 'cors') { + response = filterResponse(response, 'cors') + } else if (request.responseTainting === 'opaque') { + response = filterResponse(response, 'opaque') + } else { + assert(false) + } } -}) -webidl.converters.Request = webidl.interfaceConverter( - Request -) + // 14. Let internalResponse be response, if response is a network error, + // and response’s internal response otherwise. + let internalResponse = + response.status === 0 ? response : response.internalResponse -// https://fetch.spec.whatwg.org/#requestinfo -webidl.converters.RequestInfo = function (V) { - if (typeof V === 'string') { - return webidl.converters.USVString(V) + // 15. If internalResponse’s URL list is empty, then set it to a clone of + // request’s URL list. + if (internalResponse.urlList.length === 0) { + internalResponse.urlList.push(...request.urlList) } - if (V instanceof Request) { - return webidl.converters.Request(V) + // 16. If request’s timing allow failed flag is unset, then set + // internalResponse’s timing allow passed flag. + if (!request.timingAllowFailed) { + response.timingAllowPassed = true } - return webidl.converters.USVString(V) -} + // 17. If response is not a network error and any of the following returns + // blocked + // - should internalResponse to request be blocked as mixed content + // - should internalResponse to request be blocked by Content Security Policy + // - should internalResponse to request be blocked due to its MIME type + // - should internalResponse to request be blocked due to nosniff + // TODO -webidl.converters.AbortSignal = webidl.interfaceConverter( - AbortSignal -) + // 18. If response’s type is "opaque", internalResponse’s status is 206, + // internalResponse’s range-requested flag is set, and request’s header + // list does not contain `Range`, then set response and internalResponse + // to a network error. + if ( + response.type === 'opaque' && + internalResponse.status === 206 && + internalResponse.rangeRequested && + !request.headers.contains('range') + ) { + response = internalResponse = makeNetworkError() + } -// https://fetch.spec.whatwg.org/#requestinit -webidl.converters.RequestInit = webidl.dictionaryConverter([ - { - key: 'method', - converter: webidl.converters.ByteString - }, - { - key: 'headers', - converter: webidl.converters.HeadersInit - }, - { - key: 'body', - converter: webidl.nullableConverter( - webidl.converters.BodyInit - ) - }, - { - key: 'referrer', - converter: webidl.converters.USVString - }, - { - key: 'referrerPolicy', - converter: webidl.converters.DOMString, - // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy - allowedValues: referrerPolicy - }, - { - key: 'mode', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#concept-request-mode - allowedValues: requestMode - }, - { - key: 'credentials', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestcredentials - allowedValues: requestCredentials - }, - { - key: 'cache', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestcache - allowedValues: requestCache - }, - { - key: 'redirect', - converter: webidl.converters.DOMString, - // https://fetch.spec.whatwg.org/#requestredirect - allowedValues: requestRedirect - }, - { - key: 'integrity', - converter: webidl.converters.DOMString - }, - { - key: 'keepalive', - converter: webidl.converters.boolean - }, - { - key: 'signal', - converter: webidl.nullableConverter( - (signal) => webidl.converters.AbortSignal( - signal, - { strict: false } - ) - ) - }, - { - key: 'window', - converter: webidl.converters.any - }, - { - key: 'duplex', - converter: webidl.converters.DOMString, - allowedValues: requestDuplex + // 19. If response is not a network error and either request’s method is + // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, + // set internalResponse’s body to null and disregard any enqueuing toward + // it (if any). + if ( + response.status !== 0 && + (request.method === 'HEAD' || + request.method === 'CONNECT' || + nullBodyStatus.includes(internalResponse.status)) + ) { + internalResponse.body = null + fetchParams.controller.dump = true } -]) - -module.exports = { Request, makeRequest } + // 20. If request’s integrity metadata is not the empty string, then: + if (request.integrity) { + // 1. Let processBodyError be this step: run fetch finale given fetchParams + // and a network error. + const processBodyError = (reason) => + fetchFinale(fetchParams, makeNetworkError(reason)) -/***/ }), + // 2. If request’s response tainting is "opaque", or response’s body is null, + // then run processBodyError and abort these steps. + if (request.responseTainting === 'opaque' || response.body == null) { + processBodyError(response.error) + return + } -/***/ 7823: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 3. Let processBody given bytes be these steps: + const processBody = (bytes) => { + // 1. If bytes do not match request’s integrity metadata, + // then run processBodyError and abort these steps. [SRI] + if (!bytesMatch(bytes, request.integrity)) { + processBodyError('integrity mismatch') + return + } -"use strict"; + // 2. Set response’s body to bytes as a body. + response.body = safelyExtractBody(bytes)[0] + // 3. Run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response) + } -const { Headers, HeadersList, fill } = __nccwpck_require__(554) -const { extractBody, cloneBody, mixinBody } = __nccwpck_require__(1472) -const util = __nccwpck_require__(3983) -const { kEnumerableProperty } = util -const { - isValidReasonPhrase, - isCancelled, - isAborted, - isBlobLike, - serializeJavascriptValueToJSONString, - isErrorLike, - isomorphicEncode -} = __nccwpck_require__(2538) -const { - redirectStatusSet, - nullBodyStatus, - DOMException -} = __nccwpck_require__(1037) -const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) -const { webidl } = __nccwpck_require__(1744) -const { FormData } = __nccwpck_require__(2015) -const { getGlobalOrigin } = __nccwpck_require__(1246) -const { URLSerializer } = __nccwpck_require__(685) -const { kHeadersList, kConstruct } = __nccwpck_require__(2785) -const assert = __nccwpck_require__(9491) -const { types } = __nccwpck_require__(3837) + // 4. Fully read response’s body given processBody and processBodyError. + await fullyReadBody(response.body, processBody, processBodyError) + } else { + // 21. Otherwise, run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response) + } +} -const ReadableStream = globalThis.ReadableStream || (__nccwpck_require__(5356).ReadableStream) -const textEncoder = new TextEncoder('utf-8') +// https://fetch.spec.whatwg.org/#concept-scheme-fetch +// given a fetch params fetchParams +function schemeFetch (fetchParams) { + // Note: since the connection is destroyed on redirect, which sets fetchParams to a + // cancelled state, we do not want this condition to trigger *unless* there have been + // no redirects. See https://github.com/nodejs/undici/issues/1776 + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) { + return Promise.resolve(makeAppropriateNetworkError(fetchParams)) + } -// https://fetch.spec.whatwg.org/#response-class -class Response { - // Creates network error Response. - static error () { - // TODO - const relevantRealm = { settingsObject: {} } + // 2. Let request be fetchParams’s request. + const { request } = fetchParams - // The static error() method steps are to return the result of creating a - // Response object, given a new network error, "immutable", and this’s - // relevant Realm. - const responseObject = new Response() - responseObject[kState] = makeNetworkError() - responseObject[kRealm] = relevantRealm - responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList - responseObject[kHeaders][kGuard] = 'immutable' - responseObject[kHeaders][kRealm] = relevantRealm - return responseObject - } + const { protocol: scheme } = requestCurrentURL(request) - // https://fetch.spec.whatwg.org/#dom-response-json - static json (data, init = {}) { - webidl.argumentLengthCheck(arguments, 1, { header: 'Response.json' }) + // 3. Switch on request’s current URL’s scheme and run the associated steps: + switch (scheme) { + case 'about:': { + // If request’s current URL’s path is the string "blank", then return a new response + // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) », + // and body is the empty byte sequence as a body. - if (init !== null) { - init = webidl.converters.ResponseInit(init) + // Otherwise, return a network error. + return Promise.resolve(makeNetworkError('about scheme is not supported')) } + case 'blob:': { + if (!resolveObjectURL) { + resolveObjectURL = (__nccwpck_require__(4300).resolveObjectURL) + } - // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. - const bytes = textEncoder.encode( - serializeJavascriptValueToJSONString(data) - ) + // 1. Let blobURLEntry be request’s current URL’s blob URL entry. + const blobURLEntry = requestCurrentURL(request) - // 2. Let body be the result of extracting bytes. - const body = extractBody(bytes) + // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 + // Buffer.resolveObjectURL does not ignore URL queries. + if (blobURLEntry.search.length !== 0) { + return Promise.resolve(makeNetworkError('NetworkError when attempting to fetch resource.')) + } - // 3. Let responseObject be the result of creating a Response object, given a new response, - // "response", and this’s relevant Realm. - const relevantRealm = { settingsObject: {} } - const responseObject = new Response() - responseObject[kRealm] = relevantRealm - responseObject[kHeaders][kGuard] = 'response' - responseObject[kHeaders][kRealm] = relevantRealm + const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()) - // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). - initializeResponse(responseObject, init, { body: body[0], type: 'application/json' }) + // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s + // object is not a Blob object, then return a network error. + if (request.method !== 'GET' || !isBlobLike(blobURLEntryObject)) { + return Promise.resolve(makeNetworkError('invalid method')) + } - // 5. Return responseObject. - return responseObject - } + // 3. Let bodyWithType be the result of safely extracting blobURLEntry’s object. + const bodyWithType = safelyExtractBody(blobURLEntryObject) - // Creates a redirect Response that redirects to url with status status. - static redirect (url, status = 302) { - const relevantRealm = { settingsObject: {} } + // 4. Let body be bodyWithType’s body. + const body = bodyWithType[0] - webidl.argumentLengthCheck(arguments, 1, { header: 'Response.redirect' }) + // 5. Let length be body’s length, serialized and isomorphic encoded. + const length = isomorphicEncode(`${body.length}`) - url = webidl.converters.USVString(url) - status = webidl.converters['unsigned short'](status) + // 6. Let type be bodyWithType’s type if it is non-null; otherwise the empty byte sequence. + const type = bodyWithType[1] ?? '' - // 1. Let parsedURL be the result of parsing url with current settings - // object’s API base URL. - // 2. If parsedURL is failure, then throw a TypeError. - // TODO: base-URL? - let parsedURL - try { - parsedURL = new URL(url, getGlobalOrigin()) - } catch (err) { - throw Object.assign(new TypeError('Failed to parse URL from ' + url), { - cause: err + // 7. Return a new response whose status message is `OK`, header list is + // « (`Content-Length`, length), (`Content-Type`, type) », and body is body. + const response = makeResponse({ + statusText: 'OK', + headersList: [ + ['content-length', { name: 'Content-Length', value: length }], + ['content-type', { name: 'Content-Type', value: type }] + ] }) - } - // 3. If status is not a redirect status, then throw a RangeError. - if (!redirectStatusSet.has(status)) { - throw new RangeError('Invalid status code ' + status) - } - - // 4. Let responseObject be the result of creating a Response object, - // given a new response, "immutable", and this’s relevant Realm. - const responseObject = new Response() - responseObject[kRealm] = relevantRealm - responseObject[kHeaders][kGuard] = 'immutable' - responseObject[kHeaders][kRealm] = relevantRealm + response.body = body - // 5. Set responseObject’s response’s status to status. - responseObject[kState].status = status + return Promise.resolve(response) + } + case 'data:': { + // 1. Let dataURLStruct be the result of running the + // data: URL processor on request’s current URL. + const currentURL = requestCurrentURL(request) + const dataURLStruct = dataURLProcessor(currentURL) - // 6. Let value be parsedURL, serialized and isomorphic encoded. - const value = isomorphicEncode(URLSerializer(parsedURL)) + // 2. If dataURLStruct is failure, then return a + // network error. + if (dataURLStruct === 'failure') { + return Promise.resolve(makeNetworkError('failed to fetch the data URL')) + } - // 7. Append `Location`/value to responseObject’s response’s header list. - responseObject[kState].headersList.append('location', value) + // 3. Let mimeType be dataURLStruct’s MIME type, serialized. + const mimeType = serializeAMimeType(dataURLStruct.mimeType) - // 8. Return responseObject. - return responseObject - } + // 4. Return a response whose status message is `OK`, + // header list is « (`Content-Type`, mimeType) », + // and body is dataURLStruct’s body as a body. + return Promise.resolve(makeResponse({ + statusText: 'OK', + headersList: [ + ['content-type', { name: 'Content-Type', value: mimeType }] + ], + body: safelyExtractBody(dataURLStruct.body)[0] + })) + } + case 'file:': { + // For now, unfortunate as it is, file URLs are left as an exercise for the reader. + // When in doubt, return a network error. + return Promise.resolve(makeNetworkError('not implemented... yet...')) + } + case 'http:': + case 'https:': { + // Return the result of running HTTP fetch given fetchParams. - // https://fetch.spec.whatwg.org/#dom-response - constructor (body = null, init = {}) { - if (body !== null) { - body = webidl.converters.BodyInit(body) + return httpFetch(fetchParams) + .catch((err) => makeNetworkError(err)) } + default: { + return Promise.resolve(makeNetworkError('unknown scheme')) + } + } +} - init = webidl.converters.ResponseInit(init) +// https://fetch.spec.whatwg.org/#finalize-response +function finalizeResponse (fetchParams, response) { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true - // TODO - this[kRealm] = { settingsObject: {} } + // 2, If fetchParams’s process response done is not null, then queue a fetch + // task to run fetchParams’s process response done given response, with + // fetchParams’s task destination. + if (fetchParams.processResponseDone != null) { + queueMicrotask(() => fetchParams.processResponseDone(response)) + } +} - // 1. Set this’s response to a new response. - this[kState] = makeResponse({}) +// https://fetch.spec.whatwg.org/#fetch-finale +function fetchFinale (fetchParams, response) { + // 1. If response is a network error, then: + if (response.type === 'error') { + // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ». + response.urlList = [fetchParams.request.urlList[0]] - // 2. Set this’s headers to a new Headers object with this’s relevant - // Realm, whose header list is this’s response’s header list and guard - // is "response". - this[kHeaders] = new Headers(kConstruct) - this[kHeaders][kGuard] = 'response' - this[kHeaders][kHeadersList] = this[kState].headersList - this[kHeaders][kRealm] = this[kRealm] + // 2. Set response’s timing info to the result of creating an opaque timing + // info for fetchParams’s timing info. + response.timingInfo = createOpaqueTimingInfo({ + startTime: fetchParams.timingInfo.startTime + }) + } - // 3. Let bodyWithType be null. - let bodyWithType = null + // 2. Let processResponseEndOfBody be the following steps: + const processResponseEndOfBody = () => { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true - // 4. If body is non-null, then set bodyWithType to the result of extracting body. - if (body != null) { - const [extractedBody, type] = extractBody(body) - bodyWithType = { body: extractedBody, type } + // If fetchParams’s process response end-of-body is not null, + // then queue a fetch task to run fetchParams’s process response + // end-of-body given response with fetchParams’s task destination. + if (fetchParams.processResponseEndOfBody != null) { + queueMicrotask(() => fetchParams.processResponseEndOfBody(response)) } - - // 5. Perform initialize a response given this, init, and bodyWithType. - initializeResponse(this, init, bodyWithType) } - // Returns response’s type, e.g., "cors". - get type () { - webidl.brandCheck(this, Response) - - // The type getter steps are to return this’s response’s type. - return this[kState].type + // 3. If fetchParams’s process response is non-null, then queue a fetch task + // to run fetchParams’s process response given response, with fetchParams’s + // task destination. + if (fetchParams.processResponse != null) { + queueMicrotask(() => fetchParams.processResponse(response)) } - // Returns response’s URL, if it has one; otherwise the empty string. - get url () { - webidl.brandCheck(this, Response) - - const urlList = this[kState].urlList + // 4. If response’s body is null, then run processResponseEndOfBody. + if (response.body == null) { + processResponseEndOfBody() + } else { + // 5. Otherwise: - // The url getter steps are to return the empty string if this’s - // response’s URL is null; otherwise this’s response’s URL, - // serialized with exclude fragment set to true. - const url = urlList[urlList.length - 1] ?? null + // 1. Let transformStream be a new a TransformStream. - if (url === null) { - return '' + // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, + // enqueues chunk in transformStream. + const identityTransformAlgorithm = (chunk, controller) => { + controller.enqueue(chunk) } - return URLSerializer(url, true) - } - - // Returns whether response was obtained through a redirect. - get redirected () { - webidl.brandCheck(this, Response) + // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm + // and flushAlgorithm set to processResponseEndOfBody. + const transformStream = new TransformStream({ + start () {}, + transform: identityTransformAlgorithm, + flush: processResponseEndOfBody + }, { + size () { + return 1 + } + }, { + size () { + return 1 + } + }) - // The redirected getter steps are to return true if this’s response’s URL - // list has more than one item; otherwise false. - return this[kState].urlList.length > 1 + // 4. Set response’s body to the result of piping response’s body through transformStream. + response.body = { stream: response.body.stream.pipeThrough(transformStream) } } - // Returns response’s status. - get status () { - webidl.brandCheck(this, Response) - - // The status getter steps are to return this’s response’s status. - return this[kState].status - } + // 6. If fetchParams’s process response consume body is non-null, then: + if (fetchParams.processResponseConsumeBody != null) { + // 1. Let processBody given nullOrBytes be this step: run fetchParams’s + // process response consume body given response and nullOrBytes. + const processBody = (nullOrBytes) => fetchParams.processResponseConsumeBody(response, nullOrBytes) - // Returns whether response’s status is an ok status. - get ok () { - webidl.brandCheck(this, Response) + // 2. Let processBodyError be this step: run fetchParams’s process + // response consume body given response and failure. + const processBodyError = (failure) => fetchParams.processResponseConsumeBody(response, failure) - // The ok getter steps are to return true if this’s response’s status is an - // ok status; otherwise false. - return this[kState].status >= 200 && this[kState].status <= 299 + // 3. If response’s body is null, then queue a fetch task to run processBody + // given null, with fetchParams’s task destination. + if (response.body == null) { + queueMicrotask(() => processBody(null)) + } else { + // 4. Otherwise, fully read response’s body given processBody, processBodyError, + // and fetchParams’s task destination. + return fullyReadBody(response.body, processBody, processBodyError) + } + return Promise.resolve() } +} - // Returns response’s status message. - get statusText () { - webidl.brandCheck(this, Response) +// https://fetch.spec.whatwg.org/#http-fetch +async function httpFetch (fetchParams) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request - // The statusText getter steps are to return this’s response’s status - // message. - return this[kState].statusText - } + // 2. Let response be null. + let response = null - // Returns response’s headers as Headers. - get headers () { - webidl.brandCheck(this, Response) + // 3. Let actualResponse be null. + let actualResponse = null - // The headers getter steps are to return this’s headers. - return this[kHeaders] + // 4. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo + + // 5. If request’s service-workers mode is "all", then: + if (request.serviceWorkers === 'all') { + // TODO } - get body () { - webidl.brandCheck(this, Response) + // 6. If response is null, then: + if (response === null) { + // 1. If makeCORSPreflight is true and one of these conditions is true: + // TODO - return this[kState].body ? this[kState].body.stream : null - } + // 2. If request’s redirect mode is "follow", then set request’s + // service-workers mode to "none". + if (request.redirect === 'follow') { + request.serviceWorkers = 'none' + } - get bodyUsed () { - webidl.brandCheck(this, Response) + // 3. Set response and actualResponse to the result of running + // HTTP-network-or-cache fetch given fetchParams. + actualResponse = response = await httpNetworkOrCacheFetch(fetchParams) - return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + // 4. If request’s response tainting is "cors" and a CORS check + // for request and response returns failure, then return a network error. + if ( + request.responseTainting === 'cors' && + corsCheck(request, response) === 'failure' + ) { + return makeNetworkError('cors failure') + } + + // 5. If the TAO check for request and response returns failure, then set + // request’s timing allow failed flag. + if (TAOCheck(request, response) === 'failure') { + request.timingAllowFailed = true + } } - // Returns a clone of response. - clone () { - webidl.brandCheck(this, Response) + // 7. If either request’s response tainting or response’s type + // is "opaque", and the cross-origin resource policy check with + // request’s origin, request’s client, request’s destination, + // and actualResponse returns blocked, then return a network error. + if ( + (request.responseTainting === 'opaque' || response.type === 'opaque') && + crossOriginResourcePolicyCheck( + request.origin, + request.client, + request.destination, + actualResponse + ) === 'blocked' + ) { + return makeNetworkError('blocked') + } - // 1. If this is unusable, then throw a TypeError. - if (this.bodyUsed || (this.body && this.body.locked)) { - throw webidl.errors.exception({ - header: 'Response.clone', - message: 'Body has already been consumed.' - }) + // 8. If actualResponse’s status is a redirect status, then: + if (redirectStatusSet.has(actualResponse.status)) { + // 1. If actualResponse’s status is not 303, request’s body is not null, + // and the connection uses HTTP/2, then user agents may, and are even + // encouraged to, transmit an RST_STREAM frame. + // See, https://github.com/whatwg/fetch/issues/1288 + if (request.redirect !== 'manual') { + fetchParams.controller.connection.destroy() } - // 2. Let clonedResponse be the result of cloning this’s response. - const clonedResponse = cloneResponse(this[kState]) + // 2. Switch on request’s redirect mode: + if (request.redirect === 'error') { + // Set response to a network error. + response = makeNetworkError('unexpected redirect') + } else if (request.redirect === 'manual') { + // Set response to an opaque-redirect filtered response whose internal + // response is actualResponse. + // NOTE(spec): On the web this would return an `opaqueredirect` response, + // but that doesn't make sense server side. + // See https://github.com/nodejs/undici/issues/1193. + response = actualResponse + } else if (request.redirect === 'follow') { + // Set response to the result of running HTTP-redirect fetch given + // fetchParams and response. + response = await httpRedirectFetch(fetchParams, response) + } else { + assert(false) + } + } - // 3. Return the result of creating a Response object, given - // clonedResponse, this’s headers’s guard, and this’s relevant Realm. - const clonedResponseObject = new Response() - clonedResponseObject[kState] = clonedResponse - clonedResponseObject[kRealm] = this[kRealm] - clonedResponseObject[kHeaders][kHeadersList] = clonedResponse.headersList - clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard] - clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm] + // 9. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo - return clonedResponseObject - } + // 10. Return response. + return response } -mixinBody(Response) - -Object.defineProperties(Response.prototype, { - type: kEnumerableProperty, - url: kEnumerableProperty, - status: kEnumerableProperty, - ok: kEnumerableProperty, - redirected: kEnumerableProperty, - statusText: kEnumerableProperty, - headers: kEnumerableProperty, - clone: kEnumerableProperty, - body: kEnumerableProperty, - bodyUsed: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'Response', - configurable: true - } -}) +// https://fetch.spec.whatwg.org/#http-redirect-fetch +function httpRedirectFetch (fetchParams, response) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request -Object.defineProperties(Response, { - json: kEnumerableProperty, - redirect: kEnumerableProperty, - error: kEnumerableProperty -}) + // 2. Let actualResponse be response, if response is not a filtered response, + // and response’s internal response otherwise. + const actualResponse = response.internalResponse + ? response.internalResponse + : response -// https://fetch.spec.whatwg.org/#concept-response-clone -function cloneResponse (response) { - // To clone a response response, run these steps: + // 3. Let locationURL be actualResponse’s location URL given request’s current + // URL’s fragment. + let locationURL - // 1. If response is a filtered response, then return a new identical - // filtered response whose internal response is a clone of response’s - // internal response. - if (response.internalResponse) { - return filterResponse( - cloneResponse(response.internalResponse), - response.type + try { + locationURL = responseLocationURL( + actualResponse, + requestCurrentURL(request).hash ) + + // 4. If locationURL is null, then return response. + if (locationURL == null) { + return response + } + } catch (err) { + // 5. If locationURL is failure, then return a network error. + return Promise.resolve(makeNetworkError(err)) } - // 2. Let newResponse be a copy of response, except for its body. - const newResponse = makeResponse({ ...response, body: null }) + // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network + // error. + if (!urlIsHttpHttpsScheme(locationURL)) { + return Promise.resolve(makeNetworkError('URL scheme must be a HTTP(S) scheme')) + } - // 3. If response’s body is non-null, then set newResponse’s body to the - // result of cloning response’s body. - if (response.body != null) { - newResponse.body = cloneBody(response.body) + // 7. If request’s redirect count is 20, then return a network error. + if (request.redirectCount === 20) { + return Promise.resolve(makeNetworkError('redirect count exceeded')) } - // 4. Return newResponse. - return newResponse -} + // 8. Increase request’s redirect count by 1. + request.redirectCount += 1 -function makeResponse (init) { - return { - aborted: false, - rangeRequested: false, - timingAllowPassed: false, - requestIncludesCredentials: false, - type: 'default', - status: 200, - timingInfo: null, - cacheState: '', - statusText: '', - ...init, - headersList: init.headersList - ? new HeadersList(init.headersList) - : new HeadersList(), - urlList: init.urlList ? [...init.urlList] : [] + // 9. If request’s mode is "cors", locationURL includes credentials, and + // request’s origin is not same origin with locationURL’s origin, then return + // a network error. + if ( + request.mode === 'cors' && + (locationURL.username || locationURL.password) && + !sameOrigin(request, locationURL) + ) { + return Promise.resolve(makeNetworkError('cross origin not allowed for request mode "cors"')) } -} -function makeNetworkError (reason) { - const isError = isErrorLike(reason) - return makeResponse({ - type: 'error', - status: 0, - error: isError - ? reason - : new Error(reason ? String(reason) : reason), - aborted: reason && reason.name === 'AbortError' - }) -} + // 10. If request’s response tainting is "cors" and locationURL includes + // credentials, then return a network error. + if ( + request.responseTainting === 'cors' && + (locationURL.username || locationURL.password) + ) { + return Promise.resolve(makeNetworkError( + 'URL cannot contain credentials for request mode "cors"' + )) + } -function makeFilteredResponse (response, state) { - state = { - internalResponse: response, - ...state + // 11. If actualResponse’s status is not 303, request’s body is non-null, + // and request’s body’s source is null, then return a network error. + if ( + actualResponse.status !== 303 && + request.body != null && + request.body.source == null + ) { + return Promise.resolve(makeNetworkError()) } - return new Proxy(response, { - get (target, p) { - return p in state ? state[p] : target[p] - }, - set (target, p, value) { - assert(!(p in state)) - target[p] = value - return true + // 12. If one of the following is true + // - actualResponse’s status is 301 or 302 and request’s method is `POST` + // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD` + if ( + ([301, 302].includes(actualResponse.status) && request.method === 'POST') || + (actualResponse.status === 303 && + !GET_OR_HEAD.includes(request.method)) + ) { + // then: + // 1. Set request’s method to `GET` and request’s body to null. + request.method = 'GET' + request.body = null + + // 2. For each headerName of request-body-header name, delete headerName from + // request’s header list. + for (const headerName of requestBodyHeader) { + request.headersList.delete(headerName) } - }) -} + } -// https://fetch.spec.whatwg.org/#concept-filtered-response -function filterResponse (response, type) { - // Set response to the following filtered response with response as its - // internal response, depending on request’s response tainting: - if (type === 'basic') { - // A basic filtered response is a filtered response whose type is "basic" - // and header list excludes any headers in internal response’s header list - // whose name is a forbidden response-header name. + // 13. If request’s current URL’s origin is not same origin with locationURL’s + // origin, then for each headerName of CORS non-wildcard request-header name, + // delete headerName from request’s header list. + if (!sameOrigin(requestCurrentURL(request), locationURL)) { + // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name + request.headersList.delete('authorization') - // Note: undici does not implement forbidden response-header names - return makeFilteredResponse(response, { - type: 'basic', - headersList: response.headersList - }) - } else if (type === 'cors') { - // A CORS filtered response is a filtered response whose type is "cors" - // and header list excludes any headers in internal response’s header - // list whose name is not a CORS-safelisted response-header name, given - // internal response’s CORS-exposed header-name list. + // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. + request.headersList.delete('cookie') + request.headersList.delete('host') + } - // Note: undici does not implement CORS-safelisted response-header names - return makeFilteredResponse(response, { - type: 'cors', - headersList: response.headersList - }) - } else if (type === 'opaque') { - // An opaque filtered response is a filtered response whose type is - // "opaque", URL list is the empty list, status is 0, status message - // is the empty byte sequence, header list is empty, and body is null. + // 14. If request’s body is non-null, then set request’s body to the first return + // value of safely extracting request’s body’s source. + if (request.body != null) { + assert(request.body.source != null) + request.body = safelyExtractBody(request.body.source)[0] + } - return makeFilteredResponse(response, { - type: 'opaque', - urlList: Object.freeze([]), - status: 0, - statusText: '', - body: null - }) - } else if (type === 'opaqueredirect') { - // An opaque-redirect filtered response is a filtered response whose type - // is "opaqueredirect", status is 0, status message is the empty byte - // sequence, header list is empty, and body is null. + // 15. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo - return makeFilteredResponse(response, { - type: 'opaqueredirect', - status: 0, - statusText: '', - headersList: [], - body: null - }) - } else { - assert(false) + // 16. Set timingInfo’s redirect end time and post-redirect start time to the + // coarsened shared current time given fetchParams’s cross-origin isolated + // capability. + timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = + coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) + + // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s + // redirect start time to timingInfo’s start time. + if (timingInfo.redirectStartTime === 0) { + timingInfo.redirectStartTime = timingInfo.startTime } -} -// https://fetch.spec.whatwg.org/#appropriate-network-error -function makeAppropriateNetworkError (fetchParams, err = null) { - // 1. Assert: fetchParams is canceled. - assert(isCancelled(fetchParams)) + // 18. Append locationURL to request’s URL list. + request.urlList.push(locationURL) - // 2. Return an aborted network error if fetchParams is aborted; - // otherwise return a network error. - return isAborted(fetchParams) - ? makeNetworkError(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err })) - : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err })) + // 19. Invoke set request’s referrer policy on redirect on request and + // actualResponse. + setRequestReferrerPolicyOnRedirect(request, actualResponse) + + // 20. Return the result of running main fetch given fetchParams and true. + return mainFetch(fetchParams, true) } -// https://whatpr.org/fetch/1392.html#initialize-a-response -function initializeResponse (response, init, body) { - // 1. If init["status"] is not in the range 200 to 599, inclusive, then - // throw a RangeError. - if (init.status !== null && (init.status < 200 || init.status > 599)) { - throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.') - } +// https://fetch.spec.whatwg.org/#http-network-or-cache-fetch +async function httpNetworkOrCacheFetch ( + fetchParams, + isAuthenticationFetch = false, + isNewConnectionFetch = false +) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request - // 2. If init["statusText"] does not match the reason-phrase token production, - // then throw a TypeError. - if ('statusText' in init && init.statusText != null) { - // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2: - // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) - if (!isValidReasonPhrase(String(init.statusText))) { - throw new TypeError('Invalid statusText') - } - } + // 2. Let httpFetchParams be null. + let httpFetchParams = null - // 3. Set response’s response’s status to init["status"]. - if ('status' in init && init.status != null) { - response[kState].status = init.status - } + // 3. Let httpRequest be null. + let httpRequest = null - // 4. Set response’s response’s status message to init["statusText"]. - if ('statusText' in init && init.statusText != null) { - response[kState].statusText = init.statusText - } + // 4. Let response be null. + let response = null - // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. - if ('headers' in init && init.headers != null) { - fill(response[kHeaders], init.headers) - } + // 5. Let storedResponse be null. + // TODO: cache - // 6. If body was given, then: - if (body) { - // 1. If response's status is a null body status, then throw a TypeError. - if (nullBodyStatus.includes(response.status)) { - throw webidl.errors.exception({ - header: 'Response constructor', - message: 'Invalid response status code ' + response.status - }) - } + // 6. Let httpCache be null. + const httpCache = null - // 2. Set response's body to body's body. - response[kState].body = body.body + // 7. Let the revalidatingFlag be unset. + const revalidatingFlag = false - // 3. If body's type is non-null and response's header list does not contain - // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. - if (body.type != null && !response[kState].headersList.contains('Content-Type')) { - response[kState].headersList.append('content-type', body.type) - } + // 8. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. If request’s window is "no-window" and request’s redirect mode is + // "error", then set httpFetchParams to fetchParams and httpRequest to + // request. + if (request.window === 'no-window' && request.redirect === 'error') { + httpFetchParams = fetchParams + httpRequest = request + } else { + // Otherwise: + + // 1. Set httpRequest to a clone of request. + httpRequest = makeRequest(request) + + // 2. Set httpFetchParams to a copy of fetchParams. + httpFetchParams = { ...fetchParams } + + // 3. Set httpFetchParams’s request to httpRequest. + httpFetchParams.request = httpRequest } -} -webidl.converters.ReadableStream = webidl.interfaceConverter( - ReadableStream -) + // 3. Let includeCredentials be true if one of + const includeCredentials = + request.credentials === 'include' || + (request.credentials === 'same-origin' && + request.responseTainting === 'basic') -webidl.converters.FormData = webidl.interfaceConverter( - FormData -) + // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s + // body is non-null; otherwise null. + const contentLength = httpRequest.body ? httpRequest.body.length : null -webidl.converters.URLSearchParams = webidl.interfaceConverter( - URLSearchParams -) + // 5. Let contentLengthHeaderValue be null. + let contentLengthHeaderValue = null -// https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit -webidl.converters.XMLHttpRequestBodyInit = function (V) { - if (typeof V === 'string') { - return webidl.converters.USVString(V) + // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or + // `PUT`, then set contentLengthHeaderValue to `0`. + if ( + httpRequest.body == null && + ['POST', 'PUT'].includes(httpRequest.method) + ) { + contentLengthHeaderValue = '0' } - if (isBlobLike(V)) { - return webidl.converters.Blob(V, { strict: false }) + // 7. If contentLength is non-null, then set contentLengthHeaderValue to + // contentLength, serialized and isomorphic encoded. + if (contentLength != null) { + contentLengthHeaderValue = isomorphicEncode(`${contentLength}`) } - if (types.isArrayBuffer(V) || types.isTypedArray(V) || types.isDataView(V)) { - return webidl.converters.BufferSource(V) + // 8. If contentLengthHeaderValue is non-null, then append + // `Content-Length`/contentLengthHeaderValue to httpRequest’s header + // list. + if (contentLengthHeaderValue != null) { + httpRequest.headersList.append('content-length', contentLengthHeaderValue) } - if (util.isFormDataLike(V)) { - return webidl.converters.FormData(V, { strict: false }) + // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, + // contentLengthHeaderValue) to httpRequest’s header list. + + // 10. If contentLength is non-null and httpRequest’s keepalive is true, + // then: + if (contentLength != null && httpRequest.keepalive) { + // NOTE: keepalive is a noop outside of browser context. } - if (V instanceof URLSearchParams) { - return webidl.converters.URLSearchParams(V) + // 11. If httpRequest’s referrer is a URL, then append + // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, + // to httpRequest’s header list. + if (httpRequest.referrer instanceof URL) { + httpRequest.headersList.append('referer', isomorphicEncode(httpRequest.referrer.href)) } - return webidl.converters.DOMString(V) -} + // 12. Append a request `Origin` header for httpRequest. + appendRequestOriginHeader(httpRequest) -// https://fetch.spec.whatwg.org/#bodyinit -webidl.converters.BodyInit = function (V) { - if (V instanceof ReadableStream) { - return webidl.converters.ReadableStream(V) + // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA] + appendFetchMetadata(httpRequest) + + // 14. If httpRequest’s header list does not contain `User-Agent`, then + // user agents should append `User-Agent`/default `User-Agent` value to + // httpRequest’s header list. + if (!httpRequest.headersList.contains('user-agent')) { + httpRequest.headersList.append('user-agent', typeof esbuildDetection === 'undefined' ? 'undici' : 'node') } - // Note: the spec doesn't include async iterables, - // this is an undici extension. - if (V?.[Symbol.asyncIterator]) { - return V + // 15. If httpRequest’s cache mode is "default" and httpRequest’s header + // list contains `If-Modified-Since`, `If-None-Match`, + // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set + // httpRequest’s cache mode to "no-store". + if ( + httpRequest.cache === 'default' && + (httpRequest.headersList.contains('if-modified-since') || + httpRequest.headersList.contains('if-none-match') || + httpRequest.headersList.contains('if-unmodified-since') || + httpRequest.headersList.contains('if-match') || + httpRequest.headersList.contains('if-range')) + ) { + httpRequest.cache = 'no-store' } - return webidl.converters.XMLHttpRequestBodyInit(V) -} + // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent + // no-cache cache-control header modification flag is unset, and + // httpRequest’s header list does not contain `Cache-Control`, then append + // `Cache-Control`/`max-age=0` to httpRequest’s header list. + if ( + httpRequest.cache === 'no-cache' && + !httpRequest.preventNoCacheCacheControlHeaderModification && + !httpRequest.headersList.contains('cache-control') + ) { + httpRequest.headersList.append('cache-control', 'max-age=0') + } -webidl.converters.ResponseInit = webidl.dictionaryConverter([ - { - key: 'status', - converter: webidl.converters['unsigned short'], - defaultValue: 200 - }, - { - key: 'statusText', - converter: webidl.converters.ByteString, - defaultValue: '' - }, - { - key: 'headers', - converter: webidl.converters.HeadersInit + // 17. If httpRequest’s cache mode is "no-store" or "reload", then: + if (httpRequest.cache === 'no-store' || httpRequest.cache === 'reload') { + // 1. If httpRequest’s header list does not contain `Pragma`, then append + // `Pragma`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('pragma')) { + httpRequest.headersList.append('pragma', 'no-cache') + } + + // 2. If httpRequest’s header list does not contain `Cache-Control`, + // then append `Cache-Control`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('cache-control')) { + httpRequest.headersList.append('cache-control', 'no-cache') + } } -]) -module.exports = { - makeNetworkError, - makeResponse, - makeAppropriateNetworkError, - filterResponse, - Response, - cloneResponse -} + // 18. If httpRequest’s header list contains `Range`, then append + // `Accept-Encoding`/`identity` to httpRequest’s header list. + if (httpRequest.headersList.contains('range')) { + httpRequest.headersList.append('accept-encoding', 'identity') + } + // 19. Modify httpRequest’s header list per HTTP. Do not append a given + // header if httpRequest’s header list contains that header’s name. + // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 + if (!httpRequest.headersList.contains('accept-encoding')) { + if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { + httpRequest.headersList.append('accept-encoding', 'br, gzip, deflate') + } else { + httpRequest.headersList.append('accept-encoding', 'gzip, deflate') + } + } -/***/ }), + httpRequest.headersList.delete('host') -/***/ 5861: -/***/ ((module) => { + // 20. If includeCredentials is true, then: + if (includeCredentials) { + // 1. If the user agent is not configured to block cookies for httpRequest + // (see section 7 of [COOKIES]), then: + // TODO: credentials + // 2. If httpRequest’s header list does not contain `Authorization`, then: + // TODO: credentials + } -"use strict"; + // 21. If there’s a proxy-authentication entry, use it as appropriate. + // TODO: proxy-authentication + // 22. Set httpCache to the result of determining the HTTP cache + // partition, given httpRequest. + // TODO: cache -module.exports = { - kUrl: Symbol('url'), - kHeaders: Symbol('headers'), - kSignal: Symbol('signal'), - kState: Symbol('state'), - kGuard: Symbol('guard'), - kRealm: Symbol('realm') -} - + // 23. If httpCache is null, then set httpRequest’s cache mode to + // "no-store". + if (httpCache == null) { + httpRequest.cache = 'no-store' + } -/***/ }), + // 24. If httpRequest’s cache mode is neither "no-store" nor "reload", + // then: + if (httpRequest.mode !== 'no-store' && httpRequest.mode !== 'reload') { + // TODO: cache + } -/***/ 2538: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 9. If aborted, then return the appropriate network error for fetchParams. + // TODO -"use strict"; + // 10. If response is null, then: + if (response == null) { + // 1. If httpRequest’s cache mode is "only-if-cached", then return a + // network error. + if (httpRequest.mode === 'only-if-cached') { + return makeNetworkError('only if cached') + } + // 2. Let forwardResponse be the result of running HTTP-network fetch + // given httpFetchParams, includeCredentials, and isNewConnectionFetch. + const forwardResponse = await httpNetworkFetch( + httpFetchParams, + includeCredentials, + isNewConnectionFetch + ) -const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = __nccwpck_require__(1037) -const { getGlobalOrigin } = __nccwpck_require__(1246) -const { performance } = __nccwpck_require__(4074) -const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983) -const assert = __nccwpck_require__(9491) -const { isUint8Array } = __nccwpck_require__(9830) + // 3. If httpRequest’s method is unsafe and forwardResponse’s status is + // in the range 200 to 399, inclusive, invalidate appropriate stored + // responses in httpCache, as per the "Invalidation" chapter of HTTP + // Caching, and set storedResponse to null. [HTTP-CACHING] + if ( + !safeMethodsSet.has(httpRequest.method) && + forwardResponse.status >= 200 && + forwardResponse.status <= 399 + ) { + // TODO: cache + } -// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable -/** @type {import('crypto')|undefined} */ -let crypto + // 4. If the revalidatingFlag is set and forwardResponse’s status is 304, + // then: + if (revalidatingFlag && forwardResponse.status === 304) { + // TODO: cache + } -try { - crypto = __nccwpck_require__(6113) -} catch { + // 5. If response is null, then: + if (response == null) { + // 1. Set response to forwardResponse. + response = forwardResponse -} + // 2. Store httpRequest and forwardResponse in httpCache, as per the + // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING] + // TODO: cache + } + } -function responseURL (response) { - // https://fetch.spec.whatwg.org/#responses - // A response has an associated URL. It is a pointer to the last URL - // in response’s URL list and null if response’s URL list is empty. - const urlList = response.urlList - const length = urlList.length - return length === 0 ? null : urlList[length - 1].toString() -} + // 11. Set response’s URL list to a clone of httpRequest’s URL list. + response.urlList = [...httpRequest.urlList] -// https://fetch.spec.whatwg.org/#concept-response-location-url -function responseLocationURL (response, requestFragment) { - // 1. If response’s status is not a redirect status, then return null. - if (!redirectStatusSet.has(response.status)) { - return null + // 12. If httpRequest’s header list contains `Range`, then set response’s + // range-requested flag. + if (httpRequest.headersList.contains('range')) { + response.rangeRequested = true } - // 2. Let location be the result of extracting header list values given - // `Location` and response’s header list. - let location = response.headersList.get('location') + // 13. Set response’s request-includes-credentials to includeCredentials. + response.requestIncludesCredentials = includeCredentials - // 3. If location is a header value, then set location to the result of - // parsing location with response’s URL. - if (location !== null && isValidHeaderValue(location)) { - location = new URL(location, responseURL(response)) - } + // 14. If response’s status is 401, httpRequest’s response tainting is not + // "cors", includeCredentials is true, and request’s window is an environment + // settings object, then: + // TODO - // 4. If location is a URL whose fragment is null, then set location’s - // fragment to requestFragment. - if (location && !location.hash) { - location.hash = requestFragment - } + // 15. If response’s status is 407, then: + if (response.status === 407) { + // 1. If request’s window is "no-window", then return a network error. + if (request.window === 'no-window') { + return makeNetworkError() + } - // 5. Return location. - return location -} + // 2. ??? -/** @returns {URL} */ -function requestCurrentURL (request) { - return request.urlList[request.urlList.length - 1] -} + // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) + } -function requestBadPort (request) { - // 1. Let url be request’s current URL. - const url = requestCurrentURL(request) + // 4. Prompt the end user as appropriate in request’s window and store + // the result as a proxy-authentication entry. [HTTP-AUTH] + // TODO: Invoke some kind of callback? - // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, - // then return blocked. - if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { - return 'blocked' + // 5. Set response to the result of running HTTP-network-or-cache fetch given + // fetchParams. + // TODO + return makeNetworkError('proxy authentication required') } - // 3. Return allowed. - return 'allowed' -} - -function isErrorLike (object) { - return object instanceof Error || ( - object?.constructor?.name === 'Error' || - object?.constructor?.name === 'DOMException' - ) -} + // 16. If all of the following are true + if ( + // response’s status is 421 + response.status === 421 && + // isNewConnectionFetch is false + !isNewConnectionFetch && + // request’s body is null, or request’s body is non-null and request’s body’s source is non-null + (request.body == null || request.body.source != null) + ) { + // then: -// Check whether |statusText| is a ByteString and -// matches the Reason-Phrase token production. -// RFC 2616: https://tools.ietf.org/html/rfc2616 -// RFC 7230: https://tools.ietf.org/html/rfc7230 -// "reason-phrase = *( HTAB / SP / VCHAR / obs-text )" -// https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116 -function isValidReasonPhrase (statusText) { - for (let i = 0; i < statusText.length; ++i) { - const c = statusText.charCodeAt(i) - if ( - !( - ( - c === 0x09 || // HTAB - (c >= 0x20 && c <= 0x7e) || // SP / VCHAR - (c >= 0x80 && c <= 0xff) - ) // obs-text - ) - ) { - return false + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) } - } - return true -} -/** - * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 - * @param {number} c - */ -function isTokenCharCode (c) { - switch (c) { - case 0x22: - case 0x28: - case 0x29: - case 0x2c: - case 0x2f: - case 0x3a: - case 0x3b: - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: - case 0x40: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x7b: - case 0x7d: - // DQUOTE and "(),/:;<=>?@[\]{}" - return false - default: - // VCHAR %x21-7E - return c >= 0x21 && c <= 0x7e - } -} + // 2. Set response to the result of running HTTP-network-or-cache + // fetch given fetchParams, isAuthenticationFetch, and true. -/** - * @param {string} characters - */ -function isValidHTTPToken (characters) { - if (characters.length === 0) { - return false + // TODO (spec): The spec doesn't specify this but we need to cancel + // the active response before we can start a new one. + // https://github.com/whatwg/fetch/issues/1293 + fetchParams.controller.connection.destroy() + + response = await httpNetworkOrCacheFetch( + fetchParams, + isAuthenticationFetch, + true + ) } - for (let i = 0; i < characters.length; ++i) { - if (!isTokenCharCode(characters.charCodeAt(i))) { - return false - } + + // 17. If isAuthenticationFetch is true, then create an authentication entry + if (isAuthenticationFetch) { + // TODO } - return true + + // 18. Return response. + return response } -/** - * @see https://fetch.spec.whatwg.org/#header-name - * @param {string} potentialValue - */ -function isValidHeaderName (potentialValue) { - return isValidHTTPToken(potentialValue) -} - -/** - * @see https://fetch.spec.whatwg.org/#header-value - * @param {string} potentialValue - */ -function isValidHeaderValue (potentialValue) { - // - Has no leading or trailing HTTP tab or space bytes. - // - Contains no 0x00 (NUL) or HTTP newline bytes. - if ( - potentialValue.startsWith('\t') || - potentialValue.startsWith(' ') || - potentialValue.endsWith('\t') || - potentialValue.endsWith(' ') - ) { - return false - } +// https://fetch.spec.whatwg.org/#http-network-fetch +async function httpNetworkFetch ( + fetchParams, + includeCredentials = false, + forceNewConnection = false +) { + assert(!fetchParams.controller.connection || fetchParams.controller.connection.destroyed) - if ( - potentialValue.includes('\0') || - potentialValue.includes('\r') || - potentialValue.includes('\n') - ) { - return false + fetchParams.controller.connection = { + abort: null, + destroyed: false, + destroy (err) { + if (!this.destroyed) { + this.destroyed = true + this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')) + } + } } - return true -} - -// https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect -function setRequestReferrerPolicyOnRedirect (request, actualResponse) { - // Given a request request and a response actualResponse, this algorithm - // updates request’s referrer policy according to the Referrer-Policy - // header (if any) in actualResponse. + // 1. Let request be fetchParams’s request. + const request = fetchParams.request - // 1. Let policy be the result of executing § 8.1 Parse a referrer policy - // from a Referrer-Policy header on actualResponse. + // 2. Let response be null. + let response = null - // 8.1 Parse a referrer policy from a Referrer-Policy header - // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list. - const { headersList } = actualResponse - // 2. Let policy be the empty string. - // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. - // 4. Return policy. - const policyHeader = (headersList.get('referrer-policy') ?? '').split(',') + // 3. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo - // Note: As the referrer-policy can contain multiple policies - // separated by comma, we need to loop through all of them - // and pick the first valid one. - // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy - let policy = '' - if (policyHeader.length > 0) { - // The right-most policy takes precedence. - // The left-most policy is the fallback. - for (let i = policyHeader.length; i !== 0; i--) { - const token = policyHeader[i - 1].trim() - if (referrerPolicyTokens.has(token)) { - policy = token - break - } - } - } + // 4. Let httpCache be the result of determining the HTTP cache partition, + // given request. + // TODO: cache + const httpCache = null - // 2. If policy is not the empty string, then set request’s referrer policy to policy. - if (policy !== '') { - request.referrerPolicy = policy + // 5. If httpCache is null, then set request’s cache mode to "no-store". + if (httpCache == null) { + request.cache = 'no-store' } -} - -// https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check -function crossOriginResourcePolicyCheck () { - // TODO - return 'allowed' -} - -// https://fetch.spec.whatwg.org/#concept-cors-check -function corsCheck () { - // TODO - return 'success' -} -// https://fetch.spec.whatwg.org/#concept-tao-check -function TAOCheck () { + // 6. Let networkPartitionKey be the result of determining the network + // partition key given request. // TODO - return 'success' -} -function appendFetchMetadata (httpRequest) { - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header - // TODO + // 7. Let newConnection be "yes" if forceNewConnection is true; otherwise + // "no". + const newConnection = forceNewConnection ? 'yes' : 'no' // eslint-disable-line no-unused-vars - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header + // 8. Switch on request’s mode: + if (request.mode === 'websocket') { + // Let connection be the result of obtaining a WebSocket connection, + // given request’s current URL. + // TODO + } else { + // Let connection be the result of obtaining a connection, given + // networkPartitionKey, request’s current URL’s origin, + // includeCredentials, and forceNewConnection. + // TODO + } - // 1. Assert: r’s url is a potentially trustworthy URL. - // TODO + // 9. Run these steps, but abort when the ongoing fetch is terminated: - // 2. Let header be a Structured Header whose value is a token. - let header = null + // 1. If connection is failure, then return a network error. - // 3. Set header’s value to r’s mode. - header = httpRequest.mode + // 2. Set timingInfo’s final connection timing info to the result of + // calling clamp and coarsen connection timing info with connection’s + // timing info, timingInfo’s post-redirect start time, and fetchParams’s + // cross-origin isolated capability. - // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. - httpRequest.headersList.set('sec-fetch-mode', header) + // 3. If connection is not an HTTP/2 connection, request’s body is non-null, + // and request’s body’s source is null, then append (`Transfer-Encoding`, + // `chunked`) to request’s header list. - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header - // TODO + // 4. Set timingInfo’s final network-request start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated + // capability. - // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header - // TODO -} + // 5. Set response to the result of making an HTTP request over connection + // using request with the following caveats: -// https://fetch.spec.whatwg.org/#append-a-request-origin-header -function appendRequestOriginHeader (request) { - // 1. Let serializedOrigin be the result of byte-serializing a request origin with request. - let serializedOrigin = request.origin + // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] + // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] - // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list. - if (request.responseTainting === 'cors' || request.mode === 'websocket') { - if (serializedOrigin) { - request.headersList.append('origin', serializedOrigin) - } + // - If request’s body is non-null, and request’s body’s source is null, + // then the user agent may have a buffer of up to 64 kibibytes and store + // a part of request’s body in that buffer. If the user agent reads from + // request’s body beyond that buffer’s size and the user agent needs to + // resend request, then instead return a network error. - // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: - } else if (request.method !== 'GET' && request.method !== 'HEAD') { - // 1. Switch on request’s referrer policy: - switch (request.referrerPolicy) { - case 'no-referrer': - // Set serializedOrigin to `null`. - serializedOrigin = null - break - case 'no-referrer-when-downgrade': - case 'strict-origin': - case 'strict-origin-when-cross-origin': - // If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`. - if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { - serializedOrigin = null - } - break - case 'same-origin': - // If request’s origin is not same origin with request’s current URL’s origin, then set serializedOrigin to `null`. - if (!sameOrigin(request, requestCurrentURL(request))) { - serializedOrigin = null - } - break - default: - // Do nothing. - } + // - Set timingInfo’s final network-response start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated capability, + // immediately after the user agent’s HTTP parser receives the first byte + // of the response (e.g., frame header bytes for HTTP/2 or response status + // line for HTTP/1.x). - if (serializedOrigin) { - // 2. Append (`Origin`, serializedOrigin) to request’s header list. - request.headersList.append('origin', serializedOrigin) - } - } -} + // - Wait until all the headers are transmitted. -function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { - // TODO - return performance.now() -} + // - Any responses whose status is in the range 100 to 199, inclusive, + // and is not 101, are to be ignored, except for the purposes of setting + // timingInfo’s final network-response start time above. -// https://fetch.spec.whatwg.org/#create-an-opaque-timing-info -function createOpaqueTimingInfo (timingInfo) { - return { - startTime: timingInfo.startTime ?? 0, - redirectStartTime: 0, - redirectEndTime: 0, - postRedirectStartTime: timingInfo.startTime ?? 0, - finalServiceWorkerStartTime: 0, - finalNetworkResponseStartTime: 0, - finalNetworkRequestStartTime: 0, - endTime: 0, - encodedBodySize: 0, - decodedBodySize: 0, - finalConnectionTimingInfo: null - } -} + // - If request’s header list contains `Transfer-Encoding`/`chunked` and + // response is transferred via HTTP/1.0 or older, then return a network + // error. -// https://html.spec.whatwg.org/multipage/origin.html#policy-container -function makePolicyContainer () { - // Note: the fetch spec doesn't make use of embedder policy or CSP list - return { - referrerPolicy: 'strict-origin-when-cross-origin' - } -} + // - If the HTTP request results in a TLS client certificate dialog, then: -// https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container -function clonePolicyContainer (policyContainer) { - return { - referrerPolicy: policyContainer.referrerPolicy - } -} + // 1. If request’s window is an environment settings object, make the + // dialog available in request’s window. -// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer -function determineRequestsReferrer (request) { - // 1. Let policy be request's referrer policy. - const policy = request.referrerPolicy + // 2. Otherwise, return a network error. - // Note: policy cannot (shouldn't) be null or an empty string. - assert(policy) - - // 2. Let environment be request’s client. - - let referrerSource = null + // To transmit request’s body body, run these steps: + let requestBody = null + // 1. If body is null and fetchParams’s process request end-of-body is + // non-null, then queue a fetch task given fetchParams’s process request + // end-of-body and fetchParams’s task destination. + if (request.body == null && fetchParams.processRequestEndOfBody) { + queueMicrotask(() => fetchParams.processRequestEndOfBody()) + } else if (request.body != null) { + // 2. Otherwise, if body is non-null: - // 3. Switch on request’s referrer: - if (request.referrer === 'client') { - // Note: node isn't a browser and doesn't implement document/iframes, - // so we bypass this step and replace it with our own. + // 1. Let processBodyChunk given bytes be these steps: + const processBodyChunk = async function * (bytes) { + // 1. If the ongoing fetch is terminated, then abort these steps. + if (isCancelled(fetchParams)) { + return + } - const globalOrigin = getGlobalOrigin() + // 2. Run this step in parallel: transmit bytes. + yield bytes - if (!globalOrigin || globalOrigin.origin === 'null') { - return 'no-referrer' + // 3. If fetchParams’s process request body is non-null, then run + // fetchParams’s process request body given bytes’s length. + fetchParams.processRequestBodyChunkLength?.(bytes.byteLength) } - // note: we need to clone it as it's mutated - referrerSource = new URL(globalOrigin) - } else if (request.referrer instanceof URL) { - // Let referrerSource be request’s referrer. - referrerSource = request.referrer - } - - // 4. Let request’s referrerURL be the result of stripping referrerSource for - // use as a referrer. - let referrerURL = stripURLForReferrer(referrerSource) - - // 5. Let referrerOrigin be the result of stripping referrerSource for use as - // a referrer, with the origin-only flag set to true. - const referrerOrigin = stripURLForReferrer(referrerSource, true) - - // 6. If the result of serializing referrerURL is a string whose length is - // greater than 4096, set referrerURL to referrerOrigin. - if (referrerURL.toString().length > 4096) { - referrerURL = referrerOrigin - } - - const areSameOrigin = sameOrigin(request, referrerURL) - const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) && - !isURLPotentiallyTrustworthy(request.url) - - // 8. Execute the switch statements corresponding to the value of policy: - switch (policy) { - case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true) - case 'unsafe-url': return referrerURL - case 'same-origin': - return areSameOrigin ? referrerOrigin : 'no-referrer' - case 'origin-when-cross-origin': - return areSameOrigin ? referrerURL : referrerOrigin - case 'strict-origin-when-cross-origin': { - const currentURL = requestCurrentURL(request) + // 2. Let processEndOfBody be these steps: + const processEndOfBody = () => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return + } - // 1. If the origin of referrerURL and the origin of request’s current - // URL are the same, then return referrerURL. - if (sameOrigin(referrerURL, currentURL)) { - return referrerURL + // 2. If fetchParams’s process request end-of-body is non-null, + // then run fetchParams’s process request end-of-body. + if (fetchParams.processRequestEndOfBody) { + fetchParams.processRequestEndOfBody() } + } - // 2. If referrerURL is a potentially trustworthy URL and request’s - // current URL is not a potentially trustworthy URL, then return no - // referrer. - if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) { - return 'no-referrer' + // 3. Let processBodyError given e be these steps: + const processBodyError = (e) => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return } - // 3. Return referrerOrigin. - return referrerOrigin + // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller. + if (e.name === 'AbortError') { + fetchParams.controller.abort() + } else { + fetchParams.controller.terminate(e) + } } - case 'strict-origin': // eslint-disable-line - /** - * 1. If referrerURL is a potentially trustworthy URL and - * request’s current URL is not a potentially trustworthy URL, - * then return no referrer. - * 2. Return referrerOrigin - */ - case 'no-referrer-when-downgrade': // eslint-disable-line - /** - * 1. If referrerURL is a potentially trustworthy URL and - * request’s current URL is not a potentially trustworthy URL, - * then return no referrer. - * 2. Return referrerOrigin - */ - default: // eslint-disable-line - return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin + // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody, + // processBodyError, and fetchParams’s task destination. + requestBody = (async function * () { + try { + for await (const bytes of request.body.stream) { + yield * processBodyChunk(bytes) + } + processEndOfBody() + } catch (err) { + processBodyError(err) + } + })() } -} -/** - * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url - * @param {URL} url - * @param {boolean|undefined} originOnly - */ -function stripURLForReferrer (url, originOnly) { - // 1. Assert: url is a URL. - assert(url instanceof URL) + try { + // socket is only provided for websockets + const { body, status, statusText, headersList, socket } = await dispatch({ body: requestBody }) - // 2. If url’s scheme is a local scheme, then return no referrer. - if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'blank:') { - return 'no-referrer' - } + if (socket) { + response = makeResponse({ status, statusText, headersList, socket }) + } else { + const iterator = body[Symbol.asyncIterator]() + fetchParams.controller.next = () => iterator.next() - // 3. Set url’s username to the empty string. - url.username = '' + response = makeResponse({ status, statusText, headersList }) + } + } catch (err) { + // 10. If aborted, then: + if (err.name === 'AbortError') { + // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame. + fetchParams.controller.connection.destroy() - // 4. Set url’s password to the empty string. - url.password = '' + // 2. Return the appropriate network error for fetchParams. + return makeAppropriateNetworkError(fetchParams, err) + } - // 5. Set url’s fragment to null. - url.hash = '' + return makeNetworkError(err) + } - // 6. If the origin-only flag is true, then: - if (originOnly) { - // 1. Set url’s path to « the empty string ». - url.pathname = '' + // 11. Let pullAlgorithm be an action that resumes the ongoing fetch + // if it is suspended. + const pullAlgorithm = () => { + fetchParams.controller.resume() + } - // 2. Set url’s query to null. - url.search = '' + // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s + // controller with reason, given reason. + const cancelAlgorithm = (reason) => { + fetchParams.controller.abort(reason) } - // 7. Return url. - return url -} + // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by + // the user agent. + // TODO -function isURLPotentiallyTrustworthy (url) { - if (!(url instanceof URL)) { - return false - } + // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object + // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent. + // TODO - // If child of about, return true - if (url.href === 'about:blank' || url.href === 'about:srcdoc') { - return true + // 15. Let stream be a new ReadableStream. + // 16. Set up stream with pullAlgorithm set to pullAlgorithm, + // cancelAlgorithm set to cancelAlgorithm, highWaterMark set to + // highWaterMark, and sizeAlgorithm set to sizeAlgorithm. + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) } - // If scheme is data, return true - if (url.protocol === 'data:') return true + const stream = new ReadableStream( + { + async start (controller) { + fetchParams.controller.controller = controller + }, + async pull (controller) { + await pullAlgorithm(controller) + }, + async cancel (reason) { + await cancelAlgorithm(reason) + } + }, + { + highWaterMark: 0, + size () { + return 1 + } + } + ) - // If file, return true - if (url.protocol === 'file:') return true + // 17. Run these steps, but abort when the ongoing fetch is terminated: - return isOriginPotentiallyTrustworthy(url.origin) + // 1. Set response’s body to a new body whose stream is stream. + response.body = { stream } - function isOriginPotentiallyTrustworthy (origin) { - // If origin is explicitly null, return false - if (origin == null || origin === 'null') return false + // 2. If response is not a network error and request’s cache mode is + // not "no-store", then update response in httpCache for request. + // TODO - const originAsURL = new URL(origin) + // 3. If includeCredentials is true and the user agent is not configured + // to block cookies for request (see section 7 of [COOKIES]), then run the + // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on + // the value of each header whose name is a byte-case-insensitive match for + // `Set-Cookie` in response’s header list, if any, and request’s current URL. + // TODO - // If secure, return true - if (originAsURL.protocol === 'https:' || originAsURL.protocol === 'wss:') { - return true - } + // 18. If aborted, then: + // TODO - // If localhost or variants, return true - if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) || - (originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) || - (originAsURL.hostname.endsWith('.localhost'))) { - return true - } + // 19. Run these steps in parallel: - // If any other, return false - return false - } -} + // 1. Run these steps, but abort when fetchParams is canceled: + fetchParams.controller.on('terminated', onAborted) + fetchParams.controller.resume = async () => { + // 1. While true + while (true) { + // 1-3. See onData... -/** - * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist - * @param {Uint8Array} bytes - * @param {string} metadataList - */ -function bytesMatch (bytes, metadataList) { - // If node is not built with OpenSSL support, we cannot check - // a request's integrity, so allow it by default (the spec will - // allow requests if an invalid hash is given, as precedence). - /* istanbul ignore if: only if node is built with --without-ssl */ - if (crypto === undefined) { - return true - } + // 4. Set bytes to the result of handling content codings given + // codings and bytes. + let bytes + let isFailure + try { + const { done, value } = await fetchParams.controller.next() - // 1. Let parsedMetadata be the result of parsing metadataList. - const parsedMetadata = parseMetadata(metadataList) + if (isAborted(fetchParams)) { + break + } - // 2. If parsedMetadata is no metadata, return true. - if (parsedMetadata === 'no metadata') { - return true - } + bytes = done ? undefined : value + } catch (err) { + if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { + // zlib doesn't like empty streams. + bytes = undefined + } else { + bytes = err - // 3. If parsedMetadata is the empty set, return true. - if (parsedMetadata.length === 0) { - return true - } + // err may be propagated from the result of calling readablestream.cancel, + // which might not be an error. https://github.com/nodejs/undici/issues/2009 + isFailure = true + } + } - // 4. Let metadata be the result of getting the strongest - // metadata from parsedMetadata. - const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo)) - // get the strongest algorithm - const strongest = list[0].algo - // get all entries that use the strongest algorithm; ignore weaker - const metadata = list.filter((item) => item.algo === strongest) + if (bytes === undefined) { + // 2. Otherwise, if the bytes transmission for response’s message + // body is done normally and stream is readable, then close + // stream, finalize response for fetchParams and response, and + // abort these in-parallel steps. + readableStreamClose(fetchParams.controller.controller) - // 5. For each item in metadata: - for (const item of metadata) { - // 1. Let algorithm be the alg component of item. - const algorithm = item.algo + finalizeResponse(fetchParams, response) - // 2. Let expectedValue be the val component of item. - let expectedValue = item.hash + return + } - // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e - // "be liberal with padding". This is annoying, and it's not even in the spec. + // 5. Increase timingInfo’s decoded body size by bytes’s length. + timingInfo.decodedBodySize += bytes?.byteLength ?? 0 - if (expectedValue.endsWith('==')) { - expectedValue = expectedValue.slice(0, -2) - } + // 6. If bytes is failure, then terminate fetchParams’s controller. + if (isFailure) { + fetchParams.controller.terminate(bytes) + return + } - // 3. Let actualValue be the result of applying algorithm to bytes. - let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64') + // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes + // into stream. + fetchParams.controller.controller.enqueue(new Uint8Array(bytes)) - if (actualValue.endsWith('==')) { - actualValue = actualValue.slice(0, -2) - } + // 8. If stream is errored, then terminate the ongoing fetch. + if (isErrored(stream)) { + fetchParams.controller.terminate() + return + } - // 4. If actualValue is a case-sensitive match for expectedValue, - // return true. - if (actualValue === expectedValue) { - return true + // 9. If stream doesn’t need more data ask the user agent to suspend + // the ongoing fetch. + if (!fetchParams.controller.controller.desiredSize) { + return + } } + } - let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url') + // 2. If aborted, then: + function onAborted (reason) { + // 2. If fetchParams is aborted, then: + if (isAborted(fetchParams)) { + // 1. Set response’s aborted flag. + response.aborted = true - if (actualBase64URL.endsWith('==')) { - actualBase64URL = actualBase64URL.slice(0, -2) + // 2. If stream is readable, then error stream with the result of + // deserialize a serialized abort reason given fetchParams’s + // controller’s serialized abort reason and an + // implementation-defined realm. + if (isReadable(stream)) { + fetchParams.controller.controller.error( + fetchParams.controller.serializedAbortReason + ) + } + } else { + // 3. Otherwise, if stream is readable, error stream with a TypeError. + if (isReadable(stream)) { + fetchParams.controller.controller.error(new TypeError('terminated', { + cause: isErrorLike(reason) ? reason : undefined + })) + } } - if (actualBase64URL === expectedValue) { - return true - } + // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame. + // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so. + fetchParams.controller.connection.destroy() } - // 6. Return false. - return false -} + // 20. Return response. + return response -// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options -// https://www.w3.org/TR/CSP2/#source-list-syntax -// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 -const parseHashWithOptions = /((?sha256|sha384|sha512)-(?[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i + async function dispatch ({ body }) { + const url = requestCurrentURL(request) + /** @type {import('../..').Agent} */ + const agent = fetchParams.controller.dispatcher -/** - * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata - * @param {string} metadata - */ -function parseMetadata (metadata) { - // 1. Let result be the empty set. - /** @type {{ algo: string, hash: string }[]} */ - const result = [] + return new Promise((resolve, reject) => agent.dispatch( + { + path: url.pathname + url.search, + origin: url.origin, + method: request.method, + body: fetchParams.controller.dispatcher.isMockActive ? request.body && (request.body.source || request.body.stream) : body, + headers: request.headersList.entries, + maxRedirections: 0, + upgrade: request.mode === 'websocket' ? 'websocket' : undefined + }, + { + body: null, + abort: null, - // 2. Let empty be equal to true. - let empty = true + onConnect (abort) { + // TODO (fix): Do we need connection here? + const { connection } = fetchParams.controller - const supportedHashes = crypto.getHashes() + if (connection.destroyed) { + abort(new DOMException('The operation was aborted.', 'AbortError')) + } else { + fetchParams.controller.on('terminated', abort) + this.abort = connection.abort = abort + } + }, - // 3. For each token returned by splitting metadata on spaces: - for (const token of metadata.split(' ')) { - // 1. Set empty to false. - empty = false + onHeaders (status, headersList, resume, statusText) { + if (status < 200) { + return + } - // 2. Parse token as a hash-with-options. - const parsedToken = parseHashWithOptions.exec(token) + let codings = [] + let location = '' - // 3. If token does not parse, continue to the next token. - if (parsedToken === null || parsedToken.groups === undefined) { - // Note: Chromium blocks the request at this point, but Firefox - // gives a warning that an invalid integrity was given. The - // correct behavior is to ignore these, and subsequently not - // check the integrity of the resource. - continue - } + const headers = new Headers() - // 4. Let algorithm be the hash-algo component of token. - const algorithm = parsedToken.groups.algo + // For H2, the headers are a plain JS object + // We distinguish between them and iterate accordingly + if (Array.isArray(headersList)) { + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val.toLowerCase().split(',').map((x) => x.trim()) + } else if (key.toLowerCase() === 'location') { + location = val + } - // 5. If algorithm is a hash function recognized by the user - // agent, add the parsed token to result. - if (supportedHashes.includes(algorithm.toLowerCase())) { - result.push(parsedToken.groups) - } - } + headers[kHeadersList].append(key, val) + } + } else { + const keys = Object.keys(headersList) + for (const key of keys) { + const val = headersList[key] + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val.toLowerCase().split(',').map((x) => x.trim()).reverse() + } else if (key.toLowerCase() === 'location') { + location = val + } - // 4. Return no metadata if empty is true, otherwise return result. - if (empty === true) { - return 'no metadata' - } + headers[kHeadersList].append(key, val) + } + } - return result -} + this.body = new Readable({ read: resume }) -// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request -function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) { - // TODO -} + const decoders = [] -/** - * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin} - * @param {URL} A - * @param {URL} B - */ -function sameOrigin (A, B) { - // 1. If A and B are the same opaque origin, then return true. - if (A.origin === B.origin && A.origin === 'null') { - return true - } + const willFollow = request.redirect === 'follow' && + location && + redirectStatusSet.has(status) - // 2. If A and B are both tuple origins and their schemes, - // hosts, and port are identical, then return true. - if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) { - return true - } + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + if (request.method !== 'HEAD' && request.method !== 'CONNECT' && !nullBodyStatus.includes(status) && !willFollow) { + for (const coding of codings) { + // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 + if (coding === 'x-gzip' || coding === 'gzip') { + decoders.push(zlib.createGunzip({ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH + })) + } else if (coding === 'deflate') { + decoders.push(zlib.createInflate()) + } else if (coding === 'br') { + decoders.push(zlib.createBrotliDecompress()) + } else { + decoders.length = 0 + break + } + } + } - // 3. Return false. - return false -} + resolve({ + status, + statusText, + headersList: headers[kHeadersList], + body: decoders.length + ? pipeline(this.body, ...decoders, () => { }) + : this.body.on('error', () => {}) + }) -function createDeferredPromise () { - let res - let rej - const promise = new Promise((resolve, reject) => { - res = resolve - rej = reject - }) + return true + }, - return { promise, resolve: res, reject: rej } -} + onData (chunk) { + if (fetchParams.controller.dump) { + return + } -function isAborted (fetchParams) { - return fetchParams.controller.state === 'aborted' -} + // 1. If one or more bytes have been transmitted from response’s + // message body, then: -function isCancelled (fetchParams) { - return fetchParams.controller.state === 'aborted' || - fetchParams.controller.state === 'terminated' -} + // 1. Let bytes be the transmitted bytes. + const bytes = chunk -const normalizeMethodRecord = { - delete: 'DELETE', - DELETE: 'DELETE', - get: 'GET', - GET: 'GET', - head: 'HEAD', - HEAD: 'HEAD', - options: 'OPTIONS', - OPTIONS: 'OPTIONS', - post: 'POST', - POST: 'POST', - put: 'PUT', - PUT: 'PUT' -} + // 2. Let codings be the result of extracting header list values + // given `Content-Encoding` and response’s header list. + // See pullAlgorithm. -// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. -Object.setPrototypeOf(normalizeMethodRecord, null) + // 3. Increase timingInfo’s encoded body size by bytes’s length. + timingInfo.encodedBodySize += bytes.byteLength -/** - * @see https://fetch.spec.whatwg.org/#concept-method-normalize - * @param {string} method - */ -function normalizeMethod (method) { - return normalizeMethodRecord[method.toLowerCase()] ?? method -} + // 4. See pullAlgorithm... -// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string -function serializeJavascriptValueToJSONString (value) { - // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »). - const result = JSON.stringify(value) + return this.body.push(bytes) + }, - // 2. If result is undefined, then throw a TypeError. - if (result === undefined) { - throw new TypeError('Value is not JSON serializable') - } + onComplete () { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort) + } - // 3. Assert: result is a string. - assert(typeof result === 'string') + fetchParams.controller.ended = true - // 4. Return result. - return result -} + this.body.push(null) + }, -// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object -const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())) + onError (error) { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort) + } -/** - * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object - * @param {() => unknown[]} iterator - * @param {string} name name of the instance - * @param {'key'|'value'|'key+value'} kind - */ -function makeIterator (iterator, name, kind) { - const object = { - index: 0, - kind, - target: iterator - } + this.body?.destroy(error) - const i = { - next () { - // 1. Let interface be the interface for which the iterator prototype object exists. + fetchParams.controller.terminate(error) - // 2. Let thisValue be the this value. + reject(error) + }, - // 3. Let object be ? ToObject(thisValue). + onUpgrade (status, headersList, socket) { + if (status !== 101) { + return + } - // 4. If object is a platform object, then perform a security - // check, passing: + const headers = new Headers() - // 5. If object is not a default iterator object for interface, - // then throw a TypeError. - if (Object.getPrototypeOf(this) !== i) { - throw new TypeError( - `'next' called on an object that does not implement interface ${name} Iterator.` - ) - } + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') - // 6. Let index be object’s index. - // 7. Let kind be object’s kind. - // 8. Let values be object’s target's value pairs to iterate over. - const { index, kind, target } = object - const values = target() + headers[kHeadersList].append(key, val) + } - // 9. Let len be the length of values. - const len = values.length + resolve({ + status, + statusText: STATUS_CODES[status], + headersList: headers[kHeadersList], + socket + }) - // 10. If index is greater than or equal to len, then return - // CreateIterResultObject(undefined, true). - if (index >= len) { - return { value: undefined, done: true } + return true + } } + )) + } +} - // 11. Let pair be the entry in values at index index. - const pair = values[index] +module.exports = { + fetch, + Fetch, + fetching, + finalizeAndReportTiming +} - // 12. Set object’s index to index + 1. - object.index = index + 1 - // 13. Return the iterator result for pair and kind. - return iteratorResult(pair, kind) - }, - // The class string of an iterator prototype object for a given interface is the - // result of concatenating the identifier of the interface and the string " Iterator". - [Symbol.toStringTag]: `${name} Iterator` - } +/***/ }), - // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%. - Object.setPrototypeOf(i, esIteratorPrototype) - // esIteratorPrototype needs to be the prototype of i - // which is the prototype of an empty object. Yes, it's confusing. - return Object.setPrototypeOf({}, i) -} +/***/ 8359: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -// https://webidl.spec.whatwg.org/#iterator-result -function iteratorResult (pair, kind) { - let result +"use strict"; +/* globals AbortController */ - // 1. Let result be a value determined by the value of kind: - switch (kind) { - case 'key': { - // 1. Let idlKey be pair’s key. - // 2. Let key be the result of converting idlKey to an - // ECMAScript value. - // 3. result is key. - result = pair[0] - break - } - case 'value': { - // 1. Let idlValue be pair’s value. - // 2. Let value be the result of converting idlValue to - // an ECMAScript value. - // 3. result is value. - result = pair[1] - break - } - case 'key+value': { - // 1. Let idlKey be pair’s key. - // 2. Let idlValue be pair’s value. - // 3. Let key be the result of converting idlKey to an - // ECMAScript value. - // 4. Let value be the result of converting idlValue to - // an ECMAScript value. - // 5. Let array be ! ArrayCreate(2). - // 6. Call ! CreateDataProperty(array, "0", key). - // 7. Call ! CreateDataProperty(array, "1", value). - // 8. result is array. - result = pair - break - } - } - // 2. Return CreateIterResultObject(result, false). - return { value: result, done: false } -} - -/** - * @see https://fetch.spec.whatwg.org/#body-fully-read - */ -async function fullyReadBody (body, processBody, processBodyError) { - // 1. If taskDestination is null, then set taskDestination to - // the result of starting a new parallel queue. - // 2. Let successSteps given a byte sequence bytes be to queue a - // fetch task to run processBody given bytes, with taskDestination. - const successSteps = processBody +const { extractBody, mixinBody, cloneBody } = __nccwpck_require__(1472) +const { Headers, fill: fillHeaders, HeadersList } = __nccwpck_require__(554) +const { FinalizationRegistry } = __nccwpck_require__(6436)() +const util = __nccwpck_require__(3983) +const { + isValidHTTPToken, + sameOrigin, + normalizeMethod, + makePolicyContainer, + normalizeMethodRecord +} = __nccwpck_require__(2538) +const { + forbiddenMethodsSet, + corsSafeListedMethodsSet, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + requestDuplex +} = __nccwpck_require__(1037) +const { kEnumerableProperty } = util +const { kHeaders, kSignal, kState, kGuard, kRealm } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { URLSerializer } = __nccwpck_require__(685) +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { getMaxListeners, setMaxListeners, getEventListeners, defaultMaxListeners } = __nccwpck_require__(2361) - // 3. Let errorSteps be to queue a fetch task to run processBodyError, - // with taskDestination. - const errorSteps = processBodyError +let TransformStream = globalThis.TransformStream - // 4. Let reader be the result of getting a reader for body’s stream. - // If that threw an exception, then run errorSteps with that - // exception and return. - let reader +const kAbortController = Symbol('abortController') - try { - reader = body.stream.getReader() - } catch (e) { - errorSteps(e) - return - } +const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { + signal.removeEventListener('abort', abort) +}) - // 5. Read all bytes from reader, given successSteps and errorSteps. - try { - const result = await readAllBytes(reader) - successSteps(result) - } catch (e) { - errorSteps(e) - } -} +// https://fetch.spec.whatwg.org/#request-class +class Request { + // https://fetch.spec.whatwg.org/#dom-request + constructor (input, init = {}) { + if (input === kConstruct) { + return + } -/** @type {ReadableStream} */ -let ReadableStream = globalThis.ReadableStream + webidl.argumentLengthCheck(arguments, 1, { header: 'Request constructor' }) -function isReadableStreamLike (stream) { - if (!ReadableStream) { - ReadableStream = (__nccwpck_require__(5356).ReadableStream) - } + input = webidl.converters.RequestInfo(input) + init = webidl.converters.RequestInit(init) - return stream instanceof ReadableStream || ( - stream[Symbol.toStringTag] === 'ReadableStream' && - typeof stream.tee === 'function' - ) -} + // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object + this[kRealm] = { + settingsObject: { + baseUrl: getGlobalOrigin(), + get origin () { + return this.baseUrl?.origin + }, + policyContainer: makePolicyContainer() + } + } -const MAXIMUM_ARGUMENT_LENGTH = 65535 + // 1. Let request be null. + let request = null -/** - * @see https://infra.spec.whatwg.org/#isomorphic-decode - * @param {number[]|Uint8Array} input - */ -function isomorphicDecode (input) { - // 1. To isomorphic decode a byte sequence input, return a string whose code point - // length is equal to input’s length and whose code points have the same values - // as the values of input’s bytes, in the same order. + // 2. Let fallbackMode be null. + let fallbackMode = null - if (input.length < MAXIMUM_ARGUMENT_LENGTH) { - return String.fromCharCode(...input) - } + // 3. Let baseURL be this’s relevant settings object’s API base URL. + const baseUrl = this[kRealm].settingsObject.baseUrl - return input.reduce((previous, current) => previous + String.fromCharCode(current), '') -} + // 4. Let signal be null. + let signal = null -/** - * @param {ReadableStreamController} controller - */ -function readableStreamClose (controller) { - try { - controller.close() - } catch (err) { - // TODO: add comment explaining why this error occurs. - if (!err.message.includes('Controller is already closed')) { - throw err - } - } -} + // 5. If input is a string, then: + if (typeof input === 'string') { + // 1. Let parsedURL be the result of parsing input with baseURL. + // 2. If parsedURL is failure, then throw a TypeError. + let parsedURL + try { + parsedURL = new URL(input, baseUrl) + } catch (err) { + throw new TypeError('Failed to parse URL from ' + input, { cause: err }) + } -/** - * @see https://infra.spec.whatwg.org/#isomorphic-encode - * @param {string} input - */ -function isomorphicEncode (input) { - // 1. Assert: input contains no code points greater than U+00FF. - for (let i = 0; i < input.length; i++) { - assert(input.charCodeAt(i) <= 0xFF) - } + // 3. If parsedURL includes credentials, then throw a TypeError. + if (parsedURL.username || parsedURL.password) { + throw new TypeError( + 'Request cannot be constructed from a URL that includes credentials: ' + + input + ) + } - // 2. Return a byte sequence whose length is equal to input’s code - // point length and whose bytes have the same values as the - // values of input’s code points, in the same order - return input -} + // 4. Set request to a new request whose URL is parsedURL. + request = makeRequest({ urlList: [parsedURL] }) -/** - * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes - * @see https://streams.spec.whatwg.org/#read-loop - * @param {ReadableStreamDefaultReader} reader - */ -async function readAllBytes (reader) { - const bytes = [] - let byteLength = 0 + // 5. Set fallbackMode to "cors". + fallbackMode = 'cors' + } else { + // 6. Otherwise: - while (true) { - const { done, value: chunk } = await reader.read() + // 7. Assert: input is a Request object. + assert(input instanceof Request) - if (done) { - // 1. Call successSteps with bytes. - return Buffer.concat(bytes, byteLength) - } + // 8. Set request to input’s request. + request = input[kState] - // 1. If chunk is not a Uint8Array object, call failureSteps - // with a TypeError and abort these steps. - if (!isUint8Array(chunk)) { - throw new TypeError('Received non-Uint8Array chunk') + // 9. Set signal to input’s signal. + signal = input[kSignal] } - // 2. Append the bytes represented by chunk to bytes. - bytes.push(chunk) - byteLength += chunk.length - - // 3. Read-loop given reader, bytes, successSteps, and failureSteps. - } -} - -/** - * @see https://fetch.spec.whatwg.org/#is-local - * @param {URL} url - */ -function urlIsLocal (url) { - assert('protocol' in url) // ensure it's a url object - - const protocol = url.protocol + // 7. Let origin be this’s relevant settings object’s origin. + const origin = this[kRealm].settingsObject.origin - return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:' -} + // 8. Let window be "client". + let window = 'client' -/** - * @param {string|URL} url - */ -function urlHasHttpsScheme (url) { - if (typeof url === 'string') { - return url.startsWith('https:') - } + // 9. If request’s window is an environment settings object and its origin + // is same origin with origin, then set window to request’s window. + if ( + request.window?.constructor?.name === 'EnvironmentSettingsObject' && + sameOrigin(request.window, origin) + ) { + window = request.window + } - return url.protocol === 'https:' -} + // 10. If init["window"] exists and is non-null, then throw a TypeError. + if (init.window != null) { + throw new TypeError(`'window' option '${window}' must be null`) + } -/** - * @see https://fetch.spec.whatwg.org/#http-scheme - * @param {URL} url - */ -function urlIsHttpHttpsScheme (url) { - assert('protocol' in url) // ensure it's a url object + // 11. If init["window"] exists, then set window to "no-window". + if ('window' in init) { + window = 'no-window' + } - const protocol = url.protocol - - return protocol === 'http:' || protocol === 'https:' -} + // 12. Set request to a new request with the following properties: + request = makeRequest({ + // URL request’s URL. + // undici implementation note: this is set as the first item in request's urlList in makeRequest + // method request’s method. + method: request.method, + // header list A copy of request’s header list. + // undici implementation note: headersList is cloned in makeRequest + headersList: request.headersList, + // unsafe-request flag Set. + unsafeRequest: request.unsafeRequest, + // client This’s relevant settings object. + client: this[kRealm].settingsObject, + // window window. + window, + // priority request’s priority. + priority: request.priority, + // origin request’s origin. The propagation of the origin is only significant for navigation requests + // being handled by a service worker. In this scenario a request can have an origin that is different + // from the current client. + origin: request.origin, + // referrer request’s referrer. + referrer: request.referrer, + // referrer policy request’s referrer policy. + referrerPolicy: request.referrerPolicy, + // mode request’s mode. + mode: request.mode, + // credentials mode request’s credentials mode. + credentials: request.credentials, + // cache mode request’s cache mode. + cache: request.cache, + // redirect mode request’s redirect mode. + redirect: request.redirect, + // integrity metadata request’s integrity metadata. + integrity: request.integrity, + // keepalive request’s keepalive. + keepalive: request.keepalive, + // reload-navigation flag request’s reload-navigation flag. + reloadNavigation: request.reloadNavigation, + // history-navigation flag request’s history-navigation flag. + historyNavigation: request.historyNavigation, + // URL list A clone of request’s URL list. + urlList: [...request.urlList] + }) -/** - * Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0. - */ -const hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)) + const initHasKey = Object.keys(init).length !== 0 -module.exports = { - isAborted, - isCancelled, - createDeferredPromise, - ReadableStreamFrom, - toUSVString, - tryUpgradeRequestToAPotentiallyTrustworthyURL, - coarsenedSharedCurrentTime, - determineRequestsReferrer, - makePolicyContainer, - clonePolicyContainer, - appendFetchMetadata, - appendRequestOriginHeader, - TAOCheck, - corsCheck, - crossOriginResourcePolicyCheck, - createOpaqueTimingInfo, - setRequestReferrerPolicyOnRedirect, - isValidHTTPToken, - requestBadPort, - requestCurrentURL, - responseURL, - responseLocationURL, - isBlobLike, - isURLPotentiallyTrustworthy, - isValidReasonPhrase, - sameOrigin, - normalizeMethod, - serializeJavascriptValueToJSONString, - makeIterator, - isValidHeaderName, - isValidHeaderValue, - hasOwn, - isErrorLike, - fullyReadBody, - bytesMatch, - isReadableStreamLike, - readableStreamClose, - isomorphicEncode, - isomorphicDecode, - urlIsLocal, - urlHasHttpsScheme, - urlIsHttpHttpsScheme, - readAllBytes, - normalizeMethodRecord -} + // 13. If init is not empty, then: + if (initHasKey) { + // 1. If request’s mode is "navigate", then set it to "same-origin". + if (request.mode === 'navigate') { + request.mode = 'same-origin' + } + // 2. Unset request’s reload-navigation flag. + request.reloadNavigation = false -/***/ }), + // 3. Unset request’s history-navigation flag. + request.historyNavigation = false -/***/ 1744: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 4. Set request’s origin to "client". + request.origin = 'client' -"use strict"; + // 5. Set request’s referrer to "client" + request.referrer = 'client' + // 6. Set request’s referrer policy to the empty string. + request.referrerPolicy = '' -const { types } = __nccwpck_require__(3837) -const { hasOwn, toUSVString } = __nccwpck_require__(2538) + // 7. Set request’s URL to request’s current URL. + request.url = request.urlList[request.urlList.length - 1] -/** @type {import('../../types/webidl').Webidl} */ -const webidl = {} -webidl.converters = {} -webidl.util = {} -webidl.errors = {} + // 8. Set request’s URL list to « request’s URL ». + request.urlList = [request.url] + } -webidl.errors.exception = function (message) { - return new TypeError(`${message.header}: ${message.message}`) -} + // 14. If init["referrer"] exists, then: + if (init.referrer !== undefined) { + // 1. Let referrer be init["referrer"]. + const referrer = init.referrer -webidl.errors.conversionFailed = function (context) { - const plural = context.types.length === 1 ? '' : ' one of' - const message = - `${context.argument} could not be converted to` + - `${plural}: ${context.types.join(', ')}.` + // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". + if (referrer === '') { + request.referrer = 'no-referrer' + } else { + // 1. Let parsedReferrer be the result of parsing referrer with + // baseURL. + // 2. If parsedReferrer is failure, then throw a TypeError. + let parsedReferrer + try { + parsedReferrer = new URL(referrer, baseUrl) + } catch (err) { + throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }) + } - return webidl.errors.exception({ - header: context.prefix, - message - }) -} + // 3. If one of the following is true + // - parsedReferrer’s scheme is "about" and path is the string "client" + // - parsedReferrer’s origin is not same origin with origin + // then set request’s referrer to "client". + if ( + (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || + (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl)) + ) { + request.referrer = 'client' + } else { + // 4. Otherwise, set request’s referrer to parsedReferrer. + request.referrer = parsedReferrer + } + } + } -webidl.errors.invalidArgument = function (context) { - return webidl.errors.exception({ - header: context.prefix, - message: `"${context.value}" is an invalid ${context.type}.` - }) -} + // 15. If init["referrerPolicy"] exists, then set request’s referrer policy + // to it. + if (init.referrerPolicy !== undefined) { + request.referrerPolicy = init.referrerPolicy + } -// https://webidl.spec.whatwg.org/#implements -webidl.brandCheck = function (V, I, opts = undefined) { - if (opts?.strict !== false && !(V instanceof I)) { - throw new TypeError('Illegal invocation') - } else { - return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag] - } -} + // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. + let mode + if (init.mode !== undefined) { + mode = init.mode + } else { + mode = fallbackMode + } -webidl.argumentLengthCheck = function ({ length }, min, ctx) { - if (length < min) { - throw webidl.errors.exception({ - message: `${min} argument${min !== 1 ? 's' : ''} required, ` + - `but${length ? ' only' : ''} ${length} found.`, - ...ctx - }) - } -} + // 17. If mode is "navigate", then throw a TypeError. + if (mode === 'navigate') { + throw webidl.errors.exception({ + header: 'Request constructor', + message: 'invalid request mode navigate.' + }) + } -webidl.illegalConstructor = function () { - throw webidl.errors.exception({ - header: 'TypeError', - message: 'Illegal constructor' - }) -} + // 18. If mode is non-null, set request’s mode to mode. + if (mode != null) { + request.mode = mode + } -// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values -webidl.util.Type = function (V) { - switch (typeof V) { - case 'undefined': return 'Undefined' - case 'boolean': return 'Boolean' - case 'string': return 'String' - case 'symbol': return 'Symbol' - case 'number': return 'Number' - case 'bigint': return 'BigInt' - case 'function': - case 'object': { - if (V === null) { - return 'Null' - } + // 19. If init["credentials"] exists, then set request’s credentials mode + // to it. + if (init.credentials !== undefined) { + request.credentials = init.credentials + } - return 'Object' + // 18. If init["cache"] exists, then set request’s cache mode to it. + if (init.cache !== undefined) { + request.cache = init.cache } - } -} -// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint -webidl.util.ConvertToInt = function (V, bitLength, signedness, opts = {}) { - let upperBound - let lowerBound - - // 1. If bitLength is 64, then: - if (bitLength === 64) { - // 1. Let upperBound be 2^53 − 1. - upperBound = Math.pow(2, 53) - 1 + // 21. If request’s cache mode is "only-if-cached" and request’s mode is + // not "same-origin", then throw a TypeError. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + throw new TypeError( + "'only-if-cached' can be set only with 'same-origin' mode" + ) + } - // 2. If signedness is "unsigned", then let lowerBound be 0. - if (signedness === 'unsigned') { - lowerBound = 0 - } else { - // 3. Otherwise let lowerBound be −2^53 + 1. - lowerBound = Math.pow(-2, 53) + 1 + // 22. If init["redirect"] exists, then set request’s redirect mode to it. + if (init.redirect !== undefined) { + request.redirect = init.redirect } - } else if (signedness === 'unsigned') { - // 2. Otherwise, if signedness is "unsigned", then: - // 1. Let lowerBound be 0. - lowerBound = 0 + // 23. If init["integrity"] exists, then set request’s integrity metadata to it. + if (init.integrity != null) { + request.integrity = String(init.integrity) + } - // 2. Let upperBound be 2^bitLength − 1. - upperBound = Math.pow(2, bitLength) - 1 - } else { - // 3. Otherwise: + // 24. If init["keepalive"] exists, then set request’s keepalive to it. + if (init.keepalive !== undefined) { + request.keepalive = Boolean(init.keepalive) + } - // 1. Let lowerBound be -2^bitLength − 1. - lowerBound = Math.pow(-2, bitLength) - 1 + // 25. If init["method"] exists, then: + if (init.method !== undefined) { + // 1. Let method be init["method"]. + let method = init.method - // 2. Let upperBound be 2^bitLength − 1 − 1. - upperBound = Math.pow(2, bitLength - 1) - 1 - } + // 2. If method is not a method or method is a forbidden method, then + // throw a TypeError. + if (!isValidHTTPToken(method)) { + throw new TypeError(`'${method}' is not a valid HTTP method.`) + } - // 4. Let x be ? ToNumber(V). - let x = Number(V) + if (forbiddenMethodsSet.has(method.toUpperCase())) { + throw new TypeError(`'${method}' HTTP method is unsupported.`) + } - // 5. If x is −0, then set x to +0. - if (x === 0) { - x = 0 - } + // 3. Normalize method. + method = normalizeMethodRecord[method] ?? normalizeMethod(method) - // 6. If the conversion is to an IDL type associated - // with the [EnforceRange] extended attribute, then: - if (opts.enforceRange === true) { - // 1. If x is NaN, +∞, or −∞, then throw a TypeError. - if ( - Number.isNaN(x) || - x === Number.POSITIVE_INFINITY || - x === Number.NEGATIVE_INFINITY - ) { - throw webidl.errors.exception({ - header: 'Integer conversion', - message: `Could not convert ${V} to an integer.` - }) + // 4. Set request’s method to method. + request.method = method } - // 2. Set x to IntegerPart(x). - x = webidl.util.IntegerPart(x) - - // 3. If x < lowerBound or x > upperBound, then - // throw a TypeError. - if (x < lowerBound || x > upperBound) { - throw webidl.errors.exception({ - header: 'Integer conversion', - message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.` - }) + // 26. If init["signal"] exists, then set signal to it. + if (init.signal !== undefined) { + signal = init.signal } - // 4. Return x. - return x - } + // 27. Set this’s request to request. + this[kState] = request - // 7. If x is not NaN and the conversion is to an IDL - // type associated with the [Clamp] extended - // attribute, then: - if (!Number.isNaN(x) && opts.clamp === true) { - // 1. Set x to min(max(x, lowerBound), upperBound). - x = Math.min(Math.max(x, lowerBound), upperBound) + // 28. Set this’s signal to a new AbortSignal object with this’s relevant + // Realm. + // TODO: could this be simplified with AbortSignal.any + // (https://dom.spec.whatwg.org/#dom-abortsignal-any) + const ac = new AbortController() + this[kSignal] = ac.signal + this[kSignal][kRealm] = this[kRealm] - // 2. Round x to the nearest integer, choosing the - // even integer if it lies halfway between two, - // and choosing +0 rather than −0. - if (Math.floor(x) % 2 === 0) { - x = Math.floor(x) - } else { - x = Math.ceil(x) - } + // 29. If signal is not null, then make this’s signal follow signal. + if (signal != null) { + if ( + !signal || + typeof signal.aborted !== 'boolean' || + typeof signal.addEventListener !== 'function' + ) { + throw new TypeError( + "Failed to construct 'Request': member signal is not of type AbortSignal." + ) + } - // 3. Return x. - return x - } + if (signal.aborted) { + ac.abort(signal.reason) + } else { + // Keep a strong ref to ac while request object + // is alive. This is needed to prevent AbortController + // from being prematurely garbage collected. + // See, https://github.com/nodejs/undici/issues/1926. + this[kAbortController] = ac - // 8. If x is NaN, +0, +∞, or −∞, then return +0. - if ( - Number.isNaN(x) || - (x === 0 && Object.is(0, x)) || - x === Number.POSITIVE_INFINITY || - x === Number.NEGATIVE_INFINITY - ) { - return 0 - } + const acRef = new WeakRef(ac) + const abort = function () { + const ac = acRef.deref() + if (ac !== undefined) { + ac.abort(this.reason) + } + } - // 9. Set x to IntegerPart(x). - x = webidl.util.IntegerPart(x) + // Third-party AbortControllers may not work with these. + // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. + try { + // If the max amount of listeners is equal to the default, increase it + // This is only available in node >= v19.9.0 + if (typeof getMaxListeners === 'function' && getMaxListeners(signal) === defaultMaxListeners) { + setMaxListeners(100, signal) + } else if (getEventListeners(signal, 'abort').length >= defaultMaxListeners) { + setMaxListeners(100, signal) + } + } catch {} - // 10. Set x to x modulo 2^bitLength. - x = x % Math.pow(2, bitLength) + util.addAbortListener(signal, abort) + requestFinalizer.register(ac, { signal, abort }) + } + } - // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, - // then return x − 2^bitLength. - if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { - return x - Math.pow(2, bitLength) - } + // 30. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is request’s header list and guard is + // "request". + this[kHeaders] = new Headers(kConstruct) + this[kHeaders][kHeadersList] = request.headersList + this[kHeaders][kGuard] = 'request' + this[kHeaders][kRealm] = this[kRealm] - // 12. Otherwise, return x. - return x -} + // 31. If this’s request’s mode is "no-cors", then: + if (mode === 'no-cors') { + // 1. If this’s request’s method is not a CORS-safelisted method, + // then throw a TypeError. + if (!corsSafeListedMethodsSet.has(request.method)) { + throw new TypeError( + `'${request.method} is unsupported in no-cors mode.` + ) + } -// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart -webidl.util.IntegerPart = function (n) { - // 1. Let r be floor(abs(n)). - const r = Math.floor(Math.abs(n)) + // 2. Set this’s headers’s guard to "request-no-cors". + this[kHeaders][kGuard] = 'request-no-cors' + } - // 2. If n < 0, then return -1 × r. - if (n < 0) { - return -1 * r - } + // 32. If init is not empty, then: + if (initHasKey) { + /** @type {HeadersList} */ + const headersList = this[kHeaders][kHeadersList] + // 1. Let headers be a copy of this’s headers and its associated header + // list. + // 2. If init["headers"] exists, then set headers to init["headers"]. + const headers = init.headers !== undefined ? init.headers : new HeadersList(headersList) - // 3. Otherwise, return r. - return r -} + // 3. Empty this’s headers’s header list. + headersList.clear() -// https://webidl.spec.whatwg.org/#es-sequence -webidl.sequenceConverter = function (converter) { - return (V) => { - // 1. If Type(V) is not Object, throw a TypeError. - if (webidl.util.Type(V) !== 'Object') { - throw webidl.errors.exception({ - header: 'Sequence', - message: `Value of type ${webidl.util.Type(V)} is not an Object.` - }) + // 4. If headers is a Headers object, then for each header in its header + // list, append header’s name/header’s value to this’s headers. + if (headers instanceof HeadersList) { + for (const [key, val] of headers) { + headersList.append(key, val) + } + // Note: Copy the `set-cookie` meta-data. + headersList.cookies = headers.cookies + } else { + // 5. Otherwise, fill this’s headers with headers. + fillHeaders(this[kHeaders], headers) + } } - // 2. Let method be ? GetMethod(V, @@iterator). - /** @type {Generator} */ - const method = V?.[Symbol.iterator]?.() - const seq = [] + // 33. Let inputBody be input’s request’s body if input is a Request + // object; otherwise null. + const inputBody = input instanceof Request ? input[kState].body : null - // 3. If method is undefined, throw a TypeError. + // 34. If either init["body"] exists and is non-null or inputBody is + // non-null, and request’s method is `GET` or `HEAD`, then throw a + // TypeError. if ( - method === undefined || - typeof method.next !== 'function' + (init.body != null || inputBody != null) && + (request.method === 'GET' || request.method === 'HEAD') ) { - throw webidl.errors.exception({ - header: 'Sequence', - message: 'Object is not an iterator.' - }) + throw new TypeError('Request with GET/HEAD method cannot have body.') } - // https://webidl.spec.whatwg.org/#create-sequence-from-iterable - while (true) { - const { done, value } = method.next() - - if (done) { - break - } - - seq.push(converter(value)) - } + // 35. Let initBody be null. + let initBody = null - return seq - } -} + // 36. If init["body"] exists and is non-null, then: + if (init.body != null) { + // 1. Let Content-Type be null. + // 2. Set initBody and Content-Type to the result of extracting + // init["body"], with keepalive set to request’s keepalive. + const [extractedBody, contentType] = extractBody( + init.body, + request.keepalive + ) + initBody = extractedBody -// https://webidl.spec.whatwg.org/#es-to-record -webidl.recordConverter = function (keyConverter, valueConverter) { - return (O) => { - // 1. If Type(O) is not Object, throw a TypeError. - if (webidl.util.Type(O) !== 'Object') { - throw webidl.errors.exception({ - header: 'Record', - message: `Value of type ${webidl.util.Type(O)} is not an Object.` - }) + // 3, If Content-Type is non-null and this’s headers’s header list does + // not contain `Content-Type`, then append `Content-Type`/Content-Type to + // this’s headers. + if (contentType && !this[kHeaders][kHeadersList].contains('content-type')) { + this[kHeaders].append('content-type', contentType) + } } - // 2. Let result be a new empty instance of record. - const result = {} - - if (!types.isProxy(O)) { - // Object.keys only returns enumerable properties - const keys = Object.keys(O) - - for (const key of keys) { - // 1. Let typedKey be key converted to an IDL value of type K. - const typedKey = keyConverter(key) + // 37. Let inputOrInitBody be initBody if it is non-null; otherwise + // inputBody. + const inputOrInitBody = initBody ?? inputBody - // 2. Let value be ? Get(O, key). - // 3. Let typedValue be value converted to an IDL value of type V. - const typedValue = valueConverter(O[key]) + // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is + // null, then: + if (inputOrInitBody != null && inputOrInitBody.source == null) { + // 1. If initBody is non-null and init["duplex"] does not exist, + // then throw a TypeError. + if (initBody != null && init.duplex == null) { + throw new TypeError('RequestInit: duplex option is required when sending a body.') + } - // 4. Set result[typedKey] to typedValue. - result[typedKey] = typedValue + // 2. If this’s request’s mode is neither "same-origin" nor "cors", + // then throw a TypeError. + if (request.mode !== 'same-origin' && request.mode !== 'cors') { + throw new TypeError( + 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' + ) } - // 5. Return result. - return result + // 3. Set this’s request’s use-CORS-preflight flag. + request.useCORSPreflightFlag = true } - // 3. Let keys be ? O.[[OwnPropertyKeys]](). - const keys = Reflect.ownKeys(O) - - // 4. For each key of keys. - for (const key of keys) { - // 1. Let desc be ? O.[[GetOwnProperty]](key). - const desc = Reflect.getOwnPropertyDescriptor(O, key) + // 39. Let finalBody be inputOrInitBody. + let finalBody = inputOrInitBody - // 2. If desc is not undefined and desc.[[Enumerable]] is true: - if (desc?.enumerable) { - // 1. Let typedKey be key converted to an IDL value of type K. - const typedKey = keyConverter(key) + // 40. If initBody is null and inputBody is non-null, then: + if (initBody == null && inputBody != null) { + // 1. If input is unusable, then throw a TypeError. + if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { + throw new TypeError( + 'Cannot construct a Request with a Request object that has already been used.' + ) + } - // 2. Let value be ? Get(O, key). - // 3. Let typedValue be value converted to an IDL value of type V. - const typedValue = valueConverter(O[key]) + // 2. Set finalBody to the result of creating a proxy for inputBody. + if (!TransformStream) { + TransformStream = (__nccwpck_require__(5356).TransformStream) + } - // 4. Set result[typedKey] to typedValue. - result[typedKey] = typedValue + // https://streams.spec.whatwg.org/#readablestream-create-a-proxy + const identityTransform = new TransformStream() + inputBody.stream.pipeThrough(identityTransform) + finalBody = { + source: inputBody.source, + length: inputBody.length, + stream: identityTransform.readable } } - // 5. Return result. - return result + // 41. Set this’s request’s body to finalBody. + this[kState].body = finalBody } -} -webidl.interfaceConverter = function (i) { - return (V, opts = {}) => { - if (opts.strict !== false && !(V instanceof i)) { - throw webidl.errors.exception({ - header: i.name, - message: `Expected ${V} to be an instance of ${i.name}.` - }) - } + // Returns request’s HTTP method, which is "GET" by default. + get method () { + webidl.brandCheck(this, Request) - return V + // The method getter steps are to return this’s request’s method. + return this[kState].method } -} -webidl.dictionaryConverter = function (converters) { - return (dictionary) => { - const type = webidl.util.Type(dictionary) - const dict = {} + // Returns the URL of request as a string. + get url () { + webidl.brandCheck(this, Request) - if (type === 'Null' || type === 'Undefined') { - return dict - } else if (type !== 'Object') { - throw webidl.errors.exception({ - header: 'Dictionary', - message: `Expected ${dictionary} to be one of: Null, Undefined, Object.` - }) - } + // The url getter steps are to return this’s request’s URL, serialized. + return URLSerializer(this[kState].url) + } - for (const options of converters) { - const { key, defaultValue, required, converter } = options + // Returns a Headers object consisting of the headers associated with request. + // Note that headers added in the network layer by the user agent will not + // be accounted for in this object, e.g., the "Host" header. + get headers () { + webidl.brandCheck(this, Request) - if (required === true) { - if (!hasOwn(dictionary, key)) { - throw webidl.errors.exception({ - header: 'Dictionary', - message: `Missing required key "${key}".` - }) - } - } + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } - let value = dictionary[key] - const hasDefault = hasOwn(options, 'defaultValue') + // Returns the kind of resource requested by request, e.g., "document" + // or "script". + get destination () { + webidl.brandCheck(this, Request) - // Only use defaultValue if value is undefined and - // a defaultValue options was provided. - if (hasDefault && value !== null) { - value = value ?? defaultValue - } + // The destination getter are to return this’s request’s destination. + return this[kState].destination + } - // A key can be optional and have no default value. - // When this happens, do not perform a conversion, - // and do not assign the key a value. - if (required || hasDefault || value !== undefined) { - value = converter(value) + // Returns the referrer of request. Its value can be a same-origin URL if + // explicitly set in init, the empty string to indicate no referrer, and + // "about:client" when defaulting to the global’s default. This is used + // during fetching to determine the value of the `Referer` header of the + // request being made. + get referrer () { + webidl.brandCheck(this, Request) - if ( - options.allowedValues && - !options.allowedValues.includes(value) - ) { - throw webidl.errors.exception({ - header: 'Dictionary', - message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.` - }) - } + // 1. If this’s request’s referrer is "no-referrer", then return the + // empty string. + if (this[kState].referrer === 'no-referrer') { + return '' + } - dict[key] = value - } + // 2. If this’s request’s referrer is "client", then return + // "about:client". + if (this[kState].referrer === 'client') { + return 'about:client' } - return dict + // Return this’s request’s referrer, serialized. + return this[kState].referrer.toString() } -} -webidl.nullableConverter = function (converter) { - return (V) => { - if (V === null) { - return V - } + // Returns the referrer policy associated with request. + // This is used during fetching to compute the value of the request’s + // referrer. + get referrerPolicy () { + webidl.brandCheck(this, Request) - return converter(V) + // The referrerPolicy getter steps are to return this’s request’s referrer policy. + return this[kState].referrerPolicy } -} -// https://webidl.spec.whatwg.org/#es-DOMString -webidl.converters.DOMString = function (V, opts = {}) { - // 1. If V is null and the conversion is to an IDL type - // associated with the [LegacyNullToEmptyString] - // extended attribute, then return the DOMString value - // that represents the empty string. - if (V === null && opts.legacyNullToEmptyString) { - return '' + // Returns the mode associated with request, which is a string indicating + // whether the request will use CORS, or will be restricted to same-origin + // URLs. + get mode () { + webidl.brandCheck(this, Request) + + // The mode getter steps are to return this’s request’s mode. + return this[kState].mode } - // 2. Let x be ? ToString(V). - if (typeof V === 'symbol') { - throw new TypeError('Could not convert argument of type symbol to string.') + // Returns the credentials mode associated with request, + // which is a string indicating whether credentials will be sent with the + // request always, never, or only when sent to a same-origin URL. + get credentials () { + // The credentials getter steps are to return this’s request’s credentials mode. + return this[kState].credentials } - // 3. Return the IDL DOMString value that represents the - // same sequence of code units as the one the - // ECMAScript String value x represents. - return String(V) -} - -// https://webidl.spec.whatwg.org/#es-ByteString -webidl.converters.ByteString = function (V) { - // 1. Let x be ? ToString(V). - // Note: DOMString converter perform ? ToString(V) - const x = webidl.converters.DOMString(V) + // Returns the cache mode associated with request, + // which is a string indicating how the request will + // interact with the browser’s cache when fetching. + get cache () { + webidl.brandCheck(this, Request) - // 2. If the value of any element of x is greater than - // 255, then throw a TypeError. - for (let index = 0; index < x.length; index++) { - if (x.charCodeAt(index) > 255) { - throw new TypeError( - 'Cannot convert argument to a ByteString because the character at ' + - `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` - ) - } + // The cache getter steps are to return this’s request’s cache mode. + return this[kState].cache } - // 3. Return an IDL ByteString value whose length is the - // length of x, and where the value of each element is - // the value of the corresponding element of x. - return x -} + // Returns the redirect mode associated with request, + // which is a string indicating how redirects for the + // request will be handled during fetching. A request + // will follow redirects by default. + get redirect () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-USVString -webidl.converters.USVString = toUSVString + // The redirect getter steps are to return this’s request’s redirect mode. + return this[kState].redirect + } -// https://webidl.spec.whatwg.org/#es-boolean -webidl.converters.boolean = function (V) { - // 1. Let x be the result of computing ToBoolean(V). - const x = Boolean(V) + // Returns request’s subresource integrity metadata, which is a + // cryptographic hash of the resource being fetched. Its value + // consists of multiple hashes separated by whitespace. [SRI] + get integrity () { + webidl.brandCheck(this, Request) - // 2. Return the IDL boolean value that is the one that represents - // the same truth value as the ECMAScript Boolean value x. - return x -} + // The integrity getter steps are to return this’s request’s integrity + // metadata. + return this[kState].integrity + } -// https://webidl.spec.whatwg.org/#es-any -webidl.converters.any = function (V) { - return V -} + // Returns a boolean indicating whether or not request can outlive the + // global in which it was created. + get keepalive () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-long-long -webidl.converters['long long'] = function (V) { - // 1. Let x be ? ConvertToInt(V, 64, "signed"). - const x = webidl.util.ConvertToInt(V, 64, 'signed') + // The keepalive getter steps are to return this’s request’s keepalive. + return this[kState].keepalive + } - // 2. Return the IDL long long value that represents - // the same numeric value as x. - return x -} + // Returns a boolean indicating whether or not request is for a reload + // navigation. + get isReloadNavigation () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-unsigned-long-long -webidl.converters['unsigned long long'] = function (V) { - // 1. Let x be ? ConvertToInt(V, 64, "unsigned"). - const x = webidl.util.ConvertToInt(V, 64, 'unsigned') + // The isReloadNavigation getter steps are to return true if this’s + // request’s reload-navigation flag is set; otherwise false. + return this[kState].reloadNavigation + } - // 2. Return the IDL unsigned long long value that - // represents the same numeric value as x. - return x -} + // Returns a boolean indicating whether or not request is for a history + // navigation (a.k.a. back-foward navigation). + get isHistoryNavigation () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-unsigned-long -webidl.converters['unsigned long'] = function (V) { - // 1. Let x be ? ConvertToInt(V, 32, "unsigned"). - const x = webidl.util.ConvertToInt(V, 32, 'unsigned') + // The isHistoryNavigation getter steps are to return true if this’s request’s + // history-navigation flag is set; otherwise false. + return this[kState].historyNavigation + } - // 2. Return the IDL unsigned long value that - // represents the same numeric value as x. - return x -} + // Returns the signal associated with request, which is an AbortSignal + // object indicating whether or not request has been aborted, and its + // abort event handler. + get signal () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#es-unsigned-short -webidl.converters['unsigned short'] = function (V, opts) { - // 1. Let x be ? ConvertToInt(V, 16, "unsigned"). - const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts) + // The signal getter steps are to return this’s signal. + return this[kSignal] + } - // 2. Return the IDL unsigned short value that represents - // the same numeric value as x. - return x -} + get body () { + webidl.brandCheck(this, Request) -// https://webidl.spec.whatwg.org/#idl-ArrayBuffer -webidl.converters.ArrayBuffer = function (V, opts = {}) { - // 1. If Type(V) is not Object, or V does not have an - // [[ArrayBufferData]] internal slot, then throw a - // TypeError. - // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances - // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances - if ( - webidl.util.Type(V) !== 'Object' || - !types.isAnyArrayBuffer(V) - ) { - throw webidl.errors.conversionFailed({ - prefix: `${V}`, - argument: `${V}`, - types: ['ArrayBuffer'] - }) + return this[kState].body ? this[kState].body.stream : null } - // 2. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V) is true, then throw a - // TypeError. - if (opts.allowShared === false && types.isSharedArrayBuffer(V)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) + get bodyUsed () { + webidl.brandCheck(this, Request) + + return !!this[kState].body && util.isDisturbed(this[kState].body.stream) } - // 3. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V) is true, then throw a - // TypeError. - // Note: resizable ArrayBuffers are currently a proposal. + get duplex () { + webidl.brandCheck(this, Request) - // 4. Return the IDL ArrayBuffer value that is a - // reference to the same object as V. - return V -} + return 'half' + } -webidl.converters.TypedArray = function (V, T, opts = {}) { - // 1. Let T be the IDL type V is being converted to. + // Returns a clone of request. + clone () { + webidl.brandCheck(this, Request) - // 2. If Type(V) is not Object, or V does not have a - // [[TypedArrayName]] internal slot with a value - // equal to T’s name, then throw a TypeError. - if ( - webidl.util.Type(V) !== 'Object' || - !types.isTypedArray(V) || - V.constructor.name !== T.name - ) { - throw webidl.errors.conversionFailed({ - prefix: `${T.name}`, - argument: `${V}`, - types: [T.name] - }) - } + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || this.body?.locked) { + throw new TypeError('unusable') + } - // 3. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) - } + // 2. Let clonedRequest be the result of cloning this’s request. + const clonedRequest = cloneRequest(this[kState]) - // 4. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - // Note: resizable array buffers are currently a proposal + // 3. Let clonedRequestObject be the result of creating a Request object, + // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. + const clonedRequestObject = new Request(kConstruct) + clonedRequestObject[kState] = clonedRequest + clonedRequestObject[kRealm] = this[kRealm] + clonedRequestObject[kHeaders] = new Headers(kConstruct) + clonedRequestObject[kHeaders][kHeadersList] = clonedRequest.headersList + clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard] + clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm] - // 5. Return the IDL value of type T that is a reference - // to the same object as V. - return V + // 4. Make clonedRequestObject’s signal follow this’s signal. + const ac = new AbortController() + if (this.signal.aborted) { + ac.abort(this.signal.reason) + } else { + util.addAbortListener( + this.signal, + () => { + ac.abort(this.signal.reason) + } + ) + } + clonedRequestObject[kSignal] = ac.signal + + // 4. Return clonedRequestObject. + return clonedRequestObject + } } -webidl.converters.DataView = function (V, opts = {}) { - // 1. If Type(V) is not Object, or V does not have a - // [[DataView]] internal slot, then throw a TypeError. - if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) { - throw webidl.errors.exception({ - header: 'DataView', - message: 'Object is not a DataView.' - }) - } +mixinBody(Request) - // 2. If the conversion is not to an IDL type associated - // with the [AllowShared] extended attribute, and - // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, - // then throw a TypeError. - if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { - throw webidl.errors.exception({ - header: 'ArrayBuffer', - message: 'SharedArrayBuffer is not allowed.' - }) +function makeRequest (init) { + // https://fetch.spec.whatwg.org/#requests + const request = { + method: 'GET', + localURLsOnly: false, + unsafeRequest: false, + body: null, + client: null, + reservedClient: null, + replacesClientId: '', + window: 'client', + keepalive: false, + serviceWorkers: 'all', + initiator: '', + destination: '', + priority: null, + origin: 'client', + policyContainer: 'client', + referrer: 'client', + referrerPolicy: '', + mode: 'no-cors', + useCORSPreflightFlag: false, + credentials: 'same-origin', + useCredentials: false, + cache: 'default', + redirect: 'follow', + integrity: '', + cryptoGraphicsNonceMetadata: '', + parserMetadata: '', + reloadNavigation: false, + historyNavigation: false, + userActivation: false, + taintedOrigin: false, + redirectCount: 0, + responseTainting: 'basic', + preventNoCacheCacheControlHeaderModification: false, + done: false, + timingAllowFailed: false, + ...init, + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList() } + request.url = request.urlList[0] + return request +} - // 3. If the conversion is not to an IDL type associated - // with the [AllowResizable] extended attribute, and - // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is - // true, then throw a TypeError. - // Note: resizable ArrayBuffers are currently a proposal +// https://fetch.spec.whatwg.org/#concept-request-clone +function cloneRequest (request) { + // To clone a request request, run these steps: - // 4. Return the IDL DataView value that is a reference - // to the same object as V. - return V + // 1. Let newRequest be a copy of request, except for its body. + const newRequest = makeRequest({ ...request, body: null }) + + // 2. If request’s body is non-null, set newRequest’s body to the + // result of cloning request’s body. + if (request.body != null) { + newRequest.body = cloneBody(request.body) + } + + // 3. Return newRequest. + return newRequest } -// https://webidl.spec.whatwg.org/#BufferSource -webidl.converters.BufferSource = function (V, opts = {}) { - if (types.isAnyArrayBuffer(V)) { - return webidl.converters.ArrayBuffer(V, opts) +Object.defineProperties(Request.prototype, { + method: kEnumerableProperty, + url: kEnumerableProperty, + headers: kEnumerableProperty, + redirect: kEnumerableProperty, + clone: kEnumerableProperty, + signal: kEnumerableProperty, + duplex: kEnumerableProperty, + destination: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + isHistoryNavigation: kEnumerableProperty, + isReloadNavigation: kEnumerableProperty, + keepalive: kEnumerableProperty, + integrity: kEnumerableProperty, + cache: kEnumerableProperty, + credentials: kEnumerableProperty, + attribute: kEnumerableProperty, + referrerPolicy: kEnumerableProperty, + referrer: kEnumerableProperty, + mode: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Request', + configurable: true } +}) - if (types.isTypedArray(V)) { - return webidl.converters.TypedArray(V, V.constructor) +webidl.converters.Request = webidl.interfaceConverter( + Request +) + +// https://fetch.spec.whatwg.org/#requestinfo +webidl.converters.RequestInfo = function (V) { + if (typeof V === 'string') { + return webidl.converters.USVString(V) } - if (types.isDataView(V)) { - return webidl.converters.DataView(V, opts) + if (V instanceof Request) { + return webidl.converters.Request(V) } - throw new TypeError(`Could not convert ${V} to a BufferSource.`) + return webidl.converters.USVString(V) } -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.ByteString -) - -webidl.converters['sequence>'] = webidl.sequenceConverter( - webidl.converters['sequence'] +webidl.converters.AbortSignal = webidl.interfaceConverter( + AbortSignal ) -webidl.converters['record'] = webidl.recordConverter( - webidl.converters.ByteString, - webidl.converters.ByteString -) +// https://fetch.spec.whatwg.org/#requestinit +webidl.converters.RequestInit = webidl.dictionaryConverter([ + { + key: 'method', + converter: webidl.converters.ByteString + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit + }, + { + key: 'body', + converter: webidl.nullableConverter( + webidl.converters.BodyInit + ) + }, + { + key: 'referrer', + converter: webidl.converters.USVString + }, + { + key: 'referrerPolicy', + converter: webidl.converters.DOMString, + // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy + allowedValues: referrerPolicy + }, + { + key: 'mode', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#concept-request-mode + allowedValues: requestMode + }, + { + key: 'credentials', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcredentials + allowedValues: requestCredentials + }, + { + key: 'cache', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcache + allowedValues: requestCache + }, + { + key: 'redirect', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestredirect + allowedValues: requestRedirect + }, + { + key: 'integrity', + converter: webidl.converters.DOMString + }, + { + key: 'keepalive', + converter: webidl.converters.boolean + }, + { + key: 'signal', + converter: webidl.nullableConverter( + (signal) => webidl.converters.AbortSignal( + signal, + { strict: false } + ) + ) + }, + { + key: 'window', + converter: webidl.converters.any + }, + { + key: 'duplex', + converter: webidl.converters.DOMString, + allowedValues: requestDuplex + } +]) -module.exports = { - webidl -} +module.exports = { Request, makeRequest } /***/ }), -/***/ 4854: -/***/ ((module) => { +/***/ 7823: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -/** - * @see https://encoding.spec.whatwg.org/#concept-encoding-get - * @param {string|undefined} label - */ -function getEncoding (label) { - if (!label) { - return 'failure' - } +const { Headers, HeadersList, fill } = __nccwpck_require__(554) +const { extractBody, cloneBody, mixinBody } = __nccwpck_require__(1472) +const util = __nccwpck_require__(3983) +const { kEnumerableProperty } = util +const { + isValidReasonPhrase, + isCancelled, + isAborted, + isBlobLike, + serializeJavascriptValueToJSONString, + isErrorLike, + isomorphicEncode +} = __nccwpck_require__(2538) +const { + redirectStatusSet, + nullBodyStatus, + DOMException +} = __nccwpck_require__(1037) +const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) +const { webidl } = __nccwpck_require__(1744) +const { FormData } = __nccwpck_require__(2015) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { URLSerializer } = __nccwpck_require__(685) +const { kHeadersList, kConstruct } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { types } = __nccwpck_require__(3837) - // 1. Remove any leading and trailing ASCII whitespace from label. - // 2. If label is an ASCII case-insensitive match for any of the - // labels listed in the table below, then return the - // corresponding encoding; otherwise return failure. - switch (label.trim().toLowerCase()) { - case 'unicode-1-1-utf-8': - case 'unicode11utf8': - case 'unicode20utf8': - case 'utf-8': - case 'utf8': - case 'x-unicode20utf8': - return 'UTF-8' - case '866': - case 'cp866': - case 'csibm866': - case 'ibm866': - return 'IBM866' - case 'csisolatin2': - case 'iso-8859-2': - case 'iso-ir-101': - case 'iso8859-2': - case 'iso88592': - case 'iso_8859-2': - case 'iso_8859-2:1987': - case 'l2': - case 'latin2': - return 'ISO-8859-2' - case 'csisolatin3': - case 'iso-8859-3': - case 'iso-ir-109': - case 'iso8859-3': - case 'iso88593': - case 'iso_8859-3': - case 'iso_8859-3:1988': - case 'l3': - case 'latin3': - return 'ISO-8859-3' - case 'csisolatin4': - case 'iso-8859-4': - case 'iso-ir-110': - case 'iso8859-4': - case 'iso88594': - case 'iso_8859-4': - case 'iso_8859-4:1988': - case 'l4': - case 'latin4': - return 'ISO-8859-4' - case 'csisolatincyrillic': - case 'cyrillic': - case 'iso-8859-5': - case 'iso-ir-144': - case 'iso8859-5': - case 'iso88595': - case 'iso_8859-5': - case 'iso_8859-5:1988': - return 'ISO-8859-5' - case 'arabic': - case 'asmo-708': - case 'csiso88596e': - case 'csiso88596i': - case 'csisolatinarabic': - case 'ecma-114': - case 'iso-8859-6': - case 'iso-8859-6-e': - case 'iso-8859-6-i': - case 'iso-ir-127': - case 'iso8859-6': - case 'iso88596': - case 'iso_8859-6': - case 'iso_8859-6:1987': - return 'ISO-8859-6' - case 'csisolatingreek': - case 'ecma-118': - case 'elot_928': - case 'greek': - case 'greek8': - case 'iso-8859-7': - case 'iso-ir-126': - case 'iso8859-7': - case 'iso88597': - case 'iso_8859-7': - case 'iso_8859-7:1987': - case 'sun_eu_greek': - return 'ISO-8859-7' - case 'csiso88598e': - case 'csisolatinhebrew': - case 'hebrew': - case 'iso-8859-8': - case 'iso-8859-8-e': - case 'iso-ir-138': - case 'iso8859-8': - case 'iso88598': - case 'iso_8859-8': - case 'iso_8859-8:1988': - case 'visual': - return 'ISO-8859-8' - case 'csiso88598i': - case 'iso-8859-8-i': - case 'logical': - return 'ISO-8859-8-I' - case 'csisolatin6': - case 'iso-8859-10': - case 'iso-ir-157': - case 'iso8859-10': - case 'iso885910': - case 'l6': - case 'latin6': - return 'ISO-8859-10' - case 'iso-8859-13': - case 'iso8859-13': - case 'iso885913': - return 'ISO-8859-13' - case 'iso-8859-14': - case 'iso8859-14': - case 'iso885914': - return 'ISO-8859-14' - case 'csisolatin9': - case 'iso-8859-15': - case 'iso8859-15': - case 'iso885915': - case 'iso_8859-15': - case 'l9': - return 'ISO-8859-15' - case 'iso-8859-16': - return 'ISO-8859-16' - case 'cskoi8r': - case 'koi': - case 'koi8': - case 'koi8-r': - case 'koi8_r': - return 'KOI8-R' - case 'koi8-ru': - case 'koi8-u': - return 'KOI8-U' - case 'csmacintosh': - case 'mac': - case 'macintosh': - case 'x-mac-roman': - return 'macintosh' - case 'iso-8859-11': - case 'iso8859-11': - case 'iso885911': - case 'tis-620': - case 'windows-874': - return 'windows-874' - case 'cp1250': - case 'windows-1250': - case 'x-cp1250': - return 'windows-1250' - case 'cp1251': - case 'windows-1251': - case 'x-cp1251': - return 'windows-1251' - case 'ansi_x3.4-1968': - case 'ascii': - case 'cp1252': - case 'cp819': - case 'csisolatin1': - case 'ibm819': - case 'iso-8859-1': - case 'iso-ir-100': - case 'iso8859-1': - case 'iso88591': - case 'iso_8859-1': - case 'iso_8859-1:1987': - case 'l1': - case 'latin1': - case 'us-ascii': - case 'windows-1252': - case 'x-cp1252': - return 'windows-1252' - case 'cp1253': - case 'windows-1253': - case 'x-cp1253': - return 'windows-1253' - case 'cp1254': - case 'csisolatin5': - case 'iso-8859-9': - case 'iso-ir-148': - case 'iso8859-9': - case 'iso88599': - case 'iso_8859-9': - case 'iso_8859-9:1989': - case 'l5': - case 'latin5': - case 'windows-1254': - case 'x-cp1254': - return 'windows-1254' - case 'cp1255': - case 'windows-1255': - case 'x-cp1255': - return 'windows-1255' - case 'cp1256': - case 'windows-1256': - case 'x-cp1256': - return 'windows-1256' - case 'cp1257': - case 'windows-1257': - case 'x-cp1257': - return 'windows-1257' - case 'cp1258': - case 'windows-1258': - case 'x-cp1258': - return 'windows-1258' - case 'x-mac-cyrillic': - case 'x-mac-ukrainian': - return 'x-mac-cyrillic' - case 'chinese': - case 'csgb2312': - case 'csiso58gb231280': - case 'gb2312': - case 'gb_2312': - case 'gb_2312-80': - case 'gbk': - case 'iso-ir-58': - case 'x-gbk': - return 'GBK' - case 'gb18030': - return 'gb18030' - case 'big5': - case 'big5-hkscs': - case 'cn-big5': - case 'csbig5': - case 'x-x-big5': - return 'Big5' - case 'cseucpkdfmtjapanese': - case 'euc-jp': - case 'x-euc-jp': - return 'EUC-JP' - case 'csiso2022jp': - case 'iso-2022-jp': - return 'ISO-2022-JP' - case 'csshiftjis': - case 'ms932': - case 'ms_kanji': - case 'shift-jis': - case 'shift_jis': - case 'sjis': - case 'windows-31j': - case 'x-sjis': - return 'Shift_JIS' - case 'cseuckr': - case 'csksc56011987': - case 'euc-kr': - case 'iso-ir-149': - case 'korean': - case 'ks_c_5601-1987': - case 'ks_c_5601-1989': - case 'ksc5601': - case 'ksc_5601': - case 'windows-949': - return 'EUC-KR' - case 'csiso2022kr': - case 'hz-gb-2312': - case 'iso-2022-cn': - case 'iso-2022-cn-ext': - case 'iso-2022-kr': - case 'replacement': - return 'replacement' - case 'unicodefffe': - case 'utf-16be': - return 'UTF-16BE' - case 'csunicode': - case 'iso-10646-ucs-2': - case 'ucs-2': - case 'unicode': - case 'unicodefeff': - case 'utf-16': - case 'utf-16le': - return 'UTF-16LE' - case 'x-user-defined': - return 'x-user-defined' - default: return 'failure' +const ReadableStream = globalThis.ReadableStream || (__nccwpck_require__(5356).ReadableStream) +const textEncoder = new TextEncoder('utf-8') + +// https://fetch.spec.whatwg.org/#response-class +class Response { + // Creates network error Response. + static error () { + // TODO + const relevantRealm = { settingsObject: {} } + + // The static error() method steps are to return the result of creating a + // Response object, given a new network error, "immutable", and this’s + // relevant Realm. + const responseObject = new Response() + responseObject[kState] = makeNetworkError() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kHeadersList] = responseObject[kState].headersList + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response-json + static json (data, init = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'Response.json' }) + + if (init !== null) { + init = webidl.converters.ResponseInit(init) + } + + // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. + const bytes = textEncoder.encode( + serializeJavascriptValueToJSONString(data) + ) + + // 2. Let body be the result of extracting bytes. + const body = extractBody(bytes) + + // 3. Let responseObject be the result of creating a Response object, given a new response, + // "response", and this’s relevant Realm. + const relevantRealm = { settingsObject: {} } + const responseObject = new Response() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kGuard] = 'response' + responseObject[kHeaders][kRealm] = relevantRealm + + // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). + initializeResponse(responseObject, init, { body: body[0], type: 'application/json' }) + + // 5. Return responseObject. + return responseObject + } + + // Creates a redirect Response that redirects to url with status status. + static redirect (url, status = 302) { + const relevantRealm = { settingsObject: {} } + + webidl.argumentLengthCheck(arguments, 1, { header: 'Response.redirect' }) + + url = webidl.converters.USVString(url) + status = webidl.converters['unsigned short'](status) + + // 1. Let parsedURL be the result of parsing url with current settings + // object’s API base URL. + // 2. If parsedURL is failure, then throw a TypeError. + // TODO: base-URL? + let parsedURL + try { + parsedURL = new URL(url, getGlobalOrigin()) + } catch (err) { + throw Object.assign(new TypeError('Failed to parse URL from ' + url), { + cause: err + }) + } + + // 3. If status is not a redirect status, then throw a RangeError. + if (!redirectStatusSet.has(status)) { + throw new RangeError('Invalid status code ' + status) + } + + // 4. Let responseObject be the result of creating a Response object, + // given a new response, "immutable", and this’s relevant Realm. + const responseObject = new Response() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + + // 5. Set responseObject’s response’s status to status. + responseObject[kState].status = status + + // 6. Let value be parsedURL, serialized and isomorphic encoded. + const value = isomorphicEncode(URLSerializer(parsedURL)) + + // 7. Append `Location`/value to responseObject’s response’s header list. + responseObject[kState].headersList.append('location', value) + + // 8. Return responseObject. + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response + constructor (body = null, init = {}) { + if (body !== null) { + body = webidl.converters.BodyInit(body) + } + + init = webidl.converters.ResponseInit(init) + + // TODO + this[kRealm] = { settingsObject: {} } + + // 1. Set this’s response to a new response. + this[kState] = makeResponse({}) + + // 2. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is this’s response’s header list and guard + // is "response". + this[kHeaders] = new Headers(kConstruct) + this[kHeaders][kGuard] = 'response' + this[kHeaders][kHeadersList] = this[kState].headersList + this[kHeaders][kRealm] = this[kRealm] + + // 3. Let bodyWithType be null. + let bodyWithType = null + + // 4. If body is non-null, then set bodyWithType to the result of extracting body. + if (body != null) { + const [extractedBody, type] = extractBody(body) + bodyWithType = { body: extractedBody, type } + } + + // 5. Perform initialize a response given this, init, and bodyWithType. + initializeResponse(this, init, bodyWithType) + } + + // Returns response’s type, e.g., "cors". + get type () { + webidl.brandCheck(this, Response) + + // The type getter steps are to return this’s response’s type. + return this[kState].type + } + + // Returns response’s URL, if it has one; otherwise the empty string. + get url () { + webidl.brandCheck(this, Response) + + const urlList = this[kState].urlList + + // The url getter steps are to return the empty string if this’s + // response’s URL is null; otherwise this’s response’s URL, + // serialized with exclude fragment set to true. + const url = urlList[urlList.length - 1] ?? null + + if (url === null) { + return '' + } + + return URLSerializer(url, true) + } + + // Returns whether response was obtained through a redirect. + get redirected () { + webidl.brandCheck(this, Response) + + // The redirected getter steps are to return true if this’s response’s URL + // list has more than one item; otherwise false. + return this[kState].urlList.length > 1 + } + + // Returns response’s status. + get status () { + webidl.brandCheck(this, Response) + + // The status getter steps are to return this’s response’s status. + return this[kState].status + } + + // Returns whether response’s status is an ok status. + get ok () { + webidl.brandCheck(this, Response) + + // The ok getter steps are to return true if this’s response’s status is an + // ok status; otherwise false. + return this[kState].status >= 200 && this[kState].status <= 299 + } + + // Returns response’s status message. + get statusText () { + webidl.brandCheck(this, Response) + + // The statusText getter steps are to return this’s response’s status + // message. + return this[kState].statusText + } + + // Returns response’s headers as Headers. + get headers () { + webidl.brandCheck(this, Response) + + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } + + get body () { + webidl.brandCheck(this, Response) + + return this[kState].body ? this[kState].body.stream : null + } + + get bodyUsed () { + webidl.brandCheck(this, Response) + + return !!this[kState].body && util.isDisturbed(this[kState].body.stream) + } + + // Returns a clone of response. + clone () { + webidl.brandCheck(this, Response) + + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || (this.body && this.body.locked)) { + throw webidl.errors.exception({ + header: 'Response.clone', + message: 'Body has already been consumed.' + }) + } + + // 2. Let clonedResponse be the result of cloning this’s response. + const clonedResponse = cloneResponse(this[kState]) + + // 3. Return the result of creating a Response object, given + // clonedResponse, this’s headers’s guard, and this’s relevant Realm. + const clonedResponseObject = new Response() + clonedResponseObject[kState] = clonedResponse + clonedResponseObject[kRealm] = this[kRealm] + clonedResponseObject[kHeaders][kHeadersList] = clonedResponse.headersList + clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard] + clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm] + + return clonedResponseObject } } -module.exports = { - getEncoding +mixinBody(Response) + +Object.defineProperties(Response.prototype, { + type: kEnumerableProperty, + url: kEnumerableProperty, + status: kEnumerableProperty, + ok: kEnumerableProperty, + redirected: kEnumerableProperty, + statusText: kEnumerableProperty, + headers: kEnumerableProperty, + clone: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Response', + configurable: true + } +}) + +Object.defineProperties(Response, { + json: kEnumerableProperty, + redirect: kEnumerableProperty, + error: kEnumerableProperty +}) + +// https://fetch.spec.whatwg.org/#concept-response-clone +function cloneResponse (response) { + // To clone a response response, run these steps: + + // 1. If response is a filtered response, then return a new identical + // filtered response whose internal response is a clone of response’s + // internal response. + if (response.internalResponse) { + return filterResponse( + cloneResponse(response.internalResponse), + response.type + ) + } + + // 2. Let newResponse be a copy of response, except for its body. + const newResponse = makeResponse({ ...response, body: null }) + + // 3. If response’s body is non-null, then set newResponse’s body to the + // result of cloning response’s body. + if (response.body != null) { + newResponse.body = cloneBody(response.body) + } + + // 4. Return newResponse. + return newResponse +} + +function makeResponse (init) { + return { + aborted: false, + rangeRequested: false, + timingAllowPassed: false, + requestIncludesCredentials: false, + type: 'default', + status: 200, + timingInfo: null, + cacheState: '', + statusText: '', + ...init, + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList(), + urlList: init.urlList ? [...init.urlList] : [] + } +} + +function makeNetworkError (reason) { + const isError = isErrorLike(reason) + return makeResponse({ + type: 'error', + status: 0, + error: isError + ? reason + : new Error(reason ? String(reason) : reason), + aborted: reason && reason.name === 'AbortError' + }) } +function makeFilteredResponse (response, state) { + state = { + internalResponse: response, + ...state + } -/***/ }), - -/***/ 1446: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return new Proxy(response, { + get (target, p) { + return p in state ? state[p] : target[p] + }, + set (target, p, value) { + assert(!(p in state)) + target[p] = value + return true + } + }) +} -"use strict"; +// https://fetch.spec.whatwg.org/#concept-filtered-response +function filterResponse (response, type) { + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (type === 'basic') { + // A basic filtered response is a filtered response whose type is "basic" + // and header list excludes any headers in internal response’s header list + // whose name is a forbidden response-header name. + // Note: undici does not implement forbidden response-header names + return makeFilteredResponse(response, { + type: 'basic', + headersList: response.headersList + }) + } else if (type === 'cors') { + // A CORS filtered response is a filtered response whose type is "cors" + // and header list excludes any headers in internal response’s header + // list whose name is not a CORS-safelisted response-header name, given + // internal response’s CORS-exposed header-name list. -const { - staticPropertyDescriptors, - readOperation, - fireAProgressEvent -} = __nccwpck_require__(7530) -const { - kState, - kError, - kResult, - kEvents, - kAborted -} = __nccwpck_require__(9054) -const { webidl } = __nccwpck_require__(1744) -const { kEnumerableProperty } = __nccwpck_require__(3983) + // Note: undici does not implement CORS-safelisted response-header names + return makeFilteredResponse(response, { + type: 'cors', + headersList: response.headersList + }) + } else if (type === 'opaque') { + // An opaque filtered response is a filtered response whose type is + // "opaque", URL list is the empty list, status is 0, status message + // is the empty byte sequence, header list is empty, and body is null. -class FileReader extends EventTarget { - constructor () { - super() + return makeFilteredResponse(response, { + type: 'opaque', + urlList: Object.freeze([]), + status: 0, + statusText: '', + body: null + }) + } else if (type === 'opaqueredirect') { + // An opaque-redirect filtered response is a filtered response whose type + // is "opaqueredirect", status is 0, status message is the empty byte + // sequence, header list is empty, and body is null. - this[kState] = 'empty' - this[kResult] = null - this[kError] = null - this[kEvents] = { - loadend: null, - error: null, - abort: null, - load: null, - progress: null, - loadstart: null - } + return makeFilteredResponse(response, { + type: 'opaqueredirect', + status: 0, + statusText: '', + headersList: [], + body: null + }) + } else { + assert(false) } +} - /** - * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer - * @param {import('buffer').Blob} blob - */ - readAsArrayBuffer (blob) { - webidl.brandCheck(this, FileReader) - - webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsArrayBuffer' }) +// https://fetch.spec.whatwg.org/#appropriate-network-error +function makeAppropriateNetworkError (fetchParams, err = null) { + // 1. Assert: fetchParams is canceled. + assert(isCancelled(fetchParams)) - blob = webidl.converters.Blob(blob, { strict: false }) + // 2. Return an aborted network error if fetchParams is aborted; + // otherwise return a network error. + return isAborted(fetchParams) + ? makeNetworkError(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err })) + : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err })) +} - // The readAsArrayBuffer(blob) method, when invoked, - // must initiate a read operation for blob with ArrayBuffer. - readOperation(this, blob, 'ArrayBuffer') +// https://whatpr.org/fetch/1392.html#initialize-a-response +function initializeResponse (response, init, body) { + // 1. If init["status"] is not in the range 200 to 599, inclusive, then + // throw a RangeError. + if (init.status !== null && (init.status < 200 || init.status > 599)) { + throw new RangeError('init["status"] must be in the range of 200 to 599, inclusive.') } - /** - * @see https://w3c.github.io/FileAPI/#readAsBinaryString - * @param {import('buffer').Blob} blob - */ - readAsBinaryString (blob) { - webidl.brandCheck(this, FileReader) - - webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsBinaryString' }) + // 2. If init["statusText"] does not match the reason-phrase token production, + // then throw a TypeError. + if ('statusText' in init && init.statusText != null) { + // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2: + // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) + if (!isValidReasonPhrase(String(init.statusText))) { + throw new TypeError('Invalid statusText') + } + } - blob = webidl.converters.Blob(blob, { strict: false }) + // 3. Set response’s response’s status to init["status"]. + if ('status' in init && init.status != null) { + response[kState].status = init.status + } - // The readAsBinaryString(blob) method, when invoked, - // must initiate a read operation for blob with BinaryString. - readOperation(this, blob, 'BinaryString') + // 4. Set response’s response’s status message to init["statusText"]. + if ('statusText' in init && init.statusText != null) { + response[kState].statusText = init.statusText } - /** - * @see https://w3c.github.io/FileAPI/#readAsDataText - * @param {import('buffer').Blob} blob - * @param {string?} encoding - */ - readAsText (blob, encoding = undefined) { - webidl.brandCheck(this, FileReader) + // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. + if ('headers' in init && init.headers != null) { + fill(response[kHeaders], init.headers) + } - webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsText' }) + // 6. If body was given, then: + if (body) { + // 1. If response's status is a null body status, then throw a TypeError. + if (nullBodyStatus.includes(response.status)) { + throw webidl.errors.exception({ + header: 'Response constructor', + message: 'Invalid response status code ' + response.status + }) + } - blob = webidl.converters.Blob(blob, { strict: false }) + // 2. Set response's body to body's body. + response[kState].body = body.body - if (encoding !== undefined) { - encoding = webidl.converters.DOMString(encoding) + // 3. If body's type is non-null and response's header list does not contain + // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. + if (body.type != null && !response[kState].headersList.contains('Content-Type')) { + response[kState].headersList.append('content-type', body.type) } - - // The readAsText(blob, encoding) method, when invoked, - // must initiate a read operation for blob with Text and encoding. - readOperation(this, blob, 'Text', encoding) } +} - /** - * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL - * @param {import('buffer').Blob} blob - */ - readAsDataURL (blob) { - webidl.brandCheck(this, FileReader) +webidl.converters.ReadableStream = webidl.interfaceConverter( + ReadableStream +) - webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsDataURL' }) +webidl.converters.FormData = webidl.interfaceConverter( + FormData +) - blob = webidl.converters.Blob(blob, { strict: false }) +webidl.converters.URLSearchParams = webidl.interfaceConverter( + URLSearchParams +) - // The readAsDataURL(blob) method, when invoked, must - // initiate a read operation for blob with DataURL. - readOperation(this, blob, 'DataURL') +// https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit +webidl.converters.XMLHttpRequestBodyInit = function (V) { + if (typeof V === 'string') { + return webidl.converters.USVString(V) } - /** - * @see https://w3c.github.io/FileAPI/#dfn-abort - */ - abort () { - // 1. If this's state is "empty" or if this's state is - // "done" set this's result to null and terminate - // this algorithm. - if (this[kState] === 'empty' || this[kState] === 'done') { - this[kResult] = null - return - } - - // 2. If this's state is "loading" set this's state to - // "done" and set this's result to null. - if (this[kState] === 'loading') { - this[kState] = 'done' - this[kResult] = null - } - - // 3. If there are any tasks from this on the file reading - // task source in an affiliated task queue, then remove - // those tasks from that task queue. - this[kAborted] = true - - // 4. Terminate the algorithm for the read method being processed. - // TODO - - // 5. Fire a progress event called abort at this. - fireAProgressEvent('abort', this) + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } - // 6. If this's state is not "loading", fire a progress - // event called loadend at this. - if (this[kState] !== 'loading') { - fireAProgressEvent('loadend', this) - } + if (types.isArrayBuffer(V) || types.isTypedArray(V) || types.isDataView(V)) { + return webidl.converters.BufferSource(V) } - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate - */ - get readyState () { - webidl.brandCheck(this, FileReader) + if (util.isFormDataLike(V)) { + return webidl.converters.FormData(V, { strict: false }) + } - switch (this[kState]) { - case 'empty': return this.EMPTY - case 'loading': return this.LOADING - case 'done': return this.DONE - } + if (V instanceof URLSearchParams) { + return webidl.converters.URLSearchParams(V) } - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-result - */ - get result () { - webidl.brandCheck(this, FileReader) + return webidl.converters.DOMString(V) +} - // The result attribute’s getter, when invoked, must return - // this's result. - return this[kResult] +// https://fetch.spec.whatwg.org/#bodyinit +webidl.converters.BodyInit = function (V) { + if (V instanceof ReadableStream) { + return webidl.converters.ReadableStream(V) } - /** - * @see https://w3c.github.io/FileAPI/#dom-filereader-error - */ - get error () { - webidl.brandCheck(this, FileReader) - - // The error attribute’s getter, when invoked, must return - // this's error. - return this[kError] + // Note: the spec doesn't include async iterables, + // this is an undici extension. + if (V?.[Symbol.asyncIterator]) { + return V } - get onloadend () { - webidl.brandCheck(this, FileReader) + return webidl.converters.XMLHttpRequestBodyInit(V) +} - return this[kEvents].loadend +webidl.converters.ResponseInit = webidl.dictionaryConverter([ + { + key: 'status', + converter: webidl.converters['unsigned short'], + defaultValue: 200 + }, + { + key: 'statusText', + converter: webidl.converters.ByteString, + defaultValue: '' + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit } +]) - set onloadend (fn) { - webidl.brandCheck(this, FileReader) +module.exports = { + makeNetworkError, + makeResponse, + makeAppropriateNetworkError, + filterResponse, + Response, + cloneResponse +} - if (this[kEvents].loadend) { - this.removeEventListener('loadend', this[kEvents].loadend) - } - if (typeof fn === 'function') { - this[kEvents].loadend = fn - this.addEventListener('loadend', fn) - } else { - this[kEvents].loadend = null - } - } +/***/ }), - get onerror () { - webidl.brandCheck(this, FileReader) +/***/ 5861: +/***/ ((module) => { - return this[kEvents].error - } +"use strict"; - set onerror (fn) { - webidl.brandCheck(this, FileReader) - if (this[kEvents].error) { - this.removeEventListener('error', this[kEvents].error) - } +module.exports = { + kUrl: Symbol('url'), + kHeaders: Symbol('headers'), + kSignal: Symbol('signal'), + kState: Symbol('state'), + kGuard: Symbol('guard'), + kRealm: Symbol('realm') +} - if (typeof fn === 'function') { - this[kEvents].error = fn - this.addEventListener('error', fn) - } else { - this[kEvents].error = null - } - } - get onloadstart () { - webidl.brandCheck(this, FileReader) +/***/ }), - return this[kEvents].loadstart - } +/***/ 2538: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - set onloadstart (fn) { - webidl.brandCheck(this, FileReader) +"use strict"; - if (this[kEvents].loadstart) { - this.removeEventListener('loadstart', this[kEvents].loadstart) - } - if (typeof fn === 'function') { - this[kEvents].loadstart = fn - this.addEventListener('loadstart', fn) - } else { - this[kEvents].loadstart = null - } - } +const { redirectStatusSet, referrerPolicySet: referrerPolicyTokens, badPortsSet } = __nccwpck_require__(1037) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { performance } = __nccwpck_require__(4074) +const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983) +const assert = __nccwpck_require__(9491) +const { isUint8Array } = __nccwpck_require__(9830) - get onprogress () { - webidl.brandCheck(this, FileReader) +// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable +/** @type {import('crypto')|undefined} */ +let crypto - return this[kEvents].progress +try { + crypto = __nccwpck_require__(6113) +} catch { + +} + +function responseURL (response) { + // https://fetch.spec.whatwg.org/#responses + // A response has an associated URL. It is a pointer to the last URL + // in response’s URL list and null if response’s URL list is empty. + const urlList = response.urlList + const length = urlList.length + return length === 0 ? null : urlList[length - 1].toString() +} + +// https://fetch.spec.whatwg.org/#concept-response-location-url +function responseLocationURL (response, requestFragment) { + // 1. If response’s status is not a redirect status, then return null. + if (!redirectStatusSet.has(response.status)) { + return null } - set onprogress (fn) { - webidl.brandCheck(this, FileReader) + // 2. Let location be the result of extracting header list values given + // `Location` and response’s header list. + let location = response.headersList.get('location') - if (this[kEvents].progress) { - this.removeEventListener('progress', this[kEvents].progress) - } + // 3. If location is a header value, then set location to the result of + // parsing location with response’s URL. + if (location !== null && isValidHeaderValue(location)) { + location = new URL(location, responseURL(response)) + } - if (typeof fn === 'function') { - this[kEvents].progress = fn - this.addEventListener('progress', fn) - } else { - this[kEvents].progress = null - } + // 4. If location is a URL whose fragment is null, then set location’s + // fragment to requestFragment. + if (location && !location.hash) { + location.hash = requestFragment } - get onload () { - webidl.brandCheck(this, FileReader) + // 5. Return location. + return location +} - return this[kEvents].load +/** @returns {URL} */ +function requestCurrentURL (request) { + return request.urlList[request.urlList.length - 1] +} + +function requestBadPort (request) { + // 1. Let url be request’s current URL. + const url = requestCurrentURL(request) + + // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, + // then return blocked. + if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { + return 'blocked' } - set onload (fn) { - webidl.brandCheck(this, FileReader) + // 3. Return allowed. + return 'allowed' +} - if (this[kEvents].load) { - this.removeEventListener('load', this[kEvents].load) - } +function isErrorLike (object) { + return object instanceof Error || ( + object?.constructor?.name === 'Error' || + object?.constructor?.name === 'DOMException' + ) +} - if (typeof fn === 'function') { - this[kEvents].load = fn - this.addEventListener('load', fn) - } else { - this[kEvents].load = null +// Check whether |statusText| is a ByteString and +// matches the Reason-Phrase token production. +// RFC 2616: https://tools.ietf.org/html/rfc2616 +// RFC 7230: https://tools.ietf.org/html/rfc7230 +// "reason-phrase = *( HTAB / SP / VCHAR / obs-text )" +// https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116 +function isValidReasonPhrase (statusText) { + for (let i = 0; i < statusText.length; ++i) { + const c = statusText.charCodeAt(i) + if ( + !( + ( + c === 0x09 || // HTAB + (c >= 0x20 && c <= 0x7e) || // SP / VCHAR + (c >= 0x80 && c <= 0xff) + ) // obs-text + ) + ) { + return false } } + return true +} + +/** + * @see https://tools.ietf.org/html/rfc7230#section-3.2.6 + * @param {number} c + */ +function isTokenCharCode (c) { + switch (c) { + case 0x22: + case 0x28: + case 0x29: + case 0x2c: + case 0x2f: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x40: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x7b: + case 0x7d: + // DQUOTE and "(),/:;<=>?@[\]{}" + return false + default: + // VCHAR %x21-7E + return c >= 0x21 && c <= 0x7e + } +} - get onabort () { - webidl.brandCheck(this, FileReader) - - return this[kEvents].abort +/** + * @param {string} characters + */ +function isValidHTTPToken (characters) { + if (characters.length === 0) { + return false } - - set onabort (fn) { - webidl.brandCheck(this, FileReader) - - if (this[kEvents].abort) { - this.removeEventListener('abort', this[kEvents].abort) - } - - if (typeof fn === 'function') { - this[kEvents].abort = fn - this.addEventListener('abort', fn) - } else { - this[kEvents].abort = null + for (let i = 0; i < characters.length; ++i) { + if (!isTokenCharCode(characters.charCodeAt(i))) { + return false } } + return true } -// https://w3c.github.io/FileAPI/#dom-filereader-empty -FileReader.EMPTY = FileReader.prototype.EMPTY = 0 -// https://w3c.github.io/FileAPI/#dom-filereader-loading -FileReader.LOADING = FileReader.prototype.LOADING = 1 -// https://w3c.github.io/FileAPI/#dom-filereader-done -FileReader.DONE = FileReader.prototype.DONE = 2 +/** + * @see https://fetch.spec.whatwg.org/#header-name + * @param {string} potentialValue + */ +function isValidHeaderName (potentialValue) { + return isValidHTTPToken(potentialValue) +} -Object.defineProperties(FileReader.prototype, { - EMPTY: staticPropertyDescriptors, - LOADING: staticPropertyDescriptors, - DONE: staticPropertyDescriptors, - readAsArrayBuffer: kEnumerableProperty, - readAsBinaryString: kEnumerableProperty, - readAsText: kEnumerableProperty, - readAsDataURL: kEnumerableProperty, - abort: kEnumerableProperty, - readyState: kEnumerableProperty, - result: kEnumerableProperty, - error: kEnumerableProperty, - onloadstart: kEnumerableProperty, - onprogress: kEnumerableProperty, - onload: kEnumerableProperty, - onabort: kEnumerableProperty, - onerror: kEnumerableProperty, - onloadend: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'FileReader', - writable: false, - enumerable: false, - configurable: true +/** + * @see https://fetch.spec.whatwg.org/#header-value + * @param {string} potentialValue + */ +function isValidHeaderValue (potentialValue) { + // - Has no leading or trailing HTTP tab or space bytes. + // - Contains no 0x00 (NUL) or HTTP newline bytes. + if ( + potentialValue.startsWith('\t') || + potentialValue.startsWith(' ') || + potentialValue.endsWith('\t') || + potentialValue.endsWith(' ') + ) { + return false } -}) -Object.defineProperties(FileReader, { - EMPTY: staticPropertyDescriptors, - LOADING: staticPropertyDescriptors, - DONE: staticPropertyDescriptors -}) + if ( + potentialValue.includes('\0') || + potentialValue.includes('\r') || + potentialValue.includes('\n') + ) { + return false + } -module.exports = { - FileReader + return true } +// https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect +function setRequestReferrerPolicyOnRedirect (request, actualResponse) { + // Given a request request and a response actualResponse, this algorithm + // updates request’s referrer policy according to the Referrer-Policy + // header (if any) in actualResponse. -/***/ }), - -/***/ 5504: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; + // 1. Let policy be the result of executing § 8.1 Parse a referrer policy + // from a Referrer-Policy header on actualResponse. + // 8.1 Parse a referrer policy from a Referrer-Policy header + // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list. + const { headersList } = actualResponse + // 2. Let policy be the empty string. + // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. + // 4. Return policy. + const policyHeader = (headersList.get('referrer-policy') ?? '').split(',') -const { webidl } = __nccwpck_require__(1744) + // Note: As the referrer-policy can contain multiple policies + // separated by comma, we need to loop through all of them + // and pick the first valid one. + // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy + let policy = '' + if (policyHeader.length > 0) { + // The right-most policy takes precedence. + // The left-most policy is the fallback. + for (let i = policyHeader.length; i !== 0; i--) { + const token = policyHeader[i - 1].trim() + if (referrerPolicyTokens.has(token)) { + policy = token + break + } + } + } -const kState = Symbol('ProgressEvent state') + // 2. If policy is not the empty string, then set request’s referrer policy to policy. + if (policy !== '') { + request.referrerPolicy = policy + } +} -/** - * @see https://xhr.spec.whatwg.org/#progressevent - */ -class ProgressEvent extends Event { - constructor (type, eventInitDict = {}) { - type = webidl.converters.DOMString(type) - eventInitDict = webidl.converters.ProgressEventInit(eventInitDict ?? {}) +// https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check +function crossOriginResourcePolicyCheck () { + // TODO + return 'allowed' +} - super(type, eventInitDict) +// https://fetch.spec.whatwg.org/#concept-cors-check +function corsCheck () { + // TODO + return 'success' +} - this[kState] = { - lengthComputable: eventInitDict.lengthComputable, - loaded: eventInitDict.loaded, - total: eventInitDict.total - } - } +// https://fetch.spec.whatwg.org/#concept-tao-check +function TAOCheck () { + // TODO + return 'success' +} - get lengthComputable () { - webidl.brandCheck(this, ProgressEvent) +function appendFetchMetadata (httpRequest) { + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header + // TODO - return this[kState].lengthComputable - } + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header - get loaded () { - webidl.brandCheck(this, ProgressEvent) + // 1. Assert: r’s url is a potentially trustworthy URL. + // TODO - return this[kState].loaded - } + // 2. Let header be a Structured Header whose value is a token. + let header = null - get total () { - webidl.brandCheck(this, ProgressEvent) + // 3. Set header’s value to r’s mode. + header = httpRequest.mode - return this[kState].total - } -} + // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. + httpRequest.headersList.set('sec-fetch-mode', header) -webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ - { - key: 'lengthComputable', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'loaded', - converter: webidl.converters['unsigned long long'], - defaultValue: 0 - }, - { - key: 'total', - converter: webidl.converters['unsigned long long'], - defaultValue: 0 - }, - { - key: 'bubbles', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'cancelable', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'composed', - converter: webidl.converters.boolean, - defaultValue: false - } -]) + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header + // TODO -module.exports = { - ProgressEvent + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header + // TODO } +// https://fetch.spec.whatwg.org/#append-a-request-origin-header +function appendRequestOriginHeader (request) { + // 1. Let serializedOrigin be the result of byte-serializing a request origin with request. + let serializedOrigin = request.origin -/***/ }), - -/***/ 9054: -/***/ ((module) => { - -"use strict"; + // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list. + if (request.responseTainting === 'cors' || request.mode === 'websocket') { + if (serializedOrigin) { + request.headersList.append('origin', serializedOrigin) + } + // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: + } else if (request.method !== 'GET' && request.method !== 'HEAD') { + // 1. Switch on request’s referrer policy: + switch (request.referrerPolicy) { + case 'no-referrer': + // Set serializedOrigin to `null`. + serializedOrigin = null + break + case 'no-referrer-when-downgrade': + case 'strict-origin': + case 'strict-origin-when-cross-origin': + // If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`. + if (request.origin && urlHasHttpsScheme(request.origin) && !urlHasHttpsScheme(requestCurrentURL(request))) { + serializedOrigin = null + } + break + case 'same-origin': + // If request’s origin is not same origin with request’s current URL’s origin, then set serializedOrigin to `null`. + if (!sameOrigin(request, requestCurrentURL(request))) { + serializedOrigin = null + } + break + default: + // Do nothing. + } -module.exports = { - kState: Symbol('FileReader state'), - kResult: Symbol('FileReader result'), - kError: Symbol('FileReader error'), - kLastProgressEventFired: Symbol('FileReader last progress event fired timestamp'), - kEvents: Symbol('FileReader events'), - kAborted: Symbol('FileReader aborted') + if (serializedOrigin) { + // 2. Append (`Origin`, serializedOrigin) to request’s header list. + request.headersList.append('origin', serializedOrigin) + } + } } +function coarsenedSharedCurrentTime (crossOriginIsolatedCapability) { + // TODO + return performance.now() +} -/***/ }), +// https://fetch.spec.whatwg.org/#create-an-opaque-timing-info +function createOpaqueTimingInfo (timingInfo) { + return { + startTime: timingInfo.startTime ?? 0, + redirectStartTime: 0, + redirectEndTime: 0, + postRedirectStartTime: timingInfo.startTime ?? 0, + finalServiceWorkerStartTime: 0, + finalNetworkResponseStartTime: 0, + finalNetworkRequestStartTime: 0, + endTime: 0, + encodedBodySize: 0, + decodedBodySize: 0, + finalConnectionTimingInfo: null + } +} -/***/ 7530: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +// https://html.spec.whatwg.org/multipage/origin.html#policy-container +function makePolicyContainer () { + // Note: the fetch spec doesn't make use of embedder policy or CSP list + return { + referrerPolicy: 'strict-origin-when-cross-origin' + } +} -"use strict"; +// https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container +function clonePolicyContainer (policyContainer) { + return { + referrerPolicy: policyContainer.referrerPolicy + } +} +// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer +function determineRequestsReferrer (request) { + // 1. Let policy be request's referrer policy. + const policy = request.referrerPolicy -const { - kState, - kError, - kResult, - kAborted, - kLastProgressEventFired -} = __nccwpck_require__(9054) -const { ProgressEvent } = __nccwpck_require__(5504) -const { getEncoding } = __nccwpck_require__(4854) -const { DOMException } = __nccwpck_require__(1037) -const { serializeAMimeType, parseMIMEType } = __nccwpck_require__(685) -const { types } = __nccwpck_require__(3837) -const { StringDecoder } = __nccwpck_require__(1576) -const { btoa } = __nccwpck_require__(4300) + // Note: policy cannot (shouldn't) be null or an empty string. + assert(policy) -/** @type {PropertyDescriptor} */ -const staticPropertyDescriptors = { - enumerable: true, - writable: false, - configurable: false -} + // 2. Let environment be request’s client. -/** - * @see https://w3c.github.io/FileAPI/#readOperation - * @param {import('./filereader').FileReader} fr - * @param {import('buffer').Blob} blob - * @param {string} type - * @param {string?} encodingName - */ -function readOperation (fr, blob, type, encodingName) { - // 1. If fr’s state is "loading", throw an InvalidStateError - // DOMException. - if (fr[kState] === 'loading') { - throw new DOMException('Invalid state', 'InvalidStateError') - } + let referrerSource = null - // 2. Set fr’s state to "loading". - fr[kState] = 'loading' + // 3. Switch on request’s referrer: + if (request.referrer === 'client') { + // Note: node isn't a browser and doesn't implement document/iframes, + // so we bypass this step and replace it with our own. - // 3. Set fr’s result to null. - fr[kResult] = null + const globalOrigin = getGlobalOrigin() - // 4. Set fr’s error to null. - fr[kError] = null + if (!globalOrigin || globalOrigin.origin === 'null') { + return 'no-referrer' + } - // 5. Let stream be the result of calling get stream on blob. - /** @type {import('stream/web').ReadableStream} */ - const stream = blob.stream() + // note: we need to clone it as it's mutated + referrerSource = new URL(globalOrigin) + } else if (request.referrer instanceof URL) { + // Let referrerSource be request’s referrer. + referrerSource = request.referrer + } - // 6. Let reader be the result of getting a reader from stream. - const reader = stream.getReader() + // 4. Let request’s referrerURL be the result of stripping referrerSource for + // use as a referrer. + let referrerURL = stripURLForReferrer(referrerSource) - // 7. Let bytes be an empty byte sequence. - /** @type {Uint8Array[]} */ - const bytes = [] + // 5. Let referrerOrigin be the result of stripping referrerSource for use as + // a referrer, with the origin-only flag set to true. + const referrerOrigin = stripURLForReferrer(referrerSource, true) - // 8. Let chunkPromise be the result of reading a chunk from - // stream with reader. - let chunkPromise = reader.read() + // 6. If the result of serializing referrerURL is a string whose length is + // greater than 4096, set referrerURL to referrerOrigin. + if (referrerURL.toString().length > 4096) { + referrerURL = referrerOrigin + } - // 9. Let isFirstChunk be true. - let isFirstChunk = true + const areSameOrigin = sameOrigin(request, referrerURL) + const isNonPotentiallyTrustWorthy = isURLPotentiallyTrustworthy(referrerURL) && + !isURLPotentiallyTrustworthy(request.url) - // 10. In parallel, while true: - // Note: "In parallel" just means non-blocking - // Note 2: readOperation itself cannot be async as double - // reading the body would then reject the promise, instead - // of throwing an error. - ;(async () => { - while (!fr[kAborted]) { - // 1. Wait for chunkPromise to be fulfilled or rejected. - try { - const { done, value } = await chunkPromise + // 8. Execute the switch statements corresponding to the value of policy: + switch (policy) { + case 'origin': return referrerOrigin != null ? referrerOrigin : stripURLForReferrer(referrerSource, true) + case 'unsafe-url': return referrerURL + case 'same-origin': + return areSameOrigin ? referrerOrigin : 'no-referrer' + case 'origin-when-cross-origin': + return areSameOrigin ? referrerURL : referrerOrigin + case 'strict-origin-when-cross-origin': { + const currentURL = requestCurrentURL(request) - // 2. If chunkPromise is fulfilled, and isFirstChunk is - // true, queue a task to fire a progress event called - // loadstart at fr. - if (isFirstChunk && !fr[kAborted]) { - queueMicrotask(() => { - fireAProgressEvent('loadstart', fr) - }) - } + // 1. If the origin of referrerURL and the origin of request’s current + // URL are the same, then return referrerURL. + if (sameOrigin(referrerURL, currentURL)) { + return referrerURL + } - // 3. Set isFirstChunk to false. - isFirstChunk = false + // 2. If referrerURL is a potentially trustworthy URL and request’s + // current URL is not a potentially trustworthy URL, then return no + // referrer. + if (isURLPotentiallyTrustworthy(referrerURL) && !isURLPotentiallyTrustworthy(currentURL)) { + return 'no-referrer' + } - // 4. If chunkPromise is fulfilled with an object whose - // done property is false and whose value property is - // a Uint8Array object, run these steps: - if (!done && types.isUint8Array(value)) { - // 1. Let bs be the byte sequence represented by the - // Uint8Array object. + // 3. Return referrerOrigin. + return referrerOrigin + } + case 'strict-origin': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ + case 'no-referrer-when-downgrade': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ - // 2. Append bs to bytes. - bytes.push(value) + default: // eslint-disable-line + return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin + } +} - // 3. If roughly 50ms have passed since these steps - // were last invoked, queue a task to fire a - // progress event called progress at fr. - if ( - ( - fr[kLastProgressEventFired] === undefined || - Date.now() - fr[kLastProgressEventFired] >= 50 - ) && - !fr[kAborted] - ) { - fr[kLastProgressEventFired] = Date.now() - queueMicrotask(() => { - fireAProgressEvent('progress', fr) - }) - } +/** + * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url + * @param {URL} url + * @param {boolean|undefined} originOnly + */ +function stripURLForReferrer (url, originOnly) { + // 1. Assert: url is a URL. + assert(url instanceof URL) - // 4. Set chunkPromise to the result of reading a - // chunk from stream with reader. - chunkPromise = reader.read() - } else if (done) { - // 5. Otherwise, if chunkPromise is fulfilled with an - // object whose done property is true, queue a task - // to run the following steps and abort this algorithm: - queueMicrotask(() => { - // 1. Set fr’s state to "done". - fr[kState] = 'done' + // 2. If url’s scheme is a local scheme, then return no referrer. + if (url.protocol === 'file:' || url.protocol === 'about:' || url.protocol === 'blank:') { + return 'no-referrer' + } - // 2. Let result be the result of package data given - // bytes, type, blob’s type, and encodingName. - try { - const result = packageData(bytes, type, blob.type, encodingName) + // 3. Set url’s username to the empty string. + url.username = '' - // 4. Else: + // 4. Set url’s password to the empty string. + url.password = '' - if (fr[kAborted]) { - return - } + // 5. Set url’s fragment to null. + url.hash = '' - // 1. Set fr’s result to result. - fr[kResult] = result + // 6. If the origin-only flag is true, then: + if (originOnly) { + // 1. Set url’s path to « the empty string ». + url.pathname = '' - // 2. Fire a progress event called load at the fr. - fireAProgressEvent('load', fr) - } catch (error) { - // 3. If package data threw an exception error: + // 2. Set url’s query to null. + url.search = '' + } - // 1. Set fr’s error to error. - fr[kError] = error + // 7. Return url. + return url +} - // 2. Fire a progress event called error at fr. - fireAProgressEvent('error', fr) - } +function isURLPotentiallyTrustworthy (url) { + if (!(url instanceof URL)) { + return false + } - // 5. If fr’s state is not "loading", fire a progress - // event called loadend at the fr. - if (fr[kState] !== 'loading') { - fireAProgressEvent('loadend', fr) - } - }) + // If child of about, return true + if (url.href === 'about:blank' || url.href === 'about:srcdoc') { + return true + } - break - } - } catch (error) { - if (fr[kAborted]) { - return - } + // If scheme is data, return true + if (url.protocol === 'data:') return true - // 6. Otherwise, if chunkPromise is rejected with an - // error error, queue a task to run the following - // steps and abort this algorithm: - queueMicrotask(() => { - // 1. Set fr’s state to "done". - fr[kState] = 'done' + // If file, return true + if (url.protocol === 'file:') return true - // 2. Set fr’s error to error. - fr[kError] = error + return isOriginPotentiallyTrustworthy(url.origin) - // 3. Fire a progress event called error at fr. - fireAProgressEvent('error', fr) + function isOriginPotentiallyTrustworthy (origin) { + // If origin is explicitly null, return false + if (origin == null || origin === 'null') return false - // 4. If fr’s state is not "loading", fire a progress - // event called loadend at fr. - if (fr[kState] !== 'loading') { - fireAProgressEvent('loadend', fr) - } - }) + const originAsURL = new URL(origin) - break - } + // If secure, return true + if (originAsURL.protocol === 'https:' || originAsURL.protocol === 'wss:') { + return true } - })() -} -/** - * @see https://w3c.github.io/FileAPI/#fire-a-progress-event - * @see https://dom.spec.whatwg.org/#concept-event-fire - * @param {string} e The name of the event - * @param {import('./filereader').FileReader} reader - */ -function fireAProgressEvent (e, reader) { - // The progress event e does not bubble. e.bubbles must be false - // The progress event e is NOT cancelable. e.cancelable must be false - const event = new ProgressEvent(e, { - bubbles: false, - cancelable: false - }) + // If localhost or variants, return true + if (/^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test(originAsURL.hostname) || + (originAsURL.hostname === 'localhost' || originAsURL.hostname.includes('localhost.')) || + (originAsURL.hostname.endsWith('.localhost'))) { + return true + } - reader.dispatchEvent(event) + // If any other, return false + return false + } } /** - * @see https://w3c.github.io/FileAPI/#blob-package-data - * @param {Uint8Array[]} bytes - * @param {string} type - * @param {string?} mimeType - * @param {string?} encodingName + * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist + * @param {Uint8Array} bytes + * @param {string} metadataList */ -function packageData (bytes, type, mimeType, encodingName) { - // 1. A Blob has an associated package data algorithm, given - // bytes, a type, a optional mimeType, and a optional - // encodingName, which switches on type and runs the - // associated steps: - - switch (type) { - case 'DataURL': { - // 1. Return bytes as a DataURL [RFC2397] subject to - // the considerations below: - // * Use mimeType as part of the Data URL if it is - // available in keeping with the Data URL - // specification [RFC2397]. - // * If mimeType is not available return a Data URL - // without a media-type. [RFC2397]. +function bytesMatch (bytes, metadataList) { + // If node is not built with OpenSSL support, we cannot check + // a request's integrity, so allow it by default (the spec will + // allow requests if an invalid hash is given, as precedence). + /* istanbul ignore if: only if node is built with --without-ssl */ + if (crypto === undefined) { + return true + } - // https://datatracker.ietf.org/doc/html/rfc2397#section-3 - // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data - // mediatype := [ type "/" subtype ] *( ";" parameter ) - // data := *urlchar - // parameter := attribute "=" value - let dataURL = 'data:' + // 1. Let parsedMetadata be the result of parsing metadataList. + const parsedMetadata = parseMetadata(metadataList) - const parsed = parseMIMEType(mimeType || 'application/octet-stream') + // 2. If parsedMetadata is no metadata, return true. + if (parsedMetadata === 'no metadata') { + return true + } - if (parsed !== 'failure') { - dataURL += serializeAMimeType(parsed) - } + // 3. If parsedMetadata is the empty set, return true. + if (parsedMetadata.length === 0) { + return true + } - dataURL += ';base64,' + // 4. Let metadata be the result of getting the strongest + // metadata from parsedMetadata. + const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo)) + // get the strongest algorithm + const strongest = list[0].algo + // get all entries that use the strongest algorithm; ignore weaker + const metadata = list.filter((item) => item.algo === strongest) - const decoder = new StringDecoder('latin1') + // 5. For each item in metadata: + for (const item of metadata) { + // 1. Let algorithm be the alg component of item. + const algorithm = item.algo - for (const chunk of bytes) { - dataURL += btoa(decoder.write(chunk)) - } + // 2. Let expectedValue be the val component of item. + let expectedValue = item.hash - dataURL += btoa(decoder.end()) + // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e + // "be liberal with padding". This is annoying, and it's not even in the spec. - return dataURL + if (expectedValue.endsWith('==')) { + expectedValue = expectedValue.slice(0, -2) } - case 'Text': { - // 1. Let encoding be failure - let encoding = 'failure' - - // 2. If the encodingName is present, set encoding to the - // result of getting an encoding from encodingName. - if (encodingName) { - encoding = getEncoding(encodingName) - } - - // 3. If encoding is failure, and mimeType is present: - if (encoding === 'failure' && mimeType) { - // 1. Let type be the result of parse a MIME type - // given mimeType. - const type = parseMIMEType(mimeType) - - // 2. If type is not failure, set encoding to the result - // of getting an encoding from type’s parameters["charset"]. - if (type !== 'failure') { - encoding = getEncoding(type.parameters.get('charset')) - } - } - // 4. If encoding is failure, then set encoding to UTF-8. - if (encoding === 'failure') { - encoding = 'UTF-8' - } + // 3. Let actualValue be the result of applying algorithm to bytes. + let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64') - // 5. Decode bytes using fallback encoding encoding, and - // return the result. - return decode(bytes, encoding) + if (actualValue.endsWith('==')) { + actualValue = actualValue.slice(0, -2) } - case 'ArrayBuffer': { - // Return a new ArrayBuffer whose contents are bytes. - const sequence = combineByteSequences(bytes) - return sequence.buffer + // 4. If actualValue is a case-sensitive match for expectedValue, + // return true. + if (actualValue === expectedValue) { + return true } - case 'BinaryString': { - // Return bytes as a binary string, in which every byte - // is represented by a code unit of equal value [0..255]. - let binaryString = '' - - const decoder = new StringDecoder('latin1') - for (const chunk of bytes) { - binaryString += decoder.write(chunk) - } + let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url') - binaryString += decoder.end() + if (actualBase64URL.endsWith('==')) { + actualBase64URL = actualBase64URL.slice(0, -2) + } - return binaryString + if (actualBase64URL === expectedValue) { + return true } } + + // 6. Return false. + return false } +// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options +// https://www.w3.org/TR/CSP2/#source-list-syntax +// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 +const parseHashWithOptions = /((?sha256|sha384|sha512)-(?[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i + /** - * @see https://encoding.spec.whatwg.org/#decode - * @param {Uint8Array[]} ioQueue - * @param {string} encoding + * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata + * @param {string} metadata */ -function decode (ioQueue, encoding) { - const bytes = combineByteSequences(ioQueue) - - // 1. Let BOMEncoding be the result of BOM sniffing ioQueue. - const BOMEncoding = BOMSniffing(bytes) +function parseMetadata (metadata) { + // 1. Let result be the empty set. + /** @type {{ algo: string, hash: string }[]} */ + const result = [] - let slice = 0 + // 2. Let empty be equal to true. + let empty = true - // 2. If BOMEncoding is non-null: - if (BOMEncoding !== null) { - // 1. Set encoding to BOMEncoding. - encoding = BOMEncoding + const supportedHashes = crypto.getHashes() - // 2. Read three bytes from ioQueue, if BOMEncoding is - // UTF-8; otherwise read two bytes. - // (Do nothing with those bytes.) - slice = BOMEncoding === 'UTF-8' ? 3 : 2 - } + // 3. For each token returned by splitting metadata on spaces: + for (const token of metadata.split(' ')) { + // 1. Set empty to false. + empty = false - // 3. Process a queue with an instance of encoding’s - // decoder, ioQueue, output, and "replacement". + // 2. Parse token as a hash-with-options. + const parsedToken = parseHashWithOptions.exec(token) - // 4. Return output. + // 3. If token does not parse, continue to the next token. + if (parsedToken === null || parsedToken.groups === undefined) { + // Note: Chromium blocks the request at this point, but Firefox + // gives a warning that an invalid integrity was given. The + // correct behavior is to ignore these, and subsequently not + // check the integrity of the resource. + continue + } - const sliced = bytes.slice(slice) - return new TextDecoder(encoding).decode(sliced) -} + // 4. Let algorithm be the hash-algo component of token. + const algorithm = parsedToken.groups.algo -/** - * @see https://encoding.spec.whatwg.org/#bom-sniff - * @param {Uint8Array} ioQueue - */ -function BOMSniffing (ioQueue) { - // 1. Let BOM be the result of peeking 3 bytes from ioQueue, - // converted to a byte sequence. - const [a, b, c] = ioQueue + // 5. If algorithm is a hash function recognized by the user + // agent, add the parsed token to result. + if (supportedHashes.includes(algorithm.toLowerCase())) { + result.push(parsedToken.groups) + } + } - // 2. For each of the rows in the table below, starting with - // the first one and going down, if BOM starts with the - // bytes given in the first column, then return the - // encoding given in the cell in the second column of that - // row. Otherwise, return null. - if (a === 0xEF && b === 0xBB && c === 0xBF) { - return 'UTF-8' - } else if (a === 0xFE && b === 0xFF) { - return 'UTF-16BE' - } else if (a === 0xFF && b === 0xFE) { - return 'UTF-16LE' + // 4. Return no metadata if empty is true, otherwise return result. + if (empty === true) { + return 'no metadata' } - return null + return result +} + +// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request +function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) { + // TODO } /** - * @param {Uint8Array[]} sequences + * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin} + * @param {URL} A + * @param {URL} B */ -function combineByteSequences (sequences) { - const size = sequences.reduce((a, b) => { - return a + b.byteLength - }, 0) - - let offset = 0 +function sameOrigin (A, B) { + // 1. If A and B are the same opaque origin, then return true. + if (A.origin === B.origin && A.origin === 'null') { + return true + } - return sequences.reduce((a, b) => { - a.set(b, offset) - offset += b.byteLength - return a - }, new Uint8Array(size)) -} + // 2. If A and B are both tuple origins and their schemes, + // hosts, and port are identical, then return true. + if (A.protocol === B.protocol && A.hostname === B.hostname && A.port === B.port) { + return true + } -module.exports = { - staticPropertyDescriptors, - readOperation, - fireAProgressEvent + // 3. Return false. + return false } +function createDeferredPromise () { + let res + let rej + const promise = new Promise((resolve, reject) => { + res = resolve + rej = reject + }) -/***/ }), - -/***/ 1892: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -// We include a version number for the Dispatcher API. In case of breaking changes, -// this version number must be increased to avoid conflicts. -const globalDispatcher = Symbol.for('undici.globalDispatcher.1') -const { InvalidArgumentError } = __nccwpck_require__(8045) -const Agent = __nccwpck_require__(7890) - -if (getGlobalDispatcher() === undefined) { - setGlobalDispatcher(new Agent()) + return { promise, resolve: res, reject: rej } } -function setGlobalDispatcher (agent) { - if (!agent || typeof agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument agent must implement Agent') - } - Object.defineProperty(globalThis, globalDispatcher, { - value: agent, - writable: true, - enumerable: false, - configurable: false - }) +function isAborted (fetchParams) { + return fetchParams.controller.state === 'aborted' } -function getGlobalDispatcher () { - return globalThis[globalDispatcher] +function isCancelled (fetchParams) { + return fetchParams.controller.state === 'aborted' || + fetchParams.controller.state === 'terminated' } -module.exports = { - setGlobalDispatcher, - getGlobalDispatcher +const normalizeMethodRecord = { + delete: 'DELETE', + DELETE: 'DELETE', + get: 'GET', + GET: 'GET', + head: 'HEAD', + HEAD: 'HEAD', + options: 'OPTIONS', + OPTIONS: 'OPTIONS', + post: 'POST', + POST: 'POST', + put: 'PUT', + PUT: 'PUT' } +// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`. +Object.setPrototypeOf(normalizeMethodRecord, null) -/***/ }), - -/***/ 6930: -/***/ ((module) => { - -"use strict"; - +/** + * @see https://fetch.spec.whatwg.org/#concept-method-normalize + * @param {string} method + */ +function normalizeMethod (method) { + return normalizeMethodRecord[method.toLowerCase()] ?? method +} -module.exports = class DecoratorHandler { - constructor (handler) { - this.handler = handler - } +// https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string +function serializeJavascriptValueToJSONString (value) { + // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »). + const result = JSON.stringify(value) - onConnect (...args) { - return this.handler.onConnect(...args) + // 2. If result is undefined, then throw a TypeError. + if (result === undefined) { + throw new TypeError('Value is not JSON serializable') } - onError (...args) { - return this.handler.onError(...args) - } + // 3. Assert: result is a string. + assert(typeof result === 'string') - onUpgrade (...args) { - return this.handler.onUpgrade(...args) - } + // 4. Return result. + return result +} - onHeaders (...args) { - return this.handler.onHeaders(...args) - } +// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object +const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())) - onData (...args) { - return this.handler.onData(...args) +/** + * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object + * @param {() => unknown[]} iterator + * @param {string} name name of the instance + * @param {'key'|'value'|'key+value'} kind + */ +function makeIterator (iterator, name, kind) { + const object = { + index: 0, + kind, + target: iterator } - onComplete (...args) { - return this.handler.onComplete(...args) - } + const i = { + next () { + // 1. Let interface be the interface for which the iterator prototype object exists. - onBodySent (...args) { - return this.handler.onBodySent(...args) - } -} + // 2. Let thisValue be the this value. + // 3. Let object be ? ToObject(thisValue). -/***/ }), + // 4. If object is a platform object, then perform a security + // check, passing: -/***/ 2860: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 5. If object is not a default iterator object for interface, + // then throw a TypeError. + if (Object.getPrototypeOf(this) !== i) { + throw new TypeError( + `'next' called on an object that does not implement interface ${name} Iterator.` + ) + } -"use strict"; + // 6. Let index be object’s index. + // 7. Let kind be object’s kind. + // 8. Let values be object’s target's value pairs to iterate over. + const { index, kind, target } = object + const values = target() + // 9. Let len be the length of values. + const len = values.length -const util = __nccwpck_require__(3983) -const { kBodyUsed } = __nccwpck_require__(2785) -const assert = __nccwpck_require__(9491) -const { InvalidArgumentError } = __nccwpck_require__(8045) -const EE = __nccwpck_require__(2361) + // 10. If index is greater than or equal to len, then return + // CreateIterResultObject(undefined, true). + if (index >= len) { + return { value: undefined, done: true } + } -const redirectableStatusCodes = [300, 301, 302, 303, 307, 308] + // 11. Let pair be the entry in values at index index. + const pair = values[index] -const kBody = Symbol('body') + // 12. Set object’s index to index + 1. + object.index = index + 1 -class BodyAsyncIterable { - constructor (body) { - this[kBody] = body - this[kBodyUsed] = false + // 13. Return the iterator result for pair and kind. + return iteratorResult(pair, kind) + }, + // The class string of an iterator prototype object for a given interface is the + // result of concatenating the identifier of the interface and the string " Iterator". + [Symbol.toStringTag]: `${name} Iterator` } - async * [Symbol.asyncIterator] () { - assert(!this[kBodyUsed], 'disturbed') - this[kBodyUsed] = true - yield * this[kBody] - } + // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%. + Object.setPrototypeOf(i, esIteratorPrototype) + // esIteratorPrototype needs to be the prototype of i + // which is the prototype of an empty object. Yes, it's confusing. + return Object.setPrototypeOf({}, i) } -class RedirectHandler { - constructor (dispatch, maxRedirections, opts, handler) { - if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { - throw new InvalidArgumentError('maxRedirections must be a positive number') +// https://webidl.spec.whatwg.org/#iterator-result +function iteratorResult (pair, kind) { + let result + + // 1. Let result be a value determined by the value of kind: + switch (kind) { + case 'key': { + // 1. Let idlKey be pair’s key. + // 2. Let key be the result of converting idlKey to an + // ECMAScript value. + // 3. result is key. + result = pair[0] + break + } + case 'value': { + // 1. Let idlValue be pair’s value. + // 2. Let value be the result of converting idlValue to + // an ECMAScript value. + // 3. result is value. + result = pair[1] + break + } + case 'key+value': { + // 1. Let idlKey be pair’s key. + // 2. Let idlValue be pair’s value. + // 3. Let key be the result of converting idlKey to an + // ECMAScript value. + // 4. Let value be the result of converting idlValue to + // an ECMAScript value. + // 5. Let array be ! ArrayCreate(2). + // 6. Call ! CreateDataProperty(array, "0", key). + // 7. Call ! CreateDataProperty(array, "1", value). + // 8. result is array. + result = pair + break } + } - util.validateHandler(handler, opts.method, opts.upgrade) + // 2. Return CreateIterResultObject(result, false). + return { value: result, done: false } +} - this.dispatch = dispatch - this.location = null - this.abort = null - this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy - this.maxRedirections = maxRedirections - this.handler = handler - this.history = [] +/** + * @see https://fetch.spec.whatwg.org/#body-fully-read + */ +async function fullyReadBody (body, processBody, processBodyError) { + // 1. If taskDestination is null, then set taskDestination to + // the result of starting a new parallel queue. - if (util.isStream(this.opts.body)) { - // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp - // so that it can be dispatched again? - // TODO (fix): Do we need 100-expect support to provide a way to do this properly? - if (util.bodyLength(this.opts.body) === 0) { - this.opts.body - .on('data', function () { - assert(false) - }) - } + // 2. Let successSteps given a byte sequence bytes be to queue a + // fetch task to run processBody given bytes, with taskDestination. + const successSteps = processBody - if (typeof this.opts.body.readableDidRead !== 'boolean') { - this.opts.body[kBodyUsed] = false - EE.prototype.on.call(this.opts.body, 'data', function () { - this[kBodyUsed] = true - }) - } - } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') { - // TODO (fix): We can't access ReadableStream internal state - // to determine whether or not it has been disturbed. This is just - // a workaround. - this.opts.body = new BodyAsyncIterable(this.opts.body) - } else if ( - this.opts.body && - typeof this.opts.body !== 'string' && - !ArrayBuffer.isView(this.opts.body) && - util.isIterable(this.opts.body) - ) { - // TODO: Should we allow re-using iterable if !this.opts.idempotent - // or through some other flag? - this.opts.body = new BodyAsyncIterable(this.opts.body) - } - } + // 3. Let errorSteps be to queue a fetch task to run processBodyError, + // with taskDestination. + const errorSteps = processBodyError - onConnect (abort) { - this.abort = abort - this.handler.onConnect(abort, { history: this.history }) - } + // 4. Let reader be the result of getting a reader for body’s stream. + // If that threw an exception, then run errorSteps with that + // exception and return. + let reader - onUpgrade (statusCode, headers, socket) { - this.handler.onUpgrade(statusCode, headers, socket) + try { + reader = body.stream.getReader() + } catch (e) { + errorSteps(e) + return } - onError (error) { - this.handler.onError(error) + // 5. Read all bytes from reader, given successSteps and errorSteps. + try { + const result = await readAllBytes(reader) + successSteps(result) + } catch (e) { + errorSteps(e) } +} - onHeaders (statusCode, headers, resume, statusText) { - this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) - ? null - : parseLocation(statusCode, headers) +/** @type {ReadableStream} */ +let ReadableStream = globalThis.ReadableStream - if (this.opts.origin) { - this.history.push(new URL(this.opts.path, this.opts.origin)) - } +function isReadableStreamLike (stream) { + if (!ReadableStream) { + ReadableStream = (__nccwpck_require__(5356).ReadableStream) + } - if (!this.location) { - return this.handler.onHeaders(statusCode, headers, resume, statusText) - } + return stream instanceof ReadableStream || ( + stream[Symbol.toStringTag] === 'ReadableStream' && + typeof stream.tee === 'function' + ) +} - const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))) - const path = search ? `${pathname}${search}` : pathname +const MAXIMUM_ARGUMENT_LENGTH = 65535 - // Remove headers referring to the original URL. - // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. - // https://tools.ietf.org/html/rfc7231#section-6.4 - this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin) - this.opts.path = path - this.opts.origin = origin - this.opts.maxRedirections = 0 - this.opts.query = null +/** + * @see https://infra.spec.whatwg.org/#isomorphic-decode + * @param {number[]|Uint8Array} input + */ +function isomorphicDecode (input) { + // 1. To isomorphic decode a byte sequence input, return a string whose code point + // length is equal to input’s length and whose code points have the same values + // as the values of input’s bytes, in the same order. - // https://tools.ietf.org/html/rfc7231#section-6.4.4 - // In case of HTTP 303, always replace method to be either HEAD or GET - if (statusCode === 303 && this.opts.method !== 'HEAD') { - this.opts.method = 'GET' - this.opts.body = null - } + if (input.length < MAXIMUM_ARGUMENT_LENGTH) { + return String.fromCharCode(...input) } - onData (chunk) { - if (this.location) { - /* - https://tools.ietf.org/html/rfc7231#section-6.4 - - TLDR: undici always ignores 3xx response bodies. - - Redirection is used to serve the requested resource from another URL, so it is assumes that - no body is generated (and thus can be ignored). Even though generating a body is not prohibited. - - For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually - (which means it's optional and not mandated) contain just an hyperlink to the value of - the Location response header, so the body can be ignored safely. + return input.reduce((previous, current) => previous + String.fromCharCode(current), '') +} - For status 300, which is "Multiple Choices", the spec mentions both generating a Location - response header AND a response body with the other possible location to follow. - Since the spec explicitily chooses not to specify a format for such body and leave it to - servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. - */ - } else { - return this.handler.onData(chunk) +/** + * @param {ReadableStreamController} controller + */ +function readableStreamClose (controller) { + try { + controller.close() + } catch (err) { + // TODO: add comment explaining why this error occurs. + if (!err.message.includes('Controller is already closed')) { + throw err } } +} - onComplete (trailers) { - if (this.location) { - /* - https://tools.ietf.org/html/rfc7231#section-6.4 +/** + * @see https://infra.spec.whatwg.org/#isomorphic-encode + * @param {string} input + */ +function isomorphicEncode (input) { + // 1. Assert: input contains no code points greater than U+00FF. + for (let i = 0; i < input.length; i++) { + assert(input.charCodeAt(i) <= 0xFF) + } - TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections - and neither are useful if present. + // 2. Return a byte sequence whose length is equal to input’s code + // point length and whose bytes have the same values as the + // values of input’s code points, in the same order + return input +} - See comment on onData method above for more detailed informations. - */ +/** + * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes + * @see https://streams.spec.whatwg.org/#read-loop + * @param {ReadableStreamDefaultReader} reader + */ +async function readAllBytes (reader) { + const bytes = [] + let byteLength = 0 - this.location = null - this.abort = null + while (true) { + const { done, value: chunk } = await reader.read() - this.dispatch(this.opts, this) - } else { - this.handler.onComplete(trailers) + if (done) { + // 1. Call successSteps with bytes. + return Buffer.concat(bytes, byteLength) } - } - onBodySent (chunk) { - if (this.handler.onBodySent) { - this.handler.onBodySent(chunk) + // 1. If chunk is not a Uint8Array object, call failureSteps + // with a TypeError and abort these steps. + if (!isUint8Array(chunk)) { + throw new TypeError('Received non-Uint8Array chunk') } - } -} -function parseLocation (statusCode, headers) { - if (redirectableStatusCodes.indexOf(statusCode) === -1) { - return null - } + // 2. Append the bytes represented by chunk to bytes. + bytes.push(chunk) + byteLength += chunk.length - for (let i = 0; i < headers.length; i += 2) { - if (headers[i].toString().toLowerCase() === 'location') { - return headers[i + 1] - } + // 3. Read-loop given reader, bytes, successSteps, and failureSteps. } } -// https://tools.ietf.org/html/rfc7231#section-6.4.4 -function shouldRemoveHeader (header, removeContent, unknownOrigin) { - return ( - (header.length === 4 && header.toString().toLowerCase() === 'host') || - (removeContent && header.toString().toLowerCase().indexOf('content-') === 0) || - (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') || - (unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie') - ) +/** + * @see https://fetch.spec.whatwg.org/#is-local + * @param {URL} url + */ +function urlIsLocal (url) { + assert('protocol' in url) // ensure it's a url object + + const protocol = url.protocol + + return protocol === 'about:' || protocol === 'blob:' || protocol === 'data:' } -// https://tools.ietf.org/html/rfc7231#section-6.4 -function cleanRequestHeaders (headers, removeContent, unknownOrigin) { - const ret = [] - if (Array.isArray(headers)) { - for (let i = 0; i < headers.length; i += 2) { - if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { - ret.push(headers[i], headers[i + 1]) - } - } - } else if (headers && typeof headers === 'object') { - for (const key of Object.keys(headers)) { - if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { - ret.push(key, headers[key]) - } - } - } else { - assert(headers == null, 'headers must be an object or an array') +/** + * @param {string|URL} url + */ +function urlHasHttpsScheme (url) { + if (typeof url === 'string') { + return url.startsWith('https:') } - return ret + + return url.protocol === 'https:' } -module.exports = RedirectHandler +/** + * @see https://fetch.spec.whatwg.org/#http-scheme + * @param {URL} url + */ +function urlIsHttpHttpsScheme (url) { + assert('protocol' in url) // ensure it's a url object + + const protocol = url.protocol + + return protocol === 'http:' || protocol === 'https:' +} + +/** + * Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0. + */ +const hasOwn = Object.hasOwn || ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)) + +module.exports = { + isAborted, + isCancelled, + createDeferredPromise, + ReadableStreamFrom, + toUSVString, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + coarsenedSharedCurrentTime, + determineRequestsReferrer, + makePolicyContainer, + clonePolicyContainer, + appendFetchMetadata, + appendRequestOriginHeader, + TAOCheck, + corsCheck, + crossOriginResourcePolicyCheck, + createOpaqueTimingInfo, + setRequestReferrerPolicyOnRedirect, + isValidHTTPToken, + requestBadPort, + requestCurrentURL, + responseURL, + responseLocationURL, + isBlobLike, + isURLPotentiallyTrustworthy, + isValidReasonPhrase, + sameOrigin, + normalizeMethod, + serializeJavascriptValueToJSONString, + makeIterator, + isValidHeaderName, + isValidHeaderValue, + hasOwn, + isErrorLike, + fullyReadBody, + bytesMatch, + isReadableStreamLike, + readableStreamClose, + isomorphicEncode, + isomorphicDecode, + urlIsLocal, + urlHasHttpsScheme, + urlIsHttpHttpsScheme, + readAllBytes, + normalizeMethodRecord +} /***/ }), -/***/ 2286: +/***/ 1744: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const assert = __nccwpck_require__(9491) +"use strict"; -const { kRetryHandlerDefaultRetry } = __nccwpck_require__(2785) -const { RequestRetryError } = __nccwpck_require__(8045) -const { isDisturbed, parseHeaders, parseRangeHeader } = __nccwpck_require__(3983) -function calculateRetryAfterHeader (retryAfter) { - const current = Date.now() - const diff = new Date(retryAfter).getTime() - current +const { types } = __nccwpck_require__(3837) +const { hasOwn, toUSVString } = __nccwpck_require__(2538) - return diff +/** @type {import('../../types/webidl').Webidl} */ +const webidl = {} +webidl.converters = {} +webidl.util = {} +webidl.errors = {} + +webidl.errors.exception = function (message) { + return new TypeError(`${message.header}: ${message.message}`) } -class RetryHandler { - constructor (opts, handlers) { - const { retryOptions, ...dispatchOpts } = opts - const { - // Retry scoped - retry: retryFn, - maxRetries, - maxTimeout, - minTimeout, - timeoutFactor, - // Response scoped - methods, - errorCodes, - retryAfter, - statusCodes - } = retryOptions ?? {} +webidl.errors.conversionFailed = function (context) { + const plural = context.types.length === 1 ? '' : ' one of' + const message = + `${context.argument} could not be converted to` + + `${plural}: ${context.types.join(', ')}.` - this.dispatch = handlers.dispatch - this.handler = handlers.handler - this.opts = dispatchOpts - this.abort = null - this.aborted = false - this.retryOpts = { - retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], - retryAfter: retryAfter ?? true, - maxTimeout: maxTimeout ?? 30 * 1000, // 30s, - timeout: minTimeout ?? 500, // .5s - timeoutFactor: timeoutFactor ?? 2, - maxRetries: maxRetries ?? 5, - // What errors we should retry - methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], - // Indicates which errors to retry - statusCodes: statusCodes ?? [500, 502, 503, 504, 429], - // List of errors to retry - errorCodes: errorCodes ?? [ - 'ECONNRESET', - 'ECONNREFUSED', - 'ENOTFOUND', - 'ENETDOWN', - 'ENETUNREACH', - 'EHOSTDOWN', - 'EHOSTUNREACH', - 'EPIPE' - ] - } + return webidl.errors.exception({ + header: context.prefix, + message + }) +} - this.retryCount = 0 - this.start = 0 - this.end = null - this.etag = null - this.resume = null +webidl.errors.invalidArgument = function (context) { + return webidl.errors.exception({ + header: context.prefix, + message: `"${context.value}" is an invalid ${context.type}.` + }) +} - // Handle possible onConnect duplication - this.handler.onConnect(reason => { - this.aborted = true - if (this.abort) { - this.abort(reason) - } else { - this.reason = reason - } - }) +// https://webidl.spec.whatwg.org/#implements +webidl.brandCheck = function (V, I, opts = undefined) { + if (opts?.strict !== false && !(V instanceof I)) { + throw new TypeError('Illegal invocation') + } else { + return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag] } +} - onRequestSent () { - if (this.handler.onRequestSent) { - this.handler.onRequestSent() - } +webidl.argumentLengthCheck = function ({ length }, min, ctx) { + if (length < min) { + throw webidl.errors.exception({ + message: `${min} argument${min !== 1 ? 's' : ''} required, ` + + `but${length ? ' only' : ''} ${length} found.`, + ...ctx + }) } +} - onUpgrade (statusCode, headers, socket) { - if (this.handler.onUpgrade) { - this.handler.onUpgrade(statusCode, headers, socket) +webidl.illegalConstructor = function () { + throw webidl.errors.exception({ + header: 'TypeError', + message: 'Illegal constructor' + }) +} + +// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values +webidl.util.Type = function (V) { + switch (typeof V) { + case 'undefined': return 'Undefined' + case 'boolean': return 'Boolean' + case 'string': return 'String' + case 'symbol': return 'Symbol' + case 'number': return 'Number' + case 'bigint': return 'BigInt' + case 'function': + case 'object': { + if (V === null) { + return 'Null' + } + + return 'Object' } } +} - onConnect (abort) { - if (this.aborted) { - abort(this.reason) +// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint +webidl.util.ConvertToInt = function (V, bitLength, signedness, opts = {}) { + let upperBound + let lowerBound + + // 1. If bitLength is 64, then: + if (bitLength === 64) { + // 1. Let upperBound be 2^53 − 1. + upperBound = Math.pow(2, 53) - 1 + + // 2. If signedness is "unsigned", then let lowerBound be 0. + if (signedness === 'unsigned') { + lowerBound = 0 } else { - this.abort = abort + // 3. Otherwise let lowerBound be −2^53 + 1. + lowerBound = Math.pow(-2, 53) + 1 } - } + } else if (signedness === 'unsigned') { + // 2. Otherwise, if signedness is "unsigned", then: - onBodySent (chunk) { - if (this.handler.onBodySent) return this.handler.onBodySent(chunk) - } + // 1. Let lowerBound be 0. + lowerBound = 0 - static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { - const { statusCode, code, headers } = err - const { method, retryOptions } = opts - const { - maxRetries, - timeout, - maxTimeout, - timeoutFactor, - statusCodes, - errorCodes, - methods - } = retryOptions - let { counter, currentTimeout } = state + // 2. Let upperBound be 2^bitLength − 1. + upperBound = Math.pow(2, bitLength) - 1 + } else { + // 3. Otherwise: - currentTimeout = - currentTimeout != null && currentTimeout > 0 ? currentTimeout : timeout + // 1. Let lowerBound be -2^bitLength − 1. + lowerBound = Math.pow(-2, bitLength) - 1 - // Any code that is not a Undici's originated and allowed to retry - if ( - code && - code !== 'UND_ERR_REQ_RETRY' && - code !== 'UND_ERR_SOCKET' && - !errorCodes.includes(code) - ) { - cb(err) - return - } + // 2. Let upperBound be 2^bitLength − 1 − 1. + upperBound = Math.pow(2, bitLength - 1) - 1 + } - // If a set of method are provided and the current method is not in the list - if (Array.isArray(methods) && !methods.includes(method)) { - cb(err) - return - } + // 4. Let x be ? ToNumber(V). + let x = Number(V) - // If a set of status code are provided and the current status code is not in the list + // 5. If x is −0, then set x to +0. + if (x === 0) { + x = 0 + } + + // 6. If the conversion is to an IDL type associated + // with the [EnforceRange] extended attribute, then: + if (opts.enforceRange === true) { + // 1. If x is NaN, +∞, or −∞, then throw a TypeError. if ( - statusCode != null && - Array.isArray(statusCodes) && - !statusCodes.includes(statusCode) + Number.isNaN(x) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY ) { - cb(err) - return + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Could not convert ${V} to an integer.` + }) } - // If we reached the max number of retries - if (counter > maxRetries) { - cb(err) - return - } + // 2. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x) - let retryAfterHeader = headers != null && headers['retry-after'] - if (retryAfterHeader) { - retryAfterHeader = Number(retryAfterHeader) - retryAfterHeader = isNaN(retryAfterHeader) - ? calculateRetryAfterHeader(retryAfterHeader) - : retryAfterHeader * 1e3 // Retry-After is in seconds + // 3. If x < lowerBound or x > upperBound, then + // throw a TypeError. + if (x < lowerBound || x > upperBound) { + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.` + }) } - const retryTimeout = - retryAfterHeader > 0 - ? Math.min(retryAfterHeader, maxTimeout) - : Math.min(currentTimeout * timeoutFactor ** counter, maxTimeout) + // 4. Return x. + return x + } - state.currentTimeout = retryTimeout + // 7. If x is not NaN and the conversion is to an IDL + // type associated with the [Clamp] extended + // attribute, then: + if (!Number.isNaN(x) && opts.clamp === true) { + // 1. Set x to min(max(x, lowerBound), upperBound). + x = Math.min(Math.max(x, lowerBound), upperBound) - setTimeout(() => cb(null), retryTimeout) - } + // 2. Round x to the nearest integer, choosing the + // even integer if it lies halfway between two, + // and choosing +0 rather than −0. + if (Math.floor(x) % 2 === 0) { + x = Math.floor(x) + } else { + x = Math.ceil(x) + } - onHeaders (statusCode, rawHeaders, resume, statusMessage) { - const headers = parseHeaders(rawHeaders) + // 3. Return x. + return x + } - this.retryCount += 1 + // 8. If x is NaN, +0, +∞, or −∞, then return +0. + if ( + Number.isNaN(x) || + (x === 0 && Object.is(0, x)) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY + ) { + return 0 + } - if (statusCode >= 300) { - this.abort( - new RequestRetryError('Request failed', statusCode, { - headers, - count: this.retryCount - }) - ) - return false - } + // 9. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x) - // Checkpoint for resume from where we left it - if (this.resume != null) { - this.resume = null + // 10. Set x to x modulo 2^bitLength. + x = x % Math.pow(2, bitLength) - if (statusCode !== 206) { - return true - } + // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, + // then return x − 2^bitLength. + if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { + return x - Math.pow(2, bitLength) + } - const contentRange = parseRangeHeader(headers['content-range']) - // If no content range - if (!contentRange) { - this.abort( - new RequestRetryError('Content-Range mismatch', statusCode, { - headers, - count: this.retryCount - }) - ) - return false - } + // 12. Otherwise, return x. + return x +} - // Let's start with a weak etag check - if (this.etag != null && this.etag !== headers.etag) { - this.abort( - new RequestRetryError('ETag mismatch', statusCode, { - headers, - count: this.retryCount - }) - ) - return false - } +// https://webidl.spec.whatwg.org/#abstract-opdef-integerpart +webidl.util.IntegerPart = function (n) { + // 1. Let r be floor(abs(n)). + const r = Math.floor(Math.abs(n)) - const { start, size, end = size } = contentRange + // 2. If n < 0, then return -1 × r. + if (n < 0) { + return -1 * r + } - assert(this.start === start, 'content-range mismatch') - assert(this.end == null || this.end === end, 'content-range mismatch') + // 3. Otherwise, return r. + return r +} - this.resume = resume - return true +// https://webidl.spec.whatwg.org/#es-sequence +webidl.sequenceConverter = function (converter) { + return (V) => { + // 1. If Type(V) is not Object, throw a TypeError. + if (webidl.util.Type(V) !== 'Object') { + throw webidl.errors.exception({ + header: 'Sequence', + message: `Value of type ${webidl.util.Type(V)} is not an Object.` + }) } - if (this.end == null) { - if (statusCode === 206) { - // First time we receive 206 - const range = parseRangeHeader(headers['content-range']) - - if (range == null) { - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) - } - - const { start, size, end = size } = range + // 2. Let method be ? GetMethod(V, @@iterator). + /** @type {Generator} */ + const method = V?.[Symbol.iterator]?.() + const seq = [] - assert( - start != null && Number.isFinite(start) && this.start !== start, - 'content-range mismatch' - ) - assert(Number.isFinite(start)) - assert( - end != null && Number.isFinite(end) && this.end !== end, - 'invalid content-length' - ) + // 3. If method is undefined, throw a TypeError. + if ( + method === undefined || + typeof method.next !== 'function' + ) { + throw webidl.errors.exception({ + header: 'Sequence', + message: 'Object is not an iterator.' + }) + } - this.start = start - this.end = end - } + // https://webidl.spec.whatwg.org/#create-sequence-from-iterable + while (true) { + const { done, value } = method.next() - // We make our best to checkpoint the body for further range headers - if (this.end == null) { - const contentLength = headers['content-length'] - this.end = contentLength != null ? Number(contentLength) : null + if (done) { + break } - assert(Number.isFinite(this.start)) - assert( - this.end == null || Number.isFinite(this.end), - 'invalid content-length' - ) + seq.push(converter(value)) + } - this.resume = resume - this.etag = headers.etag != null ? headers.etag : null + return seq + } +} - return this.handler.onHeaders( - statusCode, - rawHeaders, - resume, - statusMessage - ) +// https://webidl.spec.whatwg.org/#es-to-record +webidl.recordConverter = function (keyConverter, valueConverter) { + return (O) => { + // 1. If Type(O) is not Object, throw a TypeError. + if (webidl.util.Type(O) !== 'Object') { + throw webidl.errors.exception({ + header: 'Record', + message: `Value of type ${webidl.util.Type(O)} is not an Object.` + }) } - const err = new RequestRetryError('Request failed', statusCode, { - headers, - count: this.retryCount - }) - - this.abort(err) + // 2. Let result be a new empty instance of record. + const result = {} - return false - } + if (!types.isProxy(O)) { + // Object.keys only returns enumerable properties + const keys = Object.keys(O) - onData (chunk) { - this.start += chunk.length + for (const key of keys) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key) - return this.handler.onData(chunk) - } + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key]) - onComplete (rawTrailers) { - this.retryCount = 0 - return this.handler.onComplete(rawTrailers) - } + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue + } - onError (err) { - if (this.aborted || isDisturbed(this.opts.body)) { - return this.handler.onError(err) + // 5. Return result. + return result } - this.retryOpts.retry( - err, - { - state: { counter: this.retryCount++, currentTimeout: this.retryAfter }, - opts: { retryOptions: this.retryOpts, ...this.opts } - }, - onRetry.bind(this) - ) + // 3. Let keys be ? O.[[OwnPropertyKeys]](). + const keys = Reflect.ownKeys(O) - function onRetry (err) { - if (err != null || this.aborted || isDisturbed(this.opts.body)) { - return this.handler.onError(err) - } + // 4. For each key of keys. + for (const key of keys) { + // 1. Let desc be ? O.[[GetOwnProperty]](key). + const desc = Reflect.getOwnPropertyDescriptor(O, key) - if (this.start !== 0) { - this.opts = { - ...this.opts, - headers: { - ...this.opts.headers, - range: `bytes=${this.start}-${this.end ?? ''}` - } - } - } + // 2. If desc is not undefined and desc.[[Enumerable]] is true: + if (desc?.enumerable) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key) - try { - this.dispatch(this.opts, this) - } catch (err) { - this.handler.onError(err) + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key]) + + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue } } + + // 5. Return result. + return result } } -module.exports = RetryHandler +webidl.interfaceConverter = function (i) { + return (V, opts = {}) => { + if (opts.strict !== false && !(V instanceof i)) { + throw webidl.errors.exception({ + header: i.name, + message: `Expected ${V} to be an instance of ${i.name}.` + }) + } + return V + } +} -/***/ }), +webidl.dictionaryConverter = function (converters) { + return (dictionary) => { + const type = webidl.util.Type(dictionary) + const dict = {} -/***/ 8861: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (type === 'Null' || type === 'Undefined') { + return dict + } else if (type !== 'Object') { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `Expected ${dictionary} to be one of: Null, Undefined, Object.` + }) + } -"use strict"; + for (const options of converters) { + const { key, defaultValue, required, converter } = options + if (required === true) { + if (!hasOwn(dictionary, key)) { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `Missing required key "${key}".` + }) + } + } -const RedirectHandler = __nccwpck_require__(2860) + let value = dictionary[key] + const hasDefault = hasOwn(options, 'defaultValue') -function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }) { - return (dispatch) => { - return function Intercept (opts, handler) { - const { maxRedirections = defaultMaxRedirections } = opts + // Only use defaultValue if value is undefined and + // a defaultValue options was provided. + if (hasDefault && value !== null) { + value = value ?? defaultValue + } - if (!maxRedirections) { - return dispatch(opts, handler) + // A key can be optional and have no default value. + // When this happens, do not perform a conversion, + // and do not assign the key a value. + if (required || hasDefault || value !== undefined) { + value = converter(value) + + if ( + options.allowedValues && + !options.allowedValues.includes(value) + ) { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join(', ')}.` + }) + } + + dict[key] = value } + } - const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler) - opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting. - return dispatch(opts, redirectHandler) + return dict + } +} + +webidl.nullableConverter = function (converter) { + return (V) => { + if (V === null) { + return V } + + return converter(V) } } -module.exports = createRedirectInterceptor - - -/***/ }), - -/***/ 953: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +// https://webidl.spec.whatwg.org/#es-DOMString +webidl.converters.DOMString = function (V, opts = {}) { + // 1. If V is null and the conversion is to an IDL type + // associated with the [LegacyNullToEmptyString] + // extended attribute, then return the DOMString value + // that represents the empty string. + if (V === null && opts.legacyNullToEmptyString) { + return '' + } -"use strict"; + // 2. Let x be ? ToString(V). + if (typeof V === 'symbol') { + throw new TypeError('Could not convert argument of type symbol to string.') + } -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; -const utils_1 = __nccwpck_require__(1891); -// C headers -var ERROR; -(function (ERROR) { - ERROR[ERROR["OK"] = 0] = "OK"; - ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL"; - ERROR[ERROR["STRICT"] = 2] = "STRICT"; - ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED"; - ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; - ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; - ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD"; - ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL"; - ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; - ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION"; - ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; - ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; - ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; - ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS"; - ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; - ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; - ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; - ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; - ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; - ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; - ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; - ERROR[ERROR["PAUSED"] = 21] = "PAUSED"; - ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; - ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; - ERROR[ERROR["USER"] = 24] = "USER"; -})(ERROR = exports.ERROR || (exports.ERROR = {})); -var TYPE; -(function (TYPE) { - TYPE[TYPE["BOTH"] = 0] = "BOTH"; - TYPE[TYPE["REQUEST"] = 1] = "REQUEST"; - TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE"; -})(TYPE = exports.TYPE || (exports.TYPE = {})); -var FLAGS; -(function (FLAGS) { - FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; - FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; - FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; - FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED"; - FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE"; - FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; - FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY"; - FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING"; - // 1 << 8 is unused - FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; -})(FLAGS = exports.FLAGS || (exports.FLAGS = {})); -var LENIENT_FLAGS; -(function (LENIENT_FLAGS) { - LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS"; - LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; - LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; -})(LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); -var METHODS; -(function (METHODS) { - METHODS[METHODS["DELETE"] = 0] = "DELETE"; - METHODS[METHODS["GET"] = 1] = "GET"; - METHODS[METHODS["HEAD"] = 2] = "HEAD"; - METHODS[METHODS["POST"] = 3] = "POST"; - METHODS[METHODS["PUT"] = 4] = "PUT"; - /* pathological */ - METHODS[METHODS["CONNECT"] = 5] = "CONNECT"; - METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS"; - METHODS[METHODS["TRACE"] = 7] = "TRACE"; - /* WebDAV */ - METHODS[METHODS["COPY"] = 8] = "COPY"; - METHODS[METHODS["LOCK"] = 9] = "LOCK"; - METHODS[METHODS["MKCOL"] = 10] = "MKCOL"; - METHODS[METHODS["MOVE"] = 11] = "MOVE"; - METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND"; - METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH"; - METHODS[METHODS["SEARCH"] = 14] = "SEARCH"; - METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK"; - METHODS[METHODS["BIND"] = 16] = "BIND"; - METHODS[METHODS["REBIND"] = 17] = "REBIND"; - METHODS[METHODS["UNBIND"] = 18] = "UNBIND"; - METHODS[METHODS["ACL"] = 19] = "ACL"; - /* subversion */ - METHODS[METHODS["REPORT"] = 20] = "REPORT"; - METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY"; - METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT"; - METHODS[METHODS["MERGE"] = 23] = "MERGE"; - /* upnp */ - METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH"; - METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY"; - METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE"; - METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; - /* RFC-5789 */ - METHODS[METHODS["PATCH"] = 28] = "PATCH"; - METHODS[METHODS["PURGE"] = 29] = "PURGE"; - /* CalDAV */ - METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR"; - /* RFC-2068, section 19.6.1.2 */ - METHODS[METHODS["LINK"] = 31] = "LINK"; - METHODS[METHODS["UNLINK"] = 32] = "UNLINK"; - /* icecast */ - METHODS[METHODS["SOURCE"] = 33] = "SOURCE"; - /* RFC-7540, section 11.6 */ - METHODS[METHODS["PRI"] = 34] = "PRI"; - /* RFC-2326 RTSP */ - METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE"; - METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE"; - METHODS[METHODS["SETUP"] = 37] = "SETUP"; - METHODS[METHODS["PLAY"] = 38] = "PLAY"; - METHODS[METHODS["PAUSE"] = 39] = "PAUSE"; - METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN"; - METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER"; - METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER"; - METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT"; - METHODS[METHODS["RECORD"] = 44] = "RECORD"; - /* RAOP */ - METHODS[METHODS["FLUSH"] = 45] = "FLUSH"; -})(METHODS = exports.METHODS || (exports.METHODS = {})); -exports.METHODS_HTTP = [ - METHODS.DELETE, - METHODS.GET, - METHODS.HEAD, - METHODS.POST, - METHODS.PUT, - METHODS.CONNECT, - METHODS.OPTIONS, - METHODS.TRACE, - METHODS.COPY, - METHODS.LOCK, - METHODS.MKCOL, - METHODS.MOVE, - METHODS.PROPFIND, - METHODS.PROPPATCH, - METHODS.SEARCH, - METHODS.UNLOCK, - METHODS.BIND, - METHODS.REBIND, - METHODS.UNBIND, - METHODS.ACL, - METHODS.REPORT, - METHODS.MKACTIVITY, - METHODS.CHECKOUT, - METHODS.MERGE, - METHODS['M-SEARCH'], - METHODS.NOTIFY, - METHODS.SUBSCRIBE, - METHODS.UNSUBSCRIBE, - METHODS.PATCH, - METHODS.PURGE, - METHODS.MKCALENDAR, - METHODS.LINK, - METHODS.UNLINK, - METHODS.PRI, - // TODO(indutny): should we allow it with HTTP? - METHODS.SOURCE, -]; -exports.METHODS_ICE = [ - METHODS.SOURCE, -]; -exports.METHODS_RTSP = [ - METHODS.OPTIONS, - METHODS.DESCRIBE, - METHODS.ANNOUNCE, - METHODS.SETUP, - METHODS.PLAY, - METHODS.PAUSE, - METHODS.TEARDOWN, - METHODS.GET_PARAMETER, - METHODS.SET_PARAMETER, - METHODS.REDIRECT, - METHODS.RECORD, - METHODS.FLUSH, - // For AirPlay - METHODS.GET, - METHODS.POST, -]; -exports.METHOD_MAP = utils_1.enumToMap(METHODS); -exports.H_METHOD_MAP = {}; -Object.keys(exports.METHOD_MAP).forEach((key) => { - if (/^H/.test(key)) { - exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; - } -}); -var FINISH; -(function (FINISH) { - FINISH[FINISH["SAFE"] = 0] = "SAFE"; - FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; - FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE"; -})(FINISH = exports.FINISH || (exports.FINISH = {})); -exports.ALPHA = []; -for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { - // Upper case - exports.ALPHA.push(String.fromCharCode(i)); - // Lower case - exports.ALPHA.push(String.fromCharCode(i + 0x20)); -} -exports.NUM_MAP = { - 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, - 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, -}; -exports.HEX_MAP = { - 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, - 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, - A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, - a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, -}; -exports.NUM = [ - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', -]; -exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); -exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; -exports.USERINFO_CHARS = exports.ALPHANUM - .concat(exports.MARK) - .concat(['%', ';', ':', '&', '=', '+', '$', ',']); -// TODO(indutny): use RFC -exports.STRICT_URL_CHAR = [ - '!', '"', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', - ':', ';', '<', '=', '>', - '@', '[', '\\', ']', '^', '_', - '`', - '{', '|', '}', '~', -].concat(exports.ALPHANUM); -exports.URL_CHAR = exports.STRICT_URL_CHAR - .concat(['\t', '\f']); -// All characters with 0x80 bit set to 1 -for (let i = 0x80; i <= 0xff; i++) { - exports.URL_CHAR.push(i); + // 3. Return the IDL DOMString value that represents the + // same sequence of code units as the one the + // ECMAScript String value x represents. + return String(V) } -exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); -/* Tokens as defined by rfc 2616. Also lowercases them. - * token = 1* - * separators = "(" | ")" | "<" | ">" | "@" - * | "," | ";" | ":" | "\" | <"> - * | "/" | "[" | "]" | "?" | "=" - * | "{" | "}" | SP | HT - */ -exports.STRICT_TOKEN = [ - '!', '#', '$', '%', '&', '\'', - '*', '+', '-', '.', - '^', '_', '`', - '|', '~', -].concat(exports.ALPHANUM); -exports.TOKEN = exports.STRICT_TOKEN.concat([' ']); -/* - * Verify that a char is a valid visible (printable) US-ASCII - * character or %x80-FF - */ -exports.HEADER_CHARS = ['\t']; -for (let i = 32; i <= 255; i++) { - if (i !== 127) { - exports.HEADER_CHARS.push(i); + +// https://webidl.spec.whatwg.org/#es-ByteString +webidl.converters.ByteString = function (V) { + // 1. Let x be ? ToString(V). + // Note: DOMString converter perform ? ToString(V) + const x = webidl.converters.DOMString(V) + + // 2. If the value of any element of x is greater than + // 255, then throw a TypeError. + for (let index = 0; index < x.length; index++) { + if (x.charCodeAt(index) > 255) { + throw new TypeError( + 'Cannot convert argument to a ByteString because the character at ' + + `index ${index} has a value of ${x.charCodeAt(index)} which is greater than 255.` + ) } + } + + // 3. Return an IDL ByteString value whose length is the + // length of x, and where the value of each element is + // the value of the corresponding element of x. + return x } -// ',' = \x44 -exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); -exports.MAJOR = exports.NUM_MAP; -exports.MINOR = exports.MAJOR; -var HEADER_STATE; -(function (HEADER_STATE) { - HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL"; - HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION"; - HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; - HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; - HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE"; - HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; - HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; - HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; - HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; -})(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); -exports.SPECIAL_HEADERS = { - 'connection': HEADER_STATE.CONNECTION, - 'content-length': HEADER_STATE.CONTENT_LENGTH, - 'proxy-connection': HEADER_STATE.CONNECTION, - 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, - 'upgrade': HEADER_STATE.UPGRADE, -}; -//# sourceMappingURL=constants.js.map -/***/ }), +// https://webidl.spec.whatwg.org/#es-USVString +webidl.converters.USVString = toUSVString -/***/ 1145: -/***/ ((module) => { +// https://webidl.spec.whatwg.org/#es-boolean +webidl.converters.boolean = function (V) { + // 1. Let x be the result of computing ToBoolean(V). + const x = Boolean(V) -module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ADcDACAAQShqQgA3AwAgAEEgakIANwMAIABBEGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvk8wEDDn8DfgR/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCHCIQQX9qDt0B2gEB2QECAwQFBgcICQoLDA0O2AEPENcBERLWARMUFRYXGBkaG+AB3wEcHR7VAR8gISIjJCXUASYnKCkqKyzTAdIBLS7RAdABLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVG2wFHSElKzwHOAUvNAUzMAU1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4ABgQGCAYMBhAGFAYYBhwGIAYkB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAQDscBAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxweHyAhIyUoP0BBREVGR0hJSktMTU9QUVJT3gNXWVtcXWBiZWZnaGlqa2xtb3BxcnN0dXZ3eHl6e3x9foABggGFAYYBhwGJAYsBjAGNAY4BjwGQAZEBlAGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBuAG5AboBuwG8Ab0BvgG/AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AHdAd4B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAZkCpAKwAv4C/gILIAEiBCACRw3zAUHdASEQDP8DCyABIhAgAkcN3QFBwwEhEAz+AwsgASIBIAJHDZABQfcAIRAM/QMLIAEiASACRw2GAUHvACEQDPwDCyABIgEgAkcNf0HqACEQDPsDCyABIgEgAkcNe0HoACEQDPoDCyABIgEgAkcNeEHmACEQDPkDCyABIgEgAkcNGkEYIRAM+AMLIAEiASACRw0UQRIhEAz3AwsgASIBIAJHDVlBxQAhEAz2AwsgASIBIAJHDUpBPyEQDPUDCyABIgEgAkcNSEE8IRAM9AMLIAEiASACRw1BQTEhEAzzAwsgAC0ALkEBRg3rAwyHAgsgACABIgEgAhDAgICAAEEBRw3mASAAQgA3AyAM5wELIAAgASIBIAIQtICAgAAiEA3nASABIQEM9QILAkAgASIBIAJHDQBBBiEQDPADCyAAIAFBAWoiASACELuAgIAAIhAN6AEgASEBDDELIABCADcDIEESIRAM1QMLIAEiECACRw0rQR0hEAztAwsCQCABIgEgAkYNACABQQFqIQFBECEQDNQDC0EHIRAM7AMLIABCACAAKQMgIhEgAiABIhBrrSISfSITIBMgEVYbNwMgIBEgElYiFEUN5QFBCCEQDOsDCwJAIAEiASACRg0AIABBiYCAgAA2AgggACABNgIEIAEhAUEUIRAM0gMLQQkhEAzqAwsgASEBIAApAyBQDeQBIAEhAQzyAgsCQCABIgEgAkcNAEELIRAM6QMLIAAgAUEBaiIBIAIQtoCAgAAiEA3lASABIQEM8gILIAAgASIBIAIQuICAgAAiEA3lASABIQEM8gILIAAgASIBIAIQuICAgAAiEA3mASABIQEMDQsgACABIgEgAhC6gICAACIQDecBIAEhAQzwAgsCQCABIgEgAkcNAEEPIRAM5QMLIAEtAAAiEEE7Rg0IIBBBDUcN6AEgAUEBaiEBDO8CCyAAIAEiASACELqAgIAAIhAN6AEgASEBDPICCwNAAkAgAS0AAEHwtYCAAGotAAAiEEEBRg0AIBBBAkcN6wEgACgCBCEQIABBADYCBCAAIBAgAUEBaiIBELmAgIAAIhAN6gEgASEBDPQCCyABQQFqIgEgAkcNAAtBEiEQDOIDCyAAIAEiASACELqAgIAAIhAN6QEgASEBDAoLIAEiASACRw0GQRshEAzgAwsCQCABIgEgAkcNAEEWIRAM4AMLIABBioCAgAA2AgggACABNgIEIAAgASACELiAgIAAIhAN6gEgASEBQSAhEAzGAwsCQCABIgEgAkYNAANAAkAgAS0AAEHwt4CAAGotAAAiEEECRg0AAkAgEEF/ag4E5QHsAQDrAewBCyABQQFqIQFBCCEQDMgDCyABQQFqIgEgAkcNAAtBFSEQDN8DC0EVIRAM3gMLA0ACQCABLQAAQfC5gIAAai0AACIQQQJGDQAgEEF/ag4E3gHsAeAB6wHsAQsgAUEBaiIBIAJHDQALQRghEAzdAwsCQCABIgEgAkYNACAAQYuAgIAANgIIIAAgATYCBCABIQFBByEQDMQDC0EZIRAM3AMLIAFBAWohAQwCCwJAIAEiFCACRw0AQRohEAzbAwsgFCEBAkAgFC0AAEFzag4U3QLuAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gIA7gILQQAhECAAQQA2AhwgAEGvi4CAADYCECAAQQI2AgwgACAUQQFqNgIUDNoDCwJAIAEtAAAiEEE7Rg0AIBBBDUcN6AEgAUEBaiEBDOUCCyABQQFqIQELQSIhEAy/AwsCQCABIhAgAkcNAEEcIRAM2AMLQgAhESAQIQEgEC0AAEFQag435wHmAQECAwQFBgcIAAAAAAAAAAkKCwwNDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADxAREhMUAAtBHiEQDL0DC0ICIREM5QELQgMhEQzkAQtCBCERDOMBC0IFIREM4gELQgYhEQzhAQtCByERDOABC0IIIREM3wELQgkhEQzeAQtCCiERDN0BC0ILIREM3AELQgwhEQzbAQtCDSERDNoBC0IOIREM2QELQg8hEQzYAQtCCiERDNcBC0ILIREM1gELQgwhEQzVAQtCDSERDNQBC0IOIREM0wELQg8hEQzSAQtCACERAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAQLQAAQVBqDjflAeQBAAECAwQFBgfmAeYB5gHmAeYB5gHmAQgJCgsMDeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gEODxAREhPmAQtCAiERDOQBC0IDIREM4wELQgQhEQziAQtCBSERDOEBC0IGIREM4AELQgchEQzfAQtCCCERDN4BC0IJIREM3QELQgohEQzcAQtCCyERDNsBC0IMIREM2gELQg0hEQzZAQtCDiERDNgBC0IPIREM1wELQgohEQzWAQtCCyERDNUBC0IMIREM1AELQg0hEQzTAQtCDiERDNIBC0IPIREM0QELIABCACAAKQMgIhEgAiABIhBrrSISfSITIBMgEVYbNwMgIBEgElYiFEUN0gFBHyEQDMADCwJAIAEiASACRg0AIABBiYCAgAA2AgggACABNgIEIAEhAUEkIRAMpwMLQSAhEAy/AwsgACABIhAgAhC+gICAAEF/ag4FtgEAxQIB0QHSAQtBESEQDKQDCyAAQQE6AC8gECEBDLsDCyABIgEgAkcN0gFBJCEQDLsDCyABIg0gAkcNHkHGACEQDLoDCyAAIAEiASACELKAgIAAIhAN1AEgASEBDLUBCyABIhAgAkcNJkHQACEQDLgDCwJAIAEiASACRw0AQSghEAy4AwsgAEEANgIEIABBjICAgAA2AgggACABIAEQsYCAgAAiEA3TASABIQEM2AELAkAgASIQIAJHDQBBKSEQDLcDCyAQLQAAIgFBIEYNFCABQQlHDdMBIBBBAWohAQwVCwJAIAEiASACRg0AIAFBAWohAQwXC0EqIRAMtQMLAkAgASIQIAJHDQBBKyEQDLUDCwJAIBAtAAAiAUEJRg0AIAFBIEcN1QELIAAtACxBCEYN0wEgECEBDJEDCwJAIAEiASACRw0AQSwhEAy0AwsgAS0AAEEKRw3VASABQQFqIQEMyQILIAEiDiACRw3VAUEvIRAMsgMLA0ACQCABLQAAIhBBIEYNAAJAIBBBdmoOBADcAdwBANoBCyABIQEM4AELIAFBAWoiASACRw0AC0ExIRAMsQMLQTIhECABIhQgAkYNsAMgAiAUayAAKAIAIgFqIRUgFCABa0EDaiEWAkADQCAULQAAIhdBIHIgFyAXQb9/akH/AXFBGkkbQf8BcSABQfC7gIAAai0AAEcNAQJAIAFBA0cNAEEGIQEMlgMLIAFBAWohASAUQQFqIhQgAkcNAAsgACAVNgIADLEDCyAAQQA2AgAgFCEBDNkBC0EzIRAgASIUIAJGDa8DIAIgFGsgACgCACIBaiEVIBQgAWtBCGohFgJAA0AgFC0AACIXQSByIBcgF0G/f2pB/wFxQRpJG0H/AXEgAUH0u4CAAGotAABHDQECQCABQQhHDQBBBSEBDJUDCyABQQFqIQEgFEEBaiIUIAJHDQALIAAgFTYCAAywAwsgAEEANgIAIBQhAQzYAQtBNCEQIAEiFCACRg2uAyACIBRrIAAoAgAiAWohFSAUIAFrQQVqIRYCQANAIBQtAAAiF0EgciAXIBdBv39qQf8BcUEaSRtB/wFxIAFB0MKAgABqLQAARw0BAkAgAUEFRw0AQQchAQyUAwsgAUEBaiEBIBRBAWoiFCACRw0ACyAAIBU2AgAMrwMLIABBADYCACAUIQEM1wELAkAgASIBIAJGDQADQAJAIAEtAABBgL6AgABqLQAAIhBBAUYNACAQQQJGDQogASEBDN0BCyABQQFqIgEgAkcNAAtBMCEQDK4DC0EwIRAMrQMLAkAgASIBIAJGDQADQAJAIAEtAAAiEEEgRg0AIBBBdmoOBNkB2gHaAdkB2gELIAFBAWoiASACRw0AC0E4IRAMrQMLQTghEAysAwsDQAJAIAEtAAAiEEEgRg0AIBBBCUcNAwsgAUEBaiIBIAJHDQALQTwhEAyrAwsDQAJAIAEtAAAiEEEgRg0AAkACQCAQQXZqDgTaAQEB2gEACyAQQSxGDdsBCyABIQEMBAsgAUEBaiIBIAJHDQALQT8hEAyqAwsgASEBDNsBC0HAACEQIAEiFCACRg2oAyACIBRrIAAoAgAiAWohFiAUIAFrQQZqIRcCQANAIBQtAABBIHIgAUGAwICAAGotAABHDQEgAUEGRg2OAyABQQFqIQEgFEEBaiIUIAJHDQALIAAgFjYCAAypAwsgAEEANgIAIBQhAQtBNiEQDI4DCwJAIAEiDyACRw0AQcEAIRAMpwMLIABBjICAgAA2AgggACAPNgIEIA8hASAALQAsQX9qDgTNAdUB1wHZAYcDCyABQQFqIQEMzAELAkAgASIBIAJGDQADQAJAIAEtAAAiEEEgciAQIBBBv39qQf8BcUEaSRtB/wFxIhBBCUYNACAQQSBGDQACQAJAAkACQCAQQZ1/ag4TAAMDAwMDAwMBAwMDAwMDAwMDAgMLIAFBAWohAUExIRAMkQMLIAFBAWohAUEyIRAMkAMLIAFBAWohAUEzIRAMjwMLIAEhAQzQAQsgAUEBaiIBIAJHDQALQTUhEAylAwtBNSEQDKQDCwJAIAEiASACRg0AA0ACQCABLQAAQYC8gIAAai0AAEEBRg0AIAEhAQzTAQsgAUEBaiIBIAJHDQALQT0hEAykAwtBPSEQDKMDCyAAIAEiASACELCAgIAAIhAN1gEgASEBDAELIBBBAWohAQtBPCEQDIcDCwJAIAEiASACRw0AQcIAIRAMoAMLAkADQAJAIAEtAABBd2oOGAAC/gL+AoQD/gL+Av4C/gL+Av4C/gL+Av4C/gL+Av4C/gL+Av4C/gL+Av4CAP4CCyABQQFqIgEgAkcNAAtBwgAhEAygAwsgAUEBaiEBIAAtAC1BAXFFDb0BIAEhAQtBLCEQDIUDCyABIgEgAkcN0wFBxAAhEAydAwsDQAJAIAEtAABBkMCAgABqLQAAQQFGDQAgASEBDLcCCyABQQFqIgEgAkcNAAtBxQAhEAycAwsgDS0AACIQQSBGDbMBIBBBOkcNgQMgACgCBCEBIABBADYCBCAAIAEgDRCvgICAACIBDdABIA1BAWohAQyzAgtBxwAhECABIg0gAkYNmgMgAiANayAAKAIAIgFqIRYgDSABa0EFaiEXA0AgDS0AACIUQSByIBQgFEG/f2pB/wFxQRpJG0H/AXEgAUGQwoCAAGotAABHDYADIAFBBUYN9AIgAUEBaiEBIA1BAWoiDSACRw0ACyAAIBY2AgAMmgMLQcgAIRAgASINIAJGDZkDIAIgDWsgACgCACIBaiEWIA0gAWtBCWohFwNAIA0tAAAiFEEgciAUIBRBv39qQf8BcUEaSRtB/wFxIAFBlsKAgABqLQAARw3/AgJAIAFBCUcNAEECIQEM9QILIAFBAWohASANQQFqIg0gAkcNAAsgACAWNgIADJkDCwJAIAEiDSACRw0AQckAIRAMmQMLAkACQCANLQAAIgFBIHIgASABQb9/akH/AXFBGkkbQf8BcUGSf2oOBwCAA4ADgAOAA4ADAYADCyANQQFqIQFBPiEQDIADCyANQQFqIQFBPyEQDP8CC0HKACEQIAEiDSACRg2XAyACIA1rIAAoAgAiAWohFiANIAFrQQFqIRcDQCANLQAAIhRBIHIgFCAUQb9/akH/AXFBGkkbQf8BcSABQaDCgIAAai0AAEcN/QIgAUEBRg3wAiABQQFqIQEgDUEBaiINIAJHDQALIAAgFjYCAAyXAwtBywAhECABIg0gAkYNlgMgAiANayAAKAIAIgFqIRYgDSABa0EOaiEXA0AgDS0AACIUQSByIBQgFEG/f2pB/wFxQRpJG0H/AXEgAUGiwoCAAGotAABHDfwCIAFBDkYN8AIgAUEBaiEBIA1BAWoiDSACRw0ACyAAIBY2AgAMlgMLQcwAIRAgASINIAJGDZUDIAIgDWsgACgCACIBaiEWIA0gAWtBD2ohFwNAIA0tAAAiFEEgciAUIBRBv39qQf8BcUEaSRtB/wFxIAFBwMKAgABqLQAARw37AgJAIAFBD0cNAEEDIQEM8QILIAFBAWohASANQQFqIg0gAkcNAAsgACAWNgIADJUDC0HNACEQIAEiDSACRg2UAyACIA1rIAAoAgAiAWohFiANIAFrQQVqIRcDQCANLQAAIhRBIHIgFCAUQb9/akH/AXFBGkkbQf8BcSABQdDCgIAAai0AAEcN+gICQCABQQVHDQBBBCEBDPACCyABQQFqIQEgDUEBaiINIAJHDQALIAAgFjYCAAyUAwsCQCABIg0gAkcNAEHOACEQDJQDCwJAAkACQAJAIA0tAAAiAUEgciABIAFBv39qQf8BcUEaSRtB/wFxQZ1/ag4TAP0C/QL9Av0C/QL9Av0C/QL9Av0C/QL9AgH9Av0C/QICA/0CCyANQQFqIQFBwQAhEAz9AgsgDUEBaiEBQcIAIRAM/AILIA1BAWohAUHDACEQDPsCCyANQQFqIQFBxAAhEAz6AgsCQCABIgEgAkYNACAAQY2AgIAANgIIIAAgATYCBCABIQFBxQAhEAz6AgtBzwAhEAySAwsgECEBAkACQCAQLQAAQXZqDgQBqAKoAgCoAgsgEEEBaiEBC0EnIRAM+AILAkAgASIBIAJHDQBB0QAhEAyRAwsCQCABLQAAQSBGDQAgASEBDI0BCyABQQFqIQEgAC0ALUEBcUUNxwEgASEBDIwBCyABIhcgAkcNyAFB0gAhEAyPAwtB0wAhECABIhQgAkYNjgMgAiAUayAAKAIAIgFqIRYgFCABa0EBaiEXA0AgFC0AACABQdbCgIAAai0AAEcNzAEgAUEBRg3HASABQQFqIQEgFEEBaiIUIAJHDQALIAAgFjYCAAyOAwsCQCABIgEgAkcNAEHVACEQDI4DCyABLQAAQQpHDcwBIAFBAWohAQzHAQsCQCABIgEgAkcNAEHWACEQDI0DCwJAAkAgAS0AAEF2ag4EAM0BzQEBzQELIAFBAWohAQzHAQsgAUEBaiEBQcoAIRAM8wILIAAgASIBIAIQroCAgAAiEA3LASABIQFBzQAhEAzyAgsgAC0AKUEiRg2FAwymAgsCQCABIgEgAkcNAEHbACEQDIoDC0EAIRRBASEXQQEhFkEAIRACQAJAAkACQAJAAkACQAJAAkAgAS0AAEFQag4K1AHTAQABAgMEBQYI1QELQQIhEAwGC0EDIRAMBQtBBCEQDAQLQQUhEAwDC0EGIRAMAgtBByEQDAELQQghEAtBACEXQQAhFkEAIRQMzAELQQkhEEEBIRRBACEXQQAhFgzLAQsCQCABIgEgAkcNAEHdACEQDIkDCyABLQAAQS5HDcwBIAFBAWohAQymAgsgASIBIAJHDcwBQd8AIRAMhwMLAkAgASIBIAJGDQAgAEGOgICAADYCCCAAIAE2AgQgASEBQdAAIRAM7gILQeAAIRAMhgMLQeEAIRAgASIBIAJGDYUDIAIgAWsgACgCACIUaiEWIAEgFGtBA2ohFwNAIAEtAAAgFEHiwoCAAGotAABHDc0BIBRBA0YNzAEgFEEBaiEUIAFBAWoiASACRw0ACyAAIBY2AgAMhQMLQeIAIRAgASIBIAJGDYQDIAIgAWsgACgCACIUaiEWIAEgFGtBAmohFwNAIAEtAAAgFEHmwoCAAGotAABHDcwBIBRBAkYNzgEgFEEBaiEUIAFBAWoiASACRw0ACyAAIBY2AgAMhAMLQeMAIRAgASIBIAJGDYMDIAIgAWsgACgCACIUaiEWIAEgFGtBA2ohFwNAIAEtAAAgFEHpwoCAAGotAABHDcsBIBRBA0YNzgEgFEEBaiEUIAFBAWoiASACRw0ACyAAIBY2AgAMgwMLAkAgASIBIAJHDQBB5QAhEAyDAwsgACABQQFqIgEgAhCogICAACIQDc0BIAEhAUHWACEQDOkCCwJAIAEiASACRg0AA0ACQCABLQAAIhBBIEYNAAJAAkACQCAQQbh/ag4LAAHPAc8BzwHPAc8BzwHPAc8BAs8BCyABQQFqIQFB0gAhEAztAgsgAUEBaiEBQdMAIRAM7AILIAFBAWohAUHUACEQDOsCCyABQQFqIgEgAkcNAAtB5AAhEAyCAwtB5AAhEAyBAwsDQAJAIAEtAABB8MKAgABqLQAAIhBBAUYNACAQQX5qDgPPAdAB0QHSAQsgAUEBaiIBIAJHDQALQeYAIRAMgAMLAkAgASIBIAJGDQAgAUEBaiEBDAMLQecAIRAM/wILA0ACQCABLQAAQfDEgIAAai0AACIQQQFGDQACQCAQQX5qDgTSAdMB1AEA1QELIAEhAUHXACEQDOcCCyABQQFqIgEgAkcNAAtB6AAhEAz+AgsCQCABIgEgAkcNAEHpACEQDP4CCwJAIAEtAAAiEEF2ag4augHVAdUBvAHVAdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHKAdUB1QEA0wELIAFBAWohAQtBBiEQDOMCCwNAAkAgAS0AAEHwxoCAAGotAABBAUYNACABIQEMngILIAFBAWoiASACRw0AC0HqACEQDPsCCwJAIAEiASACRg0AIAFBAWohAQwDC0HrACEQDPoCCwJAIAEiASACRw0AQewAIRAM+gILIAFBAWohAQwBCwJAIAEiASACRw0AQe0AIRAM+QILIAFBAWohAQtBBCEQDN4CCwJAIAEiFCACRw0AQe4AIRAM9wILIBQhAQJAAkACQCAULQAAQfDIgIAAai0AAEF/ag4H1AHVAdYBAJwCAQLXAQsgFEEBaiEBDAoLIBRBAWohAQzNAQtBACEQIABBADYCHCAAQZuSgIAANgIQIABBBzYCDCAAIBRBAWo2AhQM9gILAkADQAJAIAEtAABB8MiAgABqLQAAIhBBBEYNAAJAAkAgEEF/ag4H0gHTAdQB2QEABAHZAQsgASEBQdoAIRAM4AILIAFBAWohAUHcACEQDN8CCyABQQFqIgEgAkcNAAtB7wAhEAz2AgsgAUEBaiEBDMsBCwJAIAEiFCACRw0AQfAAIRAM9QILIBQtAABBL0cN1AEgFEEBaiEBDAYLAkAgASIUIAJHDQBB8QAhEAz0AgsCQCAULQAAIgFBL0cNACAUQQFqIQFB3QAhEAzbAgsgAUF2aiIEQRZLDdMBQQEgBHRBiYCAAnFFDdMBDMoCCwJAIAEiASACRg0AIAFBAWohAUHeACEQDNoCC0HyACEQDPICCwJAIAEiFCACRw0AQfQAIRAM8gILIBQhAQJAIBQtAABB8MyAgABqLQAAQX9qDgPJApQCANQBC0HhACEQDNgCCwJAIAEiFCACRg0AA0ACQCAULQAAQfDKgIAAai0AACIBQQNGDQACQCABQX9qDgLLAgDVAQsgFCEBQd8AIRAM2gILIBRBAWoiFCACRw0AC0HzACEQDPECC0HzACEQDPACCwJAIAEiASACRg0AIABBj4CAgAA2AgggACABNgIEIAEhAUHgACEQDNcCC0H1ACEQDO8CCwJAIAEiASACRw0AQfYAIRAM7wILIABBj4CAgAA2AgggACABNgIEIAEhAQtBAyEQDNQCCwNAIAEtAABBIEcNwwIgAUEBaiIBIAJHDQALQfcAIRAM7AILAkAgASIBIAJHDQBB+AAhEAzsAgsgAS0AAEEgRw3OASABQQFqIQEM7wELIAAgASIBIAIQrICAgAAiEA3OASABIQEMjgILAkAgASIEIAJHDQBB+gAhEAzqAgsgBC0AAEHMAEcN0QEgBEEBaiEBQRMhEAzPAQsCQCABIgQgAkcNAEH7ACEQDOkCCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRADQCAELQAAIAFB8M6AgABqLQAARw3QASABQQVGDc4BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQfsAIRAM6AILAkAgASIEIAJHDQBB/AAhEAzoAgsCQAJAIAQtAABBvX9qDgwA0QHRAdEB0QHRAdEB0QHRAdEB0QEB0QELIARBAWohAUHmACEQDM8CCyAEQQFqIQFB5wAhEAzOAgsCQCABIgQgAkcNAEH9ACEQDOcCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHtz4CAAGotAABHDc8BIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEH9ACEQDOcCCyAAQQA2AgAgEEEBaiEBQRAhEAzMAQsCQCABIgQgAkcNAEH+ACEQDOYCCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUH2zoCAAGotAABHDc4BIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEH+ACEQDOYCCyAAQQA2AgAgEEEBaiEBQRYhEAzLAQsCQCABIgQgAkcNAEH/ACEQDOUCCyACIARrIAAoAgAiAWohFCAEIAFrQQNqIRACQANAIAQtAAAgAUH8zoCAAGotAABHDc0BIAFBA0YNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEH/ACEQDOUCCyAAQQA2AgAgEEEBaiEBQQUhEAzKAQsCQCABIgQgAkcNAEGAASEQDOQCCyAELQAAQdkARw3LASAEQQFqIQFBCCEQDMkBCwJAIAEiBCACRw0AQYEBIRAM4wILAkACQCAELQAAQbJ/ag4DAMwBAcwBCyAEQQFqIQFB6wAhEAzKAgsgBEEBaiEBQewAIRAMyQILAkAgASIEIAJHDQBBggEhEAziAgsCQAJAIAQtAABBuH9qDggAywHLAcsBywHLAcsBAcsBCyAEQQFqIQFB6gAhEAzJAgsgBEEBaiEBQe0AIRAMyAILAkAgASIEIAJHDQBBgwEhEAzhAgsgAiAEayAAKAIAIgFqIRAgBCABa0ECaiEUAkADQCAELQAAIAFBgM+AgABqLQAARw3JASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBA2AgBBgwEhEAzhAgtBACEQIABBADYCACAUQQFqIQEMxgELAkAgASIEIAJHDQBBhAEhEAzgAgsgAiAEayAAKAIAIgFqIRQgBCABa0EEaiEQAkADQCAELQAAIAFBg8+AgABqLQAARw3IASABQQRGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBhAEhEAzgAgsgAEEANgIAIBBBAWohAUEjIRAMxQELAkAgASIEIAJHDQBBhQEhEAzfAgsCQAJAIAQtAABBtH9qDggAyAHIAcgByAHIAcgBAcgBCyAEQQFqIQFB7wAhEAzGAgsgBEEBaiEBQfAAIRAMxQILAkAgASIEIAJHDQBBhgEhEAzeAgsgBC0AAEHFAEcNxQEgBEEBaiEBDIMCCwJAIAEiBCACRw0AQYcBIRAM3QILIAIgBGsgACgCACIBaiEUIAQgAWtBA2ohEAJAA0AgBC0AACABQYjPgIAAai0AAEcNxQEgAUEDRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYcBIRAM3QILIABBADYCACAQQQFqIQFBLSEQDMIBCwJAIAEiBCACRw0AQYgBIRAM3AILIAIgBGsgACgCACIBaiEUIAQgAWtBCGohEAJAA0AgBC0AACABQdDPgIAAai0AAEcNxAEgAUEIRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYgBIRAM3AILIABBADYCACAQQQFqIQFBKSEQDMEBCwJAIAEiASACRw0AQYkBIRAM2wILQQEhECABLQAAQd8ARw3AASABQQFqIQEMgQILAkAgASIEIAJHDQBBigEhEAzaAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQA0AgBC0AACABQYzPgIAAai0AAEcNwQEgAUEBRg2vAiABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGKASEQDNkCCwJAIAEiBCACRw0AQYsBIRAM2QILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQY7PgIAAai0AAEcNwQEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYsBIRAM2QILIABBADYCACAQQQFqIQFBAiEQDL4BCwJAIAEiBCACRw0AQYwBIRAM2AILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQfDPgIAAai0AAEcNwAEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYwBIRAM2AILIABBADYCACAQQQFqIQFBHyEQDL0BCwJAIAEiBCACRw0AQY0BIRAM1wILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQfLPgIAAai0AAEcNvwEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQY0BIRAM1wILIABBADYCACAQQQFqIQFBCSEQDLwBCwJAIAEiBCACRw0AQY4BIRAM1gILAkACQCAELQAAQbd/ag4HAL8BvwG/Ab8BvwEBvwELIARBAWohAUH4ACEQDL0CCyAEQQFqIQFB+QAhEAy8AgsCQCABIgQgAkcNAEGPASEQDNUCCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUGRz4CAAGotAABHDb0BIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGPASEQDNUCCyAAQQA2AgAgEEEBaiEBQRghEAy6AQsCQCABIgQgAkcNAEGQASEQDNQCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUGXz4CAAGotAABHDbwBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGQASEQDNQCCyAAQQA2AgAgEEEBaiEBQRchEAy5AQsCQCABIgQgAkcNAEGRASEQDNMCCyACIARrIAAoAgAiAWohFCAEIAFrQQZqIRACQANAIAQtAAAgAUGaz4CAAGotAABHDbsBIAFBBkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGRASEQDNMCCyAAQQA2AgAgEEEBaiEBQRUhEAy4AQsCQCABIgQgAkcNAEGSASEQDNICCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUGhz4CAAGotAABHDboBIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGSASEQDNICCyAAQQA2AgAgEEEBaiEBQR4hEAy3AQsCQCABIgQgAkcNAEGTASEQDNECCyAELQAAQcwARw24ASAEQQFqIQFBCiEQDLYBCwJAIAQgAkcNAEGUASEQDNACCwJAAkAgBC0AAEG/f2oODwC5AbkBuQG5AbkBuQG5AbkBuQG5AbkBuQG5AQG5AQsgBEEBaiEBQf4AIRAMtwILIARBAWohAUH/ACEQDLYCCwJAIAQgAkcNAEGVASEQDM8CCwJAAkAgBC0AAEG/f2oOAwC4AQG4AQsgBEEBaiEBQf0AIRAMtgILIARBAWohBEGAASEQDLUCCwJAIAQgAkcNAEGWASEQDM4CCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRACQANAIAQtAAAgAUGnz4CAAGotAABHDbYBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGWASEQDM4CCyAAQQA2AgAgEEEBaiEBQQshEAyzAQsCQCAEIAJHDQBBlwEhEAzNAgsCQAJAAkACQCAELQAAQVNqDiMAuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AQG4AbgBuAG4AbgBArgBuAG4AQO4AQsgBEEBaiEBQfsAIRAMtgILIARBAWohAUH8ACEQDLUCCyAEQQFqIQRBgQEhEAy0AgsgBEEBaiEEQYIBIRAMswILAkAgBCACRw0AQZgBIRAMzAILIAIgBGsgACgCACIBaiEUIAQgAWtBBGohEAJAA0AgBC0AACABQanPgIAAai0AAEcNtAEgAUEERg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZgBIRAMzAILIABBADYCACAQQQFqIQFBGSEQDLEBCwJAIAQgAkcNAEGZASEQDMsCCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUGuz4CAAGotAABHDbMBIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGZASEQDMsCCyAAQQA2AgAgEEEBaiEBQQYhEAywAQsCQCAEIAJHDQBBmgEhEAzKAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFBtM+AgABqLQAARw2yASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBmgEhEAzKAgsgAEEANgIAIBBBAWohAUEcIRAMrwELAkAgBCACRw0AQZsBIRAMyQILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQbbPgIAAai0AAEcNsQEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZsBIRAMyQILIABBADYCACAQQQFqIQFBJyEQDK4BCwJAIAQgAkcNAEGcASEQDMgCCwJAAkAgBC0AAEGsf2oOAgABsQELIARBAWohBEGGASEQDK8CCyAEQQFqIQRBhwEhEAyuAgsCQCAEIAJHDQBBnQEhEAzHAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFBuM+AgABqLQAARw2vASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBnQEhEAzHAgsgAEEANgIAIBBBAWohAUEmIRAMrAELAkAgBCACRw0AQZ4BIRAMxgILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQbrPgIAAai0AAEcNrgEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZ4BIRAMxgILIABBADYCACAQQQFqIQFBAyEQDKsBCwJAIAQgAkcNAEGfASEQDMUCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHtz4CAAGotAABHDa0BIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGfASEQDMUCCyAAQQA2AgAgEEEBaiEBQQwhEAyqAQsCQCAEIAJHDQBBoAEhEAzEAgsgAiAEayAAKAIAIgFqIRQgBCABa0EDaiEQAkADQCAELQAAIAFBvM+AgABqLQAARw2sASABQQNGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBoAEhEAzEAgsgAEEANgIAIBBBAWohAUENIRAMqQELAkAgBCACRw0AQaEBIRAMwwILAkACQCAELQAAQbp/ag4LAKwBrAGsAawBrAGsAawBrAGsAQGsAQsgBEEBaiEEQYsBIRAMqgILIARBAWohBEGMASEQDKkCCwJAIAQgAkcNAEGiASEQDMICCyAELQAAQdAARw2pASAEQQFqIQQM6QELAkAgBCACRw0AQaMBIRAMwQILAkACQCAELQAAQbd/ag4HAaoBqgGqAaoBqgEAqgELIARBAWohBEGOASEQDKgCCyAEQQFqIQFBIiEQDKYBCwJAIAQgAkcNAEGkASEQDMACCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRACQANAIAQtAAAgAUHAz4CAAGotAABHDagBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGkASEQDMACCyAAQQA2AgAgEEEBaiEBQR0hEAylAQsCQCAEIAJHDQBBpQEhEAy/AgsCQAJAIAQtAABBrn9qDgMAqAEBqAELIARBAWohBEGQASEQDKYCCyAEQQFqIQFBBCEQDKQBCwJAIAQgAkcNAEGmASEQDL4CCwJAAkACQAJAAkAgBC0AAEG/f2oOFQCqAaoBqgGqAaoBqgGqAaoBqgGqAQGqAaoBAqoBqgEDqgGqAQSqAQsgBEEBaiEEQYgBIRAMqAILIARBAWohBEGJASEQDKcCCyAEQQFqIQRBigEhEAymAgsgBEEBaiEEQY8BIRAMpQILIARBAWohBEGRASEQDKQCCwJAIAQgAkcNAEGnASEQDL0CCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHtz4CAAGotAABHDaUBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGnASEQDL0CCyAAQQA2AgAgEEEBaiEBQREhEAyiAQsCQCAEIAJHDQBBqAEhEAy8AgsgAiAEayAAKAIAIgFqIRQgBCABa0ECaiEQAkADQCAELQAAIAFBws+AgABqLQAARw2kASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBqAEhEAy8AgsgAEEANgIAIBBBAWohAUEsIRAMoQELAkAgBCACRw0AQakBIRAMuwILIAIgBGsgACgCACIBaiEUIAQgAWtBBGohEAJAA0AgBC0AACABQcXPgIAAai0AAEcNowEgAUEERg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQakBIRAMuwILIABBADYCACAQQQFqIQFBKyEQDKABCwJAIAQgAkcNAEGqASEQDLoCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHKz4CAAGotAABHDaIBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGqASEQDLoCCyAAQQA2AgAgEEEBaiEBQRQhEAyfAQsCQCAEIAJHDQBBqwEhEAy5AgsCQAJAAkACQCAELQAAQb5/ag4PAAECpAGkAaQBpAGkAaQBpAGkAaQBpAGkAQOkAQsgBEEBaiEEQZMBIRAMogILIARBAWohBEGUASEQDKECCyAEQQFqIQRBlQEhEAygAgsgBEEBaiEEQZYBIRAMnwILAkAgBCACRw0AQawBIRAMuAILIAQtAABBxQBHDZ8BIARBAWohBAzgAQsCQCAEIAJHDQBBrQEhEAy3AgsgAiAEayAAKAIAIgFqIRQgBCABa0ECaiEQAkADQCAELQAAIAFBzc+AgABqLQAARw2fASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBrQEhEAy3AgsgAEEANgIAIBBBAWohAUEOIRAMnAELAkAgBCACRw0AQa4BIRAMtgILIAQtAABB0ABHDZ0BIARBAWohAUElIRAMmwELAkAgBCACRw0AQa8BIRAMtQILIAIgBGsgACgCACIBaiEUIAQgAWtBCGohEAJAA0AgBC0AACABQdDPgIAAai0AAEcNnQEgAUEIRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQa8BIRAMtQILIABBADYCACAQQQFqIQFBKiEQDJoBCwJAIAQgAkcNAEGwASEQDLQCCwJAAkAgBC0AAEGrf2oOCwCdAZ0BnQGdAZ0BnQGdAZ0BnQEBnQELIARBAWohBEGaASEQDJsCCyAEQQFqIQRBmwEhEAyaAgsCQCAEIAJHDQBBsQEhEAyzAgsCQAJAIAQtAABBv39qDhQAnAGcAZwBnAGcAZwBnAGcAZwBnAGcAZwBnAGcAZwBnAGcAZwBAZwBCyAEQQFqIQRBmQEhEAyaAgsgBEEBaiEEQZwBIRAMmQILAkAgBCACRw0AQbIBIRAMsgILIAIgBGsgACgCACIBaiEUIAQgAWtBA2ohEAJAA0AgBC0AACABQdnPgIAAai0AAEcNmgEgAUEDRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQbIBIRAMsgILIABBADYCACAQQQFqIQFBISEQDJcBCwJAIAQgAkcNAEGzASEQDLECCyACIARrIAAoAgAiAWohFCAEIAFrQQZqIRACQANAIAQtAAAgAUHdz4CAAGotAABHDZkBIAFBBkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGzASEQDLECCyAAQQA2AgAgEEEBaiEBQRohEAyWAQsCQCAEIAJHDQBBtAEhEAywAgsCQAJAAkAgBC0AAEG7f2oOEQCaAZoBmgGaAZoBmgGaAZoBmgEBmgGaAZoBmgGaAQKaAQsgBEEBaiEEQZ0BIRAMmAILIARBAWohBEGeASEQDJcCCyAEQQFqIQRBnwEhEAyWAgsCQCAEIAJHDQBBtQEhEAyvAgsgAiAEayAAKAIAIgFqIRQgBCABa0EFaiEQAkADQCAELQAAIAFB5M+AgABqLQAARw2XASABQQVGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBtQEhEAyvAgsgAEEANgIAIBBBAWohAUEoIRAMlAELAkAgBCACRw0AQbYBIRAMrgILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQerPgIAAai0AAEcNlgEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQbYBIRAMrgILIABBADYCACAQQQFqIQFBByEQDJMBCwJAIAQgAkcNAEG3ASEQDK0CCwJAAkAgBC0AAEG7f2oODgCWAZYBlgGWAZYBlgGWAZYBlgGWAZYBlgEBlgELIARBAWohBEGhASEQDJQCCyAEQQFqIQRBogEhEAyTAgsCQCAEIAJHDQBBuAEhEAysAgsgAiAEayAAKAIAIgFqIRQgBCABa0ECaiEQAkADQCAELQAAIAFB7c+AgABqLQAARw2UASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBuAEhEAysAgsgAEEANgIAIBBBAWohAUESIRAMkQELAkAgBCACRw0AQbkBIRAMqwILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQfDPgIAAai0AAEcNkwEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQbkBIRAMqwILIABBADYCACAQQQFqIQFBICEQDJABCwJAIAQgAkcNAEG6ASEQDKoCCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRACQANAIAQtAAAgAUHyz4CAAGotAABHDZIBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEG6ASEQDKoCCyAAQQA2AgAgEEEBaiEBQQ8hEAyPAQsCQCAEIAJHDQBBuwEhEAypAgsCQAJAIAQtAABBt39qDgcAkgGSAZIBkgGSAQGSAQsgBEEBaiEEQaUBIRAMkAILIARBAWohBEGmASEQDI8CCwJAIAQgAkcNAEG8ASEQDKgCCyACIARrIAAoAgAiAWohFCAEIAFrQQdqIRACQANAIAQtAAAgAUH0z4CAAGotAABHDZABIAFBB0YNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEG8ASEQDKgCCyAAQQA2AgAgEEEBaiEBQRshEAyNAQsCQCAEIAJHDQBBvQEhEAynAgsCQAJAAkAgBC0AAEG+f2oOEgCRAZEBkQGRAZEBkQGRAZEBkQEBkQGRAZEBkQGRAZEBApEBCyAEQQFqIQRBpAEhEAyPAgsgBEEBaiEEQacBIRAMjgILIARBAWohBEGoASEQDI0CCwJAIAQgAkcNAEG+ASEQDKYCCyAELQAAQc4ARw2NASAEQQFqIQQMzwELAkAgBCACRw0AQb8BIRAMpQILAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBC0AAEG/f2oOFQABAgOcAQQFBpwBnAGcAQcICQoLnAEMDQ4PnAELIARBAWohAUHoACEQDJoCCyAEQQFqIQFB6QAhEAyZAgsgBEEBaiEBQe4AIRAMmAILIARBAWohAUHyACEQDJcCCyAEQQFqIQFB8wAhEAyWAgsgBEEBaiEBQfYAIRAMlQILIARBAWohAUH3ACEQDJQCCyAEQQFqIQFB+gAhEAyTAgsgBEEBaiEEQYMBIRAMkgILIARBAWohBEGEASEQDJECCyAEQQFqIQRBhQEhEAyQAgsgBEEBaiEEQZIBIRAMjwILIARBAWohBEGYASEQDI4CCyAEQQFqIQRBoAEhEAyNAgsgBEEBaiEEQaMBIRAMjAILIARBAWohBEGqASEQDIsCCwJAIAQgAkYNACAAQZCAgIAANgIIIAAgBDYCBEGrASEQDIsCC0HAASEQDKMCCyAAIAUgAhCqgICAACIBDYsBIAUhAQxcCwJAIAYgAkYNACAGQQFqIQUMjQELQcIBIRAMoQILA0ACQCAQLQAAQXZqDgSMAQAAjwEACyAQQQFqIhAgAkcNAAtBwwEhEAygAgsCQCAHIAJGDQAgAEGRgICAADYCCCAAIAc2AgQgByEBQQEhEAyHAgtBxAEhEAyfAgsCQCAHIAJHDQBBxQEhEAyfAgsCQAJAIActAABBdmoOBAHOAc4BAM4BCyAHQQFqIQYMjQELIAdBAWohBQyJAQsCQCAHIAJHDQBBxgEhEAyeAgsCQAJAIActAABBdmoOFwGPAY8BAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAQCPAQsgB0EBaiEHC0GwASEQDIQCCwJAIAggAkcNAEHIASEQDJ0CCyAILQAAQSBHDY0BIABBADsBMiAIQQFqIQFBswEhEAyDAgsgASEXAkADQCAXIgcgAkYNASAHLQAAQVBqQf8BcSIQQQpPDcwBAkAgAC8BMiIUQZkzSw0AIAAgFEEKbCIUOwEyIBBB//8DcyAUQf7/A3FJDQAgB0EBaiEXIAAgFCAQaiIQOwEyIBBB//8DcUHoB0kNAQsLQQAhECAAQQA2AhwgAEHBiYCAADYCECAAQQ02AgwgACAHQQFqNgIUDJwCC0HHASEQDJsCCyAAIAggAhCugICAACIQRQ3KASAQQRVHDYwBIABByAE2AhwgACAINgIUIABByZeAgAA2AhAgAEEVNgIMQQAhEAyaAgsCQCAJIAJHDQBBzAEhEAyaAgtBACEUQQEhF0EBIRZBACEQAkACQAJAAkACQAJAAkACQAJAIAktAABBUGoOCpYBlQEAAQIDBAUGCJcBC0ECIRAMBgtBAyEQDAULQQQhEAwEC0EFIRAMAwtBBiEQDAILQQchEAwBC0EIIRALQQAhF0EAIRZBACEUDI4BC0EJIRBBASEUQQAhF0EAIRYMjQELAkAgCiACRw0AQc4BIRAMmQILIAotAABBLkcNjgEgCkEBaiEJDMoBCyALIAJHDY4BQdABIRAMlwILAkAgCyACRg0AIABBjoCAgAA2AgggACALNgIEQbcBIRAM/gELQdEBIRAMlgILAkAgBCACRw0AQdIBIRAMlgILIAIgBGsgACgCACIQaiEUIAQgEGtBBGohCwNAIAQtAAAgEEH8z4CAAGotAABHDY4BIBBBBEYN6QEgEEEBaiEQIARBAWoiBCACRw0ACyAAIBQ2AgBB0gEhEAyVAgsgACAMIAIQrICAgAAiAQ2NASAMIQEMuAELAkAgBCACRw0AQdQBIRAMlAILIAIgBGsgACgCACIQaiEUIAQgEGtBAWohDANAIAQtAAAgEEGB0ICAAGotAABHDY8BIBBBAUYNjgEgEEEBaiEQIARBAWoiBCACRw0ACyAAIBQ2AgBB1AEhEAyTAgsCQCAEIAJHDQBB1gEhEAyTAgsgAiAEayAAKAIAIhBqIRQgBCAQa0ECaiELA0AgBC0AACAQQYPQgIAAai0AAEcNjgEgEEECRg2QASAQQQFqIRAgBEEBaiIEIAJHDQALIAAgFDYCAEHWASEQDJICCwJAIAQgAkcNAEHXASEQDJICCwJAAkAgBC0AAEG7f2oOEACPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BAY8BCyAEQQFqIQRBuwEhEAz5AQsgBEEBaiEEQbwBIRAM+AELAkAgBCACRw0AQdgBIRAMkQILIAQtAABByABHDYwBIARBAWohBAzEAQsCQCAEIAJGDQAgAEGQgICAADYCCCAAIAQ2AgRBvgEhEAz3AQtB2QEhEAyPAgsCQCAEIAJHDQBB2gEhEAyPAgsgBC0AAEHIAEYNwwEgAEEBOgAoDLkBCyAAQQI6AC8gACAEIAIQpoCAgAAiEA2NAUHCASEQDPQBCyAALQAoQX9qDgK3AbkBuAELA0ACQCAELQAAQXZqDgQAjgGOAQCOAQsgBEEBaiIEIAJHDQALQd0BIRAMiwILIABBADoALyAALQAtQQRxRQ2EAgsgAEEAOgAvIABBAToANCABIQEMjAELIBBBFUYN2gEgAEEANgIcIAAgATYCFCAAQaeOgIAANgIQIABBEjYCDEEAIRAMiAILAkAgACAQIAIQtICAgAAiBA0AIBAhAQyBAgsCQCAEQRVHDQAgAEEDNgIcIAAgEDYCFCAAQbCYgIAANgIQIABBFTYCDEEAIRAMiAILIABBADYCHCAAIBA2AhQgAEGnjoCAADYCECAAQRI2AgxBACEQDIcCCyAQQRVGDdYBIABBADYCHCAAIAE2AhQgAEHajYCAADYCECAAQRQ2AgxBACEQDIYCCyAAKAIEIRcgAEEANgIEIBAgEadqIhYhASAAIBcgECAWIBQbIhAQtYCAgAAiFEUNjQEgAEEHNgIcIAAgEDYCFCAAIBQ2AgxBACEQDIUCCyAAIAAvATBBgAFyOwEwIAEhAQtBKiEQDOoBCyAQQRVGDdEBIABBADYCHCAAIAE2AhQgAEGDjICAADYCECAAQRM2AgxBACEQDIICCyAQQRVGDc8BIABBADYCHCAAIAE2AhQgAEGaj4CAADYCECAAQSI2AgxBACEQDIECCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQt4CAgAAiEA0AIAFBAWohAQyNAQsgAEEMNgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDIACCyAQQRVGDcwBIABBADYCHCAAIAE2AhQgAEGaj4CAADYCECAAQSI2AgxBACEQDP8BCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQt4CAgAAiEA0AIAFBAWohAQyMAQsgAEENNgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDP4BCyAQQRVGDckBIABBADYCHCAAIAE2AhQgAEHGjICAADYCECAAQSM2AgxBACEQDP0BCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQuYCAgAAiEA0AIAFBAWohAQyLAQsgAEEONgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDPwBCyAAQQA2AhwgACABNgIUIABBwJWAgAA2AhAgAEECNgIMQQAhEAz7AQsgEEEVRg3FASAAQQA2AhwgACABNgIUIABBxoyAgAA2AhAgAEEjNgIMQQAhEAz6AQsgAEEQNgIcIAAgATYCFCAAIBA2AgxBACEQDPkBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQuYCAgAAiBA0AIAFBAWohAQzxAQsgAEERNgIcIAAgBDYCDCAAIAFBAWo2AhRBACEQDPgBCyAQQRVGDcEBIABBADYCHCAAIAE2AhQgAEHGjICAADYCECAAQSM2AgxBACEQDPcBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQuYCAgAAiEA0AIAFBAWohAQyIAQsgAEETNgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDPYBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQuYCAgAAiBA0AIAFBAWohAQztAQsgAEEUNgIcIAAgBDYCDCAAIAFBAWo2AhRBACEQDPUBCyAQQRVGDb0BIABBADYCHCAAIAE2AhQgAEGaj4CAADYCECAAQSI2AgxBACEQDPQBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQt4CAgAAiEA0AIAFBAWohAQyGAQsgAEEWNgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDPMBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQt4CAgAAiBA0AIAFBAWohAQzpAQsgAEEXNgIcIAAgBDYCDCAAIAFBAWo2AhRBACEQDPIBCyAAQQA2AhwgACABNgIUIABBzZOAgAA2AhAgAEEMNgIMQQAhEAzxAQtCASERCyAQQQFqIQECQCAAKQMgIhJC//////////8PVg0AIAAgEkIEhiARhDcDICABIQEMhAELIABBADYCHCAAIAE2AhQgAEGtiYCAADYCECAAQQw2AgxBACEQDO8BCyAAQQA2AhwgACAQNgIUIABBzZOAgAA2AhAgAEEMNgIMQQAhEAzuAQsgACgCBCEXIABBADYCBCAQIBGnaiIWIQEgACAXIBAgFiAUGyIQELWAgIAAIhRFDXMgAEEFNgIcIAAgEDYCFCAAIBQ2AgxBACEQDO0BCyAAQQA2AhwgACAQNgIUIABBqpyAgAA2AhAgAEEPNgIMQQAhEAzsAQsgACAQIAIQtICAgAAiAQ0BIBAhAQtBDiEQDNEBCwJAIAFBFUcNACAAQQI2AhwgACAQNgIUIABBsJiAgAA2AhAgAEEVNgIMQQAhEAzqAQsgAEEANgIcIAAgEDYCFCAAQaeOgIAANgIQIABBEjYCDEEAIRAM6QELIAFBAWohEAJAIAAvATAiAUGAAXFFDQACQCAAIBAgAhC7gICAACIBDQAgECEBDHALIAFBFUcNugEgAEEFNgIcIAAgEDYCFCAAQfmXgIAANgIQIABBFTYCDEEAIRAM6QELAkAgAUGgBHFBoARHDQAgAC0ALUECcQ0AIABBADYCHCAAIBA2AhQgAEGWk4CAADYCECAAQQQ2AgxBACEQDOkBCyAAIBAgAhC9gICAABogECEBAkACQAJAAkACQCAAIBAgAhCzgICAAA4WAgEABAQEBAQEBAQEBAQEBAQEBAQEAwQLIABBAToALgsgACAALwEwQcAAcjsBMCAQIQELQSYhEAzRAQsgAEEjNgIcIAAgEDYCFCAAQaWWgIAANgIQIABBFTYCDEEAIRAM6QELIABBADYCHCAAIBA2AhQgAEHVi4CAADYCECAAQRE2AgxBACEQDOgBCyAALQAtQQFxRQ0BQcMBIRAMzgELAkAgDSACRg0AA0ACQCANLQAAQSBGDQAgDSEBDMQBCyANQQFqIg0gAkcNAAtBJSEQDOcBC0ElIRAM5gELIAAoAgQhBCAAQQA2AgQgACAEIA0Qr4CAgAAiBEUNrQEgAEEmNgIcIAAgBDYCDCAAIA1BAWo2AhRBACEQDOUBCyAQQRVGDasBIABBADYCHCAAIAE2AhQgAEH9jYCAADYCECAAQR02AgxBACEQDOQBCyAAQSc2AhwgACABNgIUIAAgEDYCDEEAIRAM4wELIBAhAUEBIRQCQAJAAkACQAJAAkACQCAALQAsQX5qDgcGBQUDAQIABQsgACAALwEwQQhyOwEwDAMLQQIhFAwBC0EEIRQLIABBAToALCAAIAAvATAgFHI7ATALIBAhAQtBKyEQDMoBCyAAQQA2AhwgACAQNgIUIABBq5KAgAA2AhAgAEELNgIMQQAhEAziAQsgAEEANgIcIAAgATYCFCAAQeGPgIAANgIQIABBCjYCDEEAIRAM4QELIABBADoALCAQIQEMvQELIBAhAUEBIRQCQAJAAkACQAJAIAAtACxBe2oOBAMBAgAFCyAAIAAvATBBCHI7ATAMAwtBAiEUDAELQQQhFAsgAEEBOgAsIAAgAC8BMCAUcjsBMAsgECEBC0EpIRAMxQELIABBADYCHCAAIAE2AhQgAEHwlICAADYCECAAQQM2AgxBACEQDN0BCwJAIA4tAABBDUcNACAAKAIEIQEgAEEANgIEAkAgACABIA4QsYCAgAAiAQ0AIA5BAWohAQx1CyAAQSw2AhwgACABNgIMIAAgDkEBajYCFEEAIRAM3QELIAAtAC1BAXFFDQFBxAEhEAzDAQsCQCAOIAJHDQBBLSEQDNwBCwJAAkADQAJAIA4tAABBdmoOBAIAAAMACyAOQQFqIg4gAkcNAAtBLSEQDN0BCyAAKAIEIQEgAEEANgIEAkAgACABIA4QsYCAgAAiAQ0AIA4hAQx0CyAAQSw2AhwgACAONgIUIAAgATYCDEEAIRAM3AELIAAoAgQhASAAQQA2AgQCQCAAIAEgDhCxgICAACIBDQAgDkEBaiEBDHMLIABBLDYCHCAAIAE2AgwgACAOQQFqNgIUQQAhEAzbAQsgACgCBCEEIABBADYCBCAAIAQgDhCxgICAACIEDaABIA4hAQzOAQsgEEEsRw0BIAFBAWohEEEBIQECQAJAAkACQAJAIAAtACxBe2oOBAMBAgQACyAQIQEMBAtBAiEBDAELQQQhAQsgAEEBOgAsIAAgAC8BMCABcjsBMCAQIQEMAQsgACAALwEwQQhyOwEwIBAhAQtBOSEQDL8BCyAAQQA6ACwgASEBC0E0IRAMvQELIAAgAC8BMEEgcjsBMCABIQEMAgsgACgCBCEEIABBADYCBAJAIAAgBCABELGAgIAAIgQNACABIQEMxwELIABBNzYCHCAAIAE2AhQgACAENgIMQQAhEAzUAQsgAEEIOgAsIAEhAQtBMCEQDLkBCwJAIAAtAChBAUYNACABIQEMBAsgAC0ALUEIcUUNkwEgASEBDAMLIAAtADBBIHENlAFBxQEhEAy3AQsCQCAPIAJGDQACQANAAkAgDy0AAEFQaiIBQf8BcUEKSQ0AIA8hAUE1IRAMugELIAApAyAiEUKZs+bMmbPmzBlWDQEgACARQgp+IhE3AyAgESABrUL/AYMiEkJ/hVYNASAAIBEgEnw3AyAgD0EBaiIPIAJHDQALQTkhEAzRAQsgACgCBCECIABBADYCBCAAIAIgD0EBaiIEELGAgIAAIgINlQEgBCEBDMMBC0E5IRAMzwELAkAgAC8BMCIBQQhxRQ0AIAAtAChBAUcNACAALQAtQQhxRQ2QAQsgACABQff7A3FBgARyOwEwIA8hAQtBNyEQDLQBCyAAIAAvATBBEHI7ATAMqwELIBBBFUYNiwEgAEEANgIcIAAgATYCFCAAQfCOgIAANgIQIABBHDYCDEEAIRAMywELIABBwwA2AhwgACABNgIMIAAgDUEBajYCFEEAIRAMygELAkAgAS0AAEE6Rw0AIAAoAgQhECAAQQA2AgQCQCAAIBAgARCvgICAACIQDQAgAUEBaiEBDGMLIABBwwA2AhwgACAQNgIMIAAgAUEBajYCFEEAIRAMygELIABBADYCHCAAIAE2AhQgAEGxkYCAADYCECAAQQo2AgxBACEQDMkBCyAAQQA2AhwgACABNgIUIABBoJmAgAA2AhAgAEEeNgIMQQAhEAzIAQsgAEEANgIACyAAQYASOwEqIAAgF0EBaiIBIAIQqICAgAAiEA0BIAEhAQtBxwAhEAysAQsgEEEVRw2DASAAQdEANgIcIAAgATYCFCAAQeOXgIAANgIQIABBFTYCDEEAIRAMxAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDF4LIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMwwELIABBADYCHCAAIBQ2AhQgAEHBqICAADYCECAAQQc2AgwgAEEANgIAQQAhEAzCAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMXQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAzBAQtBACEQIABBADYCHCAAIAE2AhQgAEGAkYCAADYCECAAQQk2AgwMwAELIBBBFUYNfSAAQQA2AhwgACABNgIUIABBlI2AgAA2AhAgAEEhNgIMQQAhEAy/AQtBASEWQQAhF0EAIRRBASEQCyAAIBA6ACsgAUEBaiEBAkACQCAALQAtQRBxDQACQAJAAkAgAC0AKg4DAQACBAsgFkUNAwwCCyAUDQEMAgsgF0UNAQsgACgCBCEQIABBADYCBAJAIAAgECABEK2AgIAAIhANACABIQEMXAsgAEHYADYCHCAAIAE2AhQgACAQNgIMQQAhEAy+AQsgACgCBCEEIABBADYCBAJAIAAgBCABEK2AgIAAIgQNACABIQEMrQELIABB2QA2AhwgACABNgIUIAAgBDYCDEEAIRAMvQELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARCtgICAACIEDQAgASEBDKsBCyAAQdoANgIcIAAgATYCFCAAIAQ2AgxBACEQDLwBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQrYCAgAAiBA0AIAEhAQypAQsgAEHcADYCHCAAIAE2AhQgACAENgIMQQAhEAy7AQsCQCABLQAAQVBqIhBB/wFxQQpPDQAgACAQOgAqIAFBAWohAUHPACEQDKIBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQrYCAgAAiBA0AIAEhAQynAQsgAEHeADYCHCAAIAE2AhQgACAENgIMQQAhEAy6AQsgAEEANgIAIBdBAWohAQJAIAAtAClBI08NACABIQEMWQsgAEEANgIcIAAgATYCFCAAQdOJgIAANgIQIABBCDYCDEEAIRAMuQELIABBADYCAAtBACEQIABBADYCHCAAIAE2AhQgAEGQs4CAADYCECAAQQg2AgwMtwELIABBADYCACAXQQFqIQECQCAALQApQSFHDQAgASEBDFYLIABBADYCHCAAIAE2AhQgAEGbioCAADYCECAAQQg2AgxBACEQDLYBCyAAQQA2AgAgF0EBaiEBAkAgAC0AKSIQQV1qQQtPDQAgASEBDFULAkAgEEEGSw0AQQEgEHRBygBxRQ0AIAEhAQxVC0EAIRAgAEEANgIcIAAgATYCFCAAQfeJgIAANgIQIABBCDYCDAy1AQsgEEEVRg1xIABBADYCHCAAIAE2AhQgAEG5jYCAADYCECAAQRo2AgxBACEQDLQBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxUCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLMBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdIANgIcIAAgATYCFCAAIBA2AgxBACEQDLIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDLEBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxRCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLABCyAAQQA2AhwgACABNgIUIABBxoqAgAA2AhAgAEEHNgIMQQAhEAyvAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAyuAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAytAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMTQsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAysAQsgAEEANgIcIAAgATYCFCAAQdyIgIAANgIQIABBBzYCDEEAIRAMqwELIBBBP0cNASABQQFqIQELQQUhEAyQAQtBACEQIABBADYCHCAAIAE2AhQgAEH9koCAADYCECAAQQc2AgwMqAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMpwELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMpgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEYLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMpQELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0gA2AhwgACAUNgIUIAAgATYCDEEAIRAMpAELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0wA2AhwgACAUNgIUIAAgATYCDEEAIRAMowELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDEMLIABB5QA2AhwgACAUNgIUIAAgATYCDEEAIRAMogELIABBADYCHCAAIBQ2AhQgAEHDj4CAADYCECAAQQc2AgxBACEQDKEBCyAAQQA2AhwgACABNgIUIABBw4+AgAA2AhAgAEEHNgIMQQAhEAygAQtBACEQIABBADYCHCAAIBQ2AhQgAEGMnICAADYCECAAQQc2AgwMnwELIABBADYCHCAAIBQ2AhQgAEGMnICAADYCECAAQQc2AgxBACEQDJ4BCyAAQQA2AhwgACAUNgIUIABB/pGAgAA2AhAgAEEHNgIMQQAhEAydAQsgAEEANgIcIAAgATYCFCAAQY6bgIAANgIQIABBBjYCDEEAIRAMnAELIBBBFUYNVyAAQQA2AhwgACABNgIUIABBzI6AgAA2AhAgAEEgNgIMQQAhEAybAQsgAEEANgIAIBBBAWohAUEkIRALIAAgEDoAKSAAKAIEIRAgAEEANgIEIAAgECABEKuAgIAAIhANVCABIQEMPgsgAEEANgIAC0EAIRAgAEEANgIcIAAgBDYCFCAAQfGbgIAANgIQIABBBjYCDAyXAQsgAUEVRg1QIABBADYCHCAAIAU2AhQgAEHwjICAADYCECAAQRs2AgxBACEQDJYBCyAAKAIEIQUgAEEANgIEIAAgBSAQEKmAgIAAIgUNASAQQQFqIQULQa0BIRAMewsgAEHBATYCHCAAIAU2AgwgACAQQQFqNgIUQQAhEAyTAQsgACgCBCEGIABBADYCBCAAIAYgEBCpgICAACIGDQEgEEEBaiEGC0GuASEQDHgLIABBwgE2AhwgACAGNgIMIAAgEEEBajYCFEEAIRAMkAELIABBADYCHCAAIAc2AhQgAEGXi4CAADYCECAAQQ02AgxBACEQDI8BCyAAQQA2AhwgACAINgIUIABB45CAgAA2AhAgAEEJNgIMQQAhEAyOAQsgAEEANgIcIAAgCDYCFCAAQZSNgIAANgIQIABBITYCDEEAIRAMjQELQQEhFkEAIRdBACEUQQEhEAsgACAQOgArIAlBAWohCAJAAkAgAC0ALUEQcQ0AAkACQAJAIAAtACoOAwEAAgQLIBZFDQMMAgsgFA0BDAILIBdFDQELIAAoAgQhECAAQQA2AgQgACAQIAgQrYCAgAAiEEUNPSAAQckBNgIcIAAgCDYCFCAAIBA2AgxBACEQDIwBCyAAKAIEIQQgAEEANgIEIAAgBCAIEK2AgIAAIgRFDXYgAEHKATYCHCAAIAg2AhQgACAENgIMQQAhEAyLAQsgACgCBCEEIABBADYCBCAAIAQgCRCtgICAACIERQ10IABBywE2AhwgACAJNgIUIAAgBDYCDEEAIRAMigELIAAoAgQhBCAAQQA2AgQgACAEIAoQrYCAgAAiBEUNciAAQc0BNgIcIAAgCjYCFCAAIAQ2AgxBACEQDIkBCwJAIAstAABBUGoiEEH/AXFBCk8NACAAIBA6ACogC0EBaiEKQbYBIRAMcAsgACgCBCEEIABBADYCBCAAIAQgCxCtgICAACIERQ1wIABBzwE2AhwgACALNgIUIAAgBDYCDEEAIRAMiAELIABBADYCHCAAIAQ2AhQgAEGQs4CAADYCECAAQQg2AgwgAEEANgIAQQAhEAyHAQsgAUEVRg0/IABBADYCHCAAIAw2AhQgAEHMjoCAADYCECAAQSA2AgxBACEQDIYBCyAAQYEEOwEoIAAoAgQhECAAQgA3AwAgACAQIAxBAWoiDBCrgICAACIQRQ04IABB0wE2AhwgACAMNgIUIAAgEDYCDEEAIRAMhQELIABBADYCAAtBACEQIABBADYCHCAAIAQ2AhQgAEHYm4CAADYCECAAQQg2AgwMgwELIAAoAgQhECAAQgA3AwAgACAQIAtBAWoiCxCrgICAACIQDQFBxgEhEAxpCyAAQQI6ACgMVQsgAEHVATYCHCAAIAs2AhQgACAQNgIMQQAhEAyAAQsgEEEVRg03IABBADYCHCAAIAQ2AhQgAEGkjICAADYCECAAQRA2AgxBACEQDH8LIAAtADRBAUcNNCAAIAQgAhC8gICAACIQRQ00IBBBFUcNNSAAQdwBNgIcIAAgBDYCFCAAQdWWgIAANgIQIABBFTYCDEEAIRAMfgtBACEQIABBADYCHCAAQa+LgIAANgIQIABBAjYCDCAAIBRBAWo2AhQMfQtBACEQDGMLQQIhEAxiC0ENIRAMYQtBDyEQDGALQSUhEAxfC0ETIRAMXgtBFSEQDF0LQRYhEAxcC0EXIRAMWwtBGCEQDFoLQRkhEAxZC0EaIRAMWAtBGyEQDFcLQRwhEAxWC0EdIRAMVQtBHyEQDFQLQSEhEAxTC0EjIRAMUgtBxgAhEAxRC0EuIRAMUAtBLyEQDE8LQTshEAxOC0E9IRAMTQtByAAhEAxMC0HJACEQDEsLQcsAIRAMSgtBzAAhEAxJC0HOACEQDEgLQdEAIRAMRwtB1QAhEAxGC0HYACEQDEULQdkAIRAMRAtB2wAhEAxDC0HkACEQDEILQeUAIRAMQQtB8QAhEAxAC0H0ACEQDD8LQY0BIRAMPgtBlwEhEAw9C0GpASEQDDwLQawBIRAMOwtBwAEhEAw6C0G5ASEQDDkLQa8BIRAMOAtBsQEhEAw3C0GyASEQDDYLQbQBIRAMNQtBtQEhEAw0C0G6ASEQDDMLQb0BIRAMMgtBvwEhEAwxC0HBASEQDDALIABBADYCHCAAIAQ2AhQgAEHpi4CAADYCECAAQR82AgxBACEQDEgLIABB2wE2AhwgACAENgIUIABB+paAgAA2AhAgAEEVNgIMQQAhEAxHCyAAQfgANgIcIAAgDDYCFCAAQcqYgIAANgIQIABBFTYCDEEAIRAMRgsgAEHRADYCHCAAIAU2AhQgAEGwl4CAADYCECAAQRU2AgxBACEQDEULIABB+QA2AhwgACABNgIUIAAgEDYCDEEAIRAMRAsgAEH4ADYCHCAAIAE2AhQgAEHKmICAADYCECAAQRU2AgxBACEQDEMLIABB5AA2AhwgACABNgIUIABB45eAgAA2AhAgAEEVNgIMQQAhEAxCCyAAQdcANgIcIAAgATYCFCAAQcmXgIAANgIQIABBFTYCDEEAIRAMQQsgAEEANgIcIAAgATYCFCAAQbmNgIAANgIQIABBGjYCDEEAIRAMQAsgAEHCADYCHCAAIAE2AhQgAEHjmICAADYCECAAQRU2AgxBACEQDD8LIABBADYCBCAAIA8gDxCxgICAACIERQ0BIABBOjYCHCAAIAQ2AgwgACAPQQFqNgIUQQAhEAw+CyAAKAIEIQQgAEEANgIEAkAgACAEIAEQsYCAgAAiBEUNACAAQTs2AhwgACAENgIMIAAgAUEBajYCFEEAIRAMPgsgAUEBaiEBDC0LIA9BAWohAQwtCyAAQQA2AhwgACAPNgIUIABB5JKAgAA2AhAgAEEENgIMQQAhEAw7CyAAQTY2AhwgACAENgIUIAAgAjYCDEEAIRAMOgsgAEEuNgIcIAAgDjYCFCAAIAQ2AgxBACEQDDkLIABB0AA2AhwgACABNgIUIABBkZiAgAA2AhAgAEEVNgIMQQAhEAw4CyANQQFqIQEMLAsgAEEVNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMNgsgAEEbNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMNQsgAEEPNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMNAsgAEELNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMMwsgAEEaNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMMgsgAEELNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMMQsgAEEKNgIcIAAgATYCFCAAQeSWgIAANgIQIABBFTYCDEEAIRAMMAsgAEEeNgIcIAAgATYCFCAAQfmXgIAANgIQIABBFTYCDEEAIRAMLwsgAEEANgIcIAAgEDYCFCAAQdqNgIAANgIQIABBFDYCDEEAIRAMLgsgAEEENgIcIAAgATYCFCAAQbCYgIAANgIQIABBFTYCDEEAIRAMLQsgAEEANgIAIAtBAWohCwtBuAEhEAwSCyAAQQA2AgAgEEEBaiEBQfUAIRAMEQsgASEBAkAgAC0AKUEFRw0AQeMAIRAMEQtB4gAhEAwQC0EAIRAgAEEANgIcIABB5JGAgAA2AhAgAEEHNgIMIAAgFEEBajYCFAwoCyAAQQA2AgAgF0EBaiEBQcAAIRAMDgtBASEBCyAAIAE6ACwgAEEANgIAIBdBAWohAQtBKCEQDAsLIAEhAQtBOCEQDAkLAkAgASIPIAJGDQADQAJAIA8tAABBgL6AgABqLQAAIgFBAUYNACABQQJHDQMgD0EBaiEBDAQLIA9BAWoiDyACRw0AC0E+IRAMIgtBPiEQDCELIABBADoALCAPIQEMAQtBCyEQDAYLQTohEAwFCyABQQFqIQFBLSEQDAQLIAAgAToALCAAQQA2AgAgFkEBaiEBQQwhEAwDCyAAQQA2AgAgF0EBaiEBQQohEAwCCyAAQQA2AgALIABBADoALCANIQFBCSEQDAALC0EAIRAgAEEANgIcIAAgCzYCFCAAQc2QgIAANgIQIABBCTYCDAwXC0EAIRAgAEEANgIcIAAgCjYCFCAAQemKgIAANgIQIABBCTYCDAwWC0EAIRAgAEEANgIcIAAgCTYCFCAAQbeQgIAANgIQIABBCTYCDAwVC0EAIRAgAEEANgIcIAAgCDYCFCAAQZyRgIAANgIQIABBCTYCDAwUC0EAIRAgAEEANgIcIAAgATYCFCAAQc2QgIAANgIQIABBCTYCDAwTC0EAIRAgAEEANgIcIAAgATYCFCAAQemKgIAANgIQIABBCTYCDAwSC0EAIRAgAEEANgIcIAAgATYCFCAAQbeQgIAANgIQIABBCTYCDAwRC0EAIRAgAEEANgIcIAAgATYCFCAAQZyRgIAANgIQIABBCTYCDAwQC0EAIRAgAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwPC0EAIRAgAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwOC0EAIRAgAEEANgIcIAAgATYCFCAAQcCSgIAANgIQIABBCzYCDAwNC0EAIRAgAEEANgIcIAAgATYCFCAAQZWJgIAANgIQIABBCzYCDAwMC0EAIRAgAEEANgIcIAAgATYCFCAAQeGPgIAANgIQIABBCjYCDAwLC0EAIRAgAEEANgIcIAAgATYCFCAAQfuPgIAANgIQIABBCjYCDAwKC0EAIRAgAEEANgIcIAAgATYCFCAAQfGZgIAANgIQIABBAjYCDAwJC0EAIRAgAEEANgIcIAAgATYCFCAAQcSUgIAANgIQIABBAjYCDAwIC0EAIRAgAEEANgIcIAAgATYCFCAAQfKVgIAANgIQIABBAjYCDAwHCyAAQQI2AhwgACABNgIUIABBnJqAgAA2AhAgAEEWNgIMQQAhEAwGC0EBIRAMBQtB1AAhECABIgQgAkYNBCADQQhqIAAgBCACQdjCgIAAQQoQxYCAgAAgAygCDCEEIAMoAggOAwEEAgALEMqAgIAAAAsgAEEANgIcIABBtZqAgAA2AhAgAEEXNgIMIAAgBEEBajYCFEEAIRAMAgsgAEEANgIcIAAgBDYCFCAAQcqagIAANgIQIABBCTYCDEEAIRAMAQsCQCABIgQgAkcNAEEiIRAMAQsgAEGJgICAADYCCCAAIAQ2AgRBISEQCyADQRBqJICAgIAAIBALrwEBAn8gASgCACEGAkACQCACIANGDQAgBCAGaiEEIAYgA2ogAmshByACIAZBf3MgBWoiBmohBQNAAkAgAi0AACAELQAARg0AQQIhBAwDCwJAIAYNAEEAIQQgBSECDAMLIAZBf2ohBiAEQQFqIQQgAkEBaiICIANHDQALIAchBiADIQILIABBATYCACABIAY2AgAgACACNgIEDwsgAUEANgIAIAAgBDYCACAAIAI2AgQLCgAgABDHgICAAAvyNgELfyOAgICAAEEQayIBJICAgIAAAkBBACgCoNCAgAANAEEAEMuAgIAAQYDUhIAAayICQdkASQ0AQQAhAwJAQQAoAuDTgIAAIgQNAEEAQn83AuzTgIAAQQBCgICEgICAwAA3AuTTgIAAQQAgAUEIakFwcUHYqtWqBXMiBDYC4NOAgABBAEEANgL004CAAEEAQQA2AsTTgIAAC0EAIAI2AszTgIAAQQBBgNSEgAA2AsjTgIAAQQBBgNSEgAA2ApjQgIAAQQAgBDYCrNCAgABBAEF/NgKo0ICAAANAIANBxNCAgABqIANBuNCAgABqIgQ2AgAgBCADQbDQgIAAaiIFNgIAIANBvNCAgABqIAU2AgAgA0HM0ICAAGogA0HA0ICAAGoiBTYCACAFIAQ2AgAgA0HU0ICAAGogA0HI0ICAAGoiBDYCACAEIAU2AgAgA0HQ0ICAAGogBDYCACADQSBqIgNBgAJHDQALQYDUhIAAQXhBgNSEgABrQQ9xQQBBgNSEgABBCGpBD3EbIgNqIgRBBGogAkFIaiIFIANrIgNBAXI2AgBBAEEAKALw04CAADYCpNCAgABBACADNgKU0ICAAEEAIAQ2AqDQgIAAQYDUhIAAIAVqQTg2AgQLAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB7AFLDQACQEEAKAKI0ICAACIGQRAgAEETakFwcSAAQQtJGyICQQN2IgR2IgNBA3FFDQACQAJAIANBAXEgBHJBAXMiBUEDdCIEQbDQgIAAaiIDIARBuNCAgABqKAIAIgQoAggiAkcNAEEAIAZBfiAFd3E2AojQgIAADAELIAMgAjYCCCACIAM2AgwLIARBCGohAyAEIAVBA3QiBUEDcjYCBCAEIAVqIgQgBCgCBEEBcjYCBAwMCyACQQAoApDQgIAAIgdNDQECQCADRQ0AAkACQCADIAR0QQIgBHQiA0EAIANrcnEiA0EAIANrcUF/aiIDIANBDHZBEHEiA3YiBEEFdkEIcSIFIANyIAQgBXYiA0ECdkEEcSIEciADIAR2IgNBAXZBAnEiBHIgAyAEdiIDQQF2QQFxIgRyIAMgBHZqIgRBA3QiA0Gw0ICAAGoiBSADQbjQgIAAaigCACIDKAIIIgBHDQBBACAGQX4gBHdxIgY2AojQgIAADAELIAUgADYCCCAAIAU2AgwLIAMgAkEDcjYCBCADIARBA3QiBGogBCACayIFNgIAIAMgAmoiACAFQQFyNgIEAkAgB0UNACAHQXhxQbDQgIAAaiECQQAoApzQgIAAIQQCQAJAIAZBASAHQQN2dCIIcQ0AQQAgBiAIcjYCiNCAgAAgAiEIDAELIAIoAgghCAsgCCAENgIMIAIgBDYCCCAEIAI2AgwgBCAINgIICyADQQhqIQNBACAANgKc0ICAAEEAIAU2ApDQgIAADAwLQQAoAozQgIAAIglFDQEgCUEAIAlrcUF/aiIDIANBDHZBEHEiA3YiBEEFdkEIcSIFIANyIAQgBXYiA0ECdkEEcSIEciADIAR2IgNBAXZBAnEiBHIgAyAEdiIDQQF2QQFxIgRyIAMgBHZqQQJ0QbjSgIAAaigCACIAKAIEQXhxIAJrIQQgACEFAkADQAJAIAUoAhAiAw0AIAVBFGooAgAiA0UNAgsgAygCBEF4cSACayIFIAQgBSAESSIFGyEEIAMgACAFGyEAIAMhBQwACwsgACgCGCEKAkAgACgCDCIIIABGDQAgACgCCCIDQQAoApjQgIAASRogCCADNgIIIAMgCDYCDAwLCwJAIABBFGoiBSgCACIDDQAgACgCECIDRQ0DIABBEGohBQsDQCAFIQsgAyIIQRRqIgUoAgAiAw0AIAhBEGohBSAIKAIQIgMNAAsgC0EANgIADAoLQX8hAiAAQb9/Sw0AIABBE2oiA0FwcSECQQAoAozQgIAAIgdFDQBBACELAkAgAkGAAkkNAEEfIQsgAkH///8HSw0AIANBCHYiAyADQYD+P2pBEHZBCHEiA3QiBCAEQYDgH2pBEHZBBHEiBHQiBSAFQYCAD2pBEHZBAnEiBXRBD3YgAyAEciAFcmsiA0EBdCACIANBFWp2QQFxckEcaiELC0EAIAJrIQQCQAJAAkACQCALQQJ0QbjSgIAAaigCACIFDQBBACEDQQAhCAwBC0EAIQMgAkEAQRkgC0EBdmsgC0EfRht0IQBBACEIA0ACQCAFKAIEQXhxIAJrIgYgBE8NACAGIQQgBSEIIAYNAEEAIQQgBSEIIAUhAwwDCyADIAVBFGooAgAiBiAGIAUgAEEddkEEcWpBEGooAgAiBUYbIAMgBhshAyAAQQF0IQAgBQ0ACwsCQCADIAhyDQBBACEIQQIgC3QiA0EAIANrciAHcSIDRQ0DIANBACADa3FBf2oiAyADQQx2QRBxIgN2IgVBBXZBCHEiACADciAFIAB2IgNBAnZBBHEiBXIgAyAFdiIDQQF2QQJxIgVyIAMgBXYiA0EBdkEBcSIFciADIAV2akECdEG40oCAAGooAgAhAwsgA0UNAQsDQCADKAIEQXhxIAJrIgYgBEkhAAJAIAMoAhAiBQ0AIANBFGooAgAhBQsgBiAEIAAbIQQgAyAIIAAbIQggBSEDIAUNAAsLIAhFDQAgBEEAKAKQ0ICAACACa08NACAIKAIYIQsCQCAIKAIMIgAgCEYNACAIKAIIIgNBACgCmNCAgABJGiAAIAM2AgggAyAANgIMDAkLAkAgCEEUaiIFKAIAIgMNACAIKAIQIgNFDQMgCEEQaiEFCwNAIAUhBiADIgBBFGoiBSgCACIDDQAgAEEQaiEFIAAoAhAiAw0ACyAGQQA2AgAMCAsCQEEAKAKQ0ICAACIDIAJJDQBBACgCnNCAgAAhBAJAAkAgAyACayIFQRBJDQAgBCACaiIAIAVBAXI2AgRBACAFNgKQ0ICAAEEAIAA2ApzQgIAAIAQgA2ogBTYCACAEIAJBA3I2AgQMAQsgBCADQQNyNgIEIAQgA2oiAyADKAIEQQFyNgIEQQBBADYCnNCAgABBAEEANgKQ0ICAAAsgBEEIaiEDDAoLAkBBACgClNCAgAAiACACTQ0AQQAoAqDQgIAAIgMgAmoiBCAAIAJrIgVBAXI2AgRBACAFNgKU0ICAAEEAIAQ2AqDQgIAAIAMgAkEDcjYCBCADQQhqIQMMCgsCQAJAQQAoAuDTgIAARQ0AQQAoAujTgIAAIQQMAQtBAEJ/NwLs04CAAEEAQoCAhICAgMAANwLk04CAAEEAIAFBDGpBcHFB2KrVqgVzNgLg04CAAEEAQQA2AvTTgIAAQQBBADYCxNOAgABBgIAEIQQLQQAhAwJAIAQgAkHHAGoiB2oiBkEAIARrIgtxIgggAksNAEEAQTA2AvjTgIAADAoLAkBBACgCwNOAgAAiA0UNAAJAQQAoArjTgIAAIgQgCGoiBSAETQ0AIAUgA00NAQtBACEDQQBBMDYC+NOAgAAMCgtBAC0AxNOAgABBBHENBAJAAkACQEEAKAKg0ICAACIERQ0AQcjTgIAAIQMDQAJAIAMoAgAiBSAESw0AIAUgAygCBGogBEsNAwsgAygCCCIDDQALC0EAEMuAgIAAIgBBf0YNBSAIIQYCQEEAKALk04CAACIDQX9qIgQgAHFFDQAgCCAAayAEIABqQQAgA2txaiEGCyAGIAJNDQUgBkH+////B0sNBQJAQQAoAsDTgIAAIgNFDQBBACgCuNOAgAAiBCAGaiIFIARNDQYgBSADSw0GCyAGEMuAgIAAIgMgAEcNAQwHCyAGIABrIAtxIgZB/v///wdLDQQgBhDLgICAACIAIAMoAgAgAygCBGpGDQMgACEDCwJAIANBf0YNACACQcgAaiAGTQ0AAkAgByAGa0EAKALo04CAACIEakEAIARrcSIEQf7///8HTQ0AIAMhAAwHCwJAIAQQy4CAgABBf0YNACAEIAZqIQYgAyEADAcLQQAgBmsQy4CAgAAaDAQLIAMhACADQX9HDQUMAwtBACEIDAcLQQAhAAwFCyAAQX9HDQILQQBBACgCxNOAgABBBHI2AsTTgIAACyAIQf7///8HSw0BIAgQy4CAgAAhAEEAEMuAgIAAIQMgAEF/Rg0BIANBf0YNASAAIANPDQEgAyAAayIGIAJBOGpNDQELQQBBACgCuNOAgAAgBmoiAzYCuNOAgAACQCADQQAoArzTgIAATQ0AQQAgAzYCvNOAgAALAkACQAJAAkBBACgCoNCAgAAiBEUNAEHI04CAACEDA0AgACADKAIAIgUgAygCBCIIakYNAiADKAIIIgMNAAwDCwsCQAJAQQAoApjQgIAAIgNFDQAgACADTw0BC0EAIAA2ApjQgIAAC0EAIQNBACAGNgLM04CAAEEAIAA2AsjTgIAAQQBBfzYCqNCAgABBAEEAKALg04CAADYCrNCAgABBAEEANgLU04CAAANAIANBxNCAgABqIANBuNCAgABqIgQ2AgAgBCADQbDQgIAAaiIFNgIAIANBvNCAgABqIAU2AgAgA0HM0ICAAGogA0HA0ICAAGoiBTYCACAFIAQ2AgAgA0HU0ICAAGogA0HI0ICAAGoiBDYCACAEIAU2AgAgA0HQ0ICAAGogBDYCACADQSBqIgNBgAJHDQALIABBeCAAa0EPcUEAIABBCGpBD3EbIgNqIgQgBkFIaiIFIANrIgNBAXI2AgRBAEEAKALw04CAADYCpNCAgABBACADNgKU0ICAAEEAIAQ2AqDQgIAAIAAgBWpBODYCBAwCCyADLQAMQQhxDQAgBCAFSQ0AIAQgAE8NACAEQXggBGtBD3FBACAEQQhqQQ9xGyIFaiIAQQAoApTQgIAAIAZqIgsgBWsiBUEBcjYCBCADIAggBmo2AgRBAEEAKALw04CAADYCpNCAgABBACAFNgKU0ICAAEEAIAA2AqDQgIAAIAQgC2pBODYCBAwBCwJAIABBACgCmNCAgAAiCE8NAEEAIAA2ApjQgIAAIAAhCAsgACAGaiEFQcjTgIAAIQMCQAJAAkACQAJAAkACQANAIAMoAgAgBUYNASADKAIIIgMNAAwCCwsgAy0ADEEIcUUNAQtByNOAgAAhAwNAAkAgAygCACIFIARLDQAgBSADKAIEaiIFIARLDQMLIAMoAgghAwwACwsgAyAANgIAIAMgAygCBCAGajYCBCAAQXggAGtBD3FBACAAQQhqQQ9xG2oiCyACQQNyNgIEIAVBeCAFa0EPcUEAIAVBCGpBD3EbaiIGIAsgAmoiAmshAwJAIAYgBEcNAEEAIAI2AqDQgIAAQQBBACgClNCAgAAgA2oiAzYClNCAgAAgAiADQQFyNgIEDAMLAkAgBkEAKAKc0ICAAEcNAEEAIAI2ApzQgIAAQQBBACgCkNCAgAAgA2oiAzYCkNCAgAAgAiADQQFyNgIEIAIgA2ogAzYCAAwDCwJAIAYoAgQiBEEDcUEBRw0AIARBeHEhBwJAAkAgBEH/AUsNACAGKAIIIgUgBEEDdiIIQQN0QbDQgIAAaiIARhoCQCAGKAIMIgQgBUcNAEEAQQAoAojQgIAAQX4gCHdxNgKI0ICAAAwCCyAEIABGGiAEIAU2AgggBSAENgIMDAELIAYoAhghCQJAAkAgBigCDCIAIAZGDQAgBigCCCIEIAhJGiAAIAQ2AgggBCAANgIMDAELAkAgBkEUaiIEKAIAIgUNACAGQRBqIgQoAgAiBQ0AQQAhAAwBCwNAIAQhCCAFIgBBFGoiBCgCACIFDQAgAEEQaiEEIAAoAhAiBQ0ACyAIQQA2AgALIAlFDQACQAJAIAYgBigCHCIFQQJ0QbjSgIAAaiIEKAIARw0AIAQgADYCACAADQFBAEEAKAKM0ICAAEF+IAV3cTYCjNCAgAAMAgsgCUEQQRQgCSgCECAGRhtqIAA2AgAgAEUNAQsgACAJNgIYAkAgBigCECIERQ0AIAAgBDYCECAEIAA2AhgLIAYoAhQiBEUNACAAQRRqIAQ2AgAgBCAANgIYCyAHIANqIQMgBiAHaiIGKAIEIQQLIAYgBEF+cTYCBCACIANqIAM2AgAgAiADQQFyNgIEAkAgA0H/AUsNACADQXhxQbDQgIAAaiEEAkACQEEAKAKI0ICAACIFQQEgA0EDdnQiA3ENAEEAIAUgA3I2AojQgIAAIAQhAwwBCyAEKAIIIQMLIAMgAjYCDCAEIAI2AgggAiAENgIMIAIgAzYCCAwDC0EfIQQCQCADQf///wdLDQAgA0EIdiIEIARBgP4/akEQdkEIcSIEdCIFIAVBgOAfakEQdkEEcSIFdCIAIABBgIAPakEQdkECcSIAdEEPdiAEIAVyIAByayIEQQF0IAMgBEEVanZBAXFyQRxqIQQLIAIgBDYCHCACQgA3AhAgBEECdEG40oCAAGohBQJAQQAoAozQgIAAIgBBASAEdCIIcQ0AIAUgAjYCAEEAIAAgCHI2AozQgIAAIAIgBTYCGCACIAI2AgggAiACNgIMDAMLIANBAEEZIARBAXZrIARBH0YbdCEEIAUoAgAhAANAIAAiBSgCBEF4cSADRg0CIARBHXYhACAEQQF0IQQgBSAAQQRxakEQaiIIKAIAIgANAAsgCCACNgIAIAIgBTYCGCACIAI2AgwgAiACNgIIDAILIABBeCAAa0EPcUEAIABBCGpBD3EbIgNqIgsgBkFIaiIIIANrIgNBAXI2AgQgACAIakE4NgIEIAQgBUE3IAVrQQ9xQQAgBUFJakEPcRtqQUFqIgggCCAEQRBqSRsiCEEjNgIEQQBBACgC8NOAgAA2AqTQgIAAQQAgAzYClNCAgABBACALNgKg0ICAACAIQRBqQQApAtDTgIAANwIAIAhBACkCyNOAgAA3AghBACAIQQhqNgLQ04CAAEEAIAY2AszTgIAAQQAgADYCyNOAgABBAEEANgLU04CAACAIQSRqIQMDQCADQQc2AgAgA0EEaiIDIAVJDQALIAggBEYNAyAIIAgoAgRBfnE2AgQgCCAIIARrIgA2AgAgBCAAQQFyNgIEAkAgAEH/AUsNACAAQXhxQbDQgIAAaiEDAkACQEEAKAKI0ICAACIFQQEgAEEDdnQiAHENAEEAIAUgAHI2AojQgIAAIAMhBQwBCyADKAIIIQULIAUgBDYCDCADIAQ2AgggBCADNgIMIAQgBTYCCAwEC0EfIQMCQCAAQf///wdLDQAgAEEIdiIDIANBgP4/akEQdkEIcSIDdCIFIAVBgOAfakEQdkEEcSIFdCIIIAhBgIAPakEQdkECcSIIdEEPdiADIAVyIAhyayIDQQF0IAAgA0EVanZBAXFyQRxqIQMLIAQgAzYCHCAEQgA3AhAgA0ECdEG40oCAAGohBQJAQQAoAozQgIAAIghBASADdCIGcQ0AIAUgBDYCAEEAIAggBnI2AozQgIAAIAQgBTYCGCAEIAQ2AgggBCAENgIMDAQLIABBAEEZIANBAXZrIANBH0YbdCEDIAUoAgAhCANAIAgiBSgCBEF4cSAARg0DIANBHXYhCCADQQF0IQMgBSAIQQRxakEQaiIGKAIAIggNAAsgBiAENgIAIAQgBTYCGCAEIAQ2AgwgBCAENgIIDAMLIAUoAggiAyACNgIMIAUgAjYCCCACQQA2AhggAiAFNgIMIAIgAzYCCAsgC0EIaiEDDAULIAUoAggiAyAENgIMIAUgBDYCCCAEQQA2AhggBCAFNgIMIAQgAzYCCAtBACgClNCAgAAiAyACTQ0AQQAoAqDQgIAAIgQgAmoiBSADIAJrIgNBAXI2AgRBACADNgKU0ICAAEEAIAU2AqDQgIAAIAQgAkEDcjYCBCAEQQhqIQMMAwtBACEDQQBBMDYC+NOAgAAMAgsCQCALRQ0AAkACQCAIIAgoAhwiBUECdEG40oCAAGoiAygCAEcNACADIAA2AgAgAA0BQQAgB0F+IAV3cSIHNgKM0ICAAAwCCyALQRBBFCALKAIQIAhGG2ogADYCACAARQ0BCyAAIAs2AhgCQCAIKAIQIgNFDQAgACADNgIQIAMgADYCGAsgCEEUaigCACIDRQ0AIABBFGogAzYCACADIAA2AhgLAkACQCAEQQ9LDQAgCCAEIAJqIgNBA3I2AgQgCCADaiIDIAMoAgRBAXI2AgQMAQsgCCACaiIAIARBAXI2AgQgCCACQQNyNgIEIAAgBGogBDYCAAJAIARB/wFLDQAgBEF4cUGw0ICAAGohAwJAAkBBACgCiNCAgAAiBUEBIARBA3Z0IgRxDQBBACAFIARyNgKI0ICAACADIQQMAQsgAygCCCEECyAEIAA2AgwgAyAANgIIIAAgAzYCDCAAIAQ2AggMAQtBHyEDAkAgBEH///8HSw0AIARBCHYiAyADQYD+P2pBEHZBCHEiA3QiBSAFQYDgH2pBEHZBBHEiBXQiAiACQYCAD2pBEHZBAnEiAnRBD3YgAyAFciACcmsiA0EBdCAEIANBFWp2QQFxckEcaiEDCyAAIAM2AhwgAEIANwIQIANBAnRBuNKAgABqIQUCQCAHQQEgA3QiAnENACAFIAA2AgBBACAHIAJyNgKM0ICAACAAIAU2AhggACAANgIIIAAgADYCDAwBCyAEQQBBGSADQQF2ayADQR9GG3QhAyAFKAIAIQICQANAIAIiBSgCBEF4cSAERg0BIANBHXYhAiADQQF0IQMgBSACQQRxakEQaiIGKAIAIgINAAsgBiAANgIAIAAgBTYCGCAAIAA2AgwgACAANgIIDAELIAUoAggiAyAANgIMIAUgADYCCCAAQQA2AhggACAFNgIMIAAgAzYCCAsgCEEIaiEDDAELAkAgCkUNAAJAAkAgACAAKAIcIgVBAnRBuNKAgABqIgMoAgBHDQAgAyAINgIAIAgNAUEAIAlBfiAFd3E2AozQgIAADAILIApBEEEUIAooAhAgAEYbaiAINgIAIAhFDQELIAggCjYCGAJAIAAoAhAiA0UNACAIIAM2AhAgAyAINgIYCyAAQRRqKAIAIgNFDQAgCEEUaiADNgIAIAMgCDYCGAsCQAJAIARBD0sNACAAIAQgAmoiA0EDcjYCBCAAIANqIgMgAygCBEEBcjYCBAwBCyAAIAJqIgUgBEEBcjYCBCAAIAJBA3I2AgQgBSAEaiAENgIAAkAgB0UNACAHQXhxQbDQgIAAaiECQQAoApzQgIAAIQMCQAJAQQEgB0EDdnQiCCAGcQ0AQQAgCCAGcjYCiNCAgAAgAiEIDAELIAIoAgghCAsgCCADNgIMIAIgAzYCCCADIAI2AgwgAyAINgIIC0EAIAU2ApzQgIAAQQAgBDYCkNCAgAALIABBCGohAwsgAUEQaiSAgICAACADCwoAIAAQyYCAgAAL4g0BB38CQCAARQ0AIABBeGoiASAAQXxqKAIAIgJBeHEiAGohAwJAIAJBAXENACACQQNxRQ0BIAEgASgCACICayIBQQAoApjQgIAAIgRJDQEgAiAAaiEAAkAgAUEAKAKc0ICAAEYNAAJAIAJB/wFLDQAgASgCCCIEIAJBA3YiBUEDdEGw0ICAAGoiBkYaAkAgASgCDCICIARHDQBBAEEAKAKI0ICAAEF+IAV3cTYCiNCAgAAMAwsgAiAGRhogAiAENgIIIAQgAjYCDAwCCyABKAIYIQcCQAJAIAEoAgwiBiABRg0AIAEoAggiAiAESRogBiACNgIIIAIgBjYCDAwBCwJAIAFBFGoiAigCACIEDQAgAUEQaiICKAIAIgQNAEEAIQYMAQsDQCACIQUgBCIGQRRqIgIoAgAiBA0AIAZBEGohAiAGKAIQIgQNAAsgBUEANgIACyAHRQ0BAkACQCABIAEoAhwiBEECdEG40oCAAGoiAigCAEcNACACIAY2AgAgBg0BQQBBACgCjNCAgABBfiAEd3E2AozQgIAADAMLIAdBEEEUIAcoAhAgAUYbaiAGNgIAIAZFDQILIAYgBzYCGAJAIAEoAhAiAkUNACAGIAI2AhAgAiAGNgIYCyABKAIUIgJFDQEgBkEUaiACNgIAIAIgBjYCGAwBCyADKAIEIgJBA3FBA0cNACADIAJBfnE2AgRBACAANgKQ0ICAACABIABqIAA2AgAgASAAQQFyNgIEDwsgASADTw0AIAMoAgQiAkEBcUUNAAJAAkAgAkECcQ0AAkAgA0EAKAKg0ICAAEcNAEEAIAE2AqDQgIAAQQBBACgClNCAgAAgAGoiADYClNCAgAAgASAAQQFyNgIEIAFBACgCnNCAgABHDQNBAEEANgKQ0ICAAEEAQQA2ApzQgIAADwsCQCADQQAoApzQgIAARw0AQQAgATYCnNCAgABBAEEAKAKQ0ICAACAAaiIANgKQ0ICAACABIABBAXI2AgQgASAAaiAANgIADwsgAkF4cSAAaiEAAkACQCACQf8BSw0AIAMoAggiBCACQQN2IgVBA3RBsNCAgABqIgZGGgJAIAMoAgwiAiAERw0AQQBBACgCiNCAgABBfiAFd3E2AojQgIAADAILIAIgBkYaIAIgBDYCCCAEIAI2AgwMAQsgAygCGCEHAkACQCADKAIMIgYgA0YNACADKAIIIgJBACgCmNCAgABJGiAGIAI2AgggAiAGNgIMDAELAkAgA0EUaiICKAIAIgQNACADQRBqIgIoAgAiBA0AQQAhBgwBCwNAIAIhBSAEIgZBFGoiAigCACIEDQAgBkEQaiECIAYoAhAiBA0ACyAFQQA2AgALIAdFDQACQAJAIAMgAygCHCIEQQJ0QbjSgIAAaiICKAIARw0AIAIgBjYCACAGDQFBAEEAKAKM0ICAAEF+IAR3cTYCjNCAgAAMAgsgB0EQQRQgBygCECADRhtqIAY2AgAgBkUNAQsgBiAHNgIYAkAgAygCECICRQ0AIAYgAjYCECACIAY2AhgLIAMoAhQiAkUNACAGQRRqIAI2AgAgAiAGNgIYCyABIABqIAA2AgAgASAAQQFyNgIEIAFBACgCnNCAgABHDQFBACAANgKQ0ICAAA8LIAMgAkF+cTYCBCABIABqIAA2AgAgASAAQQFyNgIECwJAIABB/wFLDQAgAEF4cUGw0ICAAGohAgJAAkBBACgCiNCAgAAiBEEBIABBA3Z0IgBxDQBBACAEIAByNgKI0ICAACACIQAMAQsgAigCCCEACyAAIAE2AgwgAiABNgIIIAEgAjYCDCABIAA2AggPC0EfIQICQCAAQf///wdLDQAgAEEIdiICIAJBgP4/akEQdkEIcSICdCIEIARBgOAfakEQdkEEcSIEdCIGIAZBgIAPakEQdkECcSIGdEEPdiACIARyIAZyayICQQF0IAAgAkEVanZBAXFyQRxqIQILIAEgAjYCHCABQgA3AhAgAkECdEG40oCAAGohBAJAAkBBACgCjNCAgAAiBkEBIAJ0IgNxDQAgBCABNgIAQQAgBiADcjYCjNCAgAAgASAENgIYIAEgATYCCCABIAE2AgwMAQsgAEEAQRkgAkEBdmsgAkEfRht0IQIgBCgCACEGAkADQCAGIgQoAgRBeHEgAEYNASACQR12IQYgAkEBdCECIAQgBkEEcWpBEGoiAygCACIGDQALIAMgATYCACABIAQ2AhggASABNgIMIAEgATYCCAwBCyAEKAIIIgAgATYCDCAEIAE2AgggAUEANgIYIAEgBDYCDCABIAA2AggLQQBBACgCqNCAgABBf2oiAUF/IAEbNgKo0ICAAAsLBAAAAAtOAAJAIAANAD8AQRB0DwsCQCAAQf//A3ENACAAQX9MDQACQCAAQRB2QAAiAEF/Rw0AQQBBMDYC+NOAgABBfw8LIABBEHQPCxDKgICAAAAL8gICA38BfgJAIAJFDQAgACABOgAAIAIgAGoiA0F/aiABOgAAIAJBA0kNACAAIAE6AAIgACABOgABIANBfWogAToAACADQX5qIAE6AAAgAkEHSQ0AIAAgAToAAyADQXxqIAE6AAAgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIFayICQSBJDQAgAa1CgYCAgBB+IQYgAyAFaiEBA0AgASAGNwMYIAEgBjcDECABIAY3AwggASAGNwMAIAFBIGohASACQWBqIgJBH0sNAAsLIAALC45IAQBBgAgLhkgBAAAAAgAAAAMAAAAAAAAAAAAAAAQAAAAFAAAAAAAAAAAAAAAGAAAABwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEludmFsaWQgY2hhciBpbiB1cmwgcXVlcnkAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9ib2R5AENvbnRlbnQtTGVuZ3RoIG92ZXJmbG93AENodW5rIHNpemUgb3ZlcmZsb3cAUmVzcG9uc2Ugb3ZlcmZsb3cASW52YWxpZCBtZXRob2QgZm9yIEhUVFAveC54IHJlcXVlc3QASW52YWxpZCBtZXRob2QgZm9yIFJUU1AveC54IHJlcXVlc3QARXhwZWN0ZWQgU09VUkNFIG1ldGhvZCBmb3IgSUNFL3gueCByZXF1ZXN0AEludmFsaWQgY2hhciBpbiB1cmwgZnJhZ21lbnQgc3RhcnQARXhwZWN0ZWQgZG90AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fc3RhdHVzAEludmFsaWQgcmVzcG9uc2Ugc3RhdHVzAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMAVXNlciBjYWxsYmFjayBlcnJvcgBgb25fcmVzZXRgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19oZWFkZXJgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8=' + // 2. Return the IDL boolean value that is the one that represents + // the same truth value as the ECMAScript Boolean value x. + return x +} +// https://webidl.spec.whatwg.org/#es-any +webidl.converters.any = function (V) { + return V +} -/***/ }), +// https://webidl.spec.whatwg.org/#es-long-long +webidl.converters['long long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 64, "signed"). + const x = webidl.util.ConvertToInt(V, 64, 'signed') -/***/ 5627: -/***/ ((module) => { + // 2. Return the IDL long long value that represents + // the same numeric value as x. + return x +} -module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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IAH9CwMAIABBMGogAf0LAwAgAEEgaiAB/QsDACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC+TzAQMOfwN+BH8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIhBBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4BS80BTMwBTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAOxwEAAQID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YWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsb3NlZWVwLWFsaXZlAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgAAAAAAAAAAAAAAAAAAAHJhbnNmZXItZW5jb2RpbmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==' +// https://webidl.spec.whatwg.org/#es-unsigned-long-long +webidl.converters['unsigned long long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 64, "unsigned"). + const x = webidl.util.ConvertToInt(V, 64, 'unsigned') + + // 2. Return the IDL unsigned long long value that + // represents the same numeric value as x. + return x +} + +// https://webidl.spec.whatwg.org/#es-unsigned-long +webidl.converters['unsigned long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 32, "unsigned"). + const x = webidl.util.ConvertToInt(V, 32, 'unsigned') + + // 2. Return the IDL unsigned long value that + // represents the same numeric value as x. + return x +} + +// https://webidl.spec.whatwg.org/#es-unsigned-short +webidl.converters['unsigned short'] = function (V, opts) { + // 1. Let x be ? ConvertToInt(V, 16, "unsigned"). + const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts) + + // 2. Return the IDL unsigned short value that represents + // the same numeric value as x. + return x +} +// https://webidl.spec.whatwg.org/#idl-ArrayBuffer +webidl.converters.ArrayBuffer = function (V, opts = {}) { + // 1. If Type(V) is not Object, or V does not have an + // [[ArrayBufferData]] internal slot, then throw a + // TypeError. + // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances + // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances + if ( + webidl.util.Type(V) !== 'Object' || + !types.isAnyArrayBuffer(V) + ) { + throw webidl.errors.conversionFailed({ + prefix: `${V}`, + argument: `${V}`, + types: ['ArrayBuffer'] + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V) is true, then throw a + // TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V) is true, then throw a + // TypeError. + // Note: resizable ArrayBuffers are currently a proposal. + + // 4. Return the IDL ArrayBuffer value that is a + // reference to the same object as V. + return V +} + +webidl.converters.TypedArray = function (V, T, opts = {}) { + // 1. Let T be the IDL type V is being converted to. + + // 2. If Type(V) is not Object, or V does not have a + // [[TypedArrayName]] internal slot with a value + // equal to T’s name, then throw a TypeError. + if ( + webidl.util.Type(V) !== 'Object' || + !types.isTypedArray(V) || + V.constructor.name !== T.name + ) { + throw webidl.errors.conversionFailed({ + prefix: `${T.name}`, + argument: `${V}`, + types: [T.name] + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 4. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + // Note: resizable array buffers are currently a proposal + + // 5. Return the IDL value of type T that is a reference + // to the same object as V. + return V +} + +webidl.converters.DataView = function (V, opts = {}) { + // 1. If Type(V) is not Object, or V does not have a + // [[DataView]] internal slot, then throw a TypeError. + if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) { + throw webidl.errors.exception({ + header: 'DataView', + message: 'Object is not a DataView.' + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, + // then throw a TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.' + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + // Note: resizable ArrayBuffers are currently a proposal + + // 4. Return the IDL DataView value that is a reference + // to the same object as V. + return V +} + +// https://webidl.spec.whatwg.org/#BufferSource +webidl.converters.BufferSource = function (V, opts = {}) { + if (types.isAnyArrayBuffer(V)) { + return webidl.converters.ArrayBuffer(V, opts) + } + + if (types.isTypedArray(V)) { + return webidl.converters.TypedArray(V, V.constructor) + } + + if (types.isDataView(V)) { + return webidl.converters.DataView(V, opts) + } + + throw new TypeError(`Could not convert ${V} to a BufferSource.`) +} -/***/ }), +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.ByteString +) -/***/ 1891: -/***/ ((__unused_webpack_module, exports) => { +webidl.converters['sequence>'] = webidl.sequenceConverter( + webidl.converters['sequence'] +) -"use strict"; +webidl.converters['record'] = webidl.recordConverter( + webidl.converters.ByteString, + webidl.converters.ByteString +) -Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.enumToMap = void 0; -function enumToMap(obj) { - const res = {}; - Object.keys(obj).forEach((key) => { - const value = obj[key]; - if (typeof value === 'number') { - res[key] = value; - } - }); - return res; +module.exports = { + webidl } -exports.enumToMap = enumToMap; -//# sourceMappingURL=utils.js.map + /***/ }), -/***/ 6771: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +/***/ 4854: +/***/ ((module) => { "use strict"; -const { kClients } = __nccwpck_require__(2785) -const Agent = __nccwpck_require__(7890) -const { - kAgent, - kMockAgentSet, - kMockAgentGet, - kDispatches, - kIsMockActive, - kNetConnect, - kGetNetConnect, - kOptions, - kFactory -} = __nccwpck_require__(4347) -const MockClient = __nccwpck_require__(8687) -const MockPool = __nccwpck_require__(6193) -const { matchValue, buildMockOptions } = __nccwpck_require__(9323) -const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8045) -const Dispatcher = __nccwpck_require__(412) -const Pluralizer = __nccwpck_require__(8891) -const PendingInterceptorsFormatter = __nccwpck_require__(6823) - -class FakeWeakRef { - constructor (value) { - this.value = value +/** + * @see https://encoding.spec.whatwg.org/#concept-encoding-get + * @param {string|undefined} label + */ +function getEncoding (label) { + if (!label) { + return 'failure' } - deref () { - return this.value + // 1. Remove any leading and trailing ASCII whitespace from label. + // 2. If label is an ASCII case-insensitive match for any of the + // labels listed in the table below, then return the + // corresponding encoding; otherwise return failure. + switch (label.trim().toLowerCase()) { + case 'unicode-1-1-utf-8': + case 'unicode11utf8': + case 'unicode20utf8': + case 'utf-8': + case 'utf8': + case 'x-unicode20utf8': + return 'UTF-8' + case '866': + case 'cp866': + case 'csibm866': + case 'ibm866': + return 'IBM866' + case 'csisolatin2': + case 'iso-8859-2': + case 'iso-ir-101': + case 'iso8859-2': + case 'iso88592': + case 'iso_8859-2': + case 'iso_8859-2:1987': + case 'l2': + case 'latin2': + return 'ISO-8859-2' + case 'csisolatin3': + case 'iso-8859-3': + case 'iso-ir-109': + case 'iso8859-3': + case 'iso88593': + case 'iso_8859-3': + case 'iso_8859-3:1988': + case 'l3': + case 'latin3': + return 'ISO-8859-3' + case 'csisolatin4': + case 'iso-8859-4': + case 'iso-ir-110': + case 'iso8859-4': + case 'iso88594': + case 'iso_8859-4': + case 'iso_8859-4:1988': + case 'l4': + case 'latin4': + return 'ISO-8859-4' + case 'csisolatincyrillic': + case 'cyrillic': + case 'iso-8859-5': + case 'iso-ir-144': + case 'iso8859-5': + case 'iso88595': + case 'iso_8859-5': + case 'iso_8859-5:1988': + return 'ISO-8859-5' + case 'arabic': + case 'asmo-708': + case 'csiso88596e': + case 'csiso88596i': + case 'csisolatinarabic': + case 'ecma-114': + case 'iso-8859-6': + case 'iso-8859-6-e': + case 'iso-8859-6-i': + case 'iso-ir-127': + case 'iso8859-6': + case 'iso88596': + case 'iso_8859-6': + case 'iso_8859-6:1987': + return 'ISO-8859-6' + case 'csisolatingreek': + case 'ecma-118': + case 'elot_928': + case 'greek': + case 'greek8': + case 'iso-8859-7': + case 'iso-ir-126': + case 'iso8859-7': + case 'iso88597': + case 'iso_8859-7': + case 'iso_8859-7:1987': + case 'sun_eu_greek': + return 'ISO-8859-7' + case 'csiso88598e': + case 'csisolatinhebrew': + case 'hebrew': + case 'iso-8859-8': + case 'iso-8859-8-e': + case 'iso-ir-138': + case 'iso8859-8': + case 'iso88598': + case 'iso_8859-8': + case 'iso_8859-8:1988': + case 'visual': + return 'ISO-8859-8' + case 'csiso88598i': + case 'iso-8859-8-i': + case 'logical': + return 'ISO-8859-8-I' + case 'csisolatin6': + case 'iso-8859-10': + case 'iso-ir-157': + case 'iso8859-10': + case 'iso885910': + case 'l6': + case 'latin6': + return 'ISO-8859-10' + case 'iso-8859-13': + case 'iso8859-13': + case 'iso885913': + return 'ISO-8859-13' + case 'iso-8859-14': + case 'iso8859-14': + case 'iso885914': + return 'ISO-8859-14' + case 'csisolatin9': + case 'iso-8859-15': + case 'iso8859-15': + case 'iso885915': + case 'iso_8859-15': + case 'l9': + return 'ISO-8859-15' + case 'iso-8859-16': + return 'ISO-8859-16' + case 'cskoi8r': + case 'koi': + case 'koi8': + case 'koi8-r': + case 'koi8_r': + return 'KOI8-R' + case 'koi8-ru': + case 'koi8-u': + return 'KOI8-U' + case 'csmacintosh': + case 'mac': + case 'macintosh': + case 'x-mac-roman': + return 'macintosh' + case 'iso-8859-11': + case 'iso8859-11': + case 'iso885911': + case 'tis-620': + case 'windows-874': + return 'windows-874' + case 'cp1250': + case 'windows-1250': + case 'x-cp1250': + return 'windows-1250' + case 'cp1251': + case 'windows-1251': + case 'x-cp1251': + return 'windows-1251' + case 'ansi_x3.4-1968': + case 'ascii': + case 'cp1252': + case 'cp819': + case 'csisolatin1': + case 'ibm819': + case 'iso-8859-1': + case 'iso-ir-100': + case 'iso8859-1': + case 'iso88591': + case 'iso_8859-1': + case 'iso_8859-1:1987': + case 'l1': + case 'latin1': + case 'us-ascii': + case 'windows-1252': + case 'x-cp1252': + return 'windows-1252' + case 'cp1253': + case 'windows-1253': + case 'x-cp1253': + return 'windows-1253' + case 'cp1254': + case 'csisolatin5': + case 'iso-8859-9': + case 'iso-ir-148': + case 'iso8859-9': + case 'iso88599': + case 'iso_8859-9': + case 'iso_8859-9:1989': + case 'l5': + case 'latin5': + case 'windows-1254': + case 'x-cp1254': + return 'windows-1254' + case 'cp1255': + case 'windows-1255': + case 'x-cp1255': + return 'windows-1255' + case 'cp1256': + case 'windows-1256': + case 'x-cp1256': + return 'windows-1256' + case 'cp1257': + case 'windows-1257': + case 'x-cp1257': + return 'windows-1257' + case 'cp1258': + case 'windows-1258': + case 'x-cp1258': + return 'windows-1258' + case 'x-mac-cyrillic': + case 'x-mac-ukrainian': + return 'x-mac-cyrillic' + case 'chinese': + case 'csgb2312': + case 'csiso58gb231280': + case 'gb2312': + case 'gb_2312': + case 'gb_2312-80': + case 'gbk': + case 'iso-ir-58': + case 'x-gbk': + return 'GBK' + case 'gb18030': + return 'gb18030' + case 'big5': + case 'big5-hkscs': + case 'cn-big5': + case 'csbig5': + case 'x-x-big5': + return 'Big5' + case 'cseucpkdfmtjapanese': + case 'euc-jp': + case 'x-euc-jp': + return 'EUC-JP' + case 'csiso2022jp': + case 'iso-2022-jp': + return 'ISO-2022-JP' + case 'csshiftjis': + case 'ms932': + case 'ms_kanji': + case 'shift-jis': + case 'shift_jis': + case 'sjis': + case 'windows-31j': + case 'x-sjis': + return 'Shift_JIS' + case 'cseuckr': + case 'csksc56011987': + case 'euc-kr': + case 'iso-ir-149': + case 'korean': + case 'ks_c_5601-1987': + case 'ks_c_5601-1989': + case 'ksc5601': + case 'ksc_5601': + case 'windows-949': + return 'EUC-KR' + case 'csiso2022kr': + case 'hz-gb-2312': + case 'iso-2022-cn': + case 'iso-2022-cn-ext': + case 'iso-2022-kr': + case 'replacement': + return 'replacement' + case 'unicodefffe': + case 'utf-16be': + return 'UTF-16BE' + case 'csunicode': + case 'iso-10646-ucs-2': + case 'ucs-2': + case 'unicode': + case 'unicodefeff': + case 'utf-16': + case 'utf-16le': + return 'UTF-16LE' + case 'x-user-defined': + return 'x-user-defined' + default: return 'failure' } } -class MockAgent extends Dispatcher { - constructor (opts) { - super(opts) - - this[kNetConnect] = true - this[kIsMockActive] = true - - // Instantiate Agent and encapsulate - if ((opts && opts.agent && typeof opts.agent.dispatch !== 'function')) { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } - const agent = opts && opts.agent ? opts.agent : new Agent(opts) - this[kAgent] = agent - - this[kClients] = agent[kClients] - this[kOptions] = buildMockOptions(opts) - } - - get (origin) { - let dispatcher = this[kMockAgentGet](origin) - - if (!dispatcher) { - dispatcher = this[kFactory](origin) - this[kMockAgentSet](origin, dispatcher) - } - return dispatcher - } - - dispatch (opts, handler) { - // Call MockAgent.get to perform additional setup before dispatching as normal - this.get(opts.origin) - return this[kAgent].dispatch(opts, handler) - } - - async close () { - await this[kAgent].close() - this[kClients].clear() - } - - deactivate () { - this[kIsMockActive] = false - } - - activate () { - this[kIsMockActive] = true - } - - enableNetConnect (matcher) { - if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { - if (Array.isArray(this[kNetConnect])) { - this[kNetConnect].push(matcher) - } else { - this[kNetConnect] = [matcher] - } - } else if (typeof matcher === 'undefined') { - this[kNetConnect] = true - } else { - throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') - } - } - - disableNetConnect () { - this[kNetConnect] = false - } - - // This is required to bypass issues caused by using global symbols - see: - // https://github.com/nodejs/undici/issues/1447 - get isMockActive () { - return this[kIsMockActive] - } - - [kMockAgentSet] (origin, dispatcher) { - this[kClients].set(origin, new FakeWeakRef(dispatcher)) - } - - [kFactory] (origin) { - const mockOptions = Object.assign({ agent: this }, this[kOptions]) - return this[kOptions] && this[kOptions].connections === 1 - ? new MockClient(origin, mockOptions) - : new MockPool(origin, mockOptions) - } - - [kMockAgentGet] (origin) { - // First check if we can immediately find it - const ref = this[kClients].get(origin) - if (ref) { - return ref.deref() - } - - // If the origin is not a string create a dummy parent pool and return to user - if (typeof origin !== 'string') { - const dispatcher = this[kFactory]('http://localhost:9999') - this[kMockAgentSet](origin, dispatcher) - return dispatcher - } - - // If we match, create a pool and assign the same dispatches - for (const [keyMatcher, nonExplicitRef] of Array.from(this[kClients])) { - const nonExplicitDispatcher = nonExplicitRef.deref() - if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { - const dispatcher = this[kFactory](origin) - this[kMockAgentSet](origin, dispatcher) - dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches] - return dispatcher - } - } - } - - [kGetNetConnect] () { - return this[kNetConnect] - } - - pendingInterceptors () { - const mockAgentClients = this[kClients] - - return Array.from(mockAgentClients.entries()) - .flatMap(([origin, scope]) => scope.deref()[kDispatches].map(dispatch => ({ ...dispatch, origin }))) - .filter(({ pending }) => pending) - } - - assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { - const pending = this.pendingInterceptors() - - if (pending.length === 0) { - return - } - - const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length) - - throw new UndiciError(` -${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: - -${pendingInterceptorsFormatter.format(pending)} -`.trim()) - } +module.exports = { + getEncoding } -module.exports = MockAgent - /***/ }), -/***/ 8687: +/***/ 1446: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { promisify } = __nccwpck_require__(3837) -const Client = __nccwpck_require__(3598) -const { buildMockDispatch } = __nccwpck_require__(9323) const { - kDispatches, - kMockAgent, - kClose, - kOriginalClose, - kOrigin, - kOriginalDispatch, - kConnected -} = __nccwpck_require__(4347) -const { MockInterceptor } = __nccwpck_require__(410) -const Symbols = __nccwpck_require__(2785) -const { InvalidArgumentError } = __nccwpck_require__(8045) - -/** - * MockClient provides an API that extends the Client to influence the mockDispatches. - */ -class MockClient extends Client { - constructor (origin, opts) { - super(origin, opts) + staticPropertyDescriptors, + readOperation, + fireAProgressEvent +} = __nccwpck_require__(7530) +const { + kState, + kError, + kResult, + kEvents, + kAborted +} = __nccwpck_require__(9054) +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) - if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') +class FileReader extends EventTarget { + constructor () { + super() + + this[kState] = 'empty' + this[kResult] = null + this[kError] = null + this[kEvents] = { + loadend: null, + error: null, + abort: null, + load: null, + progress: null, + loadstart: null } + } - this[kMockAgent] = opts.agent - this[kOrigin] = origin - this[kDispatches] = [] - this[kConnected] = 1 - this[kOriginalDispatch] = this.dispatch - this[kOriginalClose] = this.close.bind(this) + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer + * @param {import('buffer').Blob} blob + */ + readAsArrayBuffer (blob) { + webidl.brandCheck(this, FileReader) - this.dispatch = buildMockDispatch.call(this) - this.close = this[kClose] - } + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsArrayBuffer' }) - get [Symbols.kConnected] () { - return this[kConnected] + blob = webidl.converters.Blob(blob, { strict: false }) + + // The readAsArrayBuffer(blob) method, when invoked, + // must initiate a read operation for blob with ArrayBuffer. + readOperation(this, blob, 'ArrayBuffer') } /** - * Sets up the base interceptor for mocking replies from undici. + * @see https://w3c.github.io/FileAPI/#readAsBinaryString + * @param {import('buffer').Blob} blob */ - intercept (opts) { - return new MockInterceptor(opts, this[kDispatches]) - } - - async [kClose] () { - await promisify(this[kOriginalClose])() - this[kConnected] = 0 - this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) - } -} + readAsBinaryString (blob) { + webidl.brandCheck(this, FileReader) -module.exports = MockClient + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsBinaryString' }) + blob = webidl.converters.Blob(blob, { strict: false }) -/***/ }), + // The readAsBinaryString(blob) method, when invoked, + // must initiate a read operation for blob with BinaryString. + readOperation(this, blob, 'BinaryString') + } -/***/ 888: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + /** + * @see https://w3c.github.io/FileAPI/#readAsDataText + * @param {import('buffer').Blob} blob + * @param {string?} encoding + */ + readAsText (blob, encoding = undefined) { + webidl.brandCheck(this, FileReader) -"use strict"; + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsText' }) + blob = webidl.converters.Blob(blob, { strict: false }) -const { UndiciError } = __nccwpck_require__(8045) + if (encoding !== undefined) { + encoding = webidl.converters.DOMString(encoding) + } -class MockNotMatchedError extends UndiciError { - constructor (message) { - super(message) - Error.captureStackTrace(this, MockNotMatchedError) - this.name = 'MockNotMatchedError' - this.message = message || 'The request does not match any registered mock dispatches' - this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED' + // The readAsText(blob, encoding) method, when invoked, + // must initiate a read operation for blob with Text and encoding. + readOperation(this, blob, 'Text', encoding) } -} -module.exports = { - MockNotMatchedError -} + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL + * @param {import('buffer').Blob} blob + */ + readAsDataURL (blob) { + webidl.brandCheck(this, FileReader) + webidl.argumentLengthCheck(arguments, 1, { header: 'FileReader.readAsDataURL' }) -/***/ }), + blob = webidl.converters.Blob(blob, { strict: false }) -/***/ 410: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // The readAsDataURL(blob) method, when invoked, must + // initiate a read operation for blob with DataURL. + readOperation(this, blob, 'DataURL') + } -"use strict"; + /** + * @see https://w3c.github.io/FileAPI/#dfn-abort + */ + abort () { + // 1. If this's state is "empty" or if this's state is + // "done" set this's result to null and terminate + // this algorithm. + if (this[kState] === 'empty' || this[kState] === 'done') { + this[kResult] = null + return + } + + // 2. If this's state is "loading" set this's state to + // "done" and set this's result to null. + if (this[kState] === 'loading') { + this[kState] = 'done' + this[kResult] = null + } + // 3. If there are any tasks from this on the file reading + // task source in an affiliated task queue, then remove + // those tasks from that task queue. + this[kAborted] = true -const { getResponseData, buildKey, addMockDispatch } = __nccwpck_require__(9323) -const { - kDispatches, - kDispatchKey, - kDefaultHeaders, - kDefaultTrailers, - kContentLength, - kMockDispatch -} = __nccwpck_require__(4347) -const { InvalidArgumentError } = __nccwpck_require__(8045) -const { buildURL } = __nccwpck_require__(3983) + // 4. Terminate the algorithm for the read method being processed. + // TODO -/** - * Defines the scope API for an interceptor reply - */ -class MockScope { - constructor (mockDispatch) { - this[kMockDispatch] = mockDispatch + // 5. Fire a progress event called abort at this. + fireAProgressEvent('abort', this) + + // 6. If this's state is not "loading", fire a progress + // event called loadend at this. + if (this[kState] !== 'loading') { + fireAProgressEvent('loadend', this) + } } /** - * Delay a reply by a set amount in ms. + * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate */ - delay (waitInMs) { - if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { - throw new InvalidArgumentError('waitInMs must be a valid integer > 0') - } + get readyState () { + webidl.brandCheck(this, FileReader) - this[kMockDispatch].delay = waitInMs - return this + switch (this[kState]) { + case 'empty': return this.EMPTY + case 'loading': return this.LOADING + case 'done': return this.DONE + } } /** - * For a defined reply, never mark as consumed. + * @see https://w3c.github.io/FileAPI/#dom-filereader-result */ - persist () { - this[kMockDispatch].persist = true - return this + get result () { + webidl.brandCheck(this, FileReader) + + // The result attribute’s getter, when invoked, must return + // this's result. + return this[kResult] } /** - * Allow one to define a reply for a set amount of matching requests. + * @see https://w3c.github.io/FileAPI/#dom-filereader-error */ - times (repeatTimes) { - if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { - throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') - } + get error () { + webidl.brandCheck(this, FileReader) - this[kMockDispatch].times = repeatTimes - return this + // The error attribute’s getter, when invoked, must return + // this's error. + return this[kError] } -} -/** - * Defines an interceptor for a Mock - */ -class MockInterceptor { - constructor (opts, mockDispatches) { - if (typeof opts !== 'object') { - throw new InvalidArgumentError('opts must be an object') - } - if (typeof opts.path === 'undefined') { - throw new InvalidArgumentError('opts.path must be defined') - } - if (typeof opts.method === 'undefined') { - opts.method = 'GET' + get onloadend () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].loadend + } + + set onloadend (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].loadend) { + this.removeEventListener('loadend', this[kEvents].loadend) } - // See https://github.com/nodejs/undici/issues/1245 - // As per RFC 3986, clients are not supposed to send URI - // fragments to servers when they retrieve a document, - if (typeof opts.path === 'string') { - if (opts.query) { - opts.path = buildURL(opts.path, opts.query) - } else { - // Matches https://github.com/nodejs/undici/blob/main/lib/fetch/index.js#L1811 - const parsedURL = new URL(opts.path, 'data://') - opts.path = parsedURL.pathname + parsedURL.search - } + + if (typeof fn === 'function') { + this[kEvents].loadend = fn + this.addEventListener('loadend', fn) + } else { + this[kEvents].loadend = null } - if (typeof opts.method === 'string') { - opts.method = opts.method.toUpperCase() + } + + get onerror () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].error + } + + set onerror (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].error) { + this.removeEventListener('error', this[kEvents].error) } - this[kDispatchKey] = buildKey(opts) - this[kDispatches] = mockDispatches - this[kDefaultHeaders] = {} - this[kDefaultTrailers] = {} - this[kContentLength] = false + if (typeof fn === 'function') { + this[kEvents].error = fn + this.addEventListener('error', fn) + } else { + this[kEvents].error = null + } } - createMockScopeDispatchData (statusCode, data, responseOptions = {}) { - const responseData = getResponseData(data) - const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {} - const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers } - const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers } + get onloadstart () { + webidl.brandCheck(this, FileReader) - return { statusCode, data, headers, trailers } + return this[kEvents].loadstart } - validateReplyParameters (statusCode, data, responseOptions) { - if (typeof statusCode === 'undefined') { - throw new InvalidArgumentError('statusCode must be defined') - } - if (typeof data === 'undefined') { - throw new InvalidArgumentError('data must be defined') + set onloadstart (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].loadstart) { + this.removeEventListener('loadstart', this[kEvents].loadstart) } - if (typeof responseOptions !== 'object') { - throw new InvalidArgumentError('responseOptions must be an object') + + if (typeof fn === 'function') { + this[kEvents].loadstart = fn + this.addEventListener('loadstart', fn) + } else { + this[kEvents].loadstart = null } } - /** - * Mock an undici request with a defined reply. - */ - reply (replyData) { - // Values of reply aren't available right now as they - // can only be available when the reply callback is invoked. - if (typeof replyData === 'function') { - // We'll first wrap the provided callback in another function, - // this function will properly resolve the data from the callback - // when invoked. - const wrappedDefaultsCallback = (opts) => { - // Our reply options callback contains the parameter for statusCode, data and options. - const resolvedData = replyData(opts) + get onprogress () { + webidl.brandCheck(this, FileReader) - // Check if it is in the right format - if (typeof resolvedData !== 'object') { - throw new InvalidArgumentError('reply options callback must return an object') - } + return this[kEvents].progress + } - const { statusCode, data = '', responseOptions = {} } = resolvedData - this.validateReplyParameters(statusCode, data, responseOptions) - // Since the values can be obtained immediately we return them - // from this higher order function that will be resolved later. - return { - ...this.createMockScopeDispatchData(statusCode, data, responseOptions) - } - } + set onprogress (fn) { + webidl.brandCheck(this, FileReader) - // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback) - return new MockScope(newMockDispatch) + if (this[kEvents].progress) { + this.removeEventListener('progress', this[kEvents].progress) } - // We can have either one or three parameters, if we get here, - // we should have 1-3 parameters. So we spread the arguments of - // this function to obtain the parameters, since replyData will always - // just be the statusCode. - const [statusCode, data = '', responseOptions = {}] = [...arguments] - this.validateReplyParameters(statusCode, data, responseOptions) + if (typeof fn === 'function') { + this[kEvents].progress = fn + this.addEventListener('progress', fn) + } else { + this[kEvents].progress = null + } + } - // Send in-already provided data like usual - const dispatchData = this.createMockScopeDispatchData(statusCode, data, responseOptions) - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData) - return new MockScope(newMockDispatch) + get onload () { + webidl.brandCheck(this, FileReader) + + return this[kEvents].load } - /** - * Mock an undici request with a defined error. - */ - replyWithError (error) { - if (typeof error === 'undefined') { - throw new InvalidArgumentError('error must be defined') + set onload (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].load) { + this.removeEventListener('load', this[kEvents].load) } - const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }) - return new MockScope(newMockDispatch) + if (typeof fn === 'function') { + this[kEvents].load = fn + this.addEventListener('load', fn) + } else { + this[kEvents].load = null + } } - /** - * Set default reply headers on the interceptor for subsequent replies - */ - defaultReplyHeaders (headers) { - if (typeof headers === 'undefined') { - throw new InvalidArgumentError('headers must be defined') - } + get onabort () { + webidl.brandCheck(this, FileReader) - this[kDefaultHeaders] = headers - return this + return this[kEvents].abort } - /** - * Set default reply trailers on the interceptor for subsequent replies - */ - defaultReplyTrailers (trailers) { - if (typeof trailers === 'undefined') { - throw new InvalidArgumentError('trailers must be defined') + set onabort (fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].abort) { + this.removeEventListener('abort', this[kEvents].abort) } - this[kDefaultTrailers] = trailers - return this + if (typeof fn === 'function') { + this[kEvents].abort = fn + this.addEventListener('abort', fn) + } else { + this[kEvents].abort = null + } } +} - /** - * Set reply content length header for replies on the interceptor - */ - replyContentLength () { - this[kContentLength] = true - return this +// https://w3c.github.io/FileAPI/#dom-filereader-empty +FileReader.EMPTY = FileReader.prototype.EMPTY = 0 +// https://w3c.github.io/FileAPI/#dom-filereader-loading +FileReader.LOADING = FileReader.prototype.LOADING = 1 +// https://w3c.github.io/FileAPI/#dom-filereader-done +FileReader.DONE = FileReader.prototype.DONE = 2 + +Object.defineProperties(FileReader.prototype, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors, + readAsArrayBuffer: kEnumerableProperty, + readAsBinaryString: kEnumerableProperty, + readAsText: kEnumerableProperty, + readAsDataURL: kEnumerableProperty, + abort: kEnumerableProperty, + readyState: kEnumerableProperty, + result: kEnumerableProperty, + error: kEnumerableProperty, + onloadstart: kEnumerableProperty, + onprogress: kEnumerableProperty, + onload: kEnumerableProperty, + onabort: kEnumerableProperty, + onerror: kEnumerableProperty, + onloadend: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'FileReader', + writable: false, + enumerable: false, + configurable: true } -} +}) -module.exports.MockInterceptor = MockInterceptor -module.exports.MockScope = MockScope +Object.defineProperties(FileReader, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors +}) + +module.exports = { + FileReader +} /***/ }), -/***/ 6193: +/***/ 5504: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { promisify } = __nccwpck_require__(3837) -const Pool = __nccwpck_require__(4634) -const { buildMockDispatch } = __nccwpck_require__(9323) -const { - kDispatches, - kMockAgent, - kClose, - kOriginalClose, - kOrigin, - kOriginalDispatch, - kConnected -} = __nccwpck_require__(4347) -const { MockInterceptor } = __nccwpck_require__(410) -const Symbols = __nccwpck_require__(2785) -const { InvalidArgumentError } = __nccwpck_require__(8045) +const { webidl } = __nccwpck_require__(1744) + +const kState = Symbol('ProgressEvent state') /** - * MockPool provides an API that extends the Pool to influence the mockDispatches. + * @see https://xhr.spec.whatwg.org/#progressevent */ -class MockPool extends Pool { - constructor (origin, opts) { - super(origin, opts) - - if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { - throw new InvalidArgumentError('Argument opts.agent must implement Agent') - } +class ProgressEvent extends Event { + constructor (type, eventInitDict = {}) { + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.ProgressEventInit(eventInitDict ?? {}) - this[kMockAgent] = opts.agent - this[kOrigin] = origin - this[kDispatches] = [] - this[kConnected] = 1 - this[kOriginalDispatch] = this.dispatch - this[kOriginalClose] = this.close.bind(this) + super(type, eventInitDict) - this.dispatch = buildMockDispatch.call(this) - this.close = this[kClose] + this[kState] = { + lengthComputable: eventInitDict.lengthComputable, + loaded: eventInitDict.loaded, + total: eventInitDict.total + } } - get [Symbols.kConnected] () { - return this[kConnected] + get lengthComputable () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].lengthComputable } - /** - * Sets up the base interceptor for mocking replies from undici. - */ - intercept (opts) { - return new MockInterceptor(opts, this[kDispatches]) + get loaded () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].loaded } - async [kClose] () { - await promisify(this[kOriginalClose])() - this[kConnected] = 0 - this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + get total () { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].total } } -module.exports = MockPool +webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ + { + key: 'lengthComputable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'loaded', + converter: webidl.converters['unsigned long long'], + defaultValue: 0 + }, + { + key: 'total', + converter: webidl.converters['unsigned long long'], + defaultValue: 0 + }, + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: false + } +]) + +module.exports = { + ProgressEvent +} /***/ }), -/***/ 4347: +/***/ 9054: /***/ ((module) => { "use strict"; module.exports = { - kAgent: Symbol('agent'), - kOptions: Symbol('options'), - kFactory: Symbol('factory'), - kDispatches: Symbol('dispatches'), - kDispatchKey: Symbol('dispatch key'), - kDefaultHeaders: Symbol('default headers'), - kDefaultTrailers: Symbol('default trailers'), - kContentLength: Symbol('content length'), - kMockAgent: Symbol('mock agent'), - kMockAgentSet: Symbol('mock agent set'), - kMockAgentGet: Symbol('mock agent get'), - kMockDispatch: Symbol('mock dispatch'), - kClose: Symbol('close'), - kOriginalClose: Symbol('original agent close'), - kOrigin: Symbol('origin'), - kIsMockActive: Symbol('is mock active'), - kNetConnect: Symbol('net connect'), - kGetNetConnect: Symbol('get net connect'), - kConnected: Symbol('connected') + kState: Symbol('FileReader state'), + kResult: Symbol('FileReader result'), + kError: Symbol('FileReader error'), + kLastProgressEventFired: Symbol('FileReader last progress event fired timestamp'), + kEvents: Symbol('FileReader events'), + kAborted: Symbol('FileReader aborted') } /***/ }), -/***/ 9323: +/***/ 7530: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { MockNotMatchedError } = __nccwpck_require__(888) -const { - kDispatches, - kMockAgent, - kOriginalDispatch, - kOrigin, - kGetNetConnect -} = __nccwpck_require__(4347) -const { buildURL, nop } = __nccwpck_require__(3983) -const { STATUS_CODES } = __nccwpck_require__(3685) const { - types: { - isPromise - } -} = __nccwpck_require__(3837) - -function matchValue (match, value) { - if (typeof match === 'string') { - return match === value - } - if (match instanceof RegExp) { - return match.test(value) - } - if (typeof match === 'function') { - return match(value) === true - } - return false -} + kState, + kError, + kResult, + kAborted, + kLastProgressEventFired +} = __nccwpck_require__(9054) +const { ProgressEvent } = __nccwpck_require__(5504) +const { getEncoding } = __nccwpck_require__(4854) +const { DOMException } = __nccwpck_require__(1037) +const { serializeAMimeType, parseMIMEType } = __nccwpck_require__(685) +const { types } = __nccwpck_require__(3837) +const { StringDecoder } = __nccwpck_require__(1576) +const { btoa } = __nccwpck_require__(4300) -function lowerCaseEntries (headers) { - return Object.fromEntries( - Object.entries(headers).map(([headerName, headerValue]) => { - return [headerName.toLocaleLowerCase(), headerValue] - }) - ) +/** @type {PropertyDescriptor} */ +const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false } /** - * @param {import('../../index').Headers|string[]|Record} headers - * @param {string} key + * @see https://w3c.github.io/FileAPI/#readOperation + * @param {import('./filereader').FileReader} fr + * @param {import('buffer').Blob} blob + * @param {string} type + * @param {string?} encodingName */ -function getHeaderByName (headers, key) { - if (Array.isArray(headers)) { - for (let i = 0; i < headers.length; i += 2) { - if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { - return headers[i + 1] - } - } - - return undefined - } else if (typeof headers.get === 'function') { - return headers.get(key) - } else { - return lowerCaseEntries(headers)[key.toLocaleLowerCase()] +function readOperation (fr, blob, type, encodingName) { + // 1. If fr’s state is "loading", throw an InvalidStateError + // DOMException. + if (fr[kState] === 'loading') { + throw new DOMException('Invalid state', 'InvalidStateError') } -} -/** @param {string[]} headers */ -function buildHeadersFromArray (headers) { // fetch HeadersList - const clone = headers.slice() - const entries = [] - for (let index = 0; index < clone.length; index += 2) { - entries.push([clone[index], clone[index + 1]]) - } - return Object.fromEntries(entries) -} + // 2. Set fr’s state to "loading". + fr[kState] = 'loading' -function matchHeaders (mockDispatch, headers) { - if (typeof mockDispatch.headers === 'function') { - if (Array.isArray(headers)) { // fetch HeadersList - headers = buildHeadersFromArray(headers) - } - return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) - } - if (typeof mockDispatch.headers === 'undefined') { - return true - } - if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { - return false - } + // 3. Set fr’s result to null. + fr[kResult] = null - for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { - const headerValue = getHeaderByName(headers, matchHeaderName) + // 4. Set fr’s error to null. + fr[kError] = null - if (!matchValue(matchHeaderValue, headerValue)) { - return false - } - } - return true -} + // 5. Let stream be the result of calling get stream on blob. + /** @type {import('stream/web').ReadableStream} */ + const stream = blob.stream() -function safeUrl (path) { - if (typeof path !== 'string') { - return path - } + // 6. Let reader be the result of getting a reader from stream. + const reader = stream.getReader() + + // 7. Let bytes be an empty byte sequence. + /** @type {Uint8Array[]} */ + const bytes = [] + + // 8. Let chunkPromise be the result of reading a chunk from + // stream with reader. + let chunkPromise = reader.read() + + // 9. Let isFirstChunk be true. + let isFirstChunk = true + + // 10. In parallel, while true: + // Note: "In parallel" just means non-blocking + // Note 2: readOperation itself cannot be async as double + // reading the body would then reject the promise, instead + // of throwing an error. + ;(async () => { + while (!fr[kAborted]) { + // 1. Wait for chunkPromise to be fulfilled or rejected. + try { + const { done, value } = await chunkPromise + + // 2. If chunkPromise is fulfilled, and isFirstChunk is + // true, queue a task to fire a progress event called + // loadstart at fr. + if (isFirstChunk && !fr[kAborted]) { + queueMicrotask(() => { + fireAProgressEvent('loadstart', fr) + }) + } + + // 3. Set isFirstChunk to false. + isFirstChunk = false + + // 4. If chunkPromise is fulfilled with an object whose + // done property is false and whose value property is + // a Uint8Array object, run these steps: + if (!done && types.isUint8Array(value)) { + // 1. Let bs be the byte sequence represented by the + // Uint8Array object. + + // 2. Append bs to bytes. + bytes.push(value) + + // 3. If roughly 50ms have passed since these steps + // were last invoked, queue a task to fire a + // progress event called progress at fr. + if ( + ( + fr[kLastProgressEventFired] === undefined || + Date.now() - fr[kLastProgressEventFired] >= 50 + ) && + !fr[kAborted] + ) { + fr[kLastProgressEventFired] = Date.now() + queueMicrotask(() => { + fireAProgressEvent('progress', fr) + }) + } - const pathSegments = path.split('?') + // 4. Set chunkPromise to the result of reading a + // chunk from stream with reader. + chunkPromise = reader.read() + } else if (done) { + // 5. Otherwise, if chunkPromise is fulfilled with an + // object whose done property is true, queue a task + // to run the following steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done' - if (pathSegments.length !== 2) { - return path - } + // 2. Let result be the result of package data given + // bytes, type, blob’s type, and encodingName. + try { + const result = packageData(bytes, type, blob.type, encodingName) - const qp = new URLSearchParams(pathSegments.pop()) - qp.sort() - return [...pathSegments, qp.toString()].join('?') -} + // 4. Else: -function matchKey (mockDispatch, { path, method, body, headers }) { - const pathMatch = matchValue(mockDispatch.path, path) - const methodMatch = matchValue(mockDispatch.method, method) - const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true - const headersMatch = matchHeaders(mockDispatch, headers) - return pathMatch && methodMatch && bodyMatch && headersMatch -} + if (fr[kAborted]) { + return + } -function getResponseData (data) { - if (Buffer.isBuffer(data)) { - return data - } else if (typeof data === 'object') { - return JSON.stringify(data) - } else { - return data.toString() - } -} + // 1. Set fr’s result to result. + fr[kResult] = result -function getMockDispatch (mockDispatches, key) { - const basePath = key.query ? buildURL(key.path, key.query) : key.path - const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath + // 2. Fire a progress event called load at the fr. + fireAProgressEvent('load', fr) + } catch (error) { + // 3. If package data threw an exception error: - // Match path - let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath)) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) - } + // 1. Set fr’s error to error. + fr[kError] = error - // Match method - matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}'`) - } + // 2. Fire a progress event called error at fr. + fireAProgressEvent('error', fr) + } - // Match body - matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}'`) - } + // 5. If fr’s state is not "loading", fire a progress + // event called loadend at the fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr) + } + }) - // Match headers - matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)) - if (matchedMockDispatches.length === 0) { - throw new MockNotMatchedError(`Mock dispatch not matched for headers '${typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers}'`) - } + break + } + } catch (error) { + if (fr[kAborted]) { + return + } - return matchedMockDispatches[0] -} + // 6. Otherwise, if chunkPromise is rejected with an + // error error, queue a task to run the following + // steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done' -function addMockDispatch (mockDispatches, key, data) { - const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false } - const replyData = typeof data === 'function' ? { callback: data } : { ...data } - const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } } - mockDispatches.push(newMockDispatch) - return newMockDispatch -} + // 2. Set fr’s error to error. + fr[kError] = error -function deleteMockDispatch (mockDispatches, key) { - const index = mockDispatches.findIndex(dispatch => { - if (!dispatch.consumed) { - return false - } - return matchKey(dispatch, key) - }) - if (index !== -1) { - mockDispatches.splice(index, 1) - } -} + // 3. Fire a progress event called error at fr. + fireAProgressEvent('error', fr) -function buildKey (opts) { - const { path, method, body, headers, query } = opts - return { - path, - method, - body, - headers, - query - } -} + // 4. If fr’s state is not "loading", fire a progress + // event called loadend at fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr) + } + }) -function generateKeyValues (data) { - return Object.entries(data).reduce((keyValuePairs, [key, value]) => [ - ...keyValuePairs, - Buffer.from(`${key}`), - Array.isArray(value) ? value.map(x => Buffer.from(`${x}`)) : Buffer.from(`${value}`) - ], []) + break + } + } + })() } /** - * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status - * @param {number} statusCode + * @see https://w3c.github.io/FileAPI/#fire-a-progress-event + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e The name of the event + * @param {import('./filereader').FileReader} reader */ -function getStatusText (statusCode) { - return STATUS_CODES[statusCode] || 'unknown' -} +function fireAProgressEvent (e, reader) { + // The progress event e does not bubble. e.bubbles must be false + // The progress event e is NOT cancelable. e.cancelable must be false + const event = new ProgressEvent(e, { + bubbles: false, + cancelable: false + }) -async function getResponse (body) { - const buffers = [] - for await (const data of body) { - buffers.push(data) - } - return Buffer.concat(buffers).toString('utf8') + reader.dispatchEvent(event) } /** - * Mock dispatch function used to simulate undici dispatches + * @see https://w3c.github.io/FileAPI/#blob-package-data + * @param {Uint8Array[]} bytes + * @param {string} type + * @param {string?} mimeType + * @param {string?} encodingName */ -function mockDispatch (opts, handler) { - // Get mock dispatch from built key - const key = buildKey(opts) - const mockDispatch = getMockDispatch(this[kDispatches], key) - - mockDispatch.timesInvoked++ - - // Here's where we resolve a callback if a callback is present for the dispatch data. - if (mockDispatch.data.callback) { - mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) } - } +function packageData (bytes, type, mimeType, encodingName) { + // 1. A Blob has an associated package data algorithm, given + // bytes, a type, a optional mimeType, and a optional + // encodingName, which switches on type and runs the + // associated steps: - // Parse mockDispatch data - const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch - const { timesInvoked, times } = mockDispatch + switch (type) { + case 'DataURL': { + // 1. Return bytes as a DataURL [RFC2397] subject to + // the considerations below: + // * Use mimeType as part of the Data URL if it is + // available in keeping with the Data URL + // specification [RFC2397]. + // * If mimeType is not available return a Data URL + // without a media-type. [RFC2397]. - // If it's used up and not persistent, mark as consumed - mockDispatch.consumed = !persist && timesInvoked >= times - mockDispatch.pending = timesInvoked < times + // https://datatracker.ietf.org/doc/html/rfc2397#section-3 + // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + // mediatype := [ type "/" subtype ] *( ";" parameter ) + // data := *urlchar + // parameter := attribute "=" value + let dataURL = 'data:' - // If specified, trigger dispatch error - if (error !== null) { - deleteMockDispatch(this[kDispatches], key) - handler.onError(error) - return true - } + const parsed = parseMIMEType(mimeType || 'application/octet-stream') - // Handle the request with a delay if necessary - if (typeof delay === 'number' && delay > 0) { - setTimeout(() => { - handleReply(this[kDispatches]) - }, delay) - } else { - handleReply(this[kDispatches]) - } + if (parsed !== 'failure') { + dataURL += serializeAMimeType(parsed) + } - function handleReply (mockDispatches, _data = data) { - // fetch's HeadersList is a 1D string array - const optsHeaders = Array.isArray(opts.headers) - ? buildHeadersFromArray(opts.headers) - : opts.headers - const body = typeof _data === 'function' - ? _data({ ...opts, headers: optsHeaders }) - : _data + dataURL += ';base64,' - // util.types.isPromise is likely needed for jest. - if (isPromise(body)) { - // If handleReply is asynchronous, throwing an error - // in the callback will reject the promise, rather than - // synchronously throw the error, which breaks some tests. - // Rather, we wait for the callback to resolve if it is a - // promise, and then re-run handleReply with the new body. - body.then((newData) => handleReply(mockDispatches, newData)) - return - } + const decoder = new StringDecoder('latin1') - const responseData = getResponseData(body) - const responseHeaders = generateKeyValues(headers) - const responseTrailers = generateKeyValues(trailers) + for (const chunk of bytes) { + dataURL += btoa(decoder.write(chunk)) + } - handler.abort = nop - handler.onHeaders(statusCode, responseHeaders, resume, getStatusText(statusCode)) - handler.onData(Buffer.from(responseData)) - handler.onComplete(responseTrailers) - deleteMockDispatch(mockDispatches, key) - } + dataURL += btoa(decoder.end()) - function resume () {} + return dataURL + } + case 'Text': { + // 1. Let encoding be failure + let encoding = 'failure' - return true -} + // 2. If the encodingName is present, set encoding to the + // result of getting an encoding from encodingName. + if (encodingName) { + encoding = getEncoding(encodingName) + } -function buildMockDispatch () { - const agent = this[kMockAgent] - const origin = this[kOrigin] - const originalDispatch = this[kOriginalDispatch] + // 3. If encoding is failure, and mimeType is present: + if (encoding === 'failure' && mimeType) { + // 1. Let type be the result of parse a MIME type + // given mimeType. + const type = parseMIMEType(mimeType) - return function dispatch (opts, handler) { - if (agent.isMockActive) { - try { - mockDispatch.call(this, opts, handler) - } catch (error) { - if (error instanceof MockNotMatchedError) { - const netConnect = agent[kGetNetConnect]() - if (netConnect === false) { - throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`) - } - if (checkNetConnect(netConnect, origin)) { - originalDispatch.call(this, opts, handler) - } else { - throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`) - } - } else { - throw error + // 2. If type is not failure, set encoding to the result + // of getting an encoding from type’s parameters["charset"]. + if (type !== 'failure') { + encoding = getEncoding(type.parameters.get('charset')) } } - } else { - originalDispatch.call(this, opts, handler) + + // 4. If encoding is failure, then set encoding to UTF-8. + if (encoding === 'failure') { + encoding = 'UTF-8' + } + + // 5. Decode bytes using fallback encoding encoding, and + // return the result. + return decode(bytes, encoding) } - } -} + case 'ArrayBuffer': { + // Return a new ArrayBuffer whose contents are bytes. + const sequence = combineByteSequences(bytes) -function checkNetConnect (netConnect, origin) { - const url = new URL(origin) - if (netConnect === true) { - return true - } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { - return true - } - return false -} + return sequence.buffer + } + case 'BinaryString': { + // Return bytes as a binary string, in which every byte + // is represented by a code unit of equal value [0..255]. + let binaryString = '' -function buildMockOptions (opts) { - if (opts) { - const { agent, ...mockOptions } = opts - return mockOptions + const decoder = new StringDecoder('latin1') + + for (const chunk of bytes) { + binaryString += decoder.write(chunk) + } + + binaryString += decoder.end() + + return binaryString + } } } -module.exports = { - getResponseData, - getMockDispatch, - addMockDispatch, - deleteMockDispatch, - buildKey, - generateKeyValues, - matchValue, - getResponse, - getStatusText, - mockDispatch, - buildMockDispatch, - checkNetConnect, - buildMockOptions, - getHeaderByName -} +/** + * @see https://encoding.spec.whatwg.org/#decode + * @param {Uint8Array[]} ioQueue + * @param {string} encoding + */ +function decode (ioQueue, encoding) { + const bytes = combineByteSequences(ioQueue) + // 1. Let BOMEncoding be the result of BOM sniffing ioQueue. + const BOMEncoding = BOMSniffing(bytes) -/***/ }), + let slice = 0 -/***/ 6823: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // 2. If BOMEncoding is non-null: + if (BOMEncoding !== null) { + // 1. Set encoding to BOMEncoding. + encoding = BOMEncoding -"use strict"; + // 2. Read three bytes from ioQueue, if BOMEncoding is + // UTF-8; otherwise read two bytes. + // (Do nothing with those bytes.) + slice = BOMEncoding === 'UTF-8' ? 3 : 2 + } + + // 3. Process a queue with an instance of encoding’s + // decoder, ioQueue, output, and "replacement". + // 4. Return output. -const { Transform } = __nccwpck_require__(2781) -const { Console } = __nccwpck_require__(6206) + const sliced = bytes.slice(slice) + return new TextDecoder(encoding).decode(sliced) +} /** - * Gets the output of `console.table(…)` as a string. + * @see https://encoding.spec.whatwg.org/#bom-sniff + * @param {Uint8Array} ioQueue */ -module.exports = class PendingInterceptorsFormatter { - constructor ({ disableColors } = {}) { - this.transform = new Transform({ - transform (chunk, _enc, cb) { - cb(null, chunk) - } - }) +function BOMSniffing (ioQueue) { + // 1. Let BOM be the result of peeking 3 bytes from ioQueue, + // converted to a byte sequence. + const [a, b, c] = ioQueue - this.logger = new Console({ - stdout: this.transform, - inspectOptions: { - colors: !disableColors && !process.env.CI - } - }) + // 2. For each of the rows in the table below, starting with + // the first one and going down, if BOM starts with the + // bytes given in the first column, then return the + // encoding given in the cell in the second column of that + // row. Otherwise, return null. + if (a === 0xEF && b === 0xBB && c === 0xBF) { + return 'UTF-8' + } else if (a === 0xFE && b === 0xFF) { + return 'UTF-16BE' + } else if (a === 0xFF && b === 0xFE) { + return 'UTF-16LE' } - format (pendingInterceptors) { - const withPrettyHeaders = pendingInterceptors.map( - ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ - Method: method, - Origin: origin, - Path: path, - 'Status code': statusCode, - Persistent: persist ? '✅' : '❌', - Invocations: timesInvoked, - Remaining: persist ? Infinity : times - timesInvoked - })) + return null +} - this.logger.table(withPrettyHeaders) - return this.transform.read().toString() - } +/** + * @param {Uint8Array[]} sequences + */ +function combineByteSequences (sequences) { + const size = sequences.reduce((a, b) => { + return a + b.byteLength + }, 0) + + let offset = 0 + + return sequences.reduce((a, b) => { + a.set(b, offset) + offset += b.byteLength + return a + }, new Uint8Array(size)) +} + +module.exports = { + staticPropertyDescriptors, + readOperation, + fireAProgressEvent } /***/ }), -/***/ 8891: -/***/ ((module) => { +/***/ 1892: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const singulars = { - pronoun: 'it', - is: 'is', - was: 'was', - this: 'this' -} +// We include a version number for the Dispatcher API. In case of breaking changes, +// this version number must be increased to avoid conflicts. +const globalDispatcher = Symbol.for('undici.globalDispatcher.1') +const { InvalidArgumentError } = __nccwpck_require__(8045) +const Agent = __nccwpck_require__(7890) -const plurals = { - pronoun: 'they', - is: 'are', - was: 'were', - this: 'these' +if (getGlobalDispatcher() === undefined) { + setGlobalDispatcher(new Agent()) } -module.exports = class Pluralizer { - constructor (singular, plural) { - this.singular = singular - this.plural = plural +function setGlobalDispatcher (agent) { + if (!agent || typeof agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument agent must implement Agent') } + Object.defineProperty(globalThis, globalDispatcher, { + value: agent, + writable: true, + enumerable: false, + configurable: false + }) +} - pluralize (count) { - const one = count === 1 - const keys = one ? singulars : plurals - const noun = one ? this.singular : this.plural - return { ...keys, count, noun } - } +function getGlobalDispatcher () { + return globalThis[globalDispatcher] +} + +module.exports = { + setGlobalDispatcher, + getGlobalDispatcher } /***/ }), -/***/ 8266: +/***/ 6930: /***/ ((module) => { "use strict"; -/* eslint-disable */ - - - -// Extracted from node/lib/internal/fixed_queue.js - -// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. -const kSize = 2048; -const kMask = kSize - 1; - -// The FixedQueue is implemented as a singly-linked list of fixed-size -// circular buffers. It looks something like this: -// -// head tail -// | | -// v v -// +-----------+ <-----\ +-----------+ <------\ +-----------+ -// | [null] | \----- | next | \------- | next | -// +-----------+ +-----------+ +-----------+ -// | item | <-- bottom | item | <-- bottom | [empty] | -// | item | | item | | [empty] | -// | item | | item | | [empty] | -// | item | | item | | [empty] | -// | item | | item | bottom --> | item | -// | item | | item | | item | -// | ... | | ... | | ... | -// | item | | item | | item | -// | item | | item | | item | -// | [empty] | <-- top | item | | item | -// | [empty] | | item | | item | -// | [empty] | | [empty] | <-- top top --> | [empty] | -// +-----------+ +-----------+ +-----------+ -// -// Or, if there is only one circular buffer, it looks something -// like either of these: -// -// head tail head tail -// | | | | -// v v v v -// +-----------+ +-----------+ -// | [null] | | [null] | -// +-----------+ +-----------+ -// | [empty] | | item | -// | [empty] | | item | -// | item | <-- bottom top --> | [empty] | -// | item | | [empty] | -// | [empty] | <-- top bottom --> | item | -// | [empty] | | item | -// +-----------+ +-----------+ -// -// Adding a value means moving `top` forward by one, removing means -// moving `bottom` forward by one. After reaching the end, the queue -// wraps around. -// -// When `top === bottom` the current queue is empty and when -// `top + 1 === bottom` it's full. This wastes a single space of storage -// but allows much quicker checks. -class FixedCircularBuffer { - constructor() { - this.bottom = 0; - this.top = 0; - this.list = new Array(kSize); - this.next = null; - } - isEmpty() { - return this.top === this.bottom; +module.exports = class DecoratorHandler { + constructor (handler) { + this.handler = handler } - isFull() { - return ((this.top + 1) & kMask) === this.bottom; + onConnect (...args) { + return this.handler.onConnect(...args) } - push(data) { - this.list[this.top] = data; - this.top = (this.top + 1) & kMask; + onError (...args) { + return this.handler.onError(...args) } - shift() { - const nextItem = this.list[this.bottom]; - if (nextItem === undefined) - return null; - this.list[this.bottom] = undefined; - this.bottom = (this.bottom + 1) & kMask; - return nextItem; + onUpgrade (...args) { + return this.handler.onUpgrade(...args) } -} -module.exports = class FixedQueue { - constructor() { - this.head = this.tail = new FixedCircularBuffer(); + onHeaders (...args) { + return this.handler.onHeaders(...args) } - isEmpty() { - return this.head.isEmpty(); + onData (...args) { + return this.handler.onData(...args) } - push(data) { - if (this.head.isFull()) { - // Head is full: Creates a new queue, sets the old queue's `.next` to it, - // and sets it as the new main queue. - this.head = this.head.next = new FixedCircularBuffer(); - } - this.head.push(data); + onComplete (...args) { + return this.handler.onComplete(...args) } - shift() { - const tail = this.tail; - const next = tail.shift(); - if (tail.isEmpty() && tail.next !== null) { - // If there is another queue, it forms the new tail. - this.tail = tail.next; - } - return next; + onBodySent (...args) { + return this.handler.onBodySent(...args) } -}; +} /***/ }), -/***/ 3198: +/***/ 2860: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const DispatcherBase = __nccwpck_require__(4839) -const FixedQueue = __nccwpck_require__(8266) -const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = __nccwpck_require__(2785) -const PoolStats = __nccwpck_require__(9689) - -const kClients = Symbol('clients') -const kNeedDrain = Symbol('needDrain') -const kQueue = Symbol('queue') -const kClosedResolve = Symbol('closed resolve') -const kOnDrain = Symbol('onDrain') -const kOnConnect = Symbol('onConnect') -const kOnDisconnect = Symbol('onDisconnect') -const kOnConnectionError = Symbol('onConnectionError') -const kGetDispatcher = Symbol('get dispatcher') -const kAddClient = Symbol('add client') -const kRemoveClient = Symbol('remove client') -const kStats = Symbol('stats') +const util = __nccwpck_require__(3983) +const { kBodyUsed } = __nccwpck_require__(2785) +const assert = __nccwpck_require__(9491) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const EE = __nccwpck_require__(2361) -class PoolBase extends DispatcherBase { - constructor () { - super() +const redirectableStatusCodes = [300, 301, 302, 303, 307, 308] - this[kQueue] = new FixedQueue() - this[kClients] = [] - this[kQueued] = 0 +const kBody = Symbol('body') - const pool = this +class BodyAsyncIterable { + constructor (body) { + this[kBody] = body + this[kBodyUsed] = false + } - this[kOnDrain] = function onDrain (origin, targets) { - const queue = pool[kQueue] + async * [Symbol.asyncIterator] () { + assert(!this[kBodyUsed], 'disturbed') + this[kBodyUsed] = true + yield * this[kBody] + } +} - let needDrain = false +class RedirectHandler { + constructor (dispatch, maxRedirections, opts, handler) { + if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) { + throw new InvalidArgumentError('maxRedirections must be a positive number') + } - while (!needDrain) { - const item = queue.shift() - if (!item) { - break - } - pool[kQueued]-- - needDrain = !this.dispatch(item.opts, item.handler) - } + util.validateHandler(handler, opts.method, opts.upgrade) - this[kNeedDrain] = needDrain + this.dispatch = dispatch + this.location = null + this.abort = null + this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy + this.maxRedirections = maxRedirections + this.handler = handler + this.history = [] - if (!this[kNeedDrain] && pool[kNeedDrain]) { - pool[kNeedDrain] = false - pool.emit('drain', origin, [pool, ...targets]) + if (util.isStream(this.opts.body)) { + // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp + // so that it can be dispatched again? + // TODO (fix): Do we need 100-expect support to provide a way to do this properly? + if (util.bodyLength(this.opts.body) === 0) { + this.opts.body + .on('data', function () { + assert(false) + }) } - if (pool[kClosedResolve] && queue.isEmpty()) { - Promise - .all(pool[kClients].map(c => c.close())) - .then(pool[kClosedResolve]) + if (typeof this.opts.body.readableDidRead !== 'boolean') { + this.opts.body[kBodyUsed] = false + EE.prototype.on.call(this.opts.body, 'data', function () { + this[kBodyUsed] = true + }) } + } else if (this.opts.body && typeof this.opts.body.pipeTo === 'function') { + // TODO (fix): We can't access ReadableStream internal state + // to determine whether or not it has been disturbed. This is just + // a workaround. + this.opts.body = new BodyAsyncIterable(this.opts.body) + } else if ( + this.opts.body && + typeof this.opts.body !== 'string' && + !ArrayBuffer.isView(this.opts.body) && + util.isIterable(this.opts.body) + ) { + // TODO: Should we allow re-using iterable if !this.opts.idempotent + // or through some other flag? + this.opts.body = new BodyAsyncIterable(this.opts.body) } + } - this[kOnConnect] = (origin, targets) => { - pool.emit('connect', origin, [pool, ...targets]) + onConnect (abort) { + this.abort = abort + this.handler.onConnect(abort, { history: this.history }) + } + + onUpgrade (statusCode, headers, socket) { + this.handler.onUpgrade(statusCode, headers, socket) + } + + onError (error) { + this.handler.onError(error) + } + + onHeaders (statusCode, headers, resume, statusText) { + this.location = this.history.length >= this.maxRedirections || util.isDisturbed(this.opts.body) + ? null + : parseLocation(statusCode, headers) + + if (this.opts.origin) { + this.history.push(new URL(this.opts.path, this.opts.origin)) } - this[kOnDisconnect] = (origin, targets, err) => { - pool.emit('disconnect', origin, [pool, ...targets], err) + if (!this.location) { + return this.handler.onHeaders(statusCode, headers, resume, statusText) } - this[kOnConnectionError] = (origin, targets, err) => { - pool.emit('connectionError', origin, [pool, ...targets], err) - } + const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin))) + const path = search ? `${pathname}${search}` : pathname - this[kStats] = new PoolStats(this) - } + // Remove headers referring to the original URL. + // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. + // https://tools.ietf.org/html/rfc7231#section-6.4 + this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin) + this.opts.path = path + this.opts.origin = origin + this.opts.maxRedirections = 0 + this.opts.query = null - get [kBusy] () { - return this[kNeedDrain] + // https://tools.ietf.org/html/rfc7231#section-6.4.4 + // In case of HTTP 303, always replace method to be either HEAD or GET + if (statusCode === 303 && this.opts.method !== 'HEAD') { + this.opts.method = 'GET' + this.opts.body = null + } } - get [kConnected] () { - return this[kClients].filter(client => client[kConnected]).length - } + onData (chunk) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 - get [kFree] () { - return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length - } + TLDR: undici always ignores 3xx response bodies. - get [kPending] () { - let ret = this[kQueued] - for (const { [kPending]: pending } of this[kClients]) { - ret += pending - } - return ret - } + Redirection is used to serve the requested resource from another URL, so it is assumes that + no body is generated (and thus can be ignored). Even though generating a body is not prohibited. - get [kRunning] () { - let ret = 0 - for (const { [kRunning]: running } of this[kClients]) { - ret += running - } - return ret - } + For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually + (which means it's optional and not mandated) contain just an hyperlink to the value of + the Location response header, so the body can be ignored safely. - get [kSize] () { - let ret = this[kQueued] - for (const { [kSize]: size } of this[kClients]) { - ret += size + For status 300, which is "Multiple Choices", the spec mentions both generating a Location + response header AND a response body with the other possible location to follow. + Since the spec explicitily chooses not to specify a format for such body and leave it to + servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. + */ + } else { + return this.handler.onData(chunk) } - return ret } - get stats () { - return this[kStats] - } + onComplete (trailers) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 - async [kClose] () { - if (this[kQueue].isEmpty()) { - return Promise.all(this[kClients].map(c => c.close())) + TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections + and neither are useful if present. + + See comment on onData method above for more detailed informations. + */ + + this.location = null + this.abort = null + + this.dispatch(this.opts, this) } else { - return new Promise((resolve) => { - this[kClosedResolve] = resolve - }) + this.handler.onComplete(trailers) } } - async [kDestroy] (err) { - while (true) { - const item = this[kQueue].shift() - if (!item) { - break - } - item.handler.onError(err) + onBodySent (chunk) { + if (this.handler.onBodySent) { + this.handler.onBodySent(chunk) } - - return Promise.all(this[kClients].map(c => c.destroy(err))) } +} - [kDispatch] (opts, handler) { - const dispatcher = this[kGetDispatcher]() +function parseLocation (statusCode, headers) { + if (redirectableStatusCodes.indexOf(statusCode) === -1) { + return null + } - if (!dispatcher) { - this[kNeedDrain] = true - this[kQueue].push({ opts, handler }) - this[kQueued]++ - } else if (!dispatcher.dispatch(opts, handler)) { - dispatcher[kNeedDrain] = true - this[kNeedDrain] = !this[kGetDispatcher]() + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toString().toLowerCase() === 'location') { + return headers[i + 1] } - - return !this[kNeedDrain] } +} - [kAddClient] (client) { - client - .on('drain', this[kOnDrain]) - .on('connect', this[kOnConnect]) - .on('disconnect', this[kOnDisconnect]) - .on('connectionError', this[kOnConnectionError]) - - this[kClients].push(client) +// https://tools.ietf.org/html/rfc7231#section-6.4.4 +function shouldRemoveHeader (header, removeContent, unknownOrigin) { + return ( + (header.length === 4 && header.toString().toLowerCase() === 'host') || + (removeContent && header.toString().toLowerCase().indexOf('content-') === 0) || + (unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') || + (unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie') + ) +} - if (this[kNeedDrain]) { - process.nextTick(() => { - if (this[kNeedDrain]) { - this[kOnDrain](client[kUrl], [this, client]) - } - }) +// https://tools.ietf.org/html/rfc7231#section-6.4 +function cleanRequestHeaders (headers, removeContent, unknownOrigin) { + const ret = [] + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { + ret.push(headers[i], headers[i + 1]) + } } - - return this - } - - [kRemoveClient] (client) { - client.close(() => { - const idx = this[kClients].indexOf(client) - if (idx !== -1) { - this[kClients].splice(idx, 1) + } else if (headers && typeof headers === 'object') { + for (const key of Object.keys(headers)) { + if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { + ret.push(key, headers[key]) } - }) - - this[kNeedDrain] = this[kClients].some(dispatcher => ( - !dispatcher[kNeedDrain] && - dispatcher.closed !== true && - dispatcher.destroyed !== true - )) + } + } else { + assert(headers == null, 'headers must be an object or an array') } + return ret } -module.exports = { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kRemoveClient, - kGetDispatcher -} +module.exports = RedirectHandler /***/ }), -/***/ 9689: +/***/ 2286: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = __nccwpck_require__(2785) -const kPool = Symbol('pool') +const assert = __nccwpck_require__(9491) -class PoolStats { - constructor (pool) { - this[kPool] = pool - } +const { kRetryHandlerDefaultRetry } = __nccwpck_require__(2785) +const { RequestRetryError } = __nccwpck_require__(8045) +const { isDisturbed, parseHeaders, parseRangeHeader } = __nccwpck_require__(3983) - get connected () { - return this[kPool][kConnected] - } +function calculateRetryAfterHeader (retryAfter) { + const current = Date.now() + const diff = new Date(retryAfter).getTime() - current + + return diff +} + +class RetryHandler { + constructor (opts, handlers) { + const { retryOptions, ...dispatchOpts } = opts + const { + // Retry scoped + retry: retryFn, + maxRetries, + maxTimeout, + minTimeout, + timeoutFactor, + // Response scoped + methods, + errorCodes, + retryAfter, + statusCodes + } = retryOptions ?? {} + + this.dispatch = handlers.dispatch + this.handler = handlers.handler + this.opts = dispatchOpts + this.abort = null + this.aborted = false + this.retryOpts = { + retry: retryFn ?? RetryHandler[kRetryHandlerDefaultRetry], + retryAfter: retryAfter ?? true, + maxTimeout: maxTimeout ?? 30 * 1000, // 30s, + timeout: minTimeout ?? 500, // .5s + timeoutFactor: timeoutFactor ?? 2, + maxRetries: maxRetries ?? 5, + // What errors we should retry + methods: methods ?? ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'], + // Indicates which errors to retry + statusCodes: statusCodes ?? [500, 502, 503, 504, 429], + // List of errors to retry + errorCodes: errorCodes ?? [ + 'ECONNRESET', + 'ECONNREFUSED', + 'ENOTFOUND', + 'ENETDOWN', + 'ENETUNREACH', + 'EHOSTDOWN', + 'EHOSTUNREACH', + 'EPIPE' + ] + } + + this.retryCount = 0 + this.start = 0 + this.end = null + this.etag = null + this.resume = null - get free () { - return this[kPool][kFree] + // Handle possible onConnect duplication + this.handler.onConnect(reason => { + this.aborted = true + if (this.abort) { + this.abort(reason) + } else { + this.reason = reason + } + }) } - get pending () { - return this[kPool][kPending] + onRequestSent () { + if (this.handler.onRequestSent) { + this.handler.onRequestSent() + } } - get queued () { - return this[kPool][kQueued] + onUpgrade (statusCode, headers, socket) { + if (this.handler.onUpgrade) { + this.handler.onUpgrade(statusCode, headers, socket) + } } - get running () { - return this[kPool][kRunning] + onConnect (abort) { + if (this.aborted) { + abort(this.reason) + } else { + this.abort = abort + } } - get size () { - return this[kPool][kSize] + onBodySent (chunk) { + if (this.handler.onBodySent) return this.handler.onBodySent(chunk) } -} - -module.exports = PoolStats - - -/***/ }), - -/***/ 4634: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const { - PoolBase, - kClients, - kNeedDrain, - kAddClient, - kGetDispatcher -} = __nccwpck_require__(3198) -const Client = __nccwpck_require__(3598) -const { - InvalidArgumentError -} = __nccwpck_require__(8045) -const util = __nccwpck_require__(3983) -const { kUrl, kInterceptors } = __nccwpck_require__(2785) -const buildConnector = __nccwpck_require__(2067) -const kOptions = Symbol('options') -const kConnections = Symbol('connections') -const kFactory = Symbol('factory') - -function defaultFactory (origin, opts) { - return new Client(origin, opts) -} - -class Pool extends PoolBase { - constructor (origin, { - connections, - factory = defaultFactory, - connect, - connectTimeout, - tls, - maxCachedSessions, - socketPath, - autoSelectFamily, - autoSelectFamilyAttemptTimeout, - allowH2, - ...options - } = {}) { - super() + static [kRetryHandlerDefaultRetry] (err, { state, opts }, cb) { + const { statusCode, code, headers } = err + const { method, retryOptions } = opts + const { + maxRetries, + timeout, + maxTimeout, + timeoutFactor, + statusCodes, + errorCodes, + methods + } = retryOptions + let { counter, currentTimeout } = state - if (connections != null && (!Number.isFinite(connections) || connections < 0)) { - throw new InvalidArgumentError('invalid connections') - } + currentTimeout = + currentTimeout != null && currentTimeout > 0 ? currentTimeout : timeout - if (typeof factory !== 'function') { - throw new InvalidArgumentError('factory must be a function.') + // Any code that is not a Undici's originated and allowed to retry + if ( + code && + code !== 'UND_ERR_REQ_RETRY' && + code !== 'UND_ERR_SOCKET' && + !errorCodes.includes(code) + ) { + cb(err) + return } - if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { - throw new InvalidArgumentError('connect must be a function or an object') + // If a set of method are provided and the current method is not in the list + if (Array.isArray(methods) && !methods.includes(method)) { + cb(err) + return } - if (typeof connect !== 'function') { - connect = buildConnector({ - ...tls, - maxCachedSessions, - allowH2, - socketPath, - timeout: connectTimeout, - ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), - ...connect - }) + // If a set of status code are provided and the current status code is not in the list + if ( + statusCode != null && + Array.isArray(statusCodes) && + !statusCodes.includes(statusCode) + ) { + cb(err) + return } - this[kInterceptors] = options.interceptors && options.interceptors.Pool && Array.isArray(options.interceptors.Pool) - ? options.interceptors.Pool - : [] - this[kConnections] = connections || null - this[kUrl] = util.parseOrigin(origin) - this[kOptions] = { ...util.deepClone(options), connect, allowH2 } - this[kOptions].interceptors = options.interceptors - ? { ...options.interceptors } - : undefined - this[kFactory] = factory - } - - [kGetDispatcher] () { - let dispatcher = this[kClients].find(dispatcher => !dispatcher[kNeedDrain]) - - if (dispatcher) { - return dispatcher + // If we reached the max number of retries + if (counter > maxRetries) { + cb(err) + return } - if (!this[kConnections] || this[kClients].length < this[kConnections]) { - dispatcher = this[kFactory](this[kUrl], this[kOptions]) - this[kAddClient](dispatcher) + let retryAfterHeader = headers != null && headers['retry-after'] + if (retryAfterHeader) { + retryAfterHeader = Number(retryAfterHeader) + retryAfterHeader = isNaN(retryAfterHeader) + ? calculateRetryAfterHeader(retryAfterHeader) + : retryAfterHeader * 1e3 // Retry-After is in seconds } - return dispatcher - } -} + const retryTimeout = + retryAfterHeader > 0 + ? Math.min(retryAfterHeader, maxTimeout) + : Math.min(currentTimeout * timeoutFactor ** counter, maxTimeout) -module.exports = Pool + state.currentTimeout = retryTimeout + setTimeout(() => cb(null), retryTimeout) + } -/***/ }), + onHeaders (statusCode, rawHeaders, resume, statusMessage) { + const headers = parseHeaders(rawHeaders) -/***/ 7858: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.retryCount += 1 -"use strict"; + if (statusCode >= 300) { + this.abort( + new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } + // Checkpoint for resume from where we left it + if (this.resume != null) { + this.resume = null -const { kProxy, kClose, kDestroy, kInterceptors } = __nccwpck_require__(2785) -const { URL } = __nccwpck_require__(7310) -const Agent = __nccwpck_require__(7890) -const Pool = __nccwpck_require__(4634) -const DispatcherBase = __nccwpck_require__(4839) -const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8045) -const buildConnector = __nccwpck_require__(2067) + if (statusCode !== 206) { + return true + } -const kAgent = Symbol('proxy agent') -const kClient = Symbol('proxy client') -const kProxyHeaders = Symbol('proxy headers') -const kRequestTls = Symbol('request tls settings') -const kProxyTls = Symbol('proxy tls settings') -const kConnectEndpoint = Symbol('connect endpoint function') + const contentRange = parseRangeHeader(headers['content-range']) + // If no content range + if (!contentRange) { + this.abort( + new RequestRetryError('Content-Range mismatch', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } -function defaultProtocolPort (protocol) { - return protocol === 'https:' ? 443 : 80 -} + // Let's start with a weak etag check + if (this.etag != null && this.etag !== headers.etag) { + this.abort( + new RequestRetryError('ETag mismatch', statusCode, { + headers, + count: this.retryCount + }) + ) + return false + } -function buildProxyOptions (opts) { - if (typeof opts === 'string') { - opts = { uri: opts } - } + const { start, size, end = size } = contentRange - if (!opts || !opts.uri) { - throw new InvalidArgumentError('Proxy opts.uri is mandatory') - } + assert(this.start === start, 'content-range mismatch') + assert(this.end == null || this.end === end, 'content-range mismatch') - return { - uri: opts.uri, - protocol: opts.protocol || 'https' - } -} + this.resume = resume + return true + } -function defaultFactory (origin, opts) { - return new Pool(origin, opts) -} + if (this.end == null) { + if (statusCode === 206) { + // First time we receive 206 + const range = parseRangeHeader(headers['content-range']) -class ProxyAgent extends DispatcherBase { - constructor (opts) { - super(opts) - this[kProxy] = buildProxyOptions(opts) - this[kAgent] = new Agent(opts) - this[kInterceptors] = opts.interceptors && opts.interceptors.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) - ? opts.interceptors.ProxyAgent - : [] + if (range == null) { + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) + } - if (typeof opts === 'string') { - opts = { uri: opts } - } + const { start, size, end = size } = range - if (!opts || !opts.uri) { - throw new InvalidArgumentError('Proxy opts.uri is mandatory') - } + assert( + start != null && Number.isFinite(start) && this.start !== start, + 'content-range mismatch' + ) + assert(Number.isFinite(start)) + assert( + end != null && Number.isFinite(end) && this.end !== end, + 'invalid content-length' + ) - const { clientFactory = defaultFactory } = opts + this.start = start + this.end = end + } - if (typeof clientFactory !== 'function') { - throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') - } + // We make our best to checkpoint the body for further range headers + if (this.end == null) { + const contentLength = headers['content-length'] + this.end = contentLength != null ? Number(contentLength) : null + } - this[kRequestTls] = opts.requestTls - this[kProxyTls] = opts.proxyTls - this[kProxyHeaders] = opts.headers || {} + assert(Number.isFinite(this.start)) + assert( + this.end == null || Number.isFinite(this.end), + 'invalid content-length' + ) - const resolvedUrl = new URL(opts.uri) - const { origin, port, host, username, password } = resolvedUrl + this.resume = resume + this.etag = headers.etag != null ? headers.etag : null - if (opts.auth && opts.token) { - throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') - } else if (opts.auth) { - /* @deprecated in favour of opts.token */ - this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}` - } else if (opts.token) { - this[kProxyHeaders]['proxy-authorization'] = opts.token - } else if (username && password) { - this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}` + return this.handler.onHeaders( + statusCode, + rawHeaders, + resume, + statusMessage + ) } - const connect = buildConnector({ ...opts.proxyTls }) - this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }) - this[kClient] = clientFactory(resolvedUrl, { connect }) - this[kAgent] = new Agent({ - ...opts, - connect: async (opts, callback) => { - let requestedHost = opts.host - if (!opts.port) { - requestedHost += `:${defaultProtocolPort(opts.protocol)}` - } - try { - const { socket, statusCode } = await this[kClient].connect({ - origin, - port, - path: requestedHost, - signal: opts.signal, - headers: { - ...this[kProxyHeaders], - host - } - }) - if (statusCode !== 200) { - socket.on('error', () => {}).destroy() - callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)) - } - if (opts.protocol !== 'https:') { - callback(null, socket) - return - } - let servername - if (this[kRequestTls]) { - servername = this[kRequestTls].servername - } else { - servername = opts.servername - } - this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback) - } catch (err) { - callback(err) - } - } + const err = new RequestRetryError('Request failed', statusCode, { + headers, + count: this.retryCount }) - } - dispatch (opts, handler) { - const { host } = new URL(opts.origin) - const headers = buildHeaders(opts.headers) - throwIfProxyAuthIsSent(headers) - return this[kAgent].dispatch( - { - ...opts, - headers: { - ...headers, - host - } - }, - handler - ) - } + this.abort(err) - async [kClose] () { - await this[kAgent].close() - await this[kClient].close() + return false } - async [kDestroy] () { - await this[kAgent].destroy() - await this[kClient].destroy() + onData (chunk) { + this.start += chunk.length + + return this.handler.onData(chunk) } -} -/** - * @param {string[] | Record} headers - * @returns {Record} - */ -function buildHeaders (headers) { - // When using undici.fetch, the headers list is stored - // as an array. - if (Array.isArray(headers)) { - /** @type {Record} */ - const headersPair = {} + onComplete (rawTrailers) { + this.retryCount = 0 + return this.handler.onComplete(rawTrailers) + } - for (let i = 0; i < headers.length; i += 2) { - headersPair[headers[i]] = headers[i + 1] + onError (err) { + if (this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) } - return headersPair - } + this.retryOpts.retry( + err, + { + state: { counter: this.retryCount++, currentTimeout: this.retryAfter }, + opts: { retryOptions: this.retryOpts, ...this.opts } + }, + onRetry.bind(this) + ) - return headers -} + function onRetry (err) { + if (err != null || this.aborted || isDisturbed(this.opts.body)) { + return this.handler.onError(err) + } -/** - * @param {Record} headers - * - * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers - * Nevertheless, it was changed and to avoid a security vulnerability by end users - * this check was created. - * It should be removed in the next major version for performance reasons - */ -function throwIfProxyAuthIsSent (headers) { - const existProxyAuth = headers && Object.keys(headers) - .find((key) => key.toLowerCase() === 'proxy-authorization') - if (existProxyAuth) { - throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') + if (this.start !== 0) { + this.opts = { + ...this.opts, + headers: { + ...this.opts.headers, + range: `bytes=${this.start}-${this.end ?? ''}` + } + } + } + + try { + this.dispatch(this.opts, this) + } catch (err) { + this.handler.onError(err) + } + } } } -module.exports = ProxyAgent +module.exports = RetryHandler /***/ }), -/***/ 9459: -/***/ ((module) => { +/***/ 8861: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -let fastNow = Date.now() -let fastNowTimeout - -const fastTimers = [] - -function onTimeout () { - fastNow = Date.now() - - let len = fastTimers.length - let idx = 0 - while (idx < len) { - const timer = fastTimers[idx] - - if (timer.state === 0) { - timer.state = fastNow + timer.delay - } else if (timer.state > 0 && fastNow >= timer.state) { - timer.state = -1 - timer.callback(timer.opaque) - } +const RedirectHandler = __nccwpck_require__(2860) - if (timer.state === -1) { - timer.state = -2 - if (idx !== len - 1) { - fastTimers[idx] = fastTimers.pop() - } else { - fastTimers.pop() - } - len -= 1 - } else { - idx += 1 - } - } +function createRedirectInterceptor ({ maxRedirections: defaultMaxRedirections }) { + return (dispatch) => { + return function Intercept (opts, handler) { + const { maxRedirections = defaultMaxRedirections } = opts - if (fastTimers.length > 0) { - refreshTimeout() - } -} + if (!maxRedirections) { + return dispatch(opts, handler) + } -function refreshTimeout () { - if (fastNowTimeout && fastNowTimeout.refresh) { - fastNowTimeout.refresh() - } else { - clearTimeout(fastNowTimeout) - fastNowTimeout = setTimeout(onTimeout, 1e3) - if (fastNowTimeout.unref) { - fastNowTimeout.unref() + const redirectHandler = new RedirectHandler(dispatch, maxRedirections, opts, handler) + opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting. + return dispatch(opts, redirectHandler) } } } -class Timeout { - constructor (callback, delay, opaque) { - this.callback = callback - this.delay = delay - this.opaque = opaque +module.exports = createRedirectInterceptor - // -2 not in timer list - // -1 in timer list but inactive - // 0 in timer list waiting for time - // > 0 in timer list waiting for time to expire - this.state = -2 - this.refresh() - } +/***/ }), - refresh () { - if (this.state === -2) { - fastTimers.push(this) - if (!fastNowTimeout || fastTimers.length === 1) { - refreshTimeout() - } - } +/***/ 953: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - this.state = 0 - } +"use strict"; - clear () { - this.state = -1 - } +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SPECIAL_HEADERS = exports.HEADER_STATE = exports.MINOR = exports.MAJOR = exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS = exports.TOKEN = exports.STRICT_TOKEN = exports.HEX = exports.URL_CHAR = exports.STRICT_URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.NUM = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.FINISH = exports.H_METHOD_MAP = exports.METHOD_MAP = exports.METHODS_RTSP = exports.METHODS_ICE = exports.METHODS_HTTP = exports.METHODS = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0; +const utils_1 = __nccwpck_require__(1891); +// C headers +var ERROR; +(function (ERROR) { + ERROR[ERROR["OK"] = 0] = "OK"; + ERROR[ERROR["INTERNAL"] = 1] = "INTERNAL"; + ERROR[ERROR["STRICT"] = 2] = "STRICT"; + ERROR[ERROR["LF_EXPECTED"] = 3] = "LF_EXPECTED"; + ERROR[ERROR["UNEXPECTED_CONTENT_LENGTH"] = 4] = "UNEXPECTED_CONTENT_LENGTH"; + ERROR[ERROR["CLOSED_CONNECTION"] = 5] = "CLOSED_CONNECTION"; + ERROR[ERROR["INVALID_METHOD"] = 6] = "INVALID_METHOD"; + ERROR[ERROR["INVALID_URL"] = 7] = "INVALID_URL"; + ERROR[ERROR["INVALID_CONSTANT"] = 8] = "INVALID_CONSTANT"; + ERROR[ERROR["INVALID_VERSION"] = 9] = "INVALID_VERSION"; + ERROR[ERROR["INVALID_HEADER_TOKEN"] = 10] = "INVALID_HEADER_TOKEN"; + ERROR[ERROR["INVALID_CONTENT_LENGTH"] = 11] = "INVALID_CONTENT_LENGTH"; + ERROR[ERROR["INVALID_CHUNK_SIZE"] = 12] = "INVALID_CHUNK_SIZE"; + ERROR[ERROR["INVALID_STATUS"] = 13] = "INVALID_STATUS"; + ERROR[ERROR["INVALID_EOF_STATE"] = 14] = "INVALID_EOF_STATE"; + ERROR[ERROR["INVALID_TRANSFER_ENCODING"] = 15] = "INVALID_TRANSFER_ENCODING"; + ERROR[ERROR["CB_MESSAGE_BEGIN"] = 16] = "CB_MESSAGE_BEGIN"; + ERROR[ERROR["CB_HEADERS_COMPLETE"] = 17] = "CB_HEADERS_COMPLETE"; + ERROR[ERROR["CB_MESSAGE_COMPLETE"] = 18] = "CB_MESSAGE_COMPLETE"; + ERROR[ERROR["CB_CHUNK_HEADER"] = 19] = "CB_CHUNK_HEADER"; + ERROR[ERROR["CB_CHUNK_COMPLETE"] = 20] = "CB_CHUNK_COMPLETE"; + ERROR[ERROR["PAUSED"] = 21] = "PAUSED"; + ERROR[ERROR["PAUSED_UPGRADE"] = 22] = "PAUSED_UPGRADE"; + ERROR[ERROR["PAUSED_H2_UPGRADE"] = 23] = "PAUSED_H2_UPGRADE"; + ERROR[ERROR["USER"] = 24] = "USER"; +})(ERROR = exports.ERROR || (exports.ERROR = {})); +var TYPE; +(function (TYPE) { + TYPE[TYPE["BOTH"] = 0] = "BOTH"; + TYPE[TYPE["REQUEST"] = 1] = "REQUEST"; + TYPE[TYPE["RESPONSE"] = 2] = "RESPONSE"; +})(TYPE = exports.TYPE || (exports.TYPE = {})); +var FLAGS; +(function (FLAGS) { + FLAGS[FLAGS["CONNECTION_KEEP_ALIVE"] = 1] = "CONNECTION_KEEP_ALIVE"; + FLAGS[FLAGS["CONNECTION_CLOSE"] = 2] = "CONNECTION_CLOSE"; + FLAGS[FLAGS["CONNECTION_UPGRADE"] = 4] = "CONNECTION_UPGRADE"; + FLAGS[FLAGS["CHUNKED"] = 8] = "CHUNKED"; + FLAGS[FLAGS["UPGRADE"] = 16] = "UPGRADE"; + FLAGS[FLAGS["CONTENT_LENGTH"] = 32] = "CONTENT_LENGTH"; + FLAGS[FLAGS["SKIPBODY"] = 64] = "SKIPBODY"; + FLAGS[FLAGS["TRAILING"] = 128] = "TRAILING"; + // 1 << 8 is unused + FLAGS[FLAGS["TRANSFER_ENCODING"] = 512] = "TRANSFER_ENCODING"; +})(FLAGS = exports.FLAGS || (exports.FLAGS = {})); +var LENIENT_FLAGS; +(function (LENIENT_FLAGS) { + LENIENT_FLAGS[LENIENT_FLAGS["HEADERS"] = 1] = "HEADERS"; + LENIENT_FLAGS[LENIENT_FLAGS["CHUNKED_LENGTH"] = 2] = "CHUNKED_LENGTH"; + LENIENT_FLAGS[LENIENT_FLAGS["KEEP_ALIVE"] = 4] = "KEEP_ALIVE"; +})(LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})); +var METHODS; +(function (METHODS) { + METHODS[METHODS["DELETE"] = 0] = "DELETE"; + METHODS[METHODS["GET"] = 1] = "GET"; + METHODS[METHODS["HEAD"] = 2] = "HEAD"; + METHODS[METHODS["POST"] = 3] = "POST"; + METHODS[METHODS["PUT"] = 4] = "PUT"; + /* pathological */ + METHODS[METHODS["CONNECT"] = 5] = "CONNECT"; + METHODS[METHODS["OPTIONS"] = 6] = "OPTIONS"; + METHODS[METHODS["TRACE"] = 7] = "TRACE"; + /* WebDAV */ + METHODS[METHODS["COPY"] = 8] = "COPY"; + METHODS[METHODS["LOCK"] = 9] = "LOCK"; + METHODS[METHODS["MKCOL"] = 10] = "MKCOL"; + METHODS[METHODS["MOVE"] = 11] = "MOVE"; + METHODS[METHODS["PROPFIND"] = 12] = "PROPFIND"; + METHODS[METHODS["PROPPATCH"] = 13] = "PROPPATCH"; + METHODS[METHODS["SEARCH"] = 14] = "SEARCH"; + METHODS[METHODS["UNLOCK"] = 15] = "UNLOCK"; + METHODS[METHODS["BIND"] = 16] = "BIND"; + METHODS[METHODS["REBIND"] = 17] = "REBIND"; + METHODS[METHODS["UNBIND"] = 18] = "UNBIND"; + METHODS[METHODS["ACL"] = 19] = "ACL"; + /* subversion */ + METHODS[METHODS["REPORT"] = 20] = "REPORT"; + METHODS[METHODS["MKACTIVITY"] = 21] = "MKACTIVITY"; + METHODS[METHODS["CHECKOUT"] = 22] = "CHECKOUT"; + METHODS[METHODS["MERGE"] = 23] = "MERGE"; + /* upnp */ + METHODS[METHODS["M-SEARCH"] = 24] = "M-SEARCH"; + METHODS[METHODS["NOTIFY"] = 25] = "NOTIFY"; + METHODS[METHODS["SUBSCRIBE"] = 26] = "SUBSCRIBE"; + METHODS[METHODS["UNSUBSCRIBE"] = 27] = "UNSUBSCRIBE"; + /* RFC-5789 */ + METHODS[METHODS["PATCH"] = 28] = "PATCH"; + METHODS[METHODS["PURGE"] = 29] = "PURGE"; + /* CalDAV */ + METHODS[METHODS["MKCALENDAR"] = 30] = "MKCALENDAR"; + /* RFC-2068, section 19.6.1.2 */ + METHODS[METHODS["LINK"] = 31] = "LINK"; + METHODS[METHODS["UNLINK"] = 32] = "UNLINK"; + /* icecast */ + METHODS[METHODS["SOURCE"] = 33] = "SOURCE"; + /* RFC-7540, section 11.6 */ + METHODS[METHODS["PRI"] = 34] = "PRI"; + /* RFC-2326 RTSP */ + METHODS[METHODS["DESCRIBE"] = 35] = "DESCRIBE"; + METHODS[METHODS["ANNOUNCE"] = 36] = "ANNOUNCE"; + METHODS[METHODS["SETUP"] = 37] = "SETUP"; + METHODS[METHODS["PLAY"] = 38] = "PLAY"; + METHODS[METHODS["PAUSE"] = 39] = "PAUSE"; + METHODS[METHODS["TEARDOWN"] = 40] = "TEARDOWN"; + METHODS[METHODS["GET_PARAMETER"] = 41] = "GET_PARAMETER"; + METHODS[METHODS["SET_PARAMETER"] = 42] = "SET_PARAMETER"; + METHODS[METHODS["REDIRECT"] = 43] = "REDIRECT"; + METHODS[METHODS["RECORD"] = 44] = "RECORD"; + /* RAOP */ + METHODS[METHODS["FLUSH"] = 45] = "FLUSH"; +})(METHODS = exports.METHODS || (exports.METHODS = {})); +exports.METHODS_HTTP = [ + METHODS.DELETE, + METHODS.GET, + METHODS.HEAD, + METHODS.POST, + METHODS.PUT, + METHODS.CONNECT, + METHODS.OPTIONS, + METHODS.TRACE, + METHODS.COPY, + METHODS.LOCK, + METHODS.MKCOL, + METHODS.MOVE, + METHODS.PROPFIND, + METHODS.PROPPATCH, + METHODS.SEARCH, + METHODS.UNLOCK, + METHODS.BIND, + METHODS.REBIND, + METHODS.UNBIND, + METHODS.ACL, + METHODS.REPORT, + METHODS.MKACTIVITY, + METHODS.CHECKOUT, + METHODS.MERGE, + METHODS['M-SEARCH'], + METHODS.NOTIFY, + METHODS.SUBSCRIBE, + METHODS.UNSUBSCRIBE, + METHODS.PATCH, + METHODS.PURGE, + METHODS.MKCALENDAR, + METHODS.LINK, + METHODS.UNLINK, + METHODS.PRI, + // TODO(indutny): should we allow it with HTTP? + METHODS.SOURCE, +]; +exports.METHODS_ICE = [ + METHODS.SOURCE, +]; +exports.METHODS_RTSP = [ + METHODS.OPTIONS, + METHODS.DESCRIBE, + METHODS.ANNOUNCE, + METHODS.SETUP, + METHODS.PLAY, + METHODS.PAUSE, + METHODS.TEARDOWN, + METHODS.GET_PARAMETER, + METHODS.SET_PARAMETER, + METHODS.REDIRECT, + METHODS.RECORD, + METHODS.FLUSH, + // For AirPlay + METHODS.GET, + METHODS.POST, +]; +exports.METHOD_MAP = utils_1.enumToMap(METHODS); +exports.H_METHOD_MAP = {}; +Object.keys(exports.METHOD_MAP).forEach((key) => { + if (/^H/.test(key)) { + exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key]; + } +}); +var FINISH; +(function (FINISH) { + FINISH[FINISH["SAFE"] = 0] = "SAFE"; + FINISH[FINISH["SAFE_WITH_CB"] = 1] = "SAFE_WITH_CB"; + FINISH[FINISH["UNSAFE"] = 2] = "UNSAFE"; +})(FINISH = exports.FINISH || (exports.FINISH = {})); +exports.ALPHA = []; +for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { + // Upper case + exports.ALPHA.push(String.fromCharCode(i)); + // Lower case + exports.ALPHA.push(String.fromCharCode(i + 0x20)); +} +exports.NUM_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, +}; +exports.HEX_MAP = { + 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, + 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, + A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF, + a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf, +}; +exports.NUM = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', +]; +exports.ALPHANUM = exports.ALPHA.concat(exports.NUM); +exports.MARK = ['-', '_', '.', '!', '~', '*', '\'', '(', ')']; +exports.USERINFO_CHARS = exports.ALPHANUM + .concat(exports.MARK) + .concat(['%', ';', ':', '&', '=', '+', '$', ',']); +// TODO(indutny): use RFC +exports.STRICT_URL_CHAR = [ + '!', '"', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + ':', ';', '<', '=', '>', + '@', '[', '\\', ']', '^', '_', + '`', + '{', '|', '}', '~', +].concat(exports.ALPHANUM); +exports.URL_CHAR = exports.STRICT_URL_CHAR + .concat(['\t', '\f']); +// All characters with 0x80 bit set to 1 +for (let i = 0x80; i <= 0xff; i++) { + exports.URL_CHAR.push(i); } - -module.exports = { - setTimeout (callback, delay, opaque) { - return delay < 1e3 - ? setTimeout(callback, delay, opaque) - : new Timeout(callback, delay, opaque) - }, - clearTimeout (timeout) { - if (timeout instanceof Timeout) { - timeout.clear() - } else { - clearTimeout(timeout) +exports.HEX = exports.NUM.concat(['a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F']); +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +exports.STRICT_TOKEN = [ + '!', '#', '$', '%', '&', '\'', + '*', '+', '-', '.', + '^', '_', '`', + '|', '~', +].concat(exports.ALPHANUM); +exports.TOKEN = exports.STRICT_TOKEN.concat([' ']); +/* + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + */ +exports.HEADER_CHARS = ['\t']; +for (let i = 32; i <= 255; i++) { + if (i !== 127) { + exports.HEADER_CHARS.push(i); } - } } - +// ',' = \x44 +exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter((c) => c !== 44); +exports.MAJOR = exports.NUM_MAP; +exports.MINOR = exports.MAJOR; +var HEADER_STATE; +(function (HEADER_STATE) { + HEADER_STATE[HEADER_STATE["GENERAL"] = 0] = "GENERAL"; + HEADER_STATE[HEADER_STATE["CONNECTION"] = 1] = "CONNECTION"; + HEADER_STATE[HEADER_STATE["CONTENT_LENGTH"] = 2] = "CONTENT_LENGTH"; + HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING"] = 3] = "TRANSFER_ENCODING"; + HEADER_STATE[HEADER_STATE["UPGRADE"] = 4] = "UPGRADE"; + HEADER_STATE[HEADER_STATE["CONNECTION_KEEP_ALIVE"] = 5] = "CONNECTION_KEEP_ALIVE"; + HEADER_STATE[HEADER_STATE["CONNECTION_CLOSE"] = 6] = "CONNECTION_CLOSE"; + HEADER_STATE[HEADER_STATE["CONNECTION_UPGRADE"] = 7] = "CONNECTION_UPGRADE"; + HEADER_STATE[HEADER_STATE["TRANSFER_ENCODING_CHUNKED"] = 8] = "TRANSFER_ENCODING_CHUNKED"; +})(HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {})); +exports.SPECIAL_HEADERS = { + 'connection': HEADER_STATE.CONNECTION, + 'content-length': HEADER_STATE.CONTENT_LENGTH, + 'proxy-connection': HEADER_STATE.CONNECTION, + 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, + 'upgrade': HEADER_STATE.UPGRADE, +}; +//# sourceMappingURL=constants.js.map /***/ }), -/***/ 5354: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - -"use strict"; - - -const diagnosticsChannel = __nccwpck_require__(7643) -const { uid, states } = __nccwpck_require__(9188) -const { - kReadyState, - kSentClose, - kByteParser, - kReceivedClose -} = __nccwpck_require__(7578) -const { fireEvent, failWebsocketConnection } = __nccwpck_require__(5515) -const { CloseEvent } = __nccwpck_require__(2611) -const { makeRequest } = __nccwpck_require__(8359) -const { fetching } = __nccwpck_require__(4881) -const { Headers } = __nccwpck_require__(554) -const { getGlobalDispatcher } = __nccwpck_require__(1892) -const { kHeadersList } = __nccwpck_require__(2785) - -const channels = {} -channels.open = diagnosticsChannel.channel('undici:websocket:open') -channels.close = diagnosticsChannel.channel('undici:websocket:close') -channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') - -/** @type {import('crypto')} */ -let crypto -try { - crypto = __nccwpck_require__(6113) -} catch { - -} - -/** - * @see https://websockets.spec.whatwg.org/#concept-websocket-establish - * @param {URL} url - * @param {string|string[]} protocols - * @param {import('./websocket').WebSocket} ws - * @param {(response: any) => void} onEstablish - * @param {Partial} options - */ -function establishWebSocketConnection (url, protocols, ws, onEstablish, options) { - // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s - // scheme is "ws", and to "https" otherwise. - const requestURL = url - - requestURL.protocol = url.protocol === 'ws:' ? 'http:' : 'https:' - - // 2. Let request be a new request, whose URL is requestURL, client is client, - // service-workers mode is "none", referrer is "no-referrer", mode is - // "websocket", credentials mode is "include", cache mode is "no-store" , - // and redirect mode is "error". - const request = makeRequest({ - urlList: [requestURL], - serviceWorkers: 'none', - referrer: 'no-referrer', - mode: 'websocket', - credentials: 'include', - cache: 'no-store', - redirect: 'error' - }) - - // Note: undici extension, allow setting custom headers. - if (options.headers) { - const headersList = new Headers(options.headers)[kHeadersList] - - request.headersList = headersList - } - - // 3. Append (`Upgrade`, `websocket`) to request’s header list. - // 4. Append (`Connection`, `Upgrade`) to request’s header list. - // Note: both of these are handled by undici currently. - // https://github.com/nodejs/undici/blob/68c269c4144c446f3f1220951338daef4a6b5ec4/lib/client.js#L1397 - - // 5. Let keyValue be a nonce consisting of a randomly selected - // 16-byte value that has been forgiving-base64-encoded and - // isomorphic encoded. - const keyValue = crypto.randomBytes(16).toString('base64') - - // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s - // header list. - request.headersList.append('sec-websocket-key', keyValue) - - // 7. Append (`Sec-WebSocket-Version`, `13`) to request’s - // header list. - request.headersList.append('sec-websocket-version', '13') - - // 8. For each protocol in protocols, combine - // (`Sec-WebSocket-Protocol`, protocol) in request’s header - // list. - for (const protocol of protocols) { - request.headersList.append('sec-websocket-protocol', protocol) - } - - // 9. Let permessageDeflate be a user-agent defined - // "permessage-deflate" extension header value. - // https://github.com/mozilla/gecko-dev/blob/ce78234f5e653a5d3916813ff990f053510227bc/netwerk/protocol/websocket/WebSocketChannel.cpp#L2673 - // TODO: enable once permessage-deflate is supported - const permessageDeflate = '' // 'permessage-deflate; 15' +/***/ 1145: +/***/ ((module) => { - // 10. Append (`Sec-WebSocket-Extensions`, permessageDeflate) to - // request’s header list. - // request.headersList.append('sec-websocket-extensions', permessageDeflate) +module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ADcDACAAQShqQgA3AwAgAEEgakIANwMAIABBEGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvk8wEDDn8DfgR/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCHCIQQX9qDt0B2gEB2QECAwQFBgcICQoLDA0O2AEPENcBERLWARMUFRYXGBkaG+AB3wEcHR7VAR8gISIjJCXUASYnKCkqKyzTAdIBLS7RAdABLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVG2wFHSElKzwHOAUvNAUzMAU1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4ABgQGCAYMBhAGFAYYBhwGIAYkB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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FCAAIBA2AgxBACEQDLIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDLEBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxRCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLABCyAAQQA2AhwgACABNgIUIABBxoqAgAA2AhAgAEEHNgIMQQAhEAyvAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAyuAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAytAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMTQsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAysAQsgAEEANgIcIAAgATYCFCAAQdyIgIAANgIQIABBBzYCDEEAIRAMqwELIBBBP0cNASABQQFqIQELQQUhEAyQAQtBACEQIABBADYCHCAAIAE2AhQgAEH9koCAADYCECAAQQc2AgwMqAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMpwELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMpgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEYLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMpQELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0gA2AhwgACAUNgIUIAAgATYCDEEAIRAMpAELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0wA2AhwgACAUNgIUIAAgATYCDEEAIRAMowELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDEMLIABB5QA2AhwgACAUNgIUIAAgATYCDEEAIRAMogELIABBADYCHCAAIBQ2AhQgAEHDj4CAADYCECAAQQc2AgxBACEQDKEBCyAAQQA2AhwgACABNgIUIABBw4+AgAA2AhAgAEEHNgIMQQAhEAygAQtBACEQIABBADYCHCAAIBQ2AhQgAEGMnICAADYCECAAQQc2AgwMnwELIABBADYCHCAAIBQ2AhQgAEGMnICAADYCECAAQQc2AgxBACEQDJ4BCyAAQQA2AhwgACAUNgIUIABB/pGAgAA2AhAgAEEHNgIMQQAhEAydAQsgAEEANgIcIAAgATYCFCAAQY6bgIAANgIQIABBBjYCDEEAIRAMnAELIBBBFUYNVyAAQQA2AhwgACABNgIUIABBzI6AgAA2AhAgAEEgNgIMQQAhEAybAQsgAEEANgIAIBBBAWohAUEkIRALIAAgEDoAKSAAKAIEIRAgAEEANgIEIAAgECABEKuAgIAAIhANVCABIQEMPgsgAEEANgIAC0EAIRAgAEEANgIcIAAgBDYCFCAAQfGbgIAANgIQIABBBjYCDAyXAQsgAUEVRg1QIABBADYCHCAAIAU2AhQgAEHwjICAADYCECAAQRs2AgxBACEQDJYBCyAAKAIEIQUgAEEANgIEIAAgBSAQEKmAgIAAIgUNASAQQQFqIQULQa0BIRAMewsgAEHBATYCHCAAIAU2AgwgACAQQQFqNgIUQQAhEAyTAQsgACgCBCEGIABBADYCBCAAIAYgEBCpgICAACIGDQEgEEEBaiEGC0GuASEQDHgLIABBwgE2AhwgACAGNgIMIAAgEEEBajYCFEEAIRAMkAELIABBADYCHCAAIAc2AhQgAEGXi4CAADYCECAAQQ02AgxBACEQDI8BCyAAQQA2AhwgACAINgIUIABB45CAgAA2AhAgAEEJNgIMQQAhEAyOAQsgAEEANgIcIAAgCDYCFCAAQZSNgIAANgIQIABBITYCDEEAIRAMjQELQQEhFkEAIRdBACEUQQEhEAsgACAQOgArIAlBAWohCAJAAkAgAC0ALUEQcQ0AAkACQAJAIAAtACoOAwEAAgQLIBZFDQMMAgsgFA0BDAILIBdFDQELIAAoAgQhECAAQQA2AgQgACAQIAgQrYCAgAAiEEUNPSAAQckBNgIcIAAgCDYCFCAAIBA2AgxBACEQDIwBCyAAKAIEIQQgAEEANgIEIAAgBCAIEK2AgIAAIgRFDXYgAEHKATYCHCAAIAg2AhQgACAENgIMQQAhEAyLAQsgACgCBCEEIABBADYCBCAAIAQgCRCtgICAACIERQ10IABBywE2AhwgACAJNgIUIAAgBDYCDEEAIRAMigELIAAoAgQhBCAAQQA2AgQgACAEIAoQrYCAgAAiBEUNciAAQc0BNgIcIAAgCjYCFCAAIAQ2AgxBACEQDIkBCwJAIAstAABBUGoiEEH/AXFBCk8NACAAIBA6ACogC0EBaiEKQbYBIRAMcAsgACgCBCEEIABBADYCBCAAIAQgCxCtgICAACIERQ1wIABBzwE2AhwgACALNgIUIAAgBDYCDEEAIRAMiAELIABBADYCHCAAIAQ2AhQgAEGQs4CAADYCECAAQQg2AgwgAEEANgIAQQAhEAyHAQsgAUEVRg0/IABBADYCHCAAIAw2AhQgAEHMjoCAADYCECAAQSA2AgxBACEQDIYBCyAAQYEEOwEoIAAoAgQhECAAQgA3AwAgACAQIAxBAWoiDBCrgICAACIQRQ04IABB0wE2AhwgACAMNgIUIAAgEDYCDEEAIRAMhQELIABBADYCAAtBACEQIABBADYCHCAAIAQ2AhQgAEHYm4CAADYCECAAQQg2AgwMgwELIAAoAgQhECAAQgA3AwAgACAQIAtBAWoiCxCrgICAACIQDQFBxgEhEAxpCyAAQQI6ACgMVQsgAEHVATYCHCAAIAs2AhQgACAQNgIMQQAhEAyAAQsgEEEVRg03IABBADYCHCAAIAQ2AhQgAEGkjICAADYCECAAQRA2AgxBACEQDH8LIAAtADRBAUcNNCAAIAQgAhC8gICAACIQRQ00IBBBFUcNNSAAQdwBNgIcIAAgBDYCFCAAQdWWgIAANgIQIABBFTYCDEEAIRAMfgtBACEQIABBADYCHCAAQa+LgIAANgIQIABBAjYCDCAAIBRBAWo2AhQMfQtBACEQDGMLQQIhEAxiC0ENIRAMYQtBDyEQDGALQSUhEAxfC0ETIRAMXgtBFSEQDF0LQRYhEAxcC0EXIRAMWwtBGCEQDFoLQRkhEAxZC0EaIRAMWAtBGyEQDFcLQRwhEAxWC0EdIRAMVQtBHyEQDFQLQSEhEAxTC0EjIRAMUgtBxgAhEAxRC0EuIRAMUAtBLyEQDE8LQTshEAxOC0E9IRAMTQtByAAhEAxMC0HJACEQDEsLQcsAIRAMSgtBzAAhEAxJC0HOACEQDEgLQdEAIRAMRwtB1QAhEAxGC0HYACEQDEULQdkAIRAMRAtB2wAhEAxDC0HkACEQDEILQeUAIRAMQQtB8QAhEAxAC0H0ACEQDD8LQY0BIRAMPgtBlwEhEAw9C0GpASEQDDwLQawBIRAMOwtBwAEhEAw6C0G5ASEQDDkLQa8BIRAMOAtBsQEhEAw3C0GyASEQDDYLQbQBIRAMNQtBtQEhEAw0C0G6ASEQDDMLQb0BIRAMMgtBvwEhEAwxC0HBASEQDDALIABBADYCHCAAIAQ2AhQgAEHpi4CAADYCECAAQR82AgxBACEQDEgLIABB2wE2AhwgACAENgIUIABB+paAgAA2AhAgAEEVNgIMQQAhEAxHCyAAQfgANgIcIAAgDDYCFCAAQcqYgIAANgIQIABBFTYCDEEAIRAMRgsgAEHRADYCHCAAIAU2AhQgAEGwl4CAADYCECAAQRU2AgxBACEQDEULIABB+QA2AhwgACABNgIUIAAgEDYCDEEAIRAMRAsgAEH4ADYCHCAAIAE2AhQgAEHKmICAADYCECAAQRU2AgxBACEQDEMLIABB5AA2AhwgACABNgIUIABB45eAgAA2AhAgAEEVNgIMQQAhEAxCCyAAQdcANgIcIAAgATYCFCAAQcmXgIAANgIQIABBFTYCDEEAIRAMQQsgAEEANgIcIAAgATYCFCAAQbmNgIAANgIQIABBGjYCDEEAIRAMQAsgAEHCADYCHCAAIAE2AhQgAEHjmICAADYCECAAQRU2AgxBACEQDD8LIABBADYCBCAAIA8gDxCxgICAACIERQ0BIABBOjYCHCAAIAQ2AgwgACAPQQFqNgIUQQAhEAw+CyAAKAIEIQQgAEEANgIEAkAgACAEIAEQsYCAgAAiBEUNACAAQTs2AhwgACAENgIMIAAgAUEBajYCFEEAIRAMPgsgAUEBaiEBDC0LIA9BAWohAQwtCyAAQQA2AhwgACAPNgIUIABB5JKAgAA2AhAgAEEENgIMQQAhEAw7CyAAQTY2AhwgACAENgIUIAAgAjYCDEEAIRAMOgsgAEEuNgIcIAAgDjYCFCAAIAQ2AgxBACEQDDkLIABB0AA2AhwgACABNgIUIABBkZiAgAA2AhAgAEEVNgIMQQAhEAw4CyANQQFqIQEMLAsgAEEVNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMNgsgAEEbNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMNQsgAEEPNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMNAsgAEELNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMMwsgAEEaNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMMgsgAEELNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMMQsgAEEKNgIcIAAgATYCFCAAQeSWgIAANgIQIABBFTYCDEEAIRAMMAsgAEEeNgIcIAAgATYCFCAAQfmXgIAANgIQIABBFTYCDEEAIRAMLwsgAEEANgIcIAAgEDYCFCAAQdqNgIAANgIQIABBFDYCDEEAIRAMLgsgAEEENgIcIAAgATYCFCAAQbCYgIAANgIQIABBFTYCDEEAIRAMLQsgAEEANgIAIAtBAWohCwtBuAEhEAwSCyAAQQA2AgAgEEEBaiEBQfUAIRAMEQsgASEBAkAgAC0AKUEFRw0AQeMAIRAMEQtB4gAhEAwQC0EAIRAgAEEANgIcIABB5JGAgAA2AhAgAEEHNgIMIAAgFEEBajYCFAwoCyAAQQA2AgAgF0EBaiEBQcAAIRAMDgtBASEBCyAAIAE6ACwgAEEANgIAIBdBAWohAQtBKCEQDAsLIAEhAQtBOCEQDAkLAkAgASIPIAJGDQADQAJAIA8tAABBgL6AgABqLQAAIgFBAUYNACABQQJHDQMgD0EBaiEBDAQLIA9BAWoiDyACRw0AC0E+IRAMIgtBPiEQDCELIABBADoALCAPIQEMAQtBCyEQDAYLQTohEAwFCyABQQFqIQFBLSEQDAQLIAAgAToALCAAQQA2AgAgFkEBaiEBQQwhEAwDCyAAQQA2AgAgF0EBaiEBQQohEAwCCyAAQQA2AgALIABBADoALCANIQFBCSEQDAALC0EAIRAgAEEANgIcIAAgCzYCFCAAQc2QgIAANgIQIABBCTYCDAwXC0EAIRAgAEEANgIcIAAgCjYCFCAAQemKgIAANgIQIABBCTYCDAwWC0EAIRAgAEEANgIcIAAgCTYCFCAAQbeQgIAANgIQIABBCTYCDAwVC0EAIRAgAEEANgIcIAAgCDYCFCAAQZyRgIAANgIQIABBCTYCDAwUC0EAIRAgAEEANgIcIAAgATYCFCAAQc2QgIAANgIQIABBCTYCDAwTC0EAIRAgAEEANgIcIAAgATYCFCAAQemKgIAANgIQIABBCTYCDAwSC0EAIRAgAEEANgIcIAAgATYCFCAAQbeQgIAANgIQIABBCTYCDAwRC0EAIRAgAEEANgIcIAAgATYCFCAAQZyRgIAANgIQIABBCTYCDAwQC0EAIRAgAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwPC0EAIRAgAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwOC0EAIRAgAEEANgIcIAAgATYCFCAAQcCSgIAANgIQIABBCzYCDAwNC0EAIRAgAEEANgIcIAAgATYCFCAAQZWJgIAANgIQIABBCzYCDAwMC0EAIRAgAEEANgIcIAAgATYCFCAAQeGPgIAANgIQIABBCjYCDAwLC0EAIRAgAEEANgIcIAAgATYCFCAAQfuPgIAANgIQIABBCjYCDAwKC0EAIRAgAEEANgIcIAAgATYCFCAAQfGZgIAANgIQIABBAjYCDAwJC0EAIRAgAEEANgIcIAAgATYCFCAAQcSUgIAANgIQIABBAjYCDAwIC0EAIRAgAEEANgIcIAAgATYCFCAAQfKVgIAANgIQIABBAjYCDAwHCyAAQQI2AhwgACABNgIUIABBnJqAgAA2AhAgAEEWNgIMQQAhEAwGC0EBIRAMBQtB1AAhECABIgQgAkYNBCADQQhqIAAgBCACQdjCgIAAQQoQxYCAgAAgAygCDCEEIAMoAggOAwEEAgALEMqAgIAAAAsgAEEANgIcIABBtZqAgAA2AhAgAEEXNgIMIAAgBEEBajYCFEEAIRAMAgsgAEEANgIcIAAgBDYCFCAAQcqagIAANgIQIABBCTYCDEEAIRAMAQsCQCABIgQgAkcNAEEiIRAMAQsgAEGJgICAADYCCCAAIAQ2AgRBISEQCyADQRBqJICAgIAAIBALrwEBAn8gASgCACEGAkACQCACIANGDQAgBCAGaiEEIAYgA2ogAmshByACIAZBf3MgBWoiBmohBQNAAkAgAi0AACAELQAARg0AQQIhBAwDCwJAIAYNAEEAIQQgBSECDAMLIAZBf2ohBiAEQQFqIQQgAkEBaiICIANHDQALIAchBiADIQILIABBATYCACABIAY2AgAgACACNgIEDwsgAUEANgIAIAAgBDYCACAAIAI2AgQLCgAgABDHgICAAAvyNgELfyOAgICAAEEQayIBJICAgIAAAkBBACgCoNCAgAANAEEAEMuAgIAAQYDUhIAAayICQdkASQ0AQQAhAwJAQQAoAuDTgIAAIgQNAEEAQn83AuzTgIAAQQBCgICEgICAwAA3AuTTgIAAQQAgAUEIakFwcUHYqtWqBXMiBDYC4NOAgABBAEEANgL004CAAEEAQQA2AsTTgIAAC0EAIAI2AszTgIAAQQBBgNSEgAA2AsjTgIAAQQBBgNSEgAA2ApjQgIAAQQAgBDYCrNCAgABBAEF/NgKo0ICAAANAIANBxNCAgABqIANBuNCAgABqIgQ2AgAgBCADQbDQgIAAaiIFNgIAIANBvNCAgABqIAU2AgAgA0HM0ICAAGogA0HA0ICAAGoiBTYCACAFIAQ2AgAgA0HU0ICAAGogA0HI0ICAAGoiBDYCACAEIAU2AgAgA0HQ0ICAAGogBDYCACADQSBqIgNBgAJHDQALQYDUhIAAQXhBgNSEgABrQQ9xQQBBgNSEgABBCGpBD3EbIgNqIgRBBGogAkFIaiIFIANrIgNBAXI2AgBBAEEAKALw04CAADYCpNCAgABBACADNgKU0ICAAEEAIAQ2AqDQgIAAQYDUhIAAIAVqQTg2AgQLAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB7AFLDQACQEEAKAKI0ICAACIGQRAgAEETakFwcSAAQQtJGyICQQN2IgR2IgNBA3FFDQACQAJAIANBAXEgBHJBAXMiBUEDdCIEQbDQgIAAaiIDIARBuNCAgABqKAIAIgQoAggiAkcNAEEAIAZBfiAFd3E2AojQgIAADAELIAMgAjYCCCACIAM2AgwLIARBCGohAyAEIAVBA3QiBUEDcjYCBCAEIAVqIgQgBCgCBEEBcjYCBAwMCyACQQAoApDQgIAAIgdNDQECQCADRQ0AAkACQCADIAR0QQIgBHQiA0EAIANrcnEiA0EAIANrcUF/aiIDIANBDHZBEHEiA3YiBEEFdkEIcSIFIANyIAQgBXYiA0ECdkEEcSIEciADIAR2IgNBAXZBAnEiBHIgAyAEdiIDQQF2QQFxIgRyIAMgBHZqIgRBA3QiA0Gw0ICAAGoiBSADQbjQgIAAaigCACIDKAIIIgBHDQBBACAGQX4gBHdxIgY2AojQgIAADAELIAUgADYCCCAAIAU2AgwLIAMgAkEDcjYCBCADIARBA3QiBGogBCACayIFNgIAIAMgAmoiACAFQQFyNgIEAkAgB0UNACAHQXhxQbDQgIAAaiECQQAoApzQgIAAIQQCQAJAIAZBASAHQQN2dCIIcQ0AQQAgBiAIcjYCiNCAgAAgAiEIDAELIAIoAgghCAsgCCAENgIMIAIgBDYCCCAEIAI2AgwgBCAINgIICyADQQhqIQNBACAANgKc0ICAAEEAIAU2ApDQgIAADAwLQQAoAozQgIAAIglFDQEgCUEAIAlrcUF/aiIDIANBDHZBEHEiA3YiBEEFdkEIcSIFIANyIAQgBXYiA0ECdkEEcSIEciADIAR2IgNBAXZBAnEiBHIgAyAEdiIDQQF2QQFxIgRyIAMgBHZqQQJ0QbjSgIAAaigCACIAKAIEQXhxIAJrIQQgACEFAkADQAJAIAUoAhAiAw0AIAVBFGooAgAiA0UNAgsgAygCBEF4cSACayIFIAQgBSAESSIFGyEEIAMgACAFGyEAIAMhBQwACwsgACgCGCEKAkAgACgCDCIIIABGDQAgACgCCCIDQQAoApjQgIAASRogCCADNgIIIAMgCDYCDAwLCwJAIABBFGoiBSgCACIDDQAgACgCECIDRQ0DIABBEGohBQsDQCAFIQsgAyIIQRRqIgUoAgAiAw0AIAhBEGohBSAIKAIQIgMNAAsgC0EANgIADAoLQX8hAiAAQb9/Sw0AIABBE2oiA0FwcSECQQAoAozQgIAAIgdFDQBBACELAkAgAkGAAkkNAEEfIQsgAkH///8HSw0AIANBCHYiAyADQYD+P2pBEHZBCHEiA3QiBCAEQYDgH2pBEHZBBHEiBHQiBSAFQYCAD2pBEHZBAnEiBXRBD3YgAyAEciAFcmsiA0EBdCACIANBFWp2QQFxckEcaiELC0EAIAJrIQQCQAJAAkACQCALQQJ0QbjSgIAAaigCACIFDQBBACEDQQAhCAwBC0EAIQMgAkEAQRkgC0EBdmsgC0EfRht0IQBBACEIA0ACQCAFKAIEQXhxIAJrIgYgBE8NACAGIQQgBSEIIAYNAEEAIQQgBSEIIAUhAwwDCyADIAVBFGooAgAiBiAGIAUgAEEddkEEcWpBEGooAgAiBUYbIAMgBhshAyAAQQF0IQAgBQ0ACwsCQCADIAhyDQBBACEIQQIgC3QiA0EAIANrciAHcSIDRQ0DIANBACADa3FBf2oiAyADQQx2QRBxIgN2IgVBBXZBCHEiACADciAFIAB2IgNBAnZBBHEiBXIgAyAFdiIDQQF2QQJxIgVyIAMgBXYiA0EBdkEBcSIFciADIAV2akECdEG40oCAAGooAgAhAwsgA0UNAQsDQCADKAIEQXhxIAJrIgYgBEkhAAJAIAMoAhAiBQ0AIANBFGooAgAhBQsgBiAEIAAbIQQgAyAIIAAbIQggBSEDIAUNAAsLIAhFDQAgBEEAKAKQ0ICAACACa08NACAIKAIYIQsCQCAIKAIMIgAgCEYNACAIKAIIIgNBACgCmNCAgABJGiAAIAM2AgggAyAANgIMDAkLAkAgCEEUaiIFKAIAIgMNACAIKAIQIgNFDQMgCEEQaiEFCwNAIAUhBiADIgBBFGoiBSgCACIDDQAgAEEQaiEFIAAoAhAiAw0ACyAGQQA2AgAMCAsCQEEAKAKQ0ICAACIDIAJJDQBBACgCnNCAgAAhBAJAAkAgAyACayIFQRBJDQAgBCACaiIAIAVBAXI2AgRBACAFNgKQ0ICAAEEAIAA2ApzQgIAAIAQgA2ogBTYCACAEIAJBA3I2AgQMAQsgBCADQQNyNgIEIAQgA2oiAyADKAIEQQFyNgIEQQBBADYCnNCAgABBAEEANgKQ0ICAAAsgBEEIaiEDDAoLAkBBACgClNCAgAAiACACTQ0AQQAoAqDQgIAAIgMgAmoiBCAAIAJrIgVBAXI2AgRBACAFNgKU0ICAAEEAIAQ2AqDQgIAAIAMgAkEDcjYCBCADQQhqIQMMCgsCQAJAQQAoAuDTgIAARQ0AQQAoAujTgIAAIQQMAQtBAEJ/NwLs04CAAEEAQoCAhICAgMAANwLk04CAAEEAIAFBDGpBcHFB2KrVqgVzNgLg04CAAEEAQQA2AvTTgIAAQQBBADYCxNOAgABBgIAEIQQLQQAhAwJAIAQgAkHHAGoiB2oiBkEAIARrIgtxIgggAksNAEEAQTA2AvjTgIAADAoLAkBBACgCwNOAgAAiA0UNAAJAQQAoArjTgIAAIgQgCGoiBSAETQ0AIAUgA00NAQtBACEDQQBBMDYC+NOAgAAMCgtBAC0AxNOAgABBBHENBAJAAkACQEEAKAKg0ICAACIERQ0AQcjTgIAAIQMDQAJAIAMoAgAiBSAESw0AIAUgAygCBGogBEsNAwsgAygCCCIDDQALC0EAEMuAgIAAIgBBf0YNBSAIIQYCQEEAKALk04CAACIDQX9qIgQgAHFFDQAgCCAAayAEIABqQQAgA2txaiEGCyAGIAJNDQUgBkH+////B0sNBQJAQQAoAsDTgIAAIgNFDQBBACgCuNOAgAAiBCAGaiIFIARNDQYgBSADSw0GCyAGEMuAgIAAIgMgAEcNAQwHCyAGIABrIAtxIgZB/v///wdLDQQgBhDLgICAACIAIAMoAgAgAygCBGpGDQMgACEDCwJAIANBf0YNACACQcgAaiAGTQ0AAkAgByAGa0EAKALo04CAACIEakEAIARrcSIEQf7///8HTQ0AIAMhAAwHCwJAIAQQy4CAgABBf0YNACAEIAZqIQYgAyEADAcLQQAgBmsQy4CAgAAaDAQLIAMhACADQX9HDQUMAwtBACEIDAcLQQAhAAwFCyAAQX9HDQILQQBBACgCxNOAgABBBHI2AsTTgIAACyAIQf7///8HSw0BIAgQy4CAgAAhAEEAEMuAgIAAIQMgAEF/Rg0BIANBf0YNASAAIANPDQEgAyAAayIGIAJBOGpNDQELQQBBACgCuNOAgAAgBmoiAzYCuNOAgAACQCADQQAoArzTgIAATQ0AQQAgAzYCvNOAgAALAkACQAJAAkBBACgCoNCAgAAiBEUNAEHI04CAACEDA0AgACADKAIAIgUgAygCBCIIakYNAiADKAIIIgMNAAwDCwsCQAJAQQAoApjQgIAAIgNFDQAgACADTw0BC0EAIAA2ApjQgIAAC0EAIQNBACAGNgLM04CAAEEAIAA2AsjTgIAAQQBBfzYCqNCAgABBAEEAKALg04CAADYCrNCAgABBAEEANgLU04CAAANAIANBxNCAgABqIANBuNCAgABqIgQ2AgAgBCADQbDQgIAAaiIFNgIAIANBvNCAgABqIAU2AgAgA0HM0ICAAGogA0HA0ICAAGoiBTYCACAFIAQ2AgAgA0HU0ICAAGogA0HI0ICAAGoiBDYCACAEIAU2AgAgA0HQ0ICAAGogBDYCACADQSBqIgNBgAJHDQALIABBeCAAa0EPcUEAIABBCGpBD3EbIgNqIgQgBkFIaiIFIANrIgNBAXI2AgRBAEEAKALw04CAADYCpNCAgABBACADNgKU0ICAAEEAIAQ2AqDQgIAAIAAgBWpBODYCBAwCCyADLQAMQQhxDQAgBCAFSQ0AIAQgAE8NACAEQXggBGtBD3FBACAEQQhqQQ9xGyIFaiIAQQAoApTQgIAAIAZqIgsgBWsiBUEBcjYCBCADIAggBmo2AgRBAEEAKALw04CAADYCpNCAgABBACAFNgKU0ICAAEEAIAA2AqDQgIAAIAQgC2pBODYCBAwBCwJAIABBACgCmNCAgAAiCE8NAEEAIAA2ApjQgIAAIAAhCAsgACAGaiEFQcjTgIAAIQMCQAJAAkACQAJAAkACQANAIAMoAgAgBUYNASADKAIIIgMNAAwCCwsgAy0ADEEIcUUNAQtByNOAgAAhAwNAAkAgAygCACIFIARLDQAgBSADKAIEaiIFIARLDQMLIAMoAgghAwwACwsgAyAANgIAIAMgAygCBCAGajYCBCAAQXggAGtBD3FBACAAQQhqQQ9xG2oiCyACQQNyNgIEIAVBeCAFa0EPcUEAIAVBCGpBD3EbaiIGIAsgAmoiAmshAwJAIAYgBEcNAEEAIAI2AqDQgIAAQQBBACgClNCAgAAgA2oiAzYClNCAgAAgAiADQQFyNgIEDAMLAkAgBkEAKAKc0ICAAEcNAEEAIAI2ApzQgIAAQQBBACgCkNCAgAAgA2oiAzYCkNCAgAAgAiADQQFyNgIEIAIgA2ogAzYCAAwDCwJAIAYoAgQiBEEDcUEBRw0AIARBeHEhBwJAAkAgBEH/AUsNACAGKAIIIgUgBEEDdiIIQQN0QbDQgIAAaiIARhoCQCAGKAIMIgQgBUcNAEEAQQAoAojQgIAAQX4gCHdxNgKI0ICAAAwCCyAEIABGGiAEIAU2AgggBSAENgIMDAELIAYoAhghCQJAAkAgBigCDCIAIAZGDQAgBigCCCIEIAhJGiAAIAQ2AgggBCAANgIMDAELAkAgBkEUaiIEKAIAIgUNACAGQRBqIgQoAgAiBQ0AQQAhAAwBCwNAIAQhCCAFIgBBFGoiBCgCACIFDQAgAEEQaiEEIAAoAhAiBQ0ACyAIQQA2AgALIAlFDQACQAJAIAYgBigCHCIFQQJ0QbjSgIAAaiIEKAIARw0AIAQgADYCACAADQFBAEEAKAKM0ICAAEF+IAV3cTYCjNCAgAAMAgsgCUEQQRQgCSgCECAGRhtqIAA2AgAgAEUNAQsgACAJNgIYAkAgBigCECIERQ0AIAAgBDYCECAEIAA2AhgLIAYoAhQiBEUNACAAQRRqIAQ2AgAgBCAANgIYCyAHIANqIQMgBiAHaiIGKAIEIQQLIAYgBEF+cTYCBCACIANqIAM2AgAgAiADQQFyNgIEAkAgA0H/AUsNACADQXhxQbDQgIAAaiEEAkACQEEAKAKI0ICAACIFQQEgA0EDdnQiA3ENAEEAIAUgA3I2AojQgIAAIAQhAwwBCyAEKAIIIQMLIAMgAjYCDCAEIAI2AgggAiAENgIMIAIgAzYCCAwDC0EfIQQCQCADQf///wdLDQAgA0EIdiIEIARBgP4/akEQdkEIcSIEdCIFIAVBgOAfakEQdkEEcSIFdCIAIABBgIAPakEQdkECcSIAdEEPdiAEIAVyIAByayIEQQF0IAMgBEEVanZBAXFyQRxqIQQLIAIgBDYCHCACQgA3AhAgBEECdEG40oCAAGohBQJAQQAoAozQgIAAIgBBASAEdCIIcQ0AIAUgAjYCAEEAIAAgCHI2AozQgIAAIAIgBTYCGCACIAI2AgggAiACNgIMDAMLIANBAEEZIARBAXZrIARBH0YbdCEEIAUoAgAhAANAIAAiBSgCBEF4cSADRg0CIARBHXYhACAEQQF0IQQgBSAAQQRxakEQaiIIKAIAIgANAAsgCCACNgIAIAIgBTYCGCACIAI2AgwgAiACNgIIDAILIABBeCAAa0EPcUEAIABBCGpBD3EbIgNqIgsgBkFIaiIIIANrIgNBAXI2AgQgACAIakE4NgIEIAQgBUE3IAVrQQ9xQQAgBUFJakEPcRtqQUFqIgggCCAEQRBqSRsiCEEjNgIEQQBBACgC8NOAgAA2AqTQgIAAQQAgAzYClNCAgABBACALNgKg0ICAACAIQRBqQQApAtDTgIAANwIAIAhBACkCyNOAgAA3AghBACAIQQhqNgLQ04CAAEEAIAY2AszTgIAAQQAgADYCyNOAgABBAEEANgLU04CAACAIQSRqIQMDQCADQQc2AgAgA0EEaiIDIAVJDQALIAggBEYNAyAIIAgoAgRBfnE2AgQgCCAIIARrIgA2AgAgBCAAQQFyNgIEAkAgAEH/AUsNACAAQXhxQbDQgIAAaiEDAkACQEEAKAKI0ICAACIFQQEgAEEDdnQiAHENAEEAIAUgAHI2AojQgIAAIAMhBQwBCyADKAIIIQULIAUgBDYCDCADIAQ2AgggBCADNgIMIAQgBTYCCAwEC0EfIQMCQCAAQf///wdLDQAgAEEIdiIDIANBgP4/akEQdkEIcSIDdCIFIAVBgOAfakEQdkEEcSIFdCIIIAhBgIAPakEQdkECcSIIdEEPdiADIAVyIAhyayIDQQF0IAAgA0EVanZBAXFyQRxqIQMLIAQgAzYCHCAEQgA3AhAgA0ECdEG40oCAAGohBQJAQQAoAozQgIAAIghBASADdCIGcQ0AIAUgBDYCAEEAIAggBnI2AozQgIAAIAQgBTYCGCAEIAQ2AgggBCAENgIMDAQLIABBAEEZIANBAXZrIANBH0YbdCEDIAUoAgAhCANAIAgiBSgCBEF4cSAARg0DIANBHXYhCCADQQF0IQMgBSAIQQRxakEQaiIGKAIAIggNAAsgBiAENgIAIAQgBTYCGCAEIAQ2AgwgBCAENgIIDAMLIAUoAggiAyACNgIMIAUgAjYCCCACQQA2AhggAiAFNgIMIAIgAzYCCAsgC0EIaiEDDAULIAUoAggiAyAENgIMIAUgBDYCCCAEQQA2AhggBCAFNgIMIAQgAzYCCAtBACgClNCAgAAiAyACTQ0AQQAoAqDQgIAAIgQgAmoiBSADIAJrIgNBAXI2AgRBACADNgKU0ICAAEEAIAU2AqDQgIAAIAQgAkEDcjYCBCAEQQhqIQMMAwtBACEDQQBBMDYC+NOAgAAMAgsCQCALRQ0AAkACQCAIIAgoAhwiBUECdEG40oCAAGoiAygCAEcNACADIAA2AgAgAA0BQQAgB0F+IAV3cSIHNgKM0ICAAAwCCyALQRBBFCALKAIQIAhGG2ogADYCACAARQ0BCyAAIAs2AhgCQCAIKAIQIgNFDQAgACADNgIQIAMgADYCGAsgCEEUaigCACIDRQ0AIABBFGogAzYCACADIAA2AhgLAkACQCAEQQ9LDQAgCCAEIAJqIgNBA3I2AgQgCCADaiIDIAMoAgRBAXI2AgQMAQsgCCACaiIAIARBAXI2AgQgCCACQQNyNgIEIAAgBGogBDYCAAJAIARB/wFLDQAgBEF4cUGw0ICAAGohAwJAAkBBACgCiNCAgAAiBUEBIARBA3Z0IgRxDQBBACAFIARyNgKI0ICAACADIQQMAQsgAygCCCEECyAEIAA2AgwgAyAANgIIIAAgAzYCDCAAIAQ2AggMAQtBHyEDAkAgBEH///8HSw0AIARBCHYiAyADQYD+P2pBEHZBCHEiA3QiBSAFQYDgH2pBEHZBBHEiBXQiAiACQYCAD2pBEHZBAnEiAnRBD3YgAyAFciACcmsiA0EBdCAEIANBFWp2QQFxckEcaiEDCyAAIAM2AhwgAEIANwIQIANBAnRBuNKAgABqIQUCQCAHQQEgA3QiAnENACAFIAA2AgBBACAHIAJyNgKM0ICAACAAIAU2AhggACAANgIIIAAgADYCDAwBCyAEQQBBGSADQQF2ayADQR9GG3QhAyAFKAIAIQICQANAIAIiBSgCBEF4cSAERg0BIANBHXYhAiADQQF0IQMgBSACQQRxakEQaiIGKAIAIgINAAsgBiAANgIAIAAgBTYCGCAAIAA2AgwgACAANgIIDAELIAUoAggiAyAANgIMIAUgADYCCCAAQQA2AhggACAFNgIMIAAgAzYCCAsgCEEIaiEDDAELAkAgCkUNAAJAAkAgACAAKAIcIgVBAnRBuNKAgABqIgMoAgBHDQAgAyAINgIAIAgNAUEAIAlBfiAFd3E2AozQgIAADAILIApBEEEUIAooAhAgAEYbaiAINgIAIAhFDQELIAggCjYCGAJAIAAoAhAiA0UNACAIIAM2AhAgAyAINgIYCyAAQRRqKAIAIgNFDQAgCEEUaiADNgIAIAMgCDYCGAsCQAJAIARBD0sNACAAIAQgAmoiA0EDcjYCBCAAIANqIgMgAygCBEEBcjYCBAwBCyAAIAJqIgUgBEEBcjYCBCAAIAJBA3I2AgQgBSAEaiAENgIAAkAgB0UNACAHQXhxQbDQgIAAaiECQQAoApzQgIAAIQMCQAJAQQEgB0EDdnQiCCAGcQ0AQQAgCCAGcjYCiNCAgAAgAiEIDAELIAIoAgghCAsgCCADNgIMIAIgAzYCCCADIAI2AgwgAyAINgIIC0EAIAU2ApzQgIAAQQAgBDYCkNCAgAALIABBCGohAwsgAUEQaiSAgICAACADCwoAIAAQyYCAgAAL4g0BB38CQCAARQ0AIABBeGoiASAAQXxqKAIAIgJBeHEiAGohAwJAIAJBAXENACACQQNxRQ0BIAEgASgCACICayIBQQAoApjQgIAAIgRJDQEgAiAAaiEAAkAgAUEAKAKc0ICAAEYNAAJAIAJB/wFLDQAgASgCCCIEIAJBA3YiBUEDdEGw0ICAAGoiBkYaAkAgASgCDCICIARHDQBBAEEAKAKI0ICAAEF+IAV3cTYCiNCAgAAMAwsgAiAGRhogAiAENgIIIAQgAjYCDAwCCyABKAIYIQcCQAJAIAEoAgwiBiABRg0AIAEoAggiAiAESRogBiACNgIIIAIgBjYCDAwBCwJAIAFBFGoiAigCACIEDQAgAUEQaiICKAIAIgQNAEEAIQYMAQsDQCACIQUgBCIGQRRqIgIoAgAiBA0AIAZBEGohAiAGKAIQIgQNAAsgBUEANgIACyAHRQ0BAkACQCABIAEoAhwiBEECdEG40oCAAGoiAigCAEcNACACIAY2AgAgBg0BQQBBACgCjNCAgABBfiAEd3E2AozQgIAADAMLIAdBEEEUIAcoAhAgAUYbaiAGNgIAIAZFDQILIAYgBzYCGAJAIAEoAhAiAkUNACAGIAI2AhAgAiAGNgIYCyABKAIUIgJFDQEgBkEUaiACNgIAIAIgBjYCGAwBCyADKAIEIgJBA3FBA0cNACADIAJBfnE2AgRBACAANgKQ0ICAACABIABqIAA2AgAgASAAQQFyNgIEDwsgASADTw0AIAMoAgQiAkEBcUUNAAJAAkAgAkECcQ0AAkAgA0EAKAKg0ICAAEcNAEEAIAE2AqDQgIAAQQBBACgClNCAgAAgAGoiADYClNCAgAAgASAAQQFyNgIEIAFBACgCnNCAgABHDQNBAEEANgKQ0ICAAEEAQQA2ApzQgIAADwsCQCADQQAoApzQgIAARw0AQQAgATYCnNCAgABBAEEAKAKQ0ICAACAAaiIANgKQ0ICAACABIABBAXI2AgQgASAAaiAANgIADwsgAkF4cSAAaiEAAkACQCACQf8BSw0AIAMoAggiBCACQQN2IgVBA3RBsNCAgABqIgZGGgJAIAMoAgwiAiAERw0AQQBBACgCiNCAgABBfiAFd3E2AojQgIAADAILIAIgBkYaIAIgBDYCCCAEIAI2AgwMAQsgAygCGCEHAkACQCADKAIMIgYgA0YNACADKAIIIgJBACgCmNCAgABJGiAGIAI2AgggAiAGNgIMDAELAkAgA0EUaiICKAIAIgQNACADQRBqIgIoAgAiBA0AQQAhBgwBCwNAIAIhBSAEIgZBFGoiAigCACIEDQAgBkEQaiECIAYoAhAiBA0ACyAFQQA2AgALIAdFDQACQAJAIAMgAygCHCIEQQJ0QbjSgIAAaiICKAIARw0AIAIgBjYCACAGDQFBAEEAKAKM0ICAAEF+IAR3cTYCjNCAgAAMAgsgB0EQQRQgBygCECADRhtqIAY2AgAgBkUNAQsgBiAHNgIYAkAgAygCECICRQ0AIAYgAjYCECACIAY2AhgLIAMoAhQiAkUNACAGQRRqIAI2AgAgAiAGNgIYCyABIABqIAA2AgAgASAAQQFyNgIEIAFBACgCnNCAgABHDQFBACAANgKQ0ICAAA8LIAMgAkF+cTYCBCABIABqIAA2AgAgASAAQQFyNgIECwJAIABB/wFLDQAgAEF4cUGw0ICAAGohAgJAAkBBACgCiNCAgAAiBEEBIABBA3Z0IgBxDQBBACAEIAByNgKI0ICAACACIQAMAQsgAigCCCEACyAAIAE2AgwgAiABNgIIIAEgAjYCDCABIAA2AggPC0EfIQICQCAAQf///wdLDQAgAEEIdiICIAJBgP4/akEQdkEIcSICdCIEIARBgOAfakEQdkEEcSIEdCIGIAZBgIAPakEQdkECcSIGdEEPdiACIARyIAZyayICQQF0IAAgAkEVanZBAXFyQRxqIQILIAEgAjYCHCABQgA3AhAgAkECdEG40oCAAGohBAJAAkBBACgCjNCAgAAiBkEBIAJ0IgNxDQAgBCABNgIAQQAgBiADcjYCjNCAgAAgASAENgIYIAEgATYCCCABIAE2AgwMAQsgAEEAQRkgAkEBdmsgAkEfRht0IQIgBCgCACEGAkADQCAGIgQoAgRBeHEgAEYNASACQR12IQYgAkEBdCECIAQgBkEEcWpBEGoiAygCACIGDQALIAMgATYCACABIAQ2AhggASABNgIMIAEgATYCCAwBCyAEKAIIIgAgATYCDCAEIAE2AgggAUEANgIYIAEgBDYCDCABIAA2AggLQQBBACgCqNCAgABBf2oiAUF/IAEbNgKo0ICAAAsLBAAAAAtOAAJAIAANAD8AQRB0DwsCQCAAQf//A3ENACAAQX9MDQACQCAAQRB2QAAiAEF/Rw0AQQBBMDYC+NOAgABBfw8LIABBEHQPCxDKgICAAAAL8gICA38BfgJAIAJFDQAgACABOgAAIAIgAGoiA0F/aiABOgAAIAJBA0kNACAAIAE6AAIgACABOgABIANBfWogAToAACADQX5qIAE6AAAgAkEHSQ0AIAAgAToAAyADQXxqIAE6AAAgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIFayICQSBJDQAgAa1CgYCAgBB+IQYgAyAFaiEBA0AgASAGNwMYIAEgBjcDECABIAY3AwggASAGNwMAIAFBIGohASACQWBqIgJBH0sNAAsLIAALC45IAQBBgAgLhkgBAAAAAgAAAAMAAAAAAAAAAAAAAAQAAAAFAAAAAAAAAAAAAAAGAAAABwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEludmFsaWQgY2hhciBpbiB1cmwgcXVlcnkAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9ib2R5AENvbnRlbnQtTGVuZ3RoIG92ZXJmbG93AENodW5rIHNpemUgb3ZlcmZsb3cAUmVzcG9uc2Ugb3ZlcmZsb3cASW52YWxpZCBtZXRob2QgZm9yIEhUVFAveC54IHJlcXVlc3QASW52YWxpZCBtZXRob2QgZm9yIFJUU1AveC54IHJlcXVlc3QARXhwZWN0ZWQgU09VUkNFIG1ldGhvZCBmb3IgSUNFL3gueCByZXF1ZXN0AEludmFsaWQgY2hhciBpbiB1cmwgZnJhZ21lbnQgc3RhcnQARXhwZWN0ZWQgZG90AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fc3RhdHVzAEludmFsaWQgcmVzcG9uc2Ugc3RhdHVzAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMAVXNlciBjYWxsYmFjayBlcnJvcgBgb25fcmVzZXRgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19oZWFkZXJgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8=' - // 11. Fetch request with useParallelQueue set to true, and - // processResponse given response being these steps: - const controller = fetching({ - request, - useParallelQueue: true, - dispatcher: options.dispatcher ?? getGlobalDispatcher(), - processResponse (response) { - // 1. If response is a network error or its status is not 101, - // fail the WebSocket connection. - if (response.type === 'error' || response.status !== 101) { - failWebsocketConnection(ws, 'Received network error or non-101 status code.') - return - } - // 2. If protocols is not the empty list and extracting header - // list values given `Sec-WebSocket-Protocol` and response’s - // header list results in null, failure, or the empty byte - // sequence, then fail the WebSocket connection. - if (protocols.length !== 0 && !response.headersList.get('Sec-WebSocket-Protocol')) { - failWebsocketConnection(ws, 'Server did not respond with sent protocols.') - return - } +/***/ }), - // 3. Follow the requirements stated step 2 to step 6, inclusive, - // of the last set of steps in section 4.1 of The WebSocket - // Protocol to validate response. This either results in fail - // the WebSocket connection or the WebSocket connection is - // established. +/***/ 5627: +/***/ ((module) => { - // 2. If the response lacks an |Upgrade| header field or the |Upgrade| - // header field contains a value that is not an ASCII case- - // insensitive match for the value "websocket", the client MUST - // _Fail the WebSocket Connection_. - if (response.headersList.get('Upgrade')?.toLowerCase() !== 'websocket') { - failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".') - return - } +module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJsbGh0dHBfc3RhdHVzX25hbWUAIRpsbGh0dHBfc2V0X2xlbmllbnRfaGVhZGVycwAiIWxsaHR0cF9zZXRfbGVuaWVudF9jaHVua2VkX2xlbmd0aAAjHWxsaHR0cF9zZXRfbGVuaWVudF9rZWVwX2FsaXZlACQkbGxodHRwX3NldF9sZW5pZW50X3RyYW5zZmVyX2VuY29kaW5nACUYbGxodHRwX21lc3NhZ2VfbmVlZHNfZW9mAD8JFwEAQQELEQECAwQFCwYHNTk3MS8tJyspCrLgAkUCAAsIABCIgICAAAsZACAAEMKAgIAAGiAAIAI2AjggACABOgAoCxwAIAAgAC8BMiAALQAuIAAQwYCAgAAQgICAgAALKgEBf0HAABDGgICAACIBEMKAgIAAGiABQYCIgIAANgI4IAEgADoAKCABCwoAIAAQyICAgAALBwAgAC0AKAsHACAALQAqCwcAIAAtACsLBwAgAC0AKQsHACAALwEyCwcAIAAtAC4LRQEEfyAAKAIYIQEgAC0ALSECIAAtACghAyAAKAI4IQQgABDCgICAABogACAENgI4IAAgAzoAKCAAIAI6AC0gACABNgIYCxEAIAAgASABIAJqEMOAgIAACxAAIABBAEHcABDMgICAABoLZwEBf0EAIQECQCAAKAIMDQACQAJAAkACQCAALQAvDgMBAAMCCyAAKAI4IgFFDQAgASgCLCIBRQ0AIAAgARGAgICAAAAiAQ0DC0EADwsQyoCAgAAACyAAQcOWgIAANgIQQQ4hAQsgAQseAAJAIAAoAgwNACAAQdGbgIAANgIQIABBFTYCDAsLFgACQCAAKAIMQRVHDQAgAEEANgIMCwsWAAJAIAAoAgxBFkcNACAAQQA2AgwLCwcAIAAoAgwLBwAgACgCEAsJACAAIAE2AhALBwAgACgCFAsiAAJAIABBJEkNABDKgICAAAALIABBAnRBoLOAgABqKAIACyIAAkAgAEEuSQ0AEMqAgIAAAAsgAEECdEGwtICAAGooAgAL7gsBAX9B66iAgAAhAQJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABBnH9qDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0Hhp4CAAA8LQaShgIAADwtBy6yAgAAPC0H+sYCAAA8LQcCkgIAADwtBq6SAgAAPC0GNqICAAA8LQeKmgIAADwtBgLCAgAAPC0G5r4CAAA8LQdekgIAADwtB75+AgAAPC0Hhn4CAAA8LQfqfgIAADwtB8qCAgAAPC0Gor4CAAA8LQa6ygIAADwtBiLCAgAAPC0Hsp4CAAA8LQYKigIAADwtBjp2AgAAPC0HQroCAAA8LQcqjgIAADwtBxbKAgAAPC0HfnICAAA8LQdKcgIAADwtBxKCAgAAPC0HXoICAAA8LQaKfgIAADwtB7a6AgAAPC0GrsICAAA8LQdSlgIAADwtBzK6AgAAPC0H6roCAAA8LQfyrgIAADwtB0rCAgAAPC0HxnYCAAA8LQbuggIAADwtB96uAgAAPC0GQsYCAAA8LQdexgIAADwtBoq2AgAAPC0HUp4CAAA8LQeCrgIAADwtBn6yAgAAPC0HrsYCAAA8LQdWfgIAADwtByrGAgAAPC0HepYCAAA8LQdSegIAADwtB9JyAgAAPC0GnsoCAAA8LQbGdgIAADwtBoJ2AgAAPC0G5sYCAAA8LQbywgIAADwtBkqGAgAAPC0GzpoCAAA8LQemsgIAADwtBrJ6AgAAPC0HUq4CAAA8LQfemgIAADwtBgKaAgAAPC0GwoYCAAA8LQf6egIAADwtBjaOAgAAPC0GJrYCAAA8LQfeigIAADwtBoLGAgAAPC0Gun4CAAA8LQcalgIAADwtB6J6AgAAPC0GTooCAAA8LQcKvgIAADwtBw52AgAAPC0GLrICAAA8LQeGdgIAADwtBja+AgAAPC0HqoYCAAA8LQbStgIAADwtB0q+AgAAPC0HfsoCAAA8LQdKygIAADwtB8LCAgAAPC0GpooCAAA8LQfmjgIAADwtBmZ6AgAAPC0G1rICAAA8LQZuwgIAADwtBkrKAgAAPC0G2q4CAAA8LQcKigIAADwtB+LKAgAAPC0GepYCAAA8LQdCigIAADwtBup6AgAAPC0GBnoCAAA8LEMqAgIAAAAtB1qGAgAAhAQsgAQsWACAAIAAtAC1B/gFxIAFBAEdyOgAtCxkAIAAgAC0ALUH9AXEgAUEAR0EBdHI6AC0LGQAgACAALQAtQfsBcSABQQBHQQJ0cjoALQsZACAAIAAtAC1B9wFxIAFBAEdBA3RyOgAtCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAgAiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCBCIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQcaRgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIwIgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAggiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEH2ioCAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCNCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIMIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABB7ZqAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAjgiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCECIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQZWQgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAI8IgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAhQiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEGqm4CAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCQCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIYIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABB7ZOAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAkQiBEUNACAAIAQRgICAgAAAIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCJCIERQ0AIAAgBBGAgICAAAAhAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIsIgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAigiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEH2iICAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCUCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIcIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABBwpmAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAkgiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCICIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQZSUgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAJMIgRFDQAgACAEEYCAgIAAACEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAlQiBEUNACAAIAQRgICAgAAAIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCWCIERQ0AIAAgBBGAgICAAAAhAwsgAwtFAQF/AkACQCAALwEwQRRxQRRHDQBBASEDIAAtAChBAUYNASAALwEyQeUARiEDDAELIAAtAClBBUYhAwsgACADOgAuQQAL/gEBA39BASEDAkAgAC8BMCIEQQhxDQAgACkDIEIAUiEDCwJAAkAgAC0ALkUNAEEBIQUgAC0AKUEFRg0BQQEhBSAEQcAAcUUgA3FBAUcNAQtBACEFIARBwABxDQBBAiEFIARB//8DcSIDQQhxDQACQCADQYAEcUUNAAJAIAAtAChBAUcNACAALQAtQQpxDQBBBQ8LQQQPCwJAIANBIHENAAJAIAAtAChBAUYNACAALwEyQf//A3EiAEGcf2pB5ABJDQAgAEHMAUYNACAAQbACRg0AQQQhBSAEQShxRQ0CIANBiARxQYAERg0CC0EADwtBAEEDIAApAyBQGyEFCyAFC2IBAn9BACEBAkAgAC0AKEEBRg0AIAAvATJB//8DcSICQZx/akHkAEkNACACQcwBRg0AIAJBsAJGDQAgAC8BMCIAQcAAcQ0AQQEhASAAQYgEcUGABEYNACAAQShxRSEBCyABC6cBAQN/AkACQAJAIAAtACpFDQAgAC0AK0UNAEEAIQMgAC8BMCIEQQJxRQ0BDAILQQAhAyAALwEwIgRBAXFFDQELQQEhAyAALQAoQQFGDQAgAC8BMkH//wNxIgVBnH9qQeQASQ0AIAVBzAFGDQAgBUGwAkYNACAEQcAAcQ0AQQAhAyAEQYgEcUGABEYNACAEQShxQQBHIQMLIABBADsBMCAAQQA6AC8gAwuZAQECfwJAAkACQCAALQAqRQ0AIAAtACtFDQBBACEBIAAvATAiAkECcUUNAQwCC0EAIQEgAC8BMCICQQFxRQ0BC0EBIQEgAC0AKEEBRg0AIAAvATJB//8DcSIAQZx/akHkAEkNACAAQcwBRg0AIABBsAJGDQAgAkHAAHENAEEAIQEgAkGIBHFBgARGDQAgAkEocUEARyEBCyABC0kBAXsgAEEQav0MAAAAAAAAAAAAAAAAAAAAACIB/QsDACAAIAH9CwMAIABBMGogAf0LAwAgAEEgaiAB/QsDACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC+TzAQMOfwN+BH8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIhBBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4BS80BTMwBTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAOxwEAAQID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YWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsb3NlZWVwLWFsaXZlAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgAAAAAAAAAAAAAAAAAAAHJhbnNmZXItZW5jb2RpbmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==' - // 3. If the response lacks a |Connection| header field or the - // |Connection| header field doesn't contain a token that is an - // ASCII case-insensitive match for the value "Upgrade", the client - // MUST _Fail the WebSocket Connection_. - if (response.headersList.get('Connection')?.toLowerCase() !== 'upgrade') { - failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".') - return - } - // 4. If the response lacks a |Sec-WebSocket-Accept| header field or - // the |Sec-WebSocket-Accept| contains a value other than the - // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- - // Key| (as a string, not base64-decoded) with the string "258EAFA5- - // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and - // trailing whitespace, the client MUST _Fail the WebSocket - // Connection_. - const secWSAccept = response.headersList.get('Sec-WebSocket-Accept') - const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64') - if (secWSAccept !== digest) { - failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.') - return - } +/***/ }), - // 5. If the response includes a |Sec-WebSocket-Extensions| header - // field and this header field indicates the use of an extension - // that was not present in the client's handshake (the server has - // indicated an extension not requested by the client), the client - // MUST _Fail the WebSocket Connection_. (The parsing of this - // header field to determine which extensions are requested is - // discussed in Section 9.1.) - const secExtension = response.headersList.get('Sec-WebSocket-Extensions') +/***/ 1891: +/***/ ((__unused_webpack_module, exports) => { - if (secExtension !== null && secExtension !== permessageDeflate) { - failWebsocketConnection(ws, 'Received different permessage-deflate than the one set.') - return - } +"use strict"; - // 6. If the response includes a |Sec-WebSocket-Protocol| header field - // and this header field indicates the use of a subprotocol that was - // not present in the client's handshake (the server has indicated a - // subprotocol not requested by the client), the client MUST _Fail - // the WebSocket Connection_. - const secProtocol = response.headersList.get('Sec-WebSocket-Protocol') +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.enumToMap = void 0; +function enumToMap(obj) { + const res = {}; + Object.keys(obj).forEach((key) => { + const value = obj[key]; + if (typeof value === 'number') { + res[key] = value; + } + }); + return res; +} +exports.enumToMap = enumToMap; +//# sourceMappingURL=utils.js.map - if (secProtocol !== null && secProtocol !== request.headersList.get('Sec-WebSocket-Protocol')) { - failWebsocketConnection(ws, 'Protocol was not set in the opening handshake.') - return - } +/***/ }), - response.socket.on('data', onSocketData) - response.socket.on('close', onSocketClose) - response.socket.on('error', onSocketError) +/***/ 6771: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (channels.open.hasSubscribers) { - channels.open.publish({ - address: response.socket.address(), - protocol: secProtocol, - extensions: secExtension - }) - } +"use strict"; - onEstablish(response) - } - }) - return controller -} +const { kClients } = __nccwpck_require__(2785) +const Agent = __nccwpck_require__(7890) +const { + kAgent, + kMockAgentSet, + kMockAgentGet, + kDispatches, + kIsMockActive, + kNetConnect, + kGetNetConnect, + kOptions, + kFactory +} = __nccwpck_require__(4347) +const MockClient = __nccwpck_require__(8687) +const MockPool = __nccwpck_require__(6193) +const { matchValue, buildMockOptions } = __nccwpck_require__(9323) +const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8045) +const Dispatcher = __nccwpck_require__(412) +const Pluralizer = __nccwpck_require__(8891) +const PendingInterceptorsFormatter = __nccwpck_require__(6823) -/** - * @param {Buffer} chunk - */ -function onSocketData (chunk) { - if (!this.ws[kByteParser].write(chunk)) { - this.pause() +class FakeWeakRef { + constructor (value) { + this.value = value } -} -/** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 - */ -function onSocketClose () { - const { ws } = this + deref () { + return this.value + } +} - // If the TCP connection was closed after the - // WebSocket closing handshake was completed, the WebSocket connection - // is said to have been closed _cleanly_. - const wasClean = ws[kSentClose] && ws[kReceivedClose] +class MockAgent extends Dispatcher { + constructor (opts) { + super(opts) - let code = 1005 - let reason = '' + this[kNetConnect] = true + this[kIsMockActive] = true - const result = ws[kByteParser].closingInfo + // Instantiate Agent and encapsulate + if ((opts && opts.agent && typeof opts.agent.dispatch !== 'function')) { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } + const agent = opts && opts.agent ? opts.agent : new Agent(opts) + this[kAgent] = agent - if (result) { - code = result.code ?? 1005 - reason = result.reason - } else if (!ws[kSentClose]) { - // If _The WebSocket - // Connection is Closed_ and no Close control frame was received by the - // endpoint (such as could occur if the underlying transport connection - // is lost), _The WebSocket Connection Close Code_ is considered to be - // 1006. - code = 1006 + this[kClients] = agent[kClients] + this[kOptions] = buildMockOptions(opts) } - // 1. Change the ready state to CLOSED (3). - ws[kReadyState] = states.CLOSED + get (origin) { + let dispatcher = this[kMockAgentGet](origin) - // 2. If the user agent was required to fail the WebSocket - // connection, or if the WebSocket connection was closed - // after being flagged as full, fire an event named error - // at the WebSocket object. - // TODO + if (!dispatcher) { + dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + } + return dispatcher + } - // 3. Fire an event named close at the WebSocket object, - // using CloseEvent, with the wasClean attribute - // initialized to true if the connection closed cleanly - // and false otherwise, the code attribute initialized to - // the WebSocket connection close code, and the reason - // attribute initialized to the result of applying UTF-8 - // decode without BOM to the WebSocket connection close - // reason. - fireEvent('close', ws, CloseEvent, { - wasClean, code, reason - }) + dispatch (opts, handler) { + // Call MockAgent.get to perform additional setup before dispatching as normal + this.get(opts.origin) + return this[kAgent].dispatch(opts, handler) + } - if (channels.close.hasSubscribers) { - channels.close.publish({ - websocket: ws, - code, - reason - }) + async close () { + await this[kAgent].close() + this[kClients].clear() } -} -function onSocketError (error) { - const { ws } = this + deactivate () { + this[kIsMockActive] = false + } - ws[kReadyState] = states.CLOSING + activate () { + this[kIsMockActive] = true + } - if (channels.socketError.hasSubscribers) { - channels.socketError.publish(error) + enableNetConnect (matcher) { + if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) { + if (Array.isArray(this[kNetConnect])) { + this[kNetConnect].push(matcher) + } else { + this[kNetConnect] = [matcher] + } + } else if (typeof matcher === 'undefined') { + this[kNetConnect] = true + } else { + throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.') + } } - this.destroy() -} + disableNetConnect () { + this[kNetConnect] = false + } -module.exports = { - establishWebSocketConnection -} + // This is required to bypass issues caused by using global symbols - see: + // https://github.com/nodejs/undici/issues/1447 + get isMockActive () { + return this[kIsMockActive] + } + [kMockAgentSet] (origin, dispatcher) { + this[kClients].set(origin, new FakeWeakRef(dispatcher)) + } -/***/ }), + [kFactory] (origin) { + const mockOptions = Object.assign({ agent: this }, this[kOptions]) + return this[kOptions] && this[kOptions].connections === 1 + ? new MockClient(origin, mockOptions) + : new MockPool(origin, mockOptions) + } -/***/ 9188: -/***/ ((module) => { + [kMockAgentGet] (origin) { + // First check if we can immediately find it + const ref = this[kClients].get(origin) + if (ref) { + return ref.deref() + } -"use strict"; + // If the origin is not a string create a dummy parent pool and return to user + if (typeof origin !== 'string') { + const dispatcher = this[kFactory]('http://localhost:9999') + this[kMockAgentSet](origin, dispatcher) + return dispatcher + } + // If we match, create a pool and assign the same dispatches + for (const [keyMatcher, nonExplicitRef] of Array.from(this[kClients])) { + const nonExplicitDispatcher = nonExplicitRef.deref() + if (nonExplicitDispatcher && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) { + const dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches] + return dispatcher + } + } + } -// This is a Globally Unique Identifier unique used -// to validate that the endpoint accepts websocket -// connections. -// See https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3 -const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' + [kGetNetConnect] () { + return this[kNetConnect] + } -/** @type {PropertyDescriptor} */ -const staticPropertyDescriptors = { - enumerable: true, - writable: false, - configurable: false -} + pendingInterceptors () { + const mockAgentClients = this[kClients] -const states = { - CONNECTING: 0, - OPEN: 1, - CLOSING: 2, - CLOSED: 3 -} + return Array.from(mockAgentClients.entries()) + .flatMap(([origin, scope]) => scope.deref()[kDispatches].map(dispatch => ({ ...dispatch, origin }))) + .filter(({ pending }) => pending) + } -const opcodes = { - CONTINUATION: 0x0, - TEXT: 0x1, - BINARY: 0x2, - CLOSE: 0x8, - PING: 0x9, - PONG: 0xA -} + assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) { + const pending = this.pendingInterceptors() -const maxUnsigned16Bit = 2 ** 16 - 1 // 65535 + if (pending.length === 0) { + return + } -const parserStates = { - INFO: 0, - PAYLOADLENGTH_16: 2, - PAYLOADLENGTH_64: 3, - READ_DATA: 4 -} + const pluralizer = new Pluralizer('interceptor', 'interceptors').pluralize(pending.length) -const emptyBuffer = Buffer.allocUnsafe(0) + throw new UndiciError(` +${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: -module.exports = { - uid, - staticPropertyDescriptors, - states, - opcodes, - maxUnsigned16Bit, - parserStates, - emptyBuffer +${pendingInterceptorsFormatter.format(pending)} +`.trim()) + } } +module.exports = MockAgent + /***/ }), -/***/ 2611: +/***/ 8687: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { webidl } = __nccwpck_require__(1744) -const { kEnumerableProperty } = __nccwpck_require__(3983) -const { MessagePort } = __nccwpck_require__(1267) +const { promisify } = __nccwpck_require__(3837) +const Client = __nccwpck_require__(3598) +const { buildMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected +} = __nccwpck_require__(4347) +const { MockInterceptor } = __nccwpck_require__(410) +const Symbols = __nccwpck_require__(2785) +const { InvalidArgumentError } = __nccwpck_require__(8045) /** - * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent + * MockClient provides an API that extends the Client to influence the mockDispatches. */ -class MessageEvent extends Event { - #eventInit +class MockClient extends Client { + constructor (origin, opts) { + super(origin, opts) - constructor (type, eventInitDict = {}) { - webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent constructor' }) + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') + } - type = webidl.converters.DOMString(type) - eventInitDict = webidl.converters.MessageEventInit(eventInitDict) + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) - super(type, eventInitDict) + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] + } - this.#eventInit = eventInitDict + get [Symbols.kConnected] () { + return this[kConnected] } - get data () { - webidl.brandCheck(this, MessageEvent) + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor(opts, this[kDispatches]) + } - return this.#eventInit.data + async [kClose] () { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) } +} - get origin () { - webidl.brandCheck(this, MessageEvent) +module.exports = MockClient - return this.#eventInit.origin - } - get lastEventId () { - webidl.brandCheck(this, MessageEvent) +/***/ }), - return this.#eventInit.lastEventId - } +/***/ 888: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - get source () { - webidl.brandCheck(this, MessageEvent) +"use strict"; - return this.#eventInit.source + +const { UndiciError } = __nccwpck_require__(8045) + +class MockNotMatchedError extends UndiciError { + constructor (message) { + super(message) + Error.captureStackTrace(this, MockNotMatchedError) + this.name = 'MockNotMatchedError' + this.message = message || 'The request does not match any registered mock dispatches' + this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED' } +} - get ports () { - webidl.brandCheck(this, MessageEvent) +module.exports = { + MockNotMatchedError +} - if (!Object.isFrozen(this.#eventInit.ports)) { - Object.freeze(this.#eventInit.ports) - } - return this.#eventInit.ports - } +/***/ }), - initMessageEvent ( - type, - bubbles = false, - cancelable = false, - data = null, - origin = '', - lastEventId = '', - source = null, - ports = [] - ) { - webidl.brandCheck(this, MessageEvent) +/***/ 410: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent.initMessageEvent' }) +"use strict"; - return new MessageEvent(type, { - bubbles, cancelable, data, origin, lastEventId, source, ports - }) - } -} + +const { getResponseData, buildKey, addMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kDispatchKey, + kDefaultHeaders, + kDefaultTrailers, + kContentLength, + kMockDispatch +} = __nccwpck_require__(4347) +const { InvalidArgumentError } = __nccwpck_require__(8045) +const { buildURL } = __nccwpck_require__(3983) /** - * @see https://websockets.spec.whatwg.org/#the-closeevent-interface + * Defines the scope API for an interceptor reply */ -class CloseEvent extends Event { - #eventInit - - constructor (type, eventInitDict = {}) { - webidl.argumentLengthCheck(arguments, 1, { header: 'CloseEvent constructor' }) +class MockScope { + constructor (mockDispatch) { + this[kMockDispatch] = mockDispatch + } - type = webidl.converters.DOMString(type) - eventInitDict = webidl.converters.CloseEventInit(eventInitDict) + /** + * Delay a reply by a set amount in ms. + */ + delay (waitInMs) { + if (typeof waitInMs !== 'number' || !Number.isInteger(waitInMs) || waitInMs <= 0) { + throw new InvalidArgumentError('waitInMs must be a valid integer > 0') + } - super(type, eventInitDict) + this[kMockDispatch].delay = waitInMs + return this + } - this.#eventInit = eventInitDict + /** + * For a defined reply, never mark as consumed. + */ + persist () { + this[kMockDispatch].persist = true + return this } - get wasClean () { - webidl.brandCheck(this, CloseEvent) + /** + * Allow one to define a reply for a set amount of matching requests. + */ + times (repeatTimes) { + if (typeof repeatTimes !== 'number' || !Number.isInteger(repeatTimes) || repeatTimes <= 0) { + throw new InvalidArgumentError('repeatTimes must be a valid integer > 0') + } - return this.#eventInit.wasClean + this[kMockDispatch].times = repeatTimes + return this } +} - get code () { - webidl.brandCheck(this, CloseEvent) +/** + * Defines an interceptor for a Mock + */ +class MockInterceptor { + constructor (opts, mockDispatches) { + if (typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object') + } + if (typeof opts.path === 'undefined') { + throw new InvalidArgumentError('opts.path must be defined') + } + if (typeof opts.method === 'undefined') { + opts.method = 'GET' + } + // See https://github.com/nodejs/undici/issues/1245 + // As per RFC 3986, clients are not supposed to send URI + // fragments to servers when they retrieve a document, + if (typeof opts.path === 'string') { + if (opts.query) { + opts.path = buildURL(opts.path, opts.query) + } else { + // Matches https://github.com/nodejs/undici/blob/main/lib/fetch/index.js#L1811 + const parsedURL = new URL(opts.path, 'data://') + opts.path = parsedURL.pathname + parsedURL.search + } + } + if (typeof opts.method === 'string') { + opts.method = opts.method.toUpperCase() + } - return this.#eventInit.code + this[kDispatchKey] = buildKey(opts) + this[kDispatches] = mockDispatches + this[kDefaultHeaders] = {} + this[kDefaultTrailers] = {} + this[kContentLength] = false } - get reason () { - webidl.brandCheck(this, CloseEvent) + createMockScopeDispatchData (statusCode, data, responseOptions = {}) { + const responseData = getResponseData(data) + const contentLength = this[kContentLength] ? { 'content-length': responseData.length } : {} + const headers = { ...this[kDefaultHeaders], ...contentLength, ...responseOptions.headers } + const trailers = { ...this[kDefaultTrailers], ...responseOptions.trailers } - return this.#eventInit.reason + return { statusCode, data, headers, trailers } } -} -// https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface -class ErrorEvent extends Event { - #eventInit + validateReplyParameters (statusCode, data, responseOptions) { + if (typeof statusCode === 'undefined') { + throw new InvalidArgumentError('statusCode must be defined') + } + if (typeof data === 'undefined') { + throw new InvalidArgumentError('data must be defined') + } + if (typeof responseOptions !== 'object') { + throw new InvalidArgumentError('responseOptions must be an object') + } + } - constructor (type, eventInitDict) { - webidl.argumentLengthCheck(arguments, 1, { header: 'ErrorEvent constructor' }) + /** + * Mock an undici request with a defined reply. + */ + reply (replyData) { + // Values of reply aren't available right now as they + // can only be available when the reply callback is invoked. + if (typeof replyData === 'function') { + // We'll first wrap the provided callback in another function, + // this function will properly resolve the data from the callback + // when invoked. + const wrappedDefaultsCallback = (opts) => { + // Our reply options callback contains the parameter for statusCode, data and options. + const resolvedData = replyData(opts) - super(type, eventInitDict) + // Check if it is in the right format + if (typeof resolvedData !== 'object') { + throw new InvalidArgumentError('reply options callback must return an object') + } - type = webidl.converters.DOMString(type) - eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}) + const { statusCode, data = '', responseOptions = {} } = resolvedData + this.validateReplyParameters(statusCode, data, responseOptions) + // Since the values can be obtained immediately we return them + // from this higher order function that will be resolved later. + return { + ...this.createMockScopeDispatchData(statusCode, data, responseOptions) + } + } - this.#eventInit = eventInitDict - } + // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], wrappedDefaultsCallback) + return new MockScope(newMockDispatch) + } - get message () { - webidl.brandCheck(this, ErrorEvent) + // We can have either one or three parameters, if we get here, + // we should have 1-3 parameters. So we spread the arguments of + // this function to obtain the parameters, since replyData will always + // just be the statusCode. + const [statusCode, data = '', responseOptions = {}] = [...arguments] + this.validateReplyParameters(statusCode, data, responseOptions) - return this.#eventInit.message + // Send in-already provided data like usual + const dispatchData = this.createMockScopeDispatchData(statusCode, data, responseOptions) + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], dispatchData) + return new MockScope(newMockDispatch) } - get filename () { - webidl.brandCheck(this, ErrorEvent) + /** + * Mock an undici request with a defined error. + */ + replyWithError (error) { + if (typeof error === 'undefined') { + throw new InvalidArgumentError('error must be defined') + } - return this.#eventInit.filename + const newMockDispatch = addMockDispatch(this[kDispatches], this[kDispatchKey], { error }) + return new MockScope(newMockDispatch) } - get lineno () { - webidl.brandCheck(this, ErrorEvent) + /** + * Set default reply headers on the interceptor for subsequent replies + */ + defaultReplyHeaders (headers) { + if (typeof headers === 'undefined') { + throw new InvalidArgumentError('headers must be defined') + } - return this.#eventInit.lineno + this[kDefaultHeaders] = headers + return this } - get colno () { - webidl.brandCheck(this, ErrorEvent) + /** + * Set default reply trailers on the interceptor for subsequent replies + */ + defaultReplyTrailers (trailers) { + if (typeof trailers === 'undefined') { + throw new InvalidArgumentError('trailers must be defined') + } - return this.#eventInit.colno + this[kDefaultTrailers] = trailers + return this } - get error () { - webidl.brandCheck(this, ErrorEvent) - - return this.#eventInit.error + /** + * Set reply content length header for replies on the interceptor + */ + replyContentLength () { + this[kContentLength] = true + return this } } -Object.defineProperties(MessageEvent.prototype, { - [Symbol.toStringTag]: { - value: 'MessageEvent', - configurable: true - }, - data: kEnumerableProperty, - origin: kEnumerableProperty, - lastEventId: kEnumerableProperty, - source: kEnumerableProperty, - ports: kEnumerableProperty, - initMessageEvent: kEnumerableProperty -}) +module.exports.MockInterceptor = MockInterceptor +module.exports.MockScope = MockScope -Object.defineProperties(CloseEvent.prototype, { - [Symbol.toStringTag]: { - value: 'CloseEvent', - configurable: true - }, - reason: kEnumerableProperty, - code: kEnumerableProperty, - wasClean: kEnumerableProperty -}) -Object.defineProperties(ErrorEvent.prototype, { - [Symbol.toStringTag]: { - value: 'ErrorEvent', - configurable: true - }, - message: kEnumerableProperty, - filename: kEnumerableProperty, - lineno: kEnumerableProperty, - colno: kEnumerableProperty, - error: kEnumerableProperty -}) +/***/ }), -webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort) +/***/ 6193: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.MessagePort -) +"use strict"; -const eventInit = [ - { - key: 'bubbles', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'cancelable', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'composed', - converter: webidl.converters.boolean, - defaultValue: false - } -] -webidl.converters.MessageEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'data', - converter: webidl.converters.any, - defaultValue: null - }, - { - key: 'origin', - converter: webidl.converters.USVString, - defaultValue: '' - }, - { - key: 'lastEventId', - converter: webidl.converters.DOMString, - defaultValue: '' - }, - { - key: 'source', - // Node doesn't implement WindowProxy or ServiceWorker, so the only - // valid value for source is a MessagePort. - converter: webidl.nullableConverter(webidl.converters.MessagePort), - defaultValue: null - }, - { - key: 'ports', - converter: webidl.converters['sequence'], - get defaultValue () { - return [] +const { promisify } = __nccwpck_require__(3837) +const Pool = __nccwpck_require__(4634) +const { buildMockDispatch } = __nccwpck_require__(9323) +const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected +} = __nccwpck_require__(4347) +const { MockInterceptor } = __nccwpck_require__(410) +const Symbols = __nccwpck_require__(2785) +const { InvalidArgumentError } = __nccwpck_require__(8045) + +/** + * MockPool provides an API that extends the Pool to influence the mockDispatches. + */ +class MockPool extends Pool { + constructor (origin, opts) { + super(origin, opts) + + if (!opts || !opts.agent || typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument opts.agent must implement Agent') } + + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) + + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] } -]) -webidl.converters.CloseEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'wasClean', - converter: webidl.converters.boolean, - defaultValue: false - }, - { - key: 'code', - converter: webidl.converters['unsigned short'], - defaultValue: 0 - }, - { - key: 'reason', - converter: webidl.converters.USVString, - defaultValue: '' + get [Symbols.kConnected] () { + return this[kConnected] } -]) -webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ - ...eventInit, - { - key: 'message', - converter: webidl.converters.DOMString, - defaultValue: '' - }, - { - key: 'filename', - converter: webidl.converters.USVString, - defaultValue: '' - }, - { - key: 'lineno', - converter: webidl.converters['unsigned long'], - defaultValue: 0 - }, - { - key: 'colno', - converter: webidl.converters['unsigned long'], - defaultValue: 0 - }, - { - key: 'error', - converter: webidl.converters.any + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept (opts) { + return new MockInterceptor(opts, this[kDispatches]) } -]) + + async [kClose] () { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + } +} + +module.exports = MockPool + + +/***/ }), + +/***/ 4347: +/***/ ((module) => { + +"use strict"; + module.exports = { - MessageEvent, - CloseEvent, - ErrorEvent + kAgent: Symbol('agent'), + kOptions: Symbol('options'), + kFactory: Symbol('factory'), + kDispatches: Symbol('dispatches'), + kDispatchKey: Symbol('dispatch key'), + kDefaultHeaders: Symbol('default headers'), + kDefaultTrailers: Symbol('default trailers'), + kContentLength: Symbol('content length'), + kMockAgent: Symbol('mock agent'), + kMockAgentSet: Symbol('mock agent set'), + kMockAgentGet: Symbol('mock agent get'), + kMockDispatch: Symbol('mock dispatch'), + kClose: Symbol('close'), + kOriginalClose: Symbol('original agent close'), + kOrigin: Symbol('origin'), + kIsMockActive: Symbol('is mock active'), + kNetConnect: Symbol('net connect'), + kGetNetConnect: Symbol('get net connect'), + kConnected: Symbol('connected') } /***/ }), -/***/ 5444: +/***/ 9323: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -const { maxUnsigned16Bit } = __nccwpck_require__(9188) +const { MockNotMatchedError } = __nccwpck_require__(888) +const { + kDispatches, + kMockAgent, + kOriginalDispatch, + kOrigin, + kGetNetConnect +} = __nccwpck_require__(4347) +const { buildURL, nop } = __nccwpck_require__(3983) +const { STATUS_CODES } = __nccwpck_require__(3685) +const { + types: { + isPromise + } +} = __nccwpck_require__(3837) -/** @type {import('crypto')} */ -let crypto -try { - crypto = __nccwpck_require__(6113) -} catch { +function matchValue (match, value) { + if (typeof match === 'string') { + return match === value + } + if (match instanceof RegExp) { + return match.test(value) + } + if (typeof match === 'function') { + return match(value) === true + } + return false +} +function lowerCaseEntries (headers) { + return Object.fromEntries( + Object.entries(headers).map(([headerName, headerValue]) => { + return [headerName.toLocaleLowerCase(), headerValue] + }) + ) } -class WebsocketFrameSend { - /** - * @param {Buffer|undefined} data - */ - constructor (data) { - this.frameData = data - this.maskKey = crypto.randomBytes(4) +/** + * @param {import('../../index').Headers|string[]|Record} headers + * @param {string} key + */ +function getHeaderByName (headers, key) { + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { + return headers[i + 1] + } + } + + return undefined + } else if (typeof headers.get === 'function') { + return headers.get(key) + } else { + return lowerCaseEntries(headers)[key.toLocaleLowerCase()] } +} - createFrame (opcode) { - const bodyLength = this.frameData?.byteLength ?? 0 +/** @param {string[]} headers */ +function buildHeadersFromArray (headers) { // fetch HeadersList + const clone = headers.slice() + const entries = [] + for (let index = 0; index < clone.length; index += 2) { + entries.push([clone[index], clone[index + 1]]) + } + return Object.fromEntries(entries) +} - /** @type {number} */ - let payloadLength = bodyLength // 0-125 - let offset = 6 +function matchHeaders (mockDispatch, headers) { + if (typeof mockDispatch.headers === 'function') { + if (Array.isArray(headers)) { // fetch HeadersList + headers = buildHeadersFromArray(headers) + } + return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) + } + if (typeof mockDispatch.headers === 'undefined') { + return true + } + if (typeof headers !== 'object' || typeof mockDispatch.headers !== 'object') { + return false + } - if (bodyLength > maxUnsigned16Bit) { - offset += 8 // payload length is next 8 bytes - payloadLength = 127 - } else if (bodyLength > 125) { - offset += 2 // payload length is next 2 bytes - payloadLength = 126 + for (const [matchHeaderName, matchHeaderValue] of Object.entries(mockDispatch.headers)) { + const headerValue = getHeaderByName(headers, matchHeaderName) + + if (!matchValue(matchHeaderValue, headerValue)) { + return false } + } + return true +} - const buffer = Buffer.allocUnsafe(bodyLength + offset) +function safeUrl (path) { + if (typeof path !== 'string') { + return path + } - // Clear first 2 bytes, everything else is overwritten - buffer[0] = buffer[1] = 0 - buffer[0] |= 0x80 // FIN - buffer[0] = (buffer[0] & 0xF0) + opcode // opcode + const pathSegments = path.split('?') - /*! ws. MIT License. Einar Otto Stangvik */ - buffer[offset - 4] = this.maskKey[0] - buffer[offset - 3] = this.maskKey[1] - buffer[offset - 2] = this.maskKey[2] - buffer[offset - 1] = this.maskKey[3] + if (pathSegments.length !== 2) { + return path + } - buffer[1] = payloadLength + const qp = new URLSearchParams(pathSegments.pop()) + qp.sort() + return [...pathSegments, qp.toString()].join('?') +} - if (payloadLength === 126) { - buffer.writeUInt16BE(bodyLength, 2) - } else if (payloadLength === 127) { - // Clear extended payload length - buffer[2] = buffer[3] = 0 - buffer.writeUIntBE(bodyLength, 4, 6) - } +function matchKey (mockDispatch, { path, method, body, headers }) { + const pathMatch = matchValue(mockDispatch.path, path) + const methodMatch = matchValue(mockDispatch.method, method) + const bodyMatch = typeof mockDispatch.body !== 'undefined' ? matchValue(mockDispatch.body, body) : true + const headersMatch = matchHeaders(mockDispatch, headers) + return pathMatch && methodMatch && bodyMatch && headersMatch +} - buffer[1] |= 0x80 // MASK +function getResponseData (data) { + if (Buffer.isBuffer(data)) { + return data + } else if (typeof data === 'object') { + return JSON.stringify(data) + } else { + return data.toString() + } +} - // mask body - for (let i = 0; i < bodyLength; i++) { - buffer[offset + i] = this.frameData[i] ^ this.maskKey[i % 4] - } +function getMockDispatch (mockDispatches, key) { + const basePath = key.query ? buildURL(key.path, key.query) : key.path + const resolvedPath = typeof basePath === 'string' ? safeUrl(basePath) : basePath - return buffer + // Match path + let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path }) => matchValue(safeUrl(path), resolvedPath)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`) + } + + // Match method + matchedMockDispatches = matchedMockDispatches.filter(({ method }) => matchValue(method, key.method)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for method '${key.method}'`) + } + + // Match body + matchedMockDispatches = matchedMockDispatches.filter(({ body }) => typeof body !== 'undefined' ? matchValue(body, key.body) : true) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for body '${key.body}'`) + } + + // Match headers + matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => matchHeaders(mockDispatch, key.headers)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError(`Mock dispatch not matched for headers '${typeof key.headers === 'object' ? JSON.stringify(key.headers) : key.headers}'`) } -} -module.exports = { - WebsocketFrameSend + return matchedMockDispatches[0] } +function addMockDispatch (mockDispatches, key, data) { + const baseData = { timesInvoked: 0, times: 1, persist: false, consumed: false } + const replyData = typeof data === 'function' ? { callback: data } : { ...data } + const newMockDispatch = { ...baseData, ...key, pending: true, data: { error: null, ...replyData } } + mockDispatches.push(newMockDispatch) + return newMockDispatch +} -/***/ }), - -/***/ 1688: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function deleteMockDispatch (mockDispatches, key) { + const index = mockDispatches.findIndex(dispatch => { + if (!dispatch.consumed) { + return false + } + return matchKey(dispatch, key) + }) + if (index !== -1) { + mockDispatches.splice(index, 1) + } +} -"use strict"; +function buildKey (opts) { + const { path, method, body, headers, query } = opts + return { + path, + method, + body, + headers, + query + } +} +function generateKeyValues (data) { + return Object.entries(data).reduce((keyValuePairs, [key, value]) => [ + ...keyValuePairs, + Buffer.from(`${key}`), + Array.isArray(value) ? value.map(x => Buffer.from(`${x}`)) : Buffer.from(`${value}`) + ], []) +} -const { Writable } = __nccwpck_require__(2781) -const diagnosticsChannel = __nccwpck_require__(7643) -const { parserStates, opcodes, states, emptyBuffer } = __nccwpck_require__(9188) -const { kReadyState, kSentClose, kResponse, kReceivedClose } = __nccwpck_require__(7578) -const { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = __nccwpck_require__(5515) -const { WebsocketFrameSend } = __nccwpck_require__(5444) +/** + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + * @param {number} statusCode + */ +function getStatusText (statusCode) { + return STATUS_CODES[statusCode] || 'unknown' +} -// This code was influenced by ws released under the MIT license. -// Copyright (c) 2011 Einar Otto Stangvik -// Copyright (c) 2013 Arnout Kazemier and contributors -// Copyright (c) 2016 Luigi Pinca and contributors +async function getResponse (body) { + const buffers = [] + for await (const data of body) { + buffers.push(data) + } + return Buffer.concat(buffers).toString('utf8') +} -const channels = {} -channels.ping = diagnosticsChannel.channel('undici:websocket:ping') -channels.pong = diagnosticsChannel.channel('undici:websocket:pong') +/** + * Mock dispatch function used to simulate undici dispatches + */ +function mockDispatch (opts, handler) { + // Get mock dispatch from built key + const key = buildKey(opts) + const mockDispatch = getMockDispatch(this[kDispatches], key) -class ByteParser extends Writable { - #buffers = [] - #byteOffset = 0 + mockDispatch.timesInvoked++ - #state = parserStates.INFO + // Here's where we resolve a callback if a callback is present for the dispatch data. + if (mockDispatch.data.callback) { + mockDispatch.data = { ...mockDispatch.data, ...mockDispatch.data.callback(opts) } + } - #info = {} - #fragments = [] + // Parse mockDispatch data + const { data: { statusCode, data, headers, trailers, error }, delay, persist } = mockDispatch + const { timesInvoked, times } = mockDispatch - constructor (ws) { - super() + // If it's used up and not persistent, mark as consumed + mockDispatch.consumed = !persist && timesInvoked >= times + mockDispatch.pending = timesInvoked < times - this.ws = ws + // If specified, trigger dispatch error + if (error !== null) { + deleteMockDispatch(this[kDispatches], key) + handler.onError(error) + return true } - /** - * @param {Buffer} chunk - * @param {() => void} callback - */ - _write (chunk, _, callback) { - this.#buffers.push(chunk) - this.#byteOffset += chunk.length - - this.run(callback) + // Handle the request with a delay if necessary + if (typeof delay === 'number' && delay > 0) { + setTimeout(() => { + handleReply(this[kDispatches]) + }, delay) + } else { + handleReply(this[kDispatches]) } - /** - * Runs whenever a new chunk is received. - * Callback is called whenever there are no more chunks buffering, - * or not enough bytes are buffered to parse. - */ - run (callback) { - while (true) { - if (this.#state === parserStates.INFO) { - // If there aren't enough bytes to parse the payload length, etc. - if (this.#byteOffset < 2) { - return callback() - } - - const buffer = this.consume(2) + function handleReply (mockDispatches, _data = data) { + // fetch's HeadersList is a 1D string array + const optsHeaders = Array.isArray(opts.headers) + ? buildHeadersFromArray(opts.headers) + : opts.headers + const body = typeof _data === 'function' + ? _data({ ...opts, headers: optsHeaders }) + : _data - this.#info.fin = (buffer[0] & 0x80) !== 0 - this.#info.opcode = buffer[0] & 0x0F + // util.types.isPromise is likely needed for jest. + if (isPromise(body)) { + // If handleReply is asynchronous, throwing an error + // in the callback will reject the promise, rather than + // synchronously throw the error, which breaks some tests. + // Rather, we wait for the callback to resolve if it is a + // promise, and then re-run handleReply with the new body. + body.then((newData) => handleReply(mockDispatches, newData)) + return + } - // If we receive a fragmented message, we use the type of the first - // frame to parse the full message as binary/text, when it's terminated - this.#info.originalOpcode ??= this.#info.opcode + const responseData = getResponseData(body) + const responseHeaders = generateKeyValues(headers) + const responseTrailers = generateKeyValues(trailers) - this.#info.fragmented = !this.#info.fin && this.#info.opcode !== opcodes.CONTINUATION + handler.abort = nop + handler.onHeaders(statusCode, responseHeaders, resume, getStatusText(statusCode)) + handler.onData(Buffer.from(responseData)) + handler.onComplete(responseTrailers) + deleteMockDispatch(mockDispatches, key) + } - if (this.#info.fragmented && this.#info.opcode !== opcodes.BINARY && this.#info.opcode !== opcodes.TEXT) { - // Only text and binary frames can be fragmented - failWebsocketConnection(this.ws, 'Invalid frame type was fragmented.') - return - } + function resume () {} - const payloadLength = buffer[1] & 0x7F + return true +} - if (payloadLength <= 125) { - this.#info.payloadLength = payloadLength - this.#state = parserStates.READ_DATA - } else if (payloadLength === 126) { - this.#state = parserStates.PAYLOADLENGTH_16 - } else if (payloadLength === 127) { - this.#state = parserStates.PAYLOADLENGTH_64 - } +function buildMockDispatch () { + const agent = this[kMockAgent] + const origin = this[kOrigin] + const originalDispatch = this[kOriginalDispatch] - if (this.#info.fragmented && payloadLength > 125) { - // A fragmented frame can't be fragmented itself - failWebsocketConnection(this.ws, 'Fragmented frame exceeded 125 bytes.') - return - } else if ( - (this.#info.opcode === opcodes.PING || - this.#info.opcode === opcodes.PONG || - this.#info.opcode === opcodes.CLOSE) && - payloadLength > 125 - ) { - // Control frames can have a payload length of 125 bytes MAX - failWebsocketConnection(this.ws, 'Payload length for control frame exceeded 125 bytes.') - return - } else if (this.#info.opcode === opcodes.CLOSE) { - if (payloadLength === 1) { - failWebsocketConnection(this.ws, 'Received close frame with a 1-byte body.') - return + return function dispatch (opts, handler) { + if (agent.isMockActive) { + try { + mockDispatch.call(this, opts, handler) + } catch (error) { + if (error instanceof MockNotMatchedError) { + const netConnect = agent[kGetNetConnect]() + if (netConnect === false) { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)`) } - - const body = this.consume(payloadLength) - - this.#info.closeInfo = this.parseCloseBody(false, body) - - if (!this.ws[kSentClose]) { - // If an endpoint receives a Close frame and did not previously send a - // Close frame, the endpoint MUST send a Close frame in response. (When - // sending a Close frame in response, the endpoint typically echos the - // status code it received.) - const body = Buffer.allocUnsafe(2) - body.writeUInt16BE(this.#info.closeInfo.code, 0) - const closeFrame = new WebsocketFrameSend(body) - - this.ws[kResponse].socket.write( - closeFrame.createFrame(opcodes.CLOSE), - (err) => { - if (!err) { - this.ws[kSentClose] = true - } - } - ) + if (checkNetConnect(netConnect, origin)) { + originalDispatch.call(this, opts, handler) + } else { + throw new MockNotMatchedError(`${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)`) } + } else { + throw error + } + } + } else { + originalDispatch.call(this, opts, handler) + } + } +} - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - this.ws[kReadyState] = states.CLOSING - this.ws[kReceivedClose] = true +function checkNetConnect (netConnect, origin) { + const url = new URL(origin) + if (netConnect === true) { + return true + } else if (Array.isArray(netConnect) && netConnect.some((matcher) => matchValue(matcher, url.host))) { + return true + } + return false +} - this.end() +function buildMockOptions (opts) { + if (opts) { + const { agent, ...mockOptions } = opts + return mockOptions + } +} - return - } else if (this.#info.opcode === opcodes.PING) { - // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in - // response, unless it already received a Close frame. - // A Pong frame sent in response to a Ping frame must have identical - // "Application data" +module.exports = { + getResponseData, + getMockDispatch, + addMockDispatch, + deleteMockDispatch, + buildKey, + generateKeyValues, + matchValue, + getResponse, + getStatusText, + mockDispatch, + buildMockDispatch, + checkNetConnect, + buildMockOptions, + getHeaderByName +} - const body = this.consume(payloadLength) - if (!this.ws[kReceivedClose]) { - const frame = new WebsocketFrameSend(body) +/***/ }), - this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)) +/***/ 6823: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (channels.ping.hasSubscribers) { - channels.ping.publish({ - payload: body - }) - } - } +"use strict"; - this.#state = parserStates.INFO - if (this.#byteOffset > 0) { - continue - } else { - callback() - return - } - } else if (this.#info.opcode === opcodes.PONG) { - // A Pong frame MAY be sent unsolicited. This serves as a - // unidirectional heartbeat. A response to an unsolicited Pong frame is - // not expected. +const { Transform } = __nccwpck_require__(2781) +const { Console } = __nccwpck_require__(6206) - const body = this.consume(payloadLength) +/** + * Gets the output of `console.table(…)` as a string. + */ +module.exports = class PendingInterceptorsFormatter { + constructor ({ disableColors } = {}) { + this.transform = new Transform({ + transform (chunk, _enc, cb) { + cb(null, chunk) + } + }) - if (channels.pong.hasSubscribers) { - channels.pong.publish({ - payload: body - }) - } + this.logger = new Console({ + stdout: this.transform, + inspectOptions: { + colors: !disableColors && !process.env.CI + } + }) + } - if (this.#byteOffset > 0) { - continue - } else { - callback() - return - } - } - } else if (this.#state === parserStates.PAYLOADLENGTH_16) { - if (this.#byteOffset < 2) { - return callback() - } + format (pendingInterceptors) { + const withPrettyHeaders = pendingInterceptors.map( + ({ method, path, data: { statusCode }, persist, times, timesInvoked, origin }) => ({ + Method: method, + Origin: origin, + Path: path, + 'Status code': statusCode, + Persistent: persist ? '✅' : '❌', + Invocations: timesInvoked, + Remaining: persist ? Infinity : times - timesInvoked + })) - const buffer = this.consume(2) + this.logger.table(withPrettyHeaders) + return this.transform.read().toString() + } +} - this.#info.payloadLength = buffer.readUInt16BE(0) - this.#state = parserStates.READ_DATA - } else if (this.#state === parserStates.PAYLOADLENGTH_64) { - if (this.#byteOffset < 8) { - return callback() - } - const buffer = this.consume(8) - const upper = buffer.readUInt32BE(0) +/***/ }), - // 2^31 is the maxinimum bytes an arraybuffer can contain - // on 32-bit systems. Although, on 64-bit systems, this is - // 2^53-1 bytes. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length - // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275 - // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e - if (upper > 2 ** 31 - 1) { - failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.') - return - } +/***/ 8891: +/***/ ((module) => { - const lower = buffer.readUInt32BE(4) +"use strict"; - this.#info.payloadLength = (upper << 8) + lower - this.#state = parserStates.READ_DATA - } else if (this.#state === parserStates.READ_DATA) { - if (this.#byteOffset < this.#info.payloadLength) { - // If there is still more data in this chunk that needs to be read - return callback() - } else if (this.#byteOffset >= this.#info.payloadLength) { - // If the server sent multiple frames in a single chunk - const body = this.consume(this.#info.payloadLength) +const singulars = { + pronoun: 'it', + is: 'is', + was: 'was', + this: 'this' +} - this.#fragments.push(body) +const plurals = { + pronoun: 'they', + is: 'are', + was: 'were', + this: 'these' +} - // If the frame is unfragmented, or a fragmented frame was terminated, - // a message was received - if (!this.#info.fragmented || (this.#info.fin && this.#info.opcode === opcodes.CONTINUATION)) { - const fullMessage = Buffer.concat(this.#fragments) +module.exports = class Pluralizer { + constructor (singular, plural) { + this.singular = singular + this.plural = plural + } - websocketMessageReceived(this.ws, this.#info.originalOpcode, fullMessage) + pluralize (count) { + const one = count === 1 + const keys = one ? singulars : plurals + const noun = one ? this.singular : this.plural + return { ...keys, count, noun } + } +} - this.#info = {} - this.#fragments.length = 0 - } - this.#state = parserStates.INFO - } - } +/***/ }), - if (this.#byteOffset > 0) { - continue - } else { - callback() - break - } - } - } +/***/ 8266: +/***/ ((module) => { - /** - * Take n bytes from the buffered Buffers - * @param {number} n - * @returns {Buffer|null} - */ - consume (n) { - if (n > this.#byteOffset) { - return null - } else if (n === 0) { - return emptyBuffer - } +"use strict"; +/* eslint-disable */ - if (this.#buffers[0].length === n) { - this.#byteOffset -= this.#buffers[0].length - return this.#buffers.shift() - } - const buffer = Buffer.allocUnsafe(n) - let offset = 0 - while (offset !== n) { - const next = this.#buffers[0] - const { length } = next +// Extracted from node/lib/internal/fixed_queue.js - if (length + offset === n) { - buffer.set(this.#buffers.shift(), offset) - break - } else if (length + offset > n) { - buffer.set(next.subarray(0, n - offset), offset) - this.#buffers[0] = next.subarray(n - offset) - break - } else { - buffer.set(this.#buffers.shift(), offset) - offset += next.length - } - } +// Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. +const kSize = 2048; +const kMask = kSize - 1; - this.#byteOffset -= n +// The FixedQueue is implemented as a singly-linked list of fixed-size +// circular buffers. It looks something like this: +// +// head tail +// | | +// v v +// +-----------+ <-----\ +-----------+ <------\ +-----------+ +// | [null] | \----- | next | \------- | next | +// +-----------+ +-----------+ +-----------+ +// | item | <-- bottom | item | <-- bottom | [empty] | +// | item | | item | | [empty] | +// | item | | item | | [empty] | +// | item | | item | | [empty] | +// | item | | item | bottom --> | item | +// | item | | item | | item | +// | ... | | ... | | ... | +// | item | | item | | item | +// | item | | item | | item | +// | [empty] | <-- top | item | | item | +// | [empty] | | item | | item | +// | [empty] | | [empty] | <-- top top --> | [empty] | +// +-----------+ +-----------+ +-----------+ +// +// Or, if there is only one circular buffer, it looks something +// like either of these: +// +// head tail head tail +// | | | | +// v v v v +// +-----------+ +-----------+ +// | [null] | | [null] | +// +-----------+ +-----------+ +// | [empty] | | item | +// | [empty] | | item | +// | item | <-- bottom top --> | [empty] | +// | item | | [empty] | +// | [empty] | <-- top bottom --> | item | +// | [empty] | | item | +// +-----------+ +-----------+ +// +// Adding a value means moving `top` forward by one, removing means +// moving `bottom` forward by one. After reaching the end, the queue +// wraps around. +// +// When `top === bottom` the current queue is empty and when +// `top + 1 === bottom` it's full. This wastes a single space of storage +// but allows much quicker checks. - return buffer +class FixedCircularBuffer { + constructor() { + this.bottom = 0; + this.top = 0; + this.list = new Array(kSize); + this.next = null; } - parseCloseBody (onlyCode, data) { - // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 - /** @type {number|undefined} */ - let code - - if (data.length >= 2) { - // _The WebSocket Connection Close Code_ is - // defined as the status code (Section 7.4) contained in the first Close - // control frame received by the application - code = data.readUInt16BE(0) - } + isEmpty() { + return this.top === this.bottom; + } - if (onlyCode) { - if (!isValidStatusCode(code)) { - return null - } + isFull() { + return ((this.top + 1) & kMask) === this.bottom; + } - return { code } - } + push(data) { + this.list[this.top] = data; + this.top = (this.top + 1) & kMask; + } - // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 - /** @type {Buffer} */ - let reason = data.subarray(2) + shift() { + const nextItem = this.list[this.bottom]; + if (nextItem === undefined) + return null; + this.list[this.bottom] = undefined; + this.bottom = (this.bottom + 1) & kMask; + return nextItem; + } +} - // Remove BOM - if (reason[0] === 0xEF && reason[1] === 0xBB && reason[2] === 0xBF) { - reason = reason.subarray(3) - } +module.exports = class FixedQueue { + constructor() { + this.head = this.tail = new FixedCircularBuffer(); + } - if (code !== undefined && !isValidStatusCode(code)) { - return null - } + isEmpty() { + return this.head.isEmpty(); + } - try { - // TODO: optimize this - reason = new TextDecoder('utf-8', { fatal: true }).decode(reason) - } catch { - return null + push(data) { + if (this.head.isFull()) { + // Head is full: Creates a new queue, sets the old queue's `.next` to it, + // and sets it as the new main queue. + this.head = this.head.next = new FixedCircularBuffer(); } - - return { code, reason } + this.head.push(data); } - get closingInfo () { - return this.#info.closeInfo + shift() { + const tail = this.tail; + const next = tail.shift(); + if (tail.isEmpty() && tail.next !== null) { + // If there is another queue, it forms the new tail. + this.tail = tail.next; + } + return next; } -} - -module.exports = { - ByteParser -} +}; /***/ }), -/***/ 7578: -/***/ ((module) => { +/***/ 3198: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -module.exports = { - kWebSocketURL: Symbol('url'), - kReadyState: Symbol('ready state'), - kController: Symbol('controller'), - kResponse: Symbol('response'), - kBinaryType: Symbol('binary type'), - kSentClose: Symbol('sent close'), - kReceivedClose: Symbol('received close'), - kByteParser: Symbol('byte parser') -} +const DispatcherBase = __nccwpck_require__(4839) +const FixedQueue = __nccwpck_require__(8266) +const { kConnected, kSize, kRunning, kPending, kQueued, kBusy, kFree, kUrl, kClose, kDestroy, kDispatch } = __nccwpck_require__(2785) +const PoolStats = __nccwpck_require__(9689) +const kClients = Symbol('clients') +const kNeedDrain = Symbol('needDrain') +const kQueue = Symbol('queue') +const kClosedResolve = Symbol('closed resolve') +const kOnDrain = Symbol('onDrain') +const kOnConnect = Symbol('onConnect') +const kOnDisconnect = Symbol('onDisconnect') +const kOnConnectionError = Symbol('onConnectionError') +const kGetDispatcher = Symbol('get dispatcher') +const kAddClient = Symbol('add client') +const kRemoveClient = Symbol('remove client') +const kStats = Symbol('stats') -/***/ }), +class PoolBase extends DispatcherBase { + constructor () { + super() -/***/ 5515: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this[kQueue] = new FixedQueue() + this[kClients] = [] + this[kQueued] = 0 -"use strict"; + const pool = this + this[kOnDrain] = function onDrain (origin, targets) { + const queue = pool[kQueue] -const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = __nccwpck_require__(7578) -const { states, opcodes } = __nccwpck_require__(9188) -const { MessageEvent, ErrorEvent } = __nccwpck_require__(2611) + let needDrain = false -/* globals Blob */ + while (!needDrain) { + const item = queue.shift() + if (!item) { + break + } + pool[kQueued]-- + needDrain = !this.dispatch(item.opts, item.handler) + } -/** - * @param {import('./websocket').WebSocket} ws - */ -function isEstablished (ws) { - // If the server's response is validated as provided for above, it is - // said that _The WebSocket Connection is Established_ and that the - // WebSocket Connection is in the OPEN state. - return ws[kReadyState] === states.OPEN -} + this[kNeedDrain] = needDrain -/** - * @param {import('./websocket').WebSocket} ws - */ -function isClosing (ws) { - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - return ws[kReadyState] === states.CLOSING -} + if (!this[kNeedDrain] && pool[kNeedDrain]) { + pool[kNeedDrain] = false + pool.emit('drain', origin, [pool, ...targets]) + } -/** - * @param {import('./websocket').WebSocket} ws - */ -function isClosed (ws) { - return ws[kReadyState] === states.CLOSED -} + if (pool[kClosedResolve] && queue.isEmpty()) { + Promise + .all(pool[kClients].map(c => c.close())) + .then(pool[kClosedResolve]) + } + } -/** - * @see https://dom.spec.whatwg.org/#concept-event-fire - * @param {string} e - * @param {EventTarget} target - * @param {EventInit | undefined} eventInitDict - */ -function fireEvent (e, target, eventConstructor = Event, eventInitDict) { - // 1. If eventConstructor is not given, then let eventConstructor be Event. + this[kOnConnect] = (origin, targets) => { + pool.emit('connect', origin, [pool, ...targets]) + } - // 2. Let event be the result of creating an event given eventConstructor, - // in the relevant realm of target. - // 3. Initialize event’s type attribute to e. - const event = new eventConstructor(e, eventInitDict) // eslint-disable-line new-cap + this[kOnDisconnect] = (origin, targets, err) => { + pool.emit('disconnect', origin, [pool, ...targets], err) + } - // 4. Initialize any other IDL attributes of event as described in the - // invocation of this algorithm. + this[kOnConnectionError] = (origin, targets, err) => { + pool.emit('connectionError', origin, [pool, ...targets], err) + } - // 5. Return the result of dispatching event at target, with legacy target - // override flag set if set. - target.dispatchEvent(event) -} + this[kStats] = new PoolStats(this) + } -/** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - * @param {import('./websocket').WebSocket} ws - * @param {number} type Opcode - * @param {Buffer} data application data - */ -function websocketMessageReceived (ws, type, data) { - // 1. If ready state is not OPEN (1), then return. - if (ws[kReadyState] !== states.OPEN) { - return + get [kBusy] () { + return this[kNeedDrain] + } + + get [kConnected] () { + return this[kClients].filter(client => client[kConnected]).length + } + + get [kFree] () { + return this[kClients].filter(client => client[kConnected] && !client[kNeedDrain]).length + } + + get [kPending] () { + let ret = this[kQueued] + for (const { [kPending]: pending } of this[kClients]) { + ret += pending + } + return ret } - // 2. Let dataForEvent be determined by switching on type and binary type: - let dataForEvent + get [kRunning] () { + let ret = 0 + for (const { [kRunning]: running } of this[kClients]) { + ret += running + } + return ret + } - if (type === opcodes.TEXT) { - // -> type indicates that the data is Text - // a new DOMString containing data - try { - dataForEvent = new TextDecoder('utf-8', { fatal: true }).decode(data) - } catch { - failWebsocketConnection(ws, 'Received invalid UTF-8 in text frame.') - return + get [kSize] () { + let ret = this[kQueued] + for (const { [kSize]: size } of this[kClients]) { + ret += size } - } else if (type === opcodes.BINARY) { - if (ws[kBinaryType] === 'blob') { - // -> type indicates that the data is Binary and binary type is "blob" - // a new Blob object, created in the relevant Realm of the WebSocket - // object, that represents data as its raw data - dataForEvent = new Blob([data]) + return ret + } + + get stats () { + return this[kStats] + } + + async [kClose] () { + if (this[kQueue].isEmpty()) { + return Promise.all(this[kClients].map(c => c.close())) } else { - // -> type indicates that the data is Binary and binary type is "arraybuffer" - // a new ArrayBuffer object, created in the relevant Realm of the - // WebSocket object, whose contents are data - dataForEvent = new Uint8Array(data).buffer + return new Promise((resolve) => { + this[kClosedResolve] = resolve + }) } } - // 3. Fire an event named message at the WebSocket object, using MessageEvent, - // with the origin attribute initialized to the serialization of the WebSocket - // object’s url's origin, and the data attribute initialized to dataForEvent. - fireEvent('message', ws, MessageEvent, { - origin: ws[kWebSocketURL].origin, - data: dataForEvent - }) -} + async [kDestroy] (err) { + while (true) { + const item = this[kQueue].shift() + if (!item) { + break + } + item.handler.onError(err) + } -/** - * @see https://datatracker.ietf.org/doc/html/rfc6455 - * @see https://datatracker.ietf.org/doc/html/rfc2616 - * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 - * @param {string} protocol - */ -function isValidSubprotocol (protocol) { - // If present, this value indicates one - // or more comma-separated subprotocol the client wishes to speak, - // ordered by preference. The elements that comprise this value - // MUST be non-empty strings with characters in the range U+0021 to - // U+007E not including separator characters as defined in - // [RFC2616] and MUST all be unique strings. - if (protocol.length === 0) { - return false + return Promise.all(this[kClients].map(c => c.destroy(err))) } - for (const char of protocol) { - const code = char.charCodeAt(0) + [kDispatch] (opts, handler) { + const dispatcher = this[kGetDispatcher]() - if ( - code < 0x21 || - code > 0x7E || - char === '(' || - char === ')' || - char === '<' || - char === '>' || - char === '@' || - char === ',' || - char === ';' || - char === ':' || - char === '\\' || - char === '"' || - char === '/' || - char === '[' || - char === ']' || - char === '?' || - char === '=' || - char === '{' || - char === '}' || - code === 32 || // SP - code === 9 // HT - ) { - return false + if (!dispatcher) { + this[kNeedDrain] = true + this[kQueue].push({ opts, handler }) + this[kQueued]++ + } else if (!dispatcher.dispatch(opts, handler)) { + dispatcher[kNeedDrain] = true + this[kNeedDrain] = !this[kGetDispatcher]() } - } - - return true -} -/** - * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 - * @param {number} code - */ -function isValidStatusCode (code) { - if (code >= 1000 && code < 1015) { - return ( - code !== 1004 && // reserved - code !== 1005 && // "MUST NOT be set as a status code" - code !== 1006 // "MUST NOT be set as a status code" - ) + return !this[kNeedDrain] } - return code >= 3000 && code <= 4999 -} + [kAddClient] (client) { + client + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) -/** - * @param {import('./websocket').WebSocket} ws - * @param {string|undefined} reason - */ -function failWebsocketConnection (ws, reason) { - const { [kController]: controller, [kResponse]: response } = ws + this[kClients].push(client) - controller.abort() + if (this[kNeedDrain]) { + process.nextTick(() => { + if (this[kNeedDrain]) { + this[kOnDrain](client[kUrl], [this, client]) + } + }) + } - if (response?.socket && !response.socket.destroyed) { - response.socket.destroy() + return this } - if (reason) { - fireEvent('error', ws, ErrorEvent, { - error: new Error(reason) + [kRemoveClient] (client) { + client.close(() => { + const idx = this[kClients].indexOf(client) + if (idx !== -1) { + this[kClients].splice(idx, 1) + } }) + + this[kNeedDrain] = this[kClients].some(dispatcher => ( + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + )) } } module.exports = { - isEstablished, - isClosing, - isClosed, - fireEvent, - isValidSubprotocol, - isValidStatusCode, - failWebsocketConnection, - websocketMessageReceived + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher } /***/ }), -/***/ 4284: +/***/ 9689: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -"use strict"; +const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = __nccwpck_require__(2785) +const kPool = Symbol('pool') + +class PoolStats { + constructor (pool) { + this[kPool] = pool + } + get connected () { + return this[kPool][kConnected] + } -const { webidl } = __nccwpck_require__(1744) -const { DOMException } = __nccwpck_require__(1037) -const { URLSerializer } = __nccwpck_require__(685) -const { getGlobalOrigin } = __nccwpck_require__(1246) -const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = __nccwpck_require__(9188) -const { - kWebSocketURL, - kReadyState, - kController, - kBinaryType, - kResponse, - kSentClose, - kByteParser -} = __nccwpck_require__(7578) -const { isEstablished, isClosing, isValidSubprotocol, failWebsocketConnection, fireEvent } = __nccwpck_require__(5515) -const { establishWebSocketConnection } = __nccwpck_require__(5354) -const { WebsocketFrameSend } = __nccwpck_require__(5444) -const { ByteParser } = __nccwpck_require__(1688) -const { kEnumerableProperty, isBlobLike } = __nccwpck_require__(3983) -const { getGlobalDispatcher } = __nccwpck_require__(1892) -const { types } = __nccwpck_require__(3837) + get free () { + return this[kPool][kFree] + } -let experimentalWarned = false + get pending () { + return this[kPool][kPending] + } -// https://websockets.spec.whatwg.org/#interface-definition -class WebSocket extends EventTarget { - #events = { - open: null, - error: null, - close: null, - message: null + get queued () { + return this[kPool][kQueued] } - #bufferedAmount = 0 - #protocol = '' - #extensions = '' + get running () { + return this[kPool][kRunning] + } - /** - * @param {string} url - * @param {string|string[]} protocols - */ - constructor (url, protocols = []) { - super() + get size () { + return this[kPool][kSize] + } +} + +module.exports = PoolStats + + +/***/ }), - webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket constructor' }) +/***/ 4634: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - if (!experimentalWarned) { - experimentalWarned = true - process.emitWarning('WebSockets are experimental, expect them to change at any time.', { - code: 'UNDICI-WS' - }) - } +"use strict"; - const options = webidl.converters['DOMString or sequence or WebSocketInit'](protocols) - url = webidl.converters.USVString(url) - protocols = options.protocols +const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kGetDispatcher +} = __nccwpck_require__(3198) +const Client = __nccwpck_require__(3598) +const { + InvalidArgumentError +} = __nccwpck_require__(8045) +const util = __nccwpck_require__(3983) +const { kUrl, kInterceptors } = __nccwpck_require__(2785) +const buildConnector = __nccwpck_require__(2067) - // 1. Let baseURL be this's relevant settings object's API base URL. - const baseURL = getGlobalOrigin() +const kOptions = Symbol('options') +const kConnections = Symbol('connections') +const kFactory = Symbol('factory') - // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. - let urlRecord +function defaultFactory (origin, opts) { + return new Client(origin, opts) +} - try { - urlRecord = new URL(url, baseURL) - } catch (e) { - // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. - throw new DOMException(e, 'SyntaxError') - } +class Pool extends PoolBase { + constructor (origin, { + connections, + factory = defaultFactory, + connect, + connectTimeout, + tls, + maxCachedSessions, + socketPath, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + allowH2, + ...options + } = {}) { + super() - // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". - if (urlRecord.protocol === 'http:') { - urlRecord.protocol = 'ws:' - } else if (urlRecord.protocol === 'https:') { - // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". - urlRecord.protocol = 'wss:' + if (connections != null && (!Number.isFinite(connections) || connections < 0)) { + throw new InvalidArgumentError('invalid connections') } - // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. - if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { - throw new DOMException( - `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, - 'SyntaxError' - ) + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') } - // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" - // DOMException. - if (urlRecord.hash || urlRecord.href.endsWith('#')) { - throw new DOMException('Got fragment', 'SyntaxError') + if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') { + throw new InvalidArgumentError('connect must be a function or an object') } - // 8. If protocols is a string, set protocols to a sequence consisting - // of just that string. - if (typeof protocols === 'string') { - protocols = [protocols] + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), + ...connect + }) } - // 9. If any of the values in protocols occur more than once or otherwise - // fail to match the requirements for elements that comprise the value - // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket - // protocol, then throw a "SyntaxError" DOMException. - if (protocols.length !== new Set(protocols.map(p => p.toLowerCase())).size) { - throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + this[kInterceptors] = options.interceptors && options.interceptors.Pool && Array.isArray(options.interceptors.Pool) + ? options.interceptors.Pool + : [] + this[kConnections] = connections || null + this[kUrl] = util.parseOrigin(origin) + this[kOptions] = { ...util.deepClone(options), connect, allowH2 } + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined + this[kFactory] = factory + } + + [kGetDispatcher] () { + let dispatcher = this[kClients].find(dispatcher => !dispatcher[kNeedDrain]) + + if (dispatcher) { + return dispatcher } - if (protocols.length > 0 && !protocols.every(p => isValidSubprotocol(p))) { - throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + if (!this[kConnections] || this[kClients].length < this[kConnections]) { + dispatcher = this[kFactory](this[kUrl], this[kOptions]) + this[kAddClient](dispatcher) } - // 10. Set this's url to urlRecord. - this[kWebSocketURL] = new URL(urlRecord.href) + return dispatcher + } +} - // 11. Let client be this's relevant settings object. +module.exports = Pool - // 12. Run this step in parallel: - // 1. Establish a WebSocket connection given urlRecord, protocols, - // and client. - this[kController] = establishWebSocketConnection( - urlRecord, - protocols, - this, - (response) => this.#onConnectionEstablished(response), - options - ) +/***/ }), - // Each WebSocket object has an associated ready state, which is a - // number representing the state of the connection. Initially it must - // be CONNECTING (0). - this[kReadyState] = WebSocket.CONNECTING +/***/ 7858: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - // The extensions attribute must initially return the empty string. +"use strict"; - // The protocol attribute must initially return the empty string. - // Each WebSocket object has an associated binary type, which is a - // BinaryType. Initially it must be "blob". - this[kBinaryType] = 'blob' - } +const { kProxy, kClose, kDestroy, kInterceptors } = __nccwpck_require__(2785) +const { URL } = __nccwpck_require__(7310) +const Agent = __nccwpck_require__(7890) +const Pool = __nccwpck_require__(4634) +const DispatcherBase = __nccwpck_require__(4839) +const { InvalidArgumentError, RequestAbortedError } = __nccwpck_require__(8045) +const buildConnector = __nccwpck_require__(2067) - /** - * @see https://websockets.spec.whatwg.org/#dom-websocket-close - * @param {number|undefined} code - * @param {string|undefined} reason - */ - close (code = undefined, reason = undefined) { - webidl.brandCheck(this, WebSocket) +const kAgent = Symbol('proxy agent') +const kClient = Symbol('proxy client') +const kProxyHeaders = Symbol('proxy headers') +const kRequestTls = Symbol('request tls settings') +const kProxyTls = Symbol('proxy tls settings') +const kConnectEndpoint = Symbol('connect endpoint function') - if (code !== undefined) { - code = webidl.converters['unsigned short'](code, { clamp: true }) - } +function defaultProtocolPort (protocol) { + return protocol === 'https:' ? 443 : 80 +} - if (reason !== undefined) { - reason = webidl.converters.USVString(reason) - } +function buildProxyOptions (opts) { + if (typeof opts === 'string') { + opts = { uri: opts } + } - // 1. If code is present, but is neither an integer equal to 1000 nor an - // integer in the range 3000 to 4999, inclusive, throw an - // "InvalidAccessError" DOMException. - if (code !== undefined) { - if (code !== 1000 && (code < 3000 || code > 4999)) { - throw new DOMException('invalid code', 'InvalidAccessError') - } - } + if (!opts || !opts.uri) { + throw new InvalidArgumentError('Proxy opts.uri is mandatory') + } - let reasonByteLength = 0 + return { + uri: opts.uri, + protocol: opts.protocol || 'https' + } +} - // 2. If reason is present, then run these substeps: - if (reason !== undefined) { - // 1. Let reasonBytes be the result of encoding reason. - // 2. If reasonBytes is longer than 123 bytes, then throw a - // "SyntaxError" DOMException. - reasonByteLength = Buffer.byteLength(reason) +function defaultFactory (origin, opts) { + return new Pool(origin, opts) +} - if (reasonByteLength > 123) { - throw new DOMException( - `Reason must be less than 123 bytes; received ${reasonByteLength}`, - 'SyntaxError' - ) - } +class ProxyAgent extends DispatcherBase { + constructor (opts) { + super(opts) + this[kProxy] = buildProxyOptions(opts) + this[kAgent] = new Agent(opts) + this[kInterceptors] = opts.interceptors && opts.interceptors.ProxyAgent && Array.isArray(opts.interceptors.ProxyAgent) + ? opts.interceptors.ProxyAgent + : [] + + if (typeof opts === 'string') { + opts = { uri: opts } } - // 3. Run the first matching steps from the following list: - if (this[kReadyState] === WebSocket.CLOSING || this[kReadyState] === WebSocket.CLOSED) { - // If this's ready state is CLOSING (2) or CLOSED (3) - // Do nothing. - } else if (!isEstablished(this)) { - // If the WebSocket connection is not yet established - // Fail the WebSocket connection and set this's ready state - // to CLOSING (2). - failWebsocketConnection(this, 'Connection was closed before it was established.') - this[kReadyState] = WebSocket.CLOSING - } else if (!isClosing(this)) { - // If the WebSocket closing handshake has not yet been started - // Start the WebSocket closing handshake and set this's ready - // state to CLOSING (2). - // - If neither code nor reason is present, the WebSocket Close - // message must not have a body. - // - If code is present, then the status code to use in the - // WebSocket Close message must be the integer given by code. - // - If reason is also present, then reasonBytes must be - // provided in the Close message after the status code. + if (!opts || !opts.uri) { + throw new InvalidArgumentError('Proxy opts.uri is mandatory') + } - const frame = new WebsocketFrameSend() + const { clientFactory = defaultFactory } = opts + + if (typeof clientFactory !== 'function') { + throw new InvalidArgumentError('Proxy opts.clientFactory must be a function.') + } - // If neither code nor reason is present, the WebSocket Close - // message must not have a body. + this[kRequestTls] = opts.requestTls + this[kProxyTls] = opts.proxyTls + this[kProxyHeaders] = opts.headers || {} - // If code is present, then the status code to use in the - // WebSocket Close message must be the integer given by code. - if (code !== undefined && reason === undefined) { - frame.frameData = Buffer.allocUnsafe(2) - frame.frameData.writeUInt16BE(code, 0) - } else if (code !== undefined && reason !== undefined) { - // If reason is also present, then reasonBytes must be - // provided in the Close message after the status code. - frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength) - frame.frameData.writeUInt16BE(code, 0) - // the body MAY contain UTF-8-encoded data with value /reason/ - frame.frameData.write(reason, 2, 'utf-8') - } else { - frame.frameData = emptyBuffer - } + const resolvedUrl = new URL(opts.uri) + const { origin, port, host, username, password } = resolvedUrl - /** @type {import('stream').Duplex} */ - const socket = this[kResponse].socket + if (opts.auth && opts.token) { + throw new InvalidArgumentError('opts.auth cannot be used in combination with opts.token') + } else if (opts.auth) { + /* @deprecated in favour of opts.token */ + this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}` + } else if (opts.token) { + this[kProxyHeaders]['proxy-authorization'] = opts.token + } else if (username && password) { + this[kProxyHeaders]['proxy-authorization'] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString('base64')}` + } - socket.write(frame.createFrame(opcodes.CLOSE), (err) => { - if (!err) { - this[kSentClose] = true + const connect = buildConnector({ ...opts.proxyTls }) + this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }) + this[kClient] = clientFactory(resolvedUrl, { connect }) + this[kAgent] = new Agent({ + ...opts, + connect: async (opts, callback) => { + let requestedHost = opts.host + if (!opts.port) { + requestedHost += `:${defaultProtocolPort(opts.protocol)}` } - }) + try { + const { socket, statusCode } = await this[kClient].connect({ + origin, + port, + path: requestedHost, + signal: opts.signal, + headers: { + ...this[kProxyHeaders], + host + } + }) + if (statusCode !== 200) { + socket.on('error', () => {}).destroy() + callback(new RequestAbortedError(`Proxy response (${statusCode}) !== 200 when HTTP Tunneling`)) + } + if (opts.protocol !== 'https:') { + callback(null, socket) + return + } + let servername + if (this[kRequestTls]) { + servername = this[kRequestTls].servername + } else { + servername = opts.servername + } + this[kConnectEndpoint]({ ...opts, servername, httpSocket: socket }, callback) + } catch (err) { + callback(err) + } + } + }) + } - // Upon either sending or receiving a Close control frame, it is said - // that _The WebSocket Closing Handshake is Started_ and that the - // WebSocket connection is in the CLOSING state. - this[kReadyState] = states.CLOSING - } else { - // Otherwise - // Set this's ready state to CLOSING (2). - this[kReadyState] = WebSocket.CLOSING - } + dispatch (opts, handler) { + const { host } = new URL(opts.origin) + const headers = buildHeaders(opts.headers) + throwIfProxyAuthIsSent(headers) + return this[kAgent].dispatch( + { + ...opts, + headers: { + ...headers, + host + } + }, + handler + ) } - /** - * @see https://websockets.spec.whatwg.org/#dom-websocket-send - * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data - */ - send (data) { - webidl.brandCheck(this, WebSocket) + async [kClose] () { + await this[kAgent].close() + await this[kClient].close() + } - webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket.send' }) + async [kDestroy] () { + await this[kAgent].destroy() + await this[kClient].destroy() + } +} - data = webidl.converters.WebSocketSendData(data) +/** + * @param {string[] | Record} headers + * @returns {Record} + */ +function buildHeaders (headers) { + // When using undici.fetch, the headers list is stored + // as an array. + if (Array.isArray(headers)) { + /** @type {Record} */ + const headersPair = {} - // 1. If this's ready state is CONNECTING, then throw an - // "InvalidStateError" DOMException. - if (this[kReadyState] === WebSocket.CONNECTING) { - throw new DOMException('Sent before connected.', 'InvalidStateError') + for (let i = 0; i < headers.length; i += 2) { + headersPair[headers[i]] = headers[i + 1] } - // 2. Run the appropriate set of steps from the following list: - // https://datatracker.ietf.org/doc/html/rfc6455#section-6.1 - // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 + return headersPair + } - if (!isEstablished(this) || isClosing(this)) { - return - } + return headers +} - /** @type {import('stream').Duplex} */ - const socket = this[kResponse].socket +/** + * @param {Record} headers + * + * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers + * Nevertheless, it was changed and to avoid a security vulnerability by end users + * this check was created. + * It should be removed in the next major version for performance reasons + */ +function throwIfProxyAuthIsSent (headers) { + const existProxyAuth = headers && Object.keys(headers) + .find((key) => key.toLowerCase() === 'proxy-authorization') + if (existProxyAuth) { + throw new InvalidArgumentError('Proxy-Authorization should be sent in ProxyAgent constructor') + } +} - // If data is a string - if (typeof data === 'string') { - // If the WebSocket connection is established and the WebSocket - // closing handshake has not yet started, then the user agent - // must send a WebSocket Message comprised of the data argument - // using a text frame opcode; if the data cannot be sent, e.g. - // because it would need to be buffered but the buffer is full, - // the user agent must flag the WebSocket as full and then close - // the WebSocket connection. Any invocation of this method with a - // string argument that does not throw an exception must increase - // the bufferedAmount attribute by the number of bytes needed to - // express the argument as UTF-8. +module.exports = ProxyAgent - const value = Buffer.from(data) - const frame = new WebsocketFrameSend(value) - const buffer = frame.createFrame(opcodes.TEXT) - this.#bufferedAmount += value.byteLength - socket.write(buffer, () => { - this.#bufferedAmount -= value.byteLength - }) - } else if (types.isArrayBuffer(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need - // to be buffered but the buffer is full, the user agent must flag - // the WebSocket as full and then close the WebSocket connection. - // The data to be sent is the data stored in the buffer described - // by the ArrayBuffer object. Any invocation of this method with an - // ArrayBuffer argument that does not throw an exception must - // increase the bufferedAmount attribute by the length of the - // ArrayBuffer in bytes. +/***/ }), - const value = Buffer.from(data) - const frame = new WebsocketFrameSend(value) - const buffer = frame.createFrame(opcodes.BINARY) +/***/ 9459: +/***/ ((module) => { - this.#bufferedAmount += value.byteLength - socket.write(buffer, () => { - this.#bufferedAmount -= value.byteLength - }) - } else if (ArrayBuffer.isView(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need to - // be buffered but the buffer is full, the user agent must flag the - // WebSocket as full and then close the WebSocket connection. The - // data to be sent is the data stored in the section of the buffer - // described by the ArrayBuffer object that data references. Any - // invocation of this method with this kind of argument that does - // not throw an exception must increase the bufferedAmount attribute - // by the length of data’s buffer in bytes. +"use strict"; - const ab = Buffer.from(data, data.byteOffset, data.byteLength) - const frame = new WebsocketFrameSend(ab) - const buffer = frame.createFrame(opcodes.BINARY) +let fastNow = Date.now() +let fastNowTimeout - this.#bufferedAmount += ab.byteLength - socket.write(buffer, () => { - this.#bufferedAmount -= ab.byteLength - }) - } else if (isBlobLike(data)) { - // If the WebSocket connection is established, and the WebSocket - // closing handshake has not yet started, then the user agent must - // send a WebSocket Message comprised of data using a binary frame - // opcode; if the data cannot be sent, e.g. because it would need to - // be buffered but the buffer is full, the user agent must flag the - // WebSocket as full and then close the WebSocket connection. The data - // to be sent is the raw data represented by the Blob object. Any - // invocation of this method with a Blob argument that does not throw - // an exception must increase the bufferedAmount attribute by the size - // of the Blob object’s raw data, in bytes. +const fastTimers = [] - const frame = new WebsocketFrameSend() +function onTimeout () { + fastNow = Date.now() - data.arrayBuffer().then((ab) => { - const value = Buffer.from(ab) - frame.frameData = value - const buffer = frame.createFrame(opcodes.BINARY) + let len = fastTimers.length + let idx = 0 + while (idx < len) { + const timer = fastTimers[idx] + + if (timer.state === 0) { + timer.state = fastNow + timer.delay + } else if (timer.state > 0 && fastNow >= timer.state) { + timer.state = -1 + timer.callback(timer.opaque) + } - this.#bufferedAmount += value.byteLength - socket.write(buffer, () => { - this.#bufferedAmount -= value.byteLength - }) - }) + if (timer.state === -1) { + timer.state = -2 + if (idx !== len - 1) { + fastTimers[idx] = fastTimers.pop() + } else { + fastTimers.pop() + } + len -= 1 + } else { + idx += 1 } } - get readyState () { - webidl.brandCheck(this, WebSocket) + if (fastTimers.length > 0) { + refreshTimeout() + } +} - // The readyState getter steps are to return this's ready state. - return this[kReadyState] +function refreshTimeout () { + if (fastNowTimeout && fastNowTimeout.refresh) { + fastNowTimeout.refresh() + } else { + clearTimeout(fastNowTimeout) + fastNowTimeout = setTimeout(onTimeout, 1e3) + if (fastNowTimeout.unref) { + fastNowTimeout.unref() + } } +} - get bufferedAmount () { - webidl.brandCheck(this, WebSocket) +class Timeout { + constructor (callback, delay, opaque) { + this.callback = callback + this.delay = delay + this.opaque = opaque - return this.#bufferedAmount + // -2 not in timer list + // -1 in timer list but inactive + // 0 in timer list waiting for time + // > 0 in timer list waiting for time to expire + this.state = -2 + + this.refresh() } - get url () { - webidl.brandCheck(this, WebSocket) + refresh () { + if (this.state === -2) { + fastTimers.push(this) + if (!fastNowTimeout || fastTimers.length === 1) { + refreshTimeout() + } + } - // The url getter steps are to return this's url, serialized. - return URLSerializer(this[kWebSocketURL]) + this.state = 0 } - get extensions () { - webidl.brandCheck(this, WebSocket) + clear () { + this.state = -1 + } +} - return this.#extensions +module.exports = { + setTimeout (callback, delay, opaque) { + return delay < 1e3 + ? setTimeout(callback, delay, opaque) + : new Timeout(callback, delay, opaque) + }, + clearTimeout (timeout) { + if (timeout instanceof Timeout) { + timeout.clear() + } else { + clearTimeout(timeout) + } } +} - get protocol () { - webidl.brandCheck(this, WebSocket) - return this.#protocol - } +/***/ }), - get onopen () { - webidl.brandCheck(this, WebSocket) +/***/ 5354: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { - return this.#events.open - } +"use strict"; - set onopen (fn) { - webidl.brandCheck(this, WebSocket) - if (this.#events.open) { - this.removeEventListener('open', this.#events.open) - } +const diagnosticsChannel = __nccwpck_require__(7643) +const { uid, states } = __nccwpck_require__(9188) +const { + kReadyState, + kSentClose, + kByteParser, + kReceivedClose +} = __nccwpck_require__(7578) +const { fireEvent, failWebsocketConnection } = __nccwpck_require__(5515) +const { CloseEvent } = __nccwpck_require__(2611) +const { makeRequest } = __nccwpck_require__(8359) +const { fetching } = __nccwpck_require__(4881) +const { Headers } = __nccwpck_require__(554) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { kHeadersList } = __nccwpck_require__(2785) - if (typeof fn === 'function') { - this.#events.open = fn - this.addEventListener('open', fn) - } else { - this.#events.open = null - } - } +const channels = {} +channels.open = diagnosticsChannel.channel('undici:websocket:open') +channels.close = diagnosticsChannel.channel('undici:websocket:close') +channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') - get onerror () { - webidl.brandCheck(this, WebSocket) +/** @type {import('crypto')} */ +let crypto +try { + crypto = __nccwpck_require__(6113) +} catch { - return this.#events.error - } +} - set onerror (fn) { - webidl.brandCheck(this, WebSocket) +/** + * @see https://websockets.spec.whatwg.org/#concept-websocket-establish + * @param {URL} url + * @param {string|string[]} protocols + * @param {import('./websocket').WebSocket} ws + * @param {(response: any) => void} onEstablish + * @param {Partial} options + */ +function establishWebSocketConnection (url, protocols, ws, onEstablish, options) { + // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s + // scheme is "ws", and to "https" otherwise. + const requestURL = url - if (this.#events.error) { - this.removeEventListener('error', this.#events.error) - } + requestURL.protocol = url.protocol === 'ws:' ? 'http:' : 'https:' - if (typeof fn === 'function') { - this.#events.error = fn - this.addEventListener('error', fn) - } else { - this.#events.error = null - } - } + // 2. Let request be a new request, whose URL is requestURL, client is client, + // service-workers mode is "none", referrer is "no-referrer", mode is + // "websocket", credentials mode is "include", cache mode is "no-store" , + // and redirect mode is "error". + const request = makeRequest({ + urlList: [requestURL], + serviceWorkers: 'none', + referrer: 'no-referrer', + mode: 'websocket', + credentials: 'include', + cache: 'no-store', + redirect: 'error' + }) - get onclose () { - webidl.brandCheck(this, WebSocket) + // Note: undici extension, allow setting custom headers. + if (options.headers) { + const headersList = new Headers(options.headers)[kHeadersList] - return this.#events.close + request.headersList = headersList } - set onclose (fn) { - webidl.brandCheck(this, WebSocket) + // 3. Append (`Upgrade`, `websocket`) to request’s header list. + // 4. Append (`Connection`, `Upgrade`) to request’s header list. + // Note: both of these are handled by undici currently. + // https://github.com/nodejs/undici/blob/68c269c4144c446f3f1220951338daef4a6b5ec4/lib/client.js#L1397 - if (this.#events.close) { - this.removeEventListener('close', this.#events.close) - } + // 5. Let keyValue be a nonce consisting of a randomly selected + // 16-byte value that has been forgiving-base64-encoded and + // isomorphic encoded. + const keyValue = crypto.randomBytes(16).toString('base64') - if (typeof fn === 'function') { - this.#events.close = fn - this.addEventListener('close', fn) - } else { - this.#events.close = null - } - } + // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s + // header list. + request.headersList.append('sec-websocket-key', keyValue) - get onmessage () { - webidl.brandCheck(this, WebSocket) + // 7. Append (`Sec-WebSocket-Version`, `13`) to request’s + // header list. + request.headersList.append('sec-websocket-version', '13') - return this.#events.message + // 8. For each protocol in protocols, combine + // (`Sec-WebSocket-Protocol`, protocol) in request’s header + // list. + for (const protocol of protocols) { + request.headersList.append('sec-websocket-protocol', protocol) } - set onmessage (fn) { - webidl.brandCheck(this, WebSocket) + // 9. Let permessageDeflate be a user-agent defined + // "permessage-deflate" extension header value. + // https://github.com/mozilla/gecko-dev/blob/ce78234f5e653a5d3916813ff990f053510227bc/netwerk/protocol/websocket/WebSocketChannel.cpp#L2673 + // TODO: enable once permessage-deflate is supported + const permessageDeflate = '' // 'permessage-deflate; 15' - if (this.#events.message) { - this.removeEventListener('message', this.#events.message) - } + // 10. Append (`Sec-WebSocket-Extensions`, permessageDeflate) to + // request’s header list. + // request.headersList.append('sec-websocket-extensions', permessageDeflate) - if (typeof fn === 'function') { - this.#events.message = fn - this.addEventListener('message', fn) - } else { - this.#events.message = null - } - } + // 11. Fetch request with useParallelQueue set to true, and + // processResponse given response being these steps: + const controller = fetching({ + request, + useParallelQueue: true, + dispatcher: options.dispatcher ?? getGlobalDispatcher(), + processResponse (response) { + // 1. If response is a network error or its status is not 101, + // fail the WebSocket connection. + if (response.type === 'error' || response.status !== 101) { + failWebsocketConnection(ws, 'Received network error or non-101 status code.') + return + } - get binaryType () { - webidl.brandCheck(this, WebSocket) + // 2. If protocols is not the empty list and extracting header + // list values given `Sec-WebSocket-Protocol` and response’s + // header list results in null, failure, or the empty byte + // sequence, then fail the WebSocket connection. + if (protocols.length !== 0 && !response.headersList.get('Sec-WebSocket-Protocol')) { + failWebsocketConnection(ws, 'Server did not respond with sent protocols.') + return + } - return this[kBinaryType] - } + // 3. Follow the requirements stated step 2 to step 6, inclusive, + // of the last set of steps in section 4.1 of The WebSocket + // Protocol to validate response. This either results in fail + // the WebSocket connection or the WebSocket connection is + // established. - set binaryType (type) { - webidl.brandCheck(this, WebSocket) + // 2. If the response lacks an |Upgrade| header field or the |Upgrade| + // header field contains a value that is not an ASCII case- + // insensitive match for the value "websocket", the client MUST + // _Fail the WebSocket Connection_. + if (response.headersList.get('Upgrade')?.toLowerCase() !== 'websocket') { + failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".') + return + } - if (type !== 'blob' && type !== 'arraybuffer') { - this[kBinaryType] = 'blob' - } else { - this[kBinaryType] = type - } - } + // 3. If the response lacks a |Connection| header field or the + // |Connection| header field doesn't contain a token that is an + // ASCII case-insensitive match for the value "Upgrade", the client + // MUST _Fail the WebSocket Connection_. + if (response.headersList.get('Connection')?.toLowerCase() !== 'upgrade') { + failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".') + return + } - /** - * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol - */ - #onConnectionEstablished (response) { - // processResponse is called when the "response’s header list has been received and initialized." - // once this happens, the connection is open - this[kResponse] = response + // 4. If the response lacks a |Sec-WebSocket-Accept| header field or + // the |Sec-WebSocket-Accept| contains a value other than the + // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- + // Key| (as a string, not base64-decoded) with the string "258EAFA5- + // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and + // trailing whitespace, the client MUST _Fail the WebSocket + // Connection_. + const secWSAccept = response.headersList.get('Sec-WebSocket-Accept') + const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64') + if (secWSAccept !== digest) { + failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.') + return + } - const parser = new ByteParser(this) - parser.on('drain', function onParserDrain () { - this.ws[kResponse].socket.resume() - }) + // 5. If the response includes a |Sec-WebSocket-Extensions| header + // field and this header field indicates the use of an extension + // that was not present in the client's handshake (the server has + // indicated an extension not requested by the client), the client + // MUST _Fail the WebSocket Connection_. (The parsing of this + // header field to determine which extensions are requested is + // discussed in Section 9.1.) + const secExtension = response.headersList.get('Sec-WebSocket-Extensions') - response.socket.ws = this - this[kByteParser] = parser + if (secExtension !== null && secExtension !== permessageDeflate) { + failWebsocketConnection(ws, 'Received different permessage-deflate than the one set.') + return + } - // 1. Change the ready state to OPEN (1). - this[kReadyState] = states.OPEN + // 6. If the response includes a |Sec-WebSocket-Protocol| header field + // and this header field indicates the use of a subprotocol that was + // not present in the client's handshake (the server has indicated a + // subprotocol not requested by the client), the client MUST _Fail + // the WebSocket Connection_. + const secProtocol = response.headersList.get('Sec-WebSocket-Protocol') - // 2. Change the extensions attribute’s value to the extensions in use, if - // it is not the null value. - // https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 - const extensions = response.headersList.get('sec-websocket-extensions') + if (secProtocol !== null && secProtocol !== request.headersList.get('Sec-WebSocket-Protocol')) { + failWebsocketConnection(ws, 'Protocol was not set in the opening handshake.') + return + } - if (extensions !== null) { - this.#extensions = extensions - } + response.socket.on('data', onSocketData) + response.socket.on('close', onSocketClose) + response.socket.on('error', onSocketError) - // 3. Change the protocol attribute’s value to the subprotocol in use, if - // it is not the null value. - // https://datatracker.ietf.org/doc/html/rfc6455#section-1.9 - const protocol = response.headersList.get('sec-websocket-protocol') + if (channels.open.hasSubscribers) { + channels.open.publish({ + address: response.socket.address(), + protocol: secProtocol, + extensions: secExtension + }) + } - if (protocol !== null) { - this.#protocol = protocol + onEstablish(response) } + }) - // 4. Fire an event named open at the WebSocket object. - fireEvent('open', this) + return controller +} + +/** + * @param {Buffer} chunk + */ +function onSocketData (chunk) { + if (!this.ws[kByteParser].write(chunk)) { + this.pause() } } -// https://websockets.spec.whatwg.org/#dom-websocket-connecting -WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING -// https://websockets.spec.whatwg.org/#dom-websocket-open -WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN -// https://websockets.spec.whatwg.org/#dom-websocket-closing -WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING -// https://websockets.spec.whatwg.org/#dom-websocket-closed -WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED +/** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 + */ +function onSocketClose () { + const { ws } = this -Object.defineProperties(WebSocket.prototype, { - CONNECTING: staticPropertyDescriptors, - OPEN: staticPropertyDescriptors, - CLOSING: staticPropertyDescriptors, - CLOSED: staticPropertyDescriptors, - url: kEnumerableProperty, - readyState: kEnumerableProperty, - bufferedAmount: kEnumerableProperty, - onopen: kEnumerableProperty, - onerror: kEnumerableProperty, - onclose: kEnumerableProperty, - close: kEnumerableProperty, - onmessage: kEnumerableProperty, - binaryType: kEnumerableProperty, - send: kEnumerableProperty, - extensions: kEnumerableProperty, - protocol: kEnumerableProperty, - [Symbol.toStringTag]: { - value: 'WebSocket', - writable: false, - enumerable: false, - configurable: true - } -}) + // If the TCP connection was closed after the + // WebSocket closing handshake was completed, the WebSocket connection + // is said to have been closed _cleanly_. + const wasClean = ws[kSentClose] && ws[kReceivedClose] -Object.defineProperties(WebSocket, { - CONNECTING: staticPropertyDescriptors, - OPEN: staticPropertyDescriptors, - CLOSING: staticPropertyDescriptors, - CLOSED: staticPropertyDescriptors -}) + let code = 1005 + let reason = '' -webidl.converters['sequence'] = webidl.sequenceConverter( - webidl.converters.DOMString -) + const result = ws[kByteParser].closingInfo -webidl.converters['DOMString or sequence'] = function (V) { - if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) { - return webidl.converters['sequence'](V) + if (result) { + code = result.code ?? 1005 + reason = result.reason + } else if (!ws[kSentClose]) { + // If _The WebSocket + // Connection is Closed_ and no Close control frame was received by the + // endpoint (such as could occur if the underlying transport connection + // is lost), _The WebSocket Connection Close Code_ is considered to be + // 1006. + code = 1006 } - return webidl.converters.DOMString(V) -} + // 1. Change the ready state to CLOSED (3). + ws[kReadyState] = states.CLOSED -// This implements the propsal made in https://github.com/whatwg/websockets/issues/42 -webidl.converters.WebSocketInit = webidl.dictionaryConverter([ - { - key: 'protocols', - converter: webidl.converters['DOMString or sequence'], - get defaultValue () { - return [] - } - }, - { - key: 'dispatcher', - converter: (V) => V, - get defaultValue () { - return getGlobalDispatcher() - } - }, - { - key: 'headers', - converter: webidl.nullableConverter(webidl.converters.HeadersInit) - } -]) + // 2. If the user agent was required to fail the WebSocket + // connection, or if the WebSocket connection was closed + // after being flagged as full, fire an event named error + // at the WebSocket object. + // TODO -webidl.converters['DOMString or sequence or WebSocketInit'] = function (V) { - if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) { - return webidl.converters.WebSocketInit(V) - } + // 3. Fire an event named close at the WebSocket object, + // using CloseEvent, with the wasClean attribute + // initialized to true if the connection closed cleanly + // and false otherwise, the code attribute initialized to + // the WebSocket connection close code, and the reason + // attribute initialized to the result of applying UTF-8 + // decode without BOM to the WebSocket connection close + // reason. + fireEvent('close', ws, CloseEvent, { + wasClean, code, reason + }) - return { protocols: webidl.converters['DOMString or sequence'](V) } + if (channels.close.hasSubscribers) { + channels.close.publish({ + websocket: ws, + code, + reason + }) + } } -webidl.converters.WebSocketSendData = function (V) { - if (webidl.util.Type(V) === 'Object') { - if (isBlobLike(V)) { - return webidl.converters.Blob(V, { strict: false }) - } +function onSocketError (error) { + const { ws } = this - if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) { - return webidl.converters.BufferSource(V) - } + ws[kReadyState] = states.CLOSING + + if (channels.socketError.hasSubscribers) { + channels.socketError.publish(error) } - return webidl.converters.USVString(V) + this.destroy() } module.exports = { - WebSocket + establishWebSocketConnection } /***/ }), -/***/ 5840: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 9188: +/***/ ((module) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -Object.defineProperty(exports, "v1", ({ - enumerable: true, - get: function () { - return _v.default; - } -})); -Object.defineProperty(exports, "v3", ({ - enumerable: true, - get: function () { - return _v2.default; - } -})); -Object.defineProperty(exports, "v4", ({ - enumerable: true, - get: function () { - return _v3.default; - } -})); -Object.defineProperty(exports, "v5", ({ - enumerable: true, - get: function () { - return _v4.default; - } -})); -Object.defineProperty(exports, "NIL", ({ - enumerable: true, - get: function () { - return _nil.default; - } -})); -Object.defineProperty(exports, "version", ({ - enumerable: true, - get: function () { - return _version.default; - } -})); -Object.defineProperty(exports, "validate", ({ - enumerable: true, - get: function () { - return _validate.default; - } -})); -Object.defineProperty(exports, "stringify", ({ - enumerable: true, - get: function () { - return _stringify.default; - } -})); -Object.defineProperty(exports, "parse", ({ - enumerable: true, - get: function () { - return _parse.default; - } -})); - -var _v = _interopRequireDefault(__nccwpck_require__(8628)); - -var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); +// This is a Globally Unique Identifier unique used +// to validate that the endpoint accepts websocket +// connections. +// See https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3 +const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' -var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); +/** @type {PropertyDescriptor} */ +const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false +} -var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); +const states = { + CONNECTING: 0, + OPEN: 1, + CLOSING: 2, + CLOSED: 3 +} -var _nil = _interopRequireDefault(__nccwpck_require__(5332)); +const opcodes = { + CONTINUATION: 0x0, + TEXT: 0x1, + BINARY: 0x2, + CLOSE: 0x8, + PING: 0x9, + PONG: 0xA +} -var _version = _interopRequireDefault(__nccwpck_require__(1595)); +const maxUnsigned16Bit = 2 ** 16 - 1 // 65535 -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); +const parserStates = { + INFO: 0, + PAYLOADLENGTH_16: 2, + PAYLOADLENGTH_64: 3, + READ_DATA: 4 +} -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); +const emptyBuffer = Buffer.allocUnsafe(0) -var _parse = _interopRequireDefault(__nccwpck_require__(2746)); +module.exports = { + uid, + staticPropertyDescriptors, + states, + opcodes, + maxUnsigned16Bit, + parserStates, + emptyBuffer +} -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), -/***/ 4569: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 2611: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +const { webidl } = __nccwpck_require__(1744) +const { kEnumerableProperty } = __nccwpck_require__(3983) +const { MessagePort } = __nccwpck_require__(1267) -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); +/** + * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent + */ +class MessageEvent extends Event { + #eventInit -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + constructor (type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent constructor' }) -function md5(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); - } + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.MessageEventInit(eventInitDict) - return _crypto.default.createHash('md5').update(bytes).digest(); -} + super(type, eventInitDict) -var _default = md5; -exports["default"] = _default; + this.#eventInit = eventInitDict + } -/***/ }), + get data () { + webidl.brandCheck(this, MessageEvent) -/***/ 5332: -/***/ ((__unused_webpack_module, exports) => { + return this.#eventInit.data + } -"use strict"; + get origin () { + webidl.brandCheck(this, MessageEvent) + return this.#eventInit.origin + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; -var _default = '00000000-0000-0000-0000-000000000000'; -exports["default"] = _default; + get lastEventId () { + webidl.brandCheck(this, MessageEvent) -/***/ }), + return this.#eventInit.lastEventId + } -/***/ 2746: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + get source () { + webidl.brandCheck(this, MessageEvent) -"use strict"; + return this.#eventInit.source + } + get ports () { + webidl.brandCheck(this, MessageEvent) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + if (!Object.isFrozen(this.#eventInit.ports)) { + Object.freeze(this.#eventInit.ports) + } -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + return this.#eventInit.ports + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + initMessageEvent ( + type, + bubbles = false, + cancelable = false, + data = null, + origin = '', + lastEventId = '', + source = null, + ports = [] + ) { + webidl.brandCheck(this, MessageEvent) -function parse(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); + webidl.argumentLengthCheck(arguments, 1, { header: 'MessageEvent.initMessageEvent' }) + + return new MessageEvent(type, { + bubbles, cancelable, data, origin, lastEventId, source, ports + }) } +} - let v; - const arr = new Uint8Array(16); // Parse ########-....-....-....-............ +/** + * @see https://websockets.spec.whatwg.org/#the-closeevent-interface + */ +class CloseEvent extends Event { + #eventInit - arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; - arr[1] = v >>> 16 & 0xff; - arr[2] = v >>> 8 & 0xff; - arr[3] = v & 0xff; // Parse ........-####-....-....-............ + constructor (type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'CloseEvent constructor' }) - arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; - arr[5] = v & 0xff; // Parse ........-....-####-....-............ + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.CloseEventInit(eventInitDict) - arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; - arr[7] = v & 0xff; // Parse ........-....-....-####-............ + super(type, eventInitDict) - arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; - arr[9] = v & 0xff; // Parse ........-....-....-....-############ - // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + this.#eventInit = eventInitDict + } - arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; - arr[11] = v / 0x100000000 & 0xff; - arr[12] = v >>> 24 & 0xff; - arr[13] = v >>> 16 & 0xff; - arr[14] = v >>> 8 & 0xff; - arr[15] = v & 0xff; - return arr; -} + get wasClean () { + webidl.brandCheck(this, CloseEvent) -var _default = parse; -exports["default"] = _default; + return this.#eventInit.wasClean + } -/***/ }), + get code () { + webidl.brandCheck(this, CloseEvent) + + return this.#eventInit.code + } -/***/ 814: -/***/ ((__unused_webpack_module, exports) => { + get reason () { + webidl.brandCheck(this, CloseEvent) -"use strict"; + return this.#eventInit.reason + } +} +// https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface +class ErrorEvent extends Event { + #eventInit -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; -var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; -exports["default"] = _default; + constructor (type, eventInitDict) { + webidl.argumentLengthCheck(arguments, 1, { header: 'ErrorEvent constructor' }) -/***/ }), + super(type, eventInitDict) -/***/ 807: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}) -"use strict"; + this.#eventInit = eventInitDict + } + get message () { + webidl.brandCheck(this, ErrorEvent) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = rng; + return this.#eventInit.message + } -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + get filename () { + webidl.brandCheck(this, ErrorEvent) -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return this.#eventInit.filename + } -const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + get lineno () { + webidl.brandCheck(this, ErrorEvent) -let poolPtr = rnds8Pool.length; + return this.#eventInit.lineno + } -function rng() { - if (poolPtr > rnds8Pool.length - 16) { - _crypto.default.randomFillSync(rnds8Pool); + get colno () { + webidl.brandCheck(this, ErrorEvent) - poolPtr = 0; + return this.#eventInit.colno } - return rnds8Pool.slice(poolPtr, poolPtr += 16); + get error () { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.error + } } -/***/ }), +Object.defineProperties(MessageEvent.prototype, { + [Symbol.toStringTag]: { + value: 'MessageEvent', + configurable: true + }, + data: kEnumerableProperty, + origin: kEnumerableProperty, + lastEventId: kEnumerableProperty, + source: kEnumerableProperty, + ports: kEnumerableProperty, + initMessageEvent: kEnumerableProperty +}) -/***/ 5274: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +Object.defineProperties(CloseEvent.prototype, { + [Symbol.toStringTag]: { + value: 'CloseEvent', + configurable: true + }, + reason: kEnumerableProperty, + code: kEnumerableProperty, + wasClean: kEnumerableProperty +}) -"use strict"; +Object.defineProperties(ErrorEvent.prototype, { + [Symbol.toStringTag]: { + value: 'ErrorEvent', + configurable: true + }, + message: kEnumerableProperty, + filename: kEnumerableProperty, + lineno: kEnumerableProperty, + colno: kEnumerableProperty, + error: kEnumerableProperty +}) +webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.MessagePort +) -var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); +const eventInit = [ + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: false + } +] -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +webidl.converters.MessageEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'data', + converter: webidl.converters.any, + defaultValue: null + }, + { + key: 'origin', + converter: webidl.converters.USVString, + defaultValue: '' + }, + { + key: 'lastEventId', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'source', + // Node doesn't implement WindowProxy or ServiceWorker, so the only + // valid value for source is a MessagePort. + converter: webidl.nullableConverter(webidl.converters.MessagePort), + defaultValue: null + }, + { + key: 'ports', + converter: webidl.converters['sequence'], + get defaultValue () { + return [] + } + } +]) -function sha1(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes); - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8'); +webidl.converters.CloseEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'wasClean', + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: 'code', + converter: webidl.converters['unsigned short'], + defaultValue: 0 + }, + { + key: 'reason', + converter: webidl.converters.USVString, + defaultValue: '' } +]) - return _crypto.default.createHash('sha1').update(bytes).digest(); +webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'message', + converter: webidl.converters.DOMString, + defaultValue: '' + }, + { + key: 'filename', + converter: webidl.converters.USVString, + defaultValue: '' + }, + { + key: 'lineno', + converter: webidl.converters['unsigned long'], + defaultValue: 0 + }, + { + key: 'colno', + converter: webidl.converters['unsigned long'], + defaultValue: 0 + }, + { + key: 'error', + converter: webidl.converters.any + } +]) + +module.exports = { + MessageEvent, + CloseEvent, + ErrorEvent } -var _default = sha1; -exports["default"] = _default; /***/ }), -/***/ 8950: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 5444: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +const { maxUnsigned16Bit } = __nccwpck_require__(9188) + +/** @type {import('crypto')} */ +let crypto +try { + crypto = __nccwpck_require__(6113) +} catch { + +} + +class WebsocketFrameSend { + /** + * @param {Buffer|undefined} data + */ + constructor (data) { + this.frameData = data + this.maskKey = crypto.randomBytes(4) + } + + createFrame (opcode) { + const bodyLength = this.frameData?.byteLength ?? 0 + + /** @type {number} */ + let payloadLength = bodyLength // 0-125 + let offset = 6 + + if (bodyLength > maxUnsigned16Bit) { + offset += 8 // payload length is next 8 bytes + payloadLength = 127 + } else if (bodyLength > 125) { + offset += 2 // payload length is next 2 bytes + payloadLength = 126 + } -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + const buffer = Buffer.allocUnsafe(bodyLength + offset) -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + // Clear first 2 bytes, everything else is overwritten + buffer[0] = buffer[1] = 0 + buffer[0] |= 0x80 // FIN + buffer[0] = (buffer[0] & 0xF0) + opcode // opcode -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -const byteToHex = []; + /*! ws. MIT License. Einar Otto Stangvik */ + buffer[offset - 4] = this.maskKey[0] + buffer[offset - 3] = this.maskKey[1] + buffer[offset - 2] = this.maskKey[2] + buffer[offset - 1] = this.maskKey[3] -for (let i = 0; i < 256; ++i) { - byteToHex.push((i + 0x100).toString(16).substr(1)); -} + buffer[1] = payloadLength -function stringify(arr, offset = 0) { - // Note: Be careful editing this code! It's been tuned for performance - // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 - const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one - // of the following: - // - One or more input array values don't map to a hex octet (leading to - // "undefined" in the uuid) - // - Invalid input values for the RFC `version` or `variant` fields + if (payloadLength === 126) { + buffer.writeUInt16BE(bodyLength, 2) + } else if (payloadLength === 127) { + // Clear extended payload length + buffer[2] = buffer[3] = 0 + buffer.writeUIntBE(bodyLength, 4, 6) + } - if (!(0, _validate.default)(uuid)) { - throw TypeError('Stringified UUID is invalid'); + buffer[1] |= 0x80 // MASK + + // mask body + for (let i = 0; i < bodyLength; i++) { + buffer[offset + i] = this.frameData[i] ^ this.maskKey[i % 4] + } + + return buffer } +} - return uuid; +module.exports = { + WebsocketFrameSend } -var _default = stringify; -exports["default"] = _default; /***/ }), -/***/ 8628: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 1688: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; - -var _rng = _interopRequireDefault(__nccwpck_require__(807)); - -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html -let _nodeId; - -let _clockseq; // Previous uuid creation time - - -let _lastMSecs = 0; -let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details +const { Writable } = __nccwpck_require__(2781) +const diagnosticsChannel = __nccwpck_require__(7643) +const { parserStates, opcodes, states, emptyBuffer } = __nccwpck_require__(9188) +const { kReadyState, kSentClose, kResponse, kReceivedClose } = __nccwpck_require__(7578) +const { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = __nccwpck_require__(5515) +const { WebsocketFrameSend } = __nccwpck_require__(5444) -function v1(options, buf, offset) { - let i = buf && offset || 0; - const b = buf || new Array(16); - options = options || {}; - let node = options.node || _nodeId; - let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 +// This code was influenced by ws released under the MIT license. +// Copyright (c) 2011 Einar Otto Stangvik +// Copyright (c) 2013 Arnout Kazemier and contributors +// Copyright (c) 2016 Luigi Pinca and contributors - if (node == null || clockseq == null) { - const seedBytes = options.random || (options.rng || _rng.default)(); +const channels = {} +channels.ping = diagnosticsChannel.channel('undici:websocket:ping') +channels.pong = diagnosticsChannel.channel('undici:websocket:pong') - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; - } +class ByteParser extends Writable { + #buffers = [] + #byteOffset = 0 - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + #state = parserStates.INFO + #info = {} + #fragments = [] - let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock + constructor (ws) { + super() - let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + this.ws = ws + } - const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + /** + * @param {Buffer} chunk + * @param {() => void} callback + */ + _write (chunk, _, callback) { + this.#buffers.push(chunk) + this.#byteOffset += chunk.length - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval + this.run(callback) + } + /** + * Runs whenever a new chunk is received. + * Callback is called whenever there are no more chunks buffering, + * or not enough bytes are buffered to parse. + */ + run (callback) { + while (true) { + if (this.#state === parserStates.INFO) { + // If there aren't enough bytes to parse the payload length, etc. + if (this.#byteOffset < 2) { + return callback() + } - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } // Per 4.2.1.2 Throw error if too many uuids are requested + const buffer = this.consume(2) + this.#info.fin = (buffer[0] & 0x80) !== 0 + this.#info.opcode = buffer[0] & 0x0F - if (nsecs >= 10000) { - throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); - } + // If we receive a fragmented message, we use the type of the first + // frame to parse the full message as binary/text, when it's terminated + this.#info.originalOpcode ??= this.#info.opcode - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + this.#info.fragmented = !this.#info.fin && this.#info.opcode !== opcodes.CONTINUATION - msecs += 12219292800000; // `time_low` + if (this.#info.fragmented && this.#info.opcode !== opcodes.BINARY && this.#info.opcode !== opcodes.TEXT) { + // Only text and binary frames can be fragmented + failWebsocketConnection(this.ws, 'Invalid frame type was fragmented.') + return + } - const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; // `time_mid` + const payloadLength = buffer[1] & 0x7F - const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; // `time_high_and_version` + if (payloadLength <= 125) { + this.#info.payloadLength = payloadLength + this.#state = parserStates.READ_DATA + } else if (payloadLength === 126) { + this.#state = parserStates.PAYLOADLENGTH_16 + } else if (payloadLength === 127) { + this.#state = parserStates.PAYLOADLENGTH_64 + } - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + if (this.#info.fragmented && payloadLength > 125) { + // A fragmented frame can't be fragmented itself + failWebsocketConnection(this.ws, 'Fragmented frame exceeded 125 bytes.') + return + } else if ( + (this.#info.opcode === opcodes.PING || + this.#info.opcode === opcodes.PONG || + this.#info.opcode === opcodes.CLOSE) && + payloadLength > 125 + ) { + // Control frames can have a payload length of 125 bytes MAX + failWebsocketConnection(this.ws, 'Payload length for control frame exceeded 125 bytes.') + return + } else if (this.#info.opcode === opcodes.CLOSE) { + if (payloadLength === 1) { + failWebsocketConnection(this.ws, 'Received close frame with a 1-byte body.') + return + } - b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + const body = this.consume(payloadLength) - b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + this.#info.closeInfo = this.parseCloseBody(false, body) - b[i++] = clockseq & 0xff; // `node` + if (!this.ws[kSentClose]) { + // If an endpoint receives a Close frame and did not previously send a + // Close frame, the endpoint MUST send a Close frame in response. (When + // sending a Close frame in response, the endpoint typically echos the + // status code it received.) + const body = Buffer.allocUnsafe(2) + body.writeUInt16BE(this.#info.closeInfo.code, 0) + const closeFrame = new WebsocketFrameSend(body) - for (let n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } + this.ws[kResponse].socket.write( + closeFrame.createFrame(opcodes.CLOSE), + (err) => { + if (!err) { + this.ws[kSentClose] = true + } + } + ) + } - return buf || (0, _stringify.default)(b); -} + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this.ws[kReadyState] = states.CLOSING + this.ws[kReceivedClose] = true -var _default = v1; -exports["default"] = _default; + this.end() -/***/ }), + return + } else if (this.#info.opcode === opcodes.PING) { + // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in + // response, unless it already received a Close frame. + // A Pong frame sent in response to a Ping frame must have identical + // "Application data" -/***/ 6409: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + const body = this.consume(payloadLength) -"use strict"; + if (!this.ws[kReceivedClose]) { + const frame = new WebsocketFrameSend(body) + this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + if (channels.ping.hasSubscribers) { + channels.ping.publish({ + payload: body + }) + } + } -var _v = _interopRequireDefault(__nccwpck_require__(5998)); + this.#state = parserStates.INFO -var _md = _interopRequireDefault(__nccwpck_require__(4569)); + if (this.#byteOffset > 0) { + continue + } else { + callback() + return + } + } else if (this.#info.opcode === opcodes.PONG) { + // A Pong frame MAY be sent unsolicited. This serves as a + // unidirectional heartbeat. A response to an unsolicited Pong frame is + // not expected. -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + const body = this.consume(payloadLength) -const v3 = (0, _v.default)('v3', 0x30, _md.default); -var _default = v3; -exports["default"] = _default; + if (channels.pong.hasSubscribers) { + channels.pong.publish({ + payload: body + }) + } -/***/ }), + if (this.#byteOffset > 0) { + continue + } else { + callback() + return + } + } + } else if (this.#state === parserStates.PAYLOADLENGTH_16) { + if (this.#byteOffset < 2) { + return callback() + } -/***/ 5998: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + const buffer = this.consume(2) -"use strict"; + this.#info.payloadLength = buffer.readUInt16BE(0) + this.#state = parserStates.READ_DATA + } else if (this.#state === parserStates.PAYLOADLENGTH_64) { + if (this.#byteOffset < 8) { + return callback() + } + const buffer = this.consume(8) + const upper = buffer.readUInt32BE(0) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = _default; -exports.URL = exports.DNS = void 0; + // 2^31 is the maxinimum bytes an arraybuffer can contain + // on 32-bit systems. Although, on 64-bit systems, this is + // 2^53-1 bytes. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275 + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e + if (upper > 2 ** 31 - 1) { + failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.') + return + } -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + const lower = buffer.readUInt32BE(4) -var _parse = _interopRequireDefault(__nccwpck_require__(2746)); + this.#info.payloadLength = (upper << 8) + lower + this.#state = parserStates.READ_DATA + } else if (this.#state === parserStates.READ_DATA) { + if (this.#byteOffset < this.#info.payloadLength) { + // If there is still more data in this chunk that needs to be read + return callback() + } else if (this.#byteOffset >= this.#info.payloadLength) { + // If the server sent multiple frames in a single chunk -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + const body = this.consume(this.#info.payloadLength) -function stringToBytes(str) { - str = unescape(encodeURIComponent(str)); // UTF8 escape + this.#fragments.push(body) - const bytes = []; + // If the frame is unfragmented, or a fragmented frame was terminated, + // a message was received + if (!this.#info.fragmented || (this.#info.fin && this.#info.opcode === opcodes.CONTINUATION)) { + const fullMessage = Buffer.concat(this.#fragments) - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)); - } + websocketMessageReceived(this.ws, this.#info.originalOpcode, fullMessage) - return bytes; -} + this.#info = {} + this.#fragments.length = 0 + } -const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; -exports.DNS = DNS; -const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; -exports.URL = URL; + this.#state = parserStates.INFO + } + } -function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value); + if (this.#byteOffset > 0) { + continue + } else { + callback() + break + } } + } - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace); + /** + * Take n bytes from the buffered Buffers + * @param {number} n + * @returns {Buffer|null} + */ + consume (n) { + if (n > this.#byteOffset) { + return null + } else if (n === 0) { + return emptyBuffer } - if (namespace.length !== 16) { - throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` - + if (this.#buffers[0].length === n) { + this.#byteOffset -= this.#buffers[0].length + return this.#buffers.shift() + } - let bytes = new Uint8Array(16 + value.length); - bytes.set(namespace); - bytes.set(value, namespace.length); - bytes = hashfunc(bytes); - bytes[6] = bytes[6] & 0x0f | version; - bytes[8] = bytes[8] & 0x3f | 0x80; + const buffer = Buffer.allocUnsafe(n) + let offset = 0 - if (buf) { - offset = offset || 0; + while (offset !== n) { + const next = this.#buffers[0] + const { length } = next - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i]; + if (length + offset === n) { + buffer.set(this.#buffers.shift(), offset) + break + } else if (length + offset > n) { + buffer.set(next.subarray(0, n - offset), offset) + this.#buffers[0] = next.subarray(n - offset) + break + } else { + buffer.set(this.#buffers.shift(), offset) + offset += next.length } - - return buf; } - return (0, _stringify.default)(bytes); - } // Function#name is not settable on some platforms (#270) - - - try { - generateUUID.name = name; // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support + this.#byteOffset -= n + return buffer + } - generateUUID.DNS = DNS; - generateUUID.URL = URL; - return generateUUID; -} + parseCloseBody (onlyCode, data) { + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 + /** @type {number|undefined} */ + let code -/***/ }), + if (data.length >= 2) { + // _The WebSocket Connection Close Code_ is + // defined as the status code (Section 7.4) contained in the first Close + // control frame received by the application + code = data.readUInt16BE(0) + } -/***/ 5122: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if (onlyCode) { + if (!isValidStatusCode(code)) { + return null + } -"use strict"; + return { code } + } + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 + /** @type {Buffer} */ + let reason = data.subarray(2) -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + // Remove BOM + if (reason[0] === 0xEF && reason[1] === 0xBB && reason[2] === 0xBF) { + reason = reason.subarray(3) + } -var _rng = _interopRequireDefault(__nccwpck_require__(807)); + if (code !== undefined && !isValidStatusCode(code)) { + return null + } -var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + try { + // TODO: optimize this + reason = new TextDecoder('utf-8', { fatal: true }).decode(reason) + } catch { + return null + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + return { code, reason } + } -function v4(options, buf, offset) { - options = options || {}; + get closingInfo () { + return this.#info.closeInfo + } +} - const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` +module.exports = { + ByteParser +} - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided +/***/ }), - if (buf) { - offset = offset || 0; +/***/ 7578: +/***/ ((module) => { - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; - } +"use strict"; - return buf; - } - return (0, _stringify.default)(rnds); +module.exports = { + kWebSocketURL: Symbol('url'), + kReadyState: Symbol('ready state'), + kController: Symbol('controller'), + kResponse: Symbol('response'), + kBinaryType: Symbol('binary type'), + kSentClose: Symbol('sent close'), + kReceivedClose: Symbol('received close'), + kByteParser: Symbol('byte parser') } -var _default = v4; -exports["default"] = _default; /***/ }), -/***/ 9120: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ 5515: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +const { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = __nccwpck_require__(7578) +const { states, opcodes } = __nccwpck_require__(9188) +const { MessageEvent, ErrorEvent } = __nccwpck_require__(2611) -var _v = _interopRequireDefault(__nccwpck_require__(5998)); +/* globals Blob */ -var _sha = _interopRequireDefault(__nccwpck_require__(5274)); +/** + * @param {import('./websocket').WebSocket} ws + */ +function isEstablished (ws) { + // If the server's response is validated as provided for above, it is + // said that _The WebSocket Connection is Established_ and that the + // WebSocket Connection is in the OPEN state. + return ws[kReadyState] === states.OPEN +} -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/** + * @param {import('./websocket').WebSocket} ws + */ +function isClosing (ws) { + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + return ws[kReadyState] === states.CLOSING +} -const v5 = (0, _v.default)('v5', 0x50, _sha.default); -var _default = v5; -exports["default"] = _default; +/** + * @param {import('./websocket').WebSocket} ws + */ +function isClosed (ws) { + return ws[kReadyState] === states.CLOSED +} -/***/ }), +/** + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e + * @param {EventTarget} target + * @param {EventInit | undefined} eventInitDict + */ +function fireEvent (e, target, eventConstructor = Event, eventInitDict) { + // 1. If eventConstructor is not given, then let eventConstructor be Event. -/***/ 6900: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + // 2. Let event be the result of creating an event given eventConstructor, + // in the relevant realm of target. + // 3. Initialize event’s type attribute to e. + const event = new eventConstructor(e, eventInitDict) // eslint-disable-line new-cap -"use strict"; + // 4. Initialize any other IDL attributes of event as described in the + // invocation of this algorithm. + // 5. Return the result of dispatching event at target, with legacy target + // override flag set if set. + target.dispatchEvent(event) +} -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; +/** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @param {import('./websocket').WebSocket} ws + * @param {number} type Opcode + * @param {Buffer} data application data + */ +function websocketMessageReceived (ws, type, data) { + // 1. If ready state is not OPEN (1), then return. + if (ws[kReadyState] !== states.OPEN) { + return + } -var _regex = _interopRequireDefault(__nccwpck_require__(814)); + // 2. Let dataForEvent be determined by switching on type and binary type: + let dataForEvent -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (type === opcodes.TEXT) { + // -> type indicates that the data is Text + // a new DOMString containing data + try { + dataForEvent = new TextDecoder('utf-8', { fatal: true }).decode(data) + } catch { + failWebsocketConnection(ws, 'Received invalid UTF-8 in text frame.') + return + } + } else if (type === opcodes.BINARY) { + if (ws[kBinaryType] === 'blob') { + // -> type indicates that the data is Binary and binary type is "blob" + // a new Blob object, created in the relevant Realm of the WebSocket + // object, that represents data as its raw data + dataForEvent = new Blob([data]) + } else { + // -> type indicates that the data is Binary and binary type is "arraybuffer" + // a new ArrayBuffer object, created in the relevant Realm of the + // WebSocket object, whose contents are data + dataForEvent = new Uint8Array(data).buffer + } + } -function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid); + // 3. Fire an event named message at the WebSocket object, using MessageEvent, + // with the origin attribute initialized to the serialization of the WebSocket + // object’s url's origin, and the data attribute initialized to dataForEvent. + fireEvent('message', ws, MessageEvent, { + origin: ws[kWebSocketURL].origin, + data: dataForEvent + }) } -var _default = validate; -exports["default"] = _default; +/** + * @see https://datatracker.ietf.org/doc/html/rfc6455 + * @see https://datatracker.ietf.org/doc/html/rfc2616 + * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 + * @param {string} protocol + */ +function isValidSubprotocol (protocol) { + // If present, this value indicates one + // or more comma-separated subprotocol the client wishes to speak, + // ordered by preference. The elements that comprise this value + // MUST be non-empty strings with characters in the range U+0021 to + // U+007E not including separator characters as defined in + // [RFC2616] and MUST all be unique strings. + if (protocol.length === 0) { + return false + } -/***/ }), + for (const char of protocol) { + const code = char.charCodeAt(0) -/***/ 1595: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + if ( + code < 0x21 || + code > 0x7E || + char === '(' || + char === ')' || + char === '<' || + char === '>' || + char === '@' || + char === ',' || + char === ';' || + char === ':' || + char === '\\' || + char === '"' || + char === '/' || + char === '[' || + char === ']' || + char === '?' || + char === '=' || + char === '{' || + char === '}' || + code === 32 || // SP + code === 9 // HT + ) { + return false + } + } -"use strict"; + return true +} +/** + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 + * @param {number} code + */ +function isValidStatusCode (code) { + if (code >= 1000 && code < 1015) { + return ( + code !== 1004 && // reserved + code !== 1005 && // "MUST NOT be set as a status code" + code !== 1006 // "MUST NOT be set as a status code" + ) + } -Object.defineProperty(exports, "__esModule", ({ - value: true -})); -exports["default"] = void 0; + return code >= 3000 && code <= 4999 +} -var _validate = _interopRequireDefault(__nccwpck_require__(6900)); +/** + * @param {import('./websocket').WebSocket} ws + * @param {string|undefined} reason + */ +function failWebsocketConnection (ws, reason) { + const { [kController]: controller, [kResponse]: response } = ws -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + controller.abort() -function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID'); + if (response?.socket && !response.socket.destroyed) { + response.socket.destroy() } - return parseInt(uuid.substr(14, 1), 16); + if (reason) { + fireEvent('error', ws, ErrorEvent, { + error: new Error(reason) + }) + } +} + +module.exports = { + isEstablished, + isClosing, + isClosed, + fireEvent, + isValidSubprotocol, + isValidStatusCode, + failWebsocketConnection, + websocketMessageReceived } -var _default = version; -exports["default"] = _default; /***/ }), -/***/ 3922: +/***/ 4284: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -module.exports = -{ - parallel : __nccwpck_require__(3085), - serial : __nccwpck_require__(7380), - serialOrdered : __nccwpck_require__(7704) -}; +"use strict"; -/***/ }), +const { webidl } = __nccwpck_require__(1744) +const { DOMException } = __nccwpck_require__(1037) +const { URLSerializer } = __nccwpck_require__(685) +const { getGlobalOrigin } = __nccwpck_require__(1246) +const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = __nccwpck_require__(9188) +const { + kWebSocketURL, + kReadyState, + kController, + kBinaryType, + kResponse, + kSentClose, + kByteParser +} = __nccwpck_require__(7578) +const { isEstablished, isClosing, isValidSubprotocol, failWebsocketConnection, fireEvent } = __nccwpck_require__(5515) +const { establishWebSocketConnection } = __nccwpck_require__(5354) +const { WebsocketFrameSend } = __nccwpck_require__(5444) +const { ByteParser } = __nccwpck_require__(1688) +const { kEnumerableProperty, isBlobLike } = __nccwpck_require__(3983) +const { getGlobalDispatcher } = __nccwpck_require__(1892) +const { types } = __nccwpck_require__(3837) -/***/ 94: -/***/ ((module) => { +let experimentalWarned = false -// API -module.exports = abort; +// https://websockets.spec.whatwg.org/#interface-definition +class WebSocket extends EventTarget { + #events = { + open: null, + error: null, + close: null, + message: null + } -/** - * Aborts leftover active jobs - * - * @param {object} state - current state object - */ -function abort(state) -{ - Object.keys(state.jobs).forEach(clean.bind(state)); + #bufferedAmount = 0 + #protocol = '' + #extensions = '' - // reset leftover jobs - state.jobs = {}; -} + /** + * @param {string} url + * @param {string|string[]} protocols + */ + constructor (url, protocols = []) { + super() -/** - * Cleans up leftover job by invoking abort function for the provided job id - * - * @this state - * @param {string|number} key - job id to abort - */ -function clean(key) -{ - if (typeof this.jobs[key] == 'function') - { - this.jobs[key](); - } -} + webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket constructor' }) + if (!experimentalWarned) { + experimentalWarned = true + process.emitWarning('WebSockets are experimental, expect them to change at any time.', { + code: 'UNDICI-WS' + }) + } -/***/ }), + const options = webidl.converters['DOMString or sequence or WebSocketInit'](protocols) -/***/ 2824: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + url = webidl.converters.USVString(url) + protocols = options.protocols -var defer = __nccwpck_require__(4237); + // 1. Let baseURL be this's relevant settings object's API base URL. + const baseURL = getGlobalOrigin() -// API -module.exports = async; + // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. + let urlRecord -/** - * Runs provided callback asynchronously - * even if callback itself is not - * - * @param {function} callback - callback to invoke - * @returns {function} - augmented callback - */ -function async(callback) -{ - var isAsync = false; + try { + urlRecord = new URL(url, baseURL) + } catch (e) { + // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. + throw new DOMException(e, 'SyntaxError') + } - // check if async happened - defer(function() { isAsync = true; }); + // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". + if (urlRecord.protocol === 'http:') { + urlRecord.protocol = 'ws:' + } else if (urlRecord.protocol === 'https:') { + // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". + urlRecord.protocol = 'wss:' + } - return function async_callback(err, result) - { - if (isAsync) - { - callback(err, result); + // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. + if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { + throw new DOMException( + `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, + 'SyntaxError' + ) } - else - { - defer(function nextTick_callback() - { - callback(err, result); - }); + + // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" + // DOMException. + if (urlRecord.hash || urlRecord.href.endsWith('#')) { + throw new DOMException('Got fragment', 'SyntaxError') } - }; -} + // 8. If protocols is a string, set protocols to a sequence consisting + // of just that string. + if (typeof protocols === 'string') { + protocols = [protocols] + } -/***/ }), + // 9. If any of the values in protocols occur more than once or otherwise + // fail to match the requirements for elements that comprise the value + // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket + // protocol, then throw a "SyntaxError" DOMException. + if (protocols.length !== new Set(protocols.map(p => p.toLowerCase())).size) { + throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + } -/***/ 4237: -/***/ ((module) => { + if (protocols.length > 0 && !protocols.every(p => isValidSubprotocol(p))) { + throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') + } -module.exports = defer; + // 10. Set this's url to urlRecord. + this[kWebSocketURL] = new URL(urlRecord.href) -/** - * Runs provided function on next iteration of the event loop - * - * @param {function} fn - function to run - */ -function defer(fn) -{ - var nextTick = typeof setImmediate == 'function' - ? setImmediate - : ( - typeof process == 'object' && typeof process.nextTick == 'function' - ? process.nextTick - : null - ); + // 11. Let client be this's relevant settings object. - if (nextTick) - { - nextTick(fn); - } - else - { - setTimeout(fn, 0); - } -} + // 12. Run this step in parallel: + // 1. Establish a WebSocket connection given urlRecord, protocols, + // and client. + this[kController] = establishWebSocketConnection( + urlRecord, + protocols, + this, + (response) => this.#onConnectionEstablished(response), + options + ) -/***/ }), + // Each WebSocket object has an associated ready state, which is a + // number representing the state of the connection. Initially it must + // be CONNECTING (0). + this[kReadyState] = WebSocket.CONNECTING -/***/ 6600: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + // The extensions attribute must initially return the empty string. -var async = __nccwpck_require__(2824) - , abort = __nccwpck_require__(94) - ; + // The protocol attribute must initially return the empty string. -// API -module.exports = iterate; + // Each WebSocket object has an associated binary type, which is a + // BinaryType. Initially it must be "blob". + this[kBinaryType] = 'blob' + } -/** - * Iterates over each job object - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {object} state - current job status - * @param {function} callback - invoked when all elements processed - */ -function iterate(list, iterator, state, callback) -{ - // store current index - var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-close + * @param {number|undefined} code + * @param {string|undefined} reason + */ + close (code = undefined, reason = undefined) { + webidl.brandCheck(this, WebSocket) - state.jobs[key] = runJob(iterator, key, list[key], function(error, output) - { - // don't repeat yourself - // skip secondary callbacks - if (!(key in state.jobs)) - { - return; + if (code !== undefined) { + code = webidl.converters['unsigned short'](code, { clamp: true }) } - // clean up jobs - delete state.jobs[key]; - - if (error) - { - // don't process rest of the results - // stop still active jobs - // and reset the list - abort(state); + if (reason !== undefined) { + reason = webidl.converters.USVString(reason) } - else - { - state.results[key] = output; + + // 1. If code is present, but is neither an integer equal to 1000 nor an + // integer in the range 3000 to 4999, inclusive, throw an + // "InvalidAccessError" DOMException. + if (code !== undefined) { + if (code !== 1000 && (code < 3000 || code > 4999)) { + throw new DOMException('invalid code', 'InvalidAccessError') + } } - // return salvaged results - callback(error, state.results); - }); -} + let reasonByteLength = 0 -/** - * Runs iterator over provided job element - * - * @param {function} iterator - iterator to invoke - * @param {string|number} key - key/index of the element in the list of jobs - * @param {mixed} item - job description - * @param {function} callback - invoked after iterator is done with the job - * @returns {function|mixed} - job abort function or something else - */ -function runJob(iterator, key, item, callback) -{ - var aborter; + // 2. If reason is present, then run these substeps: + if (reason !== undefined) { + // 1. Let reasonBytes be the result of encoding reason. + // 2. If reasonBytes is longer than 123 bytes, then throw a + // "SyntaxError" DOMException. + reasonByteLength = Buffer.byteLength(reason) + + if (reasonByteLength > 123) { + throw new DOMException( + `Reason must be less than 123 bytes; received ${reasonByteLength}`, + 'SyntaxError' + ) + } + } - // allow shortcut if iterator expects only two arguments - if (iterator.length == 2) - { - aborter = iterator(item, async(callback)); - } - // otherwise go with full three arguments - else - { - aborter = iterator(item, key, async(callback)); - } + // 3. Run the first matching steps from the following list: + if (this[kReadyState] === WebSocket.CLOSING || this[kReadyState] === WebSocket.CLOSED) { + // If this's ready state is CLOSING (2) or CLOSED (3) + // Do nothing. + } else if (!isEstablished(this)) { + // If the WebSocket connection is not yet established + // Fail the WebSocket connection and set this's ready state + // to CLOSING (2). + failWebsocketConnection(this, 'Connection was closed before it was established.') + this[kReadyState] = WebSocket.CLOSING + } else if (!isClosing(this)) { + // If the WebSocket closing handshake has not yet been started + // Start the WebSocket closing handshake and set this's ready + // state to CLOSING (2). + // - If neither code nor reason is present, the WebSocket Close + // message must not have a body. + // - If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + // - If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. - return aborter; -} + const frame = new WebsocketFrameSend() + // If neither code nor reason is present, the WebSocket Close + // message must not have a body. -/***/ }), + // If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + if (code !== undefined && reason === undefined) { + frame.frameData = Buffer.allocUnsafe(2) + frame.frameData.writeUInt16BE(code, 0) + } else if (code !== undefined && reason !== undefined) { + // If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. + frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength) + frame.frameData.writeUInt16BE(code, 0) + // the body MAY contain UTF-8-encoded data with value /reason/ + frame.frameData.write(reason, 2, 'utf-8') + } else { + frame.frameData = emptyBuffer + } -/***/ 1077: -/***/ ((module) => { + /** @type {import('stream').Duplex} */ + const socket = this[kResponse].socket -// API -module.exports = state; + socket.write(frame.createFrame(opcodes.CLOSE), (err) => { + if (!err) { + this[kSentClose] = true + } + }) -/** - * Creates initial state object - * for iteration over list - * - * @param {array|object} list - list to iterate over - * @param {function|null} sortMethod - function to use for keys sort, - * or `null` to keep them as is - * @returns {object} - initial state object - */ -function state(list, sortMethod) -{ - var isNamedList = !Array.isArray(list) - , initState = - { - index : 0, - keyedList: isNamedList || sortMethod ? Object.keys(list) : null, - jobs : {}, - results : isNamedList ? {} : [], - size : isNamedList ? Object.keys(list).length : list.length + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this[kReadyState] = states.CLOSING + } else { + // Otherwise + // Set this's ready state to CLOSING (2). + this[kReadyState] = WebSocket.CLOSING } - ; - - if (sortMethod) - { - // sort array keys based on it's values - // sort object's keys just on own merit - initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) - { - return sortMethod(list[a], list[b]); - }); } - return initState; -} - + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-send + * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data + */ + send (data) { + webidl.brandCheck(this, WebSocket) -/***/ }), + webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket.send' }) -/***/ 4506: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + data = webidl.converters.WebSocketSendData(data) -var abort = __nccwpck_require__(94) - , async = __nccwpck_require__(2824) - ; + // 1. If this's ready state is CONNECTING, then throw an + // "InvalidStateError" DOMException. + if (this[kReadyState] === WebSocket.CONNECTING) { + throw new DOMException('Sent before connected.', 'InvalidStateError') + } -// API -module.exports = terminator; + // 2. Run the appropriate set of steps from the following list: + // https://datatracker.ietf.org/doc/html/rfc6455#section-6.1 + // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 -/** - * Terminates jobs in the attached state context - * - * @this AsyncKitState# - * @param {function} callback - final callback to invoke after termination - */ -function terminator(callback) -{ - if (!Object.keys(this.jobs).length) - { - return; - } + if (!isEstablished(this) || isClosing(this)) { + return + } - // fast forward iteration index - this.index = this.size; + /** @type {import('stream').Duplex} */ + const socket = this[kResponse].socket - // abort jobs - abort(this); + // If data is a string + if (typeof data === 'string') { + // If the WebSocket connection is established and the WebSocket + // closing handshake has not yet started, then the user agent + // must send a WebSocket Message comprised of the data argument + // using a text frame opcode; if the data cannot be sent, e.g. + // because it would need to be buffered but the buffer is full, + // the user agent must flag the WebSocket as full and then close + // the WebSocket connection. Any invocation of this method with a + // string argument that does not throw an exception must increase + // the bufferedAmount attribute by the number of bytes needed to + // express the argument as UTF-8. - // send back results we have so far - async(callback)(null, this.results); -} + const value = Buffer.from(data) + const frame = new WebsocketFrameSend(value) + const buffer = frame.createFrame(opcodes.TEXT) + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + } else if (types.isArrayBuffer(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need + // to be buffered but the buffer is full, the user agent must flag + // the WebSocket as full and then close the WebSocket connection. + // The data to be sent is the data stored in the buffer described + // by the ArrayBuffer object. Any invocation of this method with an + // ArrayBuffer argument that does not throw an exception must + // increase the bufferedAmount attribute by the length of the + // ArrayBuffer in bytes. -/***/ }), + const value = Buffer.from(data) + const frame = new WebsocketFrameSend(value) + const buffer = frame.createFrame(opcodes.BINARY) -/***/ 3085: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + } else if (ArrayBuffer.isView(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The + // data to be sent is the data stored in the section of the buffer + // described by the ArrayBuffer object that data references. Any + // invocation of this method with this kind of argument that does + // not throw an exception must increase the bufferedAmount attribute + // by the length of data’s buffer in bytes. -var iterate = __nccwpck_require__(6600) - , initState = __nccwpck_require__(1077) - , terminator = __nccwpck_require__(4506) - ; + const ab = Buffer.from(data, data.byteOffset, data.byteLength) -// Public API -module.exports = parallel; + const frame = new WebsocketFrameSend(ab) + const buffer = frame.createFrame(opcodes.BINARY) -/** - * Runs iterator over provided array elements in parallel - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator - */ -function parallel(list, iterator, callback) -{ - var state = initState(list); + this.#bufferedAmount += ab.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= ab.byteLength + }) + } else if (isBlobLike(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The data + // to be sent is the raw data represented by the Blob object. Any + // invocation of this method with a Blob argument that does not throw + // an exception must increase the bufferedAmount attribute by the size + // of the Blob object’s raw data, in bytes. - while (state.index < (state['keyedList'] || list).length) - { - iterate(list, iterator, state, function(error, result) - { - if (error) - { - callback(error, result); - return; - } + const frame = new WebsocketFrameSend() - // looks like it's the last one - if (Object.keys(state.jobs).length === 0) - { - callback(null, state.results); - return; - } - }); + data.arrayBuffer().then((ab) => { + const value = Buffer.from(ab) + frame.frameData = value + const buffer = frame.createFrame(opcodes.BINARY) - state.index++; + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + }) + } } - return terminator.bind(state, callback); -} + get readyState () { + webidl.brandCheck(this, WebSocket) + // The readyState getter steps are to return this's ready state. + return this[kReadyState] + } -/***/ }), + get bufferedAmount () { + webidl.brandCheck(this, WebSocket) -/***/ 7380: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return this.#bufferedAmount + } -var serialOrdered = __nccwpck_require__(7704); + get url () { + webidl.brandCheck(this, WebSocket) -// Public API -module.exports = serial; + // The url getter steps are to return this's url, serialized. + return URLSerializer(this[kWebSocketURL]) + } -/** - * Runs iterator over provided array elements in series - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator - */ -function serial(list, iterator, callback) -{ - return serialOrdered(list, iterator, null, callback); -} + get extensions () { + webidl.brandCheck(this, WebSocket) + return this.#extensions + } -/***/ }), + get protocol () { + webidl.brandCheck(this, WebSocket) -/***/ 7704: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + return this.#protocol + } -var iterate = __nccwpck_require__(6600) - , initState = __nccwpck_require__(1077) - , terminator = __nccwpck_require__(4506) - ; + get onopen () { + webidl.brandCheck(this, WebSocket) -// Public API -module.exports = serialOrdered; -// sorting helpers -module.exports.ascending = ascending; -module.exports.descending = descending; + return this.#events.open + } -/** - * Runs iterator over provided sorted array elements in series - * - * @param {array|object} list - array or object (named list) to iterate over - * @param {function} iterator - iterator to run - * @param {function} sortMethod - custom sort function - * @param {function} callback - invoked when all elements processed - * @returns {function} - jobs terminator - */ -function serialOrdered(list, iterator, sortMethod, callback) -{ - var state = initState(list, sortMethod); + set onopen (fn) { + webidl.brandCheck(this, WebSocket) - iterate(list, iterator, state, function iteratorHandler(error, result) - { - if (error) - { - callback(error, result); - return; + if (this.#events.open) { + this.removeEventListener('open', this.#events.open) } - state.index++; - - // are we there yet? - if (state.index < (state['keyedList'] || list).length) - { - iterate(list, iterator, state, iteratorHandler); - return; + if (typeof fn === 'function') { + this.#events.open = fn + this.addEventListener('open', fn) + } else { + this.#events.open = null } + } - // done here - callback(null, state.results); - }); - - return terminator.bind(state, callback); -} - -/* - * -- Sort methods - */ - -/** - * sort helper to sort array elements in ascending order - * - * @param {mixed} a - an item to compare - * @param {mixed} b - an item to compare - * @returns {number} - comparison result - */ -function ascending(a, b) -{ - return a < b ? -1 : a > b ? 1 : 0; -} + get onerror () { + webidl.brandCheck(this, WebSocket) -/** - * sort helper to sort array elements in descending order - * - * @param {mixed} a - an item to compare - * @param {mixed} b - an item to compare - * @returns {number} - comparison result - */ -function descending(a, b) -{ - return -1 * ascending(a, b); -} + return this.#events.error + } + set onerror (fn) { + webidl.brandCheck(this, WebSocket) -/***/ }), + if (this.#events.error) { + this.removeEventListener('error', this.#events.error) + } -/***/ 3141: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + if (typeof fn === 'function') { + this.#events.error = fn + this.addEventListener('error', fn) + } else { + this.#events.error = null + } + } -var util = __nccwpck_require__(3837); -var Stream = (__nccwpck_require__(2781).Stream); -var DelayedStream = __nccwpck_require__(2959); + get onclose () { + webidl.brandCheck(this, WebSocket) -module.exports = CombinedStream; -function CombinedStream() { - this.writable = false; - this.readable = true; - this.dataSize = 0; - this.maxDataSize = 2 * 1024 * 1024; - this.pauseStreams = true; + return this.#events.close + } - this._released = false; - this._streams = []; - this._currentStream = null; - this._insideLoop = false; - this._pendingNext = false; -} -util.inherits(CombinedStream, Stream); + set onclose (fn) { + webidl.brandCheck(this, WebSocket) -CombinedStream.create = function(options) { - var combinedStream = new this(); + if (this.#events.close) { + this.removeEventListener('close', this.#events.close) + } - options = options || {}; - for (var option in options) { - combinedStream[option] = options[option]; + if (typeof fn === 'function') { + this.#events.close = fn + this.addEventListener('close', fn) + } else { + this.#events.close = null + } } - return combinedStream; -}; + get onmessage () { + webidl.brandCheck(this, WebSocket) -CombinedStream.isStreamLike = function(stream) { - return (typeof stream !== 'function') - && (typeof stream !== 'string') - && (typeof stream !== 'boolean') - && (typeof stream !== 'number') - && (!Buffer.isBuffer(stream)); -}; + return this.#events.message + } -CombinedStream.prototype.append = function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); + set onmessage (fn) { + webidl.brandCheck(this, WebSocket) - if (isStreamLike) { - if (!(stream instanceof DelayedStream)) { - var newStream = DelayedStream.create(stream, { - maxDataSize: Infinity, - pauseStream: this.pauseStreams, - }); - stream.on('data', this._checkDataSize.bind(this)); - stream = newStream; + if (this.#events.message) { + this.removeEventListener('message', this.#events.message) } - this._handleErrors(stream); - - if (this.pauseStreams) { - stream.pause(); + if (typeof fn === 'function') { + this.#events.message = fn + this.addEventListener('message', fn) + } else { + this.#events.message = null } } - this._streams.push(stream); - return this; -}; + get binaryType () { + webidl.brandCheck(this, WebSocket) -CombinedStream.prototype.pipe = function(dest, options) { - Stream.prototype.pipe.call(this, dest, options); - this.resume(); - return dest; -}; + return this[kBinaryType] + } -CombinedStream.prototype._getNext = function() { - this._currentStream = null; + set binaryType (type) { + webidl.brandCheck(this, WebSocket) - if (this._insideLoop) { - this._pendingNext = true; - return; // defer call + if (type !== 'blob' && type !== 'arraybuffer') { + this[kBinaryType] = 'blob' + } else { + this[kBinaryType] = type + } } - this._insideLoop = true; - try { - do { - this._pendingNext = false; - this._realGetNext(); - } while (this._pendingNext); - } finally { - this._insideLoop = false; - } -}; + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + */ + #onConnectionEstablished (response) { + // processResponse is called when the "response’s header list has been received and initialized." + // once this happens, the connection is open + this[kResponse] = response -CombinedStream.prototype._realGetNext = function() { - var stream = this._streams.shift(); + const parser = new ByteParser(this) + parser.on('drain', function onParserDrain () { + this.ws[kResponse].socket.resume() + }) + response.socket.ws = this + this[kByteParser] = parser - if (typeof stream == 'undefined') { - this.end(); - return; - } + // 1. Change the ready state to OPEN (1). + this[kReadyState] = states.OPEN - if (typeof stream !== 'function') { - this._pipeNext(stream); - return; - } + // 2. Change the extensions attribute’s value to the extensions in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 + const extensions = response.headersList.get('sec-websocket-extensions') - var getStream = stream; - getStream(function(stream) { - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('data', this._checkDataSize.bind(this)); - this._handleErrors(stream); + if (extensions !== null) { + this.#extensions = extensions } - this._pipeNext(stream); - }.bind(this)); -}; + // 3. Change the protocol attribute’s value to the subprotocol in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-1.9 + const protocol = response.headersList.get('sec-websocket-protocol') -CombinedStream.prototype._pipeNext = function(stream) { - this._currentStream = stream; + if (protocol !== null) { + this.#protocol = protocol + } - var isStreamLike = CombinedStream.isStreamLike(stream); - if (isStreamLike) { - stream.on('end', this._getNext.bind(this)); - stream.pipe(this, {end: false}); - return; + // 4. Fire an event named open at the WebSocket object. + fireEvent('open', this) } +} - var value = stream; - this.write(value); - this._getNext(); -}; +// https://websockets.spec.whatwg.org/#dom-websocket-connecting +WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING +// https://websockets.spec.whatwg.org/#dom-websocket-open +WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN +// https://websockets.spec.whatwg.org/#dom-websocket-closing +WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING +// https://websockets.spec.whatwg.org/#dom-websocket-closed +WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED -CombinedStream.prototype._handleErrors = function(stream) { - var self = this; - stream.on('error', function(err) { - self._emitError(err); - }); -}; +Object.defineProperties(WebSocket.prototype, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors, + url: kEnumerableProperty, + readyState: kEnumerableProperty, + bufferedAmount: kEnumerableProperty, + onopen: kEnumerableProperty, + onerror: kEnumerableProperty, + onclose: kEnumerableProperty, + close: kEnumerableProperty, + onmessage: kEnumerableProperty, + binaryType: kEnumerableProperty, + send: kEnumerableProperty, + extensions: kEnumerableProperty, + protocol: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'WebSocket', + writable: false, + enumerable: false, + configurable: true + } +}) -CombinedStream.prototype.write = function(data) { - this.emit('data', data); -}; +Object.defineProperties(WebSocket, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors +}) -CombinedStream.prototype.pause = function() { - if (!this.pauseStreams) { - return; +webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.DOMString +) + +webidl.converters['DOMString or sequence'] = function (V) { + if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) { + return webidl.converters['sequence'](V) } - if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); - this.emit('pause'); -}; + return webidl.converters.DOMString(V) +} -CombinedStream.prototype.resume = function() { - if (!this._released) { - this._released = true; - this.writable = true; - this._getNext(); +// This implements the propsal made in https://github.com/whatwg/websockets/issues/42 +webidl.converters.WebSocketInit = webidl.dictionaryConverter([ + { + key: 'protocols', + converter: webidl.converters['DOMString or sequence'], + get defaultValue () { + return [] + } + }, + { + key: 'dispatcher', + converter: (V) => V, + get defaultValue () { + return getGlobalDispatcher() + } + }, + { + key: 'headers', + converter: webidl.nullableConverter(webidl.converters.HeadersInit) } +]) - if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); - this.emit('resume'); -}; - -CombinedStream.prototype.end = function() { - this._reset(); - this.emit('end'); -}; +webidl.converters['DOMString or sequence or WebSocketInit'] = function (V) { + if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) { + return webidl.converters.WebSocketInit(V) + } -CombinedStream.prototype.destroy = function() { - this._reset(); - this.emit('close'); -}; + return { protocols: webidl.converters['DOMString or sequence'](V) } +} -CombinedStream.prototype._reset = function() { - this.writable = false; - this._streams = []; - this._currentStream = null; -}; +webidl.converters.WebSocketSendData = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } -CombinedStream.prototype._checkDataSize = function() { - this._updateDataSize(); - if (this.dataSize <= this.maxDataSize) { - return; + if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) { + return webidl.converters.BufferSource(V) + } } - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; - this._emitError(new Error(message)); -}; + return webidl.converters.USVString(V) +} -CombinedStream.prototype._updateDataSize = function() { - this.dataSize = 0; +module.exports = { + WebSocket +} - var self = this; - this._streams.forEach(function(stream) { - if (!stream.dataSize) { - return; - } - self.dataSize += stream.dataSize; - }); +/***/ }), + +/***/ 5840: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "v1", ({ + enumerable: true, + get: function () { + return _v.default; + } +})); +Object.defineProperty(exports, "v3", ({ + enumerable: true, + get: function () { + return _v2.default; + } +})); +Object.defineProperty(exports, "v4", ({ + enumerable: true, + get: function () { + return _v3.default; + } +})); +Object.defineProperty(exports, "v5", ({ + enumerable: true, + get: function () { + return _v4.default; + } +})); +Object.defineProperty(exports, "NIL", ({ + enumerable: true, + get: function () { + return _nil.default; + } +})); +Object.defineProperty(exports, "version", ({ + enumerable: true, + get: function () { + return _version.default; + } +})); +Object.defineProperty(exports, "validate", ({ + enumerable: true, + get: function () { + return _validate.default; + } +})); +Object.defineProperty(exports, "stringify", ({ + enumerable: true, + get: function () { + return _stringify.default; + } +})); +Object.defineProperty(exports, "parse", ({ + enumerable: true, + get: function () { + return _parse.default; + } +})); + +var _v = _interopRequireDefault(__nccwpck_require__(8628)); - if (this._currentStream && this._currentStream.dataSize) { - this.dataSize += this._currentStream.dataSize; - } -}; +var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); -CombinedStream.prototype._emitError = function(err) { - this._reset(); - this.emit('error', err); -}; +var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); +var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); -/***/ }), +var _nil = _interopRequireDefault(__nccwpck_require__(5332)); -/***/ 2959: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var _version = _interopRequireDefault(__nccwpck_require__(1595)); -var Stream = (__nccwpck_require__(2781).Stream); -var util = __nccwpck_require__(3837); +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -module.exports = DelayedStream; -function DelayedStream() { - this.source = null; - this.dataSize = 0; - this.maxDataSize = 1024 * 1024; - this.pauseStream = true; +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - this._maxDataSizeExceeded = false; - this._released = false; - this._bufferedEvents = []; -} -util.inherits(DelayedStream, Stream); +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); -DelayedStream.create = function(source, options) { - var delayedStream = new this(); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - options = options || {}; - for (var option in options) { - delayedStream[option] = options[option]; - } +/***/ }), - delayedStream.source = source; +/***/ 4569: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var realEmit = source.emit; - source.emit = function() { - delayedStream._handleEmit(arguments); - return realEmit.apply(source, arguments); - }; +"use strict"; - source.on('error', function() {}); - if (delayedStream.pauseStream) { - source.pause(); - } - return delayedStream; -}; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -Object.defineProperty(DelayedStream.prototype, 'readable', { - configurable: true, - enumerable: true, - get: function() { - return this.source.readable; - } -}); +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); -DelayedStream.prototype.setEncoding = function() { - return this.source.setEncoding.apply(this.source, arguments); -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -DelayedStream.prototype.resume = function() { - if (!this._released) { - this.release(); +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); } - this.source.resume(); -}; + return _crypto.default.createHash('md5').update(bytes).digest(); +} -DelayedStream.prototype.pause = function() { - this.source.pause(); -}; +var _default = md5; +exports["default"] = _default; -DelayedStream.prototype.release = function() { - this._released = true; +/***/ }), - this._bufferedEvents.forEach(function(args) { - this.emit.apply(this, args); - }.bind(this)); - this._bufferedEvents = []; -}; +/***/ 5332: +/***/ ((__unused_webpack_module, exports) => { -DelayedStream.prototype.pipe = function() { - var r = Stream.prototype.pipe.apply(this, arguments); - this.resume(); - return r; -}; +"use strict"; -DelayedStream.prototype._handleEmit = function(args) { - if (this._released) { - this.emit.apply(this, args); - return; - } - if (args[0] === 'data') { - this.dataSize += args[1].length; - this._checkIfMaxDataSizeExceeded(); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports["default"] = _default; - this._bufferedEvents.push(args); -}; +/***/ }), -DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { - if (this._maxDataSizeExceeded) { - return; - } +/***/ 2746: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (this.dataSize <= this.maxDataSize) { - return; - } +"use strict"; - this._maxDataSizeExceeded = true; - var message = - 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' - this.emit('error', new Error(message)); -}; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -/***/ }), +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); -/***/ 5685: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var CombinedStream = __nccwpck_require__(3141); -var util = __nccwpck_require__(3837); -var path = __nccwpck_require__(1017); -var http = __nccwpck_require__(3685); -var https = __nccwpck_require__(5687); -var parseUrl = (__nccwpck_require__(7310).parse); -var fs = __nccwpck_require__(7147); -var mime = __nccwpck_require__(4991); -var asynckit = __nccwpck_require__(3922); -var populate = __nccwpck_require__(3061); +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } -// Public API -module.exports = FormData; + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ -// make it a Stream -util.inherits(FormData, CombinedStream); + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ -/** - * Create readable "multipart/form-data" streams. - * Can be used to submit forms - * and file uploads to other web applications. - * - * @constructor - * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream - */ -function FormData(options) { - if (!(this instanceof FormData)) { - return new FormData(); - } + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ - this._overheadLength = 0; - this._valueLength = 0; - this._valuesToMeasure = []; + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ - CombinedStream.call(this); + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) - options = options || {}; - for (var option in options) { - this[option] = options[option]; - } + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; } -FormData.LINE_BREAK = '\r\n'; -FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; +var _default = parse; +exports["default"] = _default; -FormData.prototype.append = function(field, value, options) { +/***/ }), - options = options || {}; +/***/ 814: +/***/ ((__unused_webpack_module, exports) => { - // allow filename as single option - if (typeof options == 'string') { - options = {filename: options}; - } +"use strict"; - var append = CombinedStream.prototype.append.bind(this); - // all that streamy business can't handle numbers - if (typeof value == 'number') { - value = '' + value; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports["default"] = _default; - // https://github.com/felixge/node-form-data/issues/38 - if (util.isArray(value)) { - // Please convert your array into string - // the way web server expects it - this._error(new Error('Arrays are not supported.')); - return; - } +/***/ }), - var header = this._multiPartHeader(field, value, options); - var footer = this._multiPartFooter(); +/***/ 807: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - append(header); - append(value); - append(footer); +"use strict"; - // pass along options.knownLength - this._trackLength(header, value, options); -}; -FormData.prototype._trackLength = function(header, value, options) { - var valueLength = 0; +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = rng; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // used w/ getLengthSync(), when length is known. - // e.g. for streaming directly from a remote server, - // w/ a known file a size, and not wanting to wait for - // incoming file to finish to get its size. - if (options.knownLength != null) { - valueLength += +options.knownLength; - } else if (Buffer.isBuffer(value)) { - valueLength = value.length; - } else if (typeof value === 'string') { - valueLength = Buffer.byteLength(value); - } +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate - this._valueLength += valueLength; +let poolPtr = rnds8Pool.length; - // @check why add CRLF? does this account for custom/multiple CRLFs? - this._overheadLength += - Buffer.byteLength(header) + - FormData.LINE_BREAK.length; +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool); - // empty or either doesn't have path or not an http response - if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { - return; + poolPtr = 0; } - // no need to bother with the length - if (!options.knownLength) { - this._valuesToMeasure.push(value); - } -}; + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} -FormData.prototype._lengthRetriever = function(value, callback) { +/***/ }), - if (value.hasOwnProperty('fd')) { +/***/ 5274: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // take read range into a account - // `end` = Infinity –> read file till the end - // - // TODO: Looks like there is bug in Node fs.createReadStream - // it doesn't respect `end` options without `start` options - // Fix it when node fixes it. - // https://github.com/joyent/node/issues/7819 - if (value.end != undefined && value.end != Infinity && value.start != undefined) { +"use strict"; - // when end specified - // no need to calculate range - // inclusive, starts with 0 - callback(null, value.end + 1 - (value.start ? value.start : 0)); - // not that fast snoopy - } else { - // still need to fetch file size from fs - fs.stat(value.path, function(err, stat) { +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - var fileSize; +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); - if (err) { - callback(err); - return; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // update final size based on the range options - fileSize = stat.size - (value.start ? value.start : 0); - callback(null, fileSize); - }); - } +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } - // or http response - } else if (value.hasOwnProperty('httpVersion')) { - callback(null, +value.headers['content-length']); + return _crypto.default.createHash('sha1').update(bytes).digest(); +} - // or request stream http://github.com/mikeal/request - } else if (value.hasOwnProperty('httpModule')) { - // wait till response come back - value.on('response', function(response) { - value.pause(); - callback(null, +response.headers['content-length']); - }); - value.resume(); +var _default = sha1; +exports["default"] = _default; - // something else - } else { - callback('Unknown stream'); - } -}; +/***/ }), -FormData.prototype._multiPartHeader = function(field, value, options) { - // custom header specified (as string)? - // it becomes responsible for boundary - // (e.g. to handle extra CRLFs on .NET servers) - if (typeof options.header == 'string') { - return options.header; - } +/***/ 8950: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - var contentDisposition = this._getContentDisposition(value, options); - var contentType = this._getContentType(value, options); +"use strict"; - var contents = ''; - var headers = { - // add custom disposition as third element or keep it two elements if not - 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), - // if no content type. allow it to be empty array - 'Content-Type': [].concat(contentType || []) - }; - // allow custom headers. - if (typeof options.header == 'object') { - populate(headers, options.header); - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - var header; - for (var prop in headers) { - if (!headers.hasOwnProperty(prop)) continue; - header = headers[prop]; +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - // skip nullish headers. - if (header == null) { - continue; - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // convert all headers to arrays. - if (!Array.isArray(header)) { - header = [header]; - } +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; - // add non-empty headers. - if (header.length) { - contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; - } +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).substr(1)); +} + +function stringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); } - return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; -}; + return uuid; +} -FormData.prototype._getContentDisposition = function(value, options) { +var _default = stringify; +exports["default"] = _default; - var filename - , contentDisposition - ; +/***/ }), - if (typeof options.filepath === 'string') { - // custom filepath for relative paths - filename = path.normalize(options.filepath).replace(/\\/g, '/'); - } else if (options.filename || value.name || value.path) { - // custom filename take precedence - // formidable and the browser add a name property - // fs- and request- streams have path property - filename = path.basename(options.filename || value.name || value.path); - } else if (value.readable && value.hasOwnProperty('httpVersion')) { - // or try http response - filename = path.basename(value.client._httpMessage.path || ''); - } +/***/ 8628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (filename) { - contentDisposition = 'filename="' + filename + '"'; - } +"use strict"; - return contentDisposition; -}; -FormData.prototype._getContentType = function(value, options) { +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - // use custom content-type above all - var contentType = options.contentType; +var _rng = _interopRequireDefault(__nccwpck_require__(807)); - // or try `name` from formidable, browser - if (!contentType && value.name) { - contentType = mime.lookup(value.name); - } +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - // or try `path` from fs-, request- streams - if (!contentType && value.path) { - contentType = mime.lookup(value.path); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // or if it's http-reponse - if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { - contentType = value.headers['content-type']; - } +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; - // or guess it from the filepath or filename - if (!contentType && (options.filepath || options.filename)) { - contentType = mime.lookup(options.filepath || options.filename); - } +let _clockseq; // Previous uuid creation time - // fallback to the default content type if `value` is not simple value - if (!contentType && typeof value == 'object') { - contentType = FormData.DEFAULT_CONTENT_TYPE; - } - return contentType; -}; +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details -FormData.prototype._multiPartFooter = function() { - return function(next) { - var footer = FormData.LINE_BREAK; +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 - var lastPart = (this._streams.length === 0); - if (lastPart) { - footer += this._lastBoundary(); + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - next(footer); - }.bind(this); -}; -FormData.prototype._lastBoundary = function() { - return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; -}; + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock -FormData.prototype.getHeaders = function(userHeaders) { - var header; - var formHeaders = { - 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() - }; + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) - for (header in userHeaders) { - if (userHeaders.hasOwnProperty(header)) { - formHeaders[header.toLowerCase()] = userHeaders[header]; - } - } + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression - return formHeaders; -}; + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval -FormData.prototype.getBoundary = function() { - if (!this._boundary) { - this._generateBoundary(); - } - return this._boundary; -}; + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested -FormData.prototype.getBuffer = function() { - var dataBuffer = new Buffer.alloc( 0 ); - var boundary = this.getBoundary(); - // Create the form content. Add Line breaks to the end of data. - for (var i = 0, len = this._streams.length; i < len; i++) { - if (typeof this._streams[i] !== 'function') { + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } - // Add content to the buffer. - if(Buffer.isBuffer(this._streams[i])) { - dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); - }else { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); - } + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - // Add break after content. - if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); - } - } - } + msecs += 12219292800000; // `time_low` - // Add the footer and return the Buffer object. - return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); -}; + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` -FormData.prototype._generateBoundary = function() { - // This generates a 50 character boundary similar to those used by Firefox. - // They are optimized for boyer-moore parsing. - var boundary = '--------------------------'; - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16); - } + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` - this._boundary = boundary; -}; + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version -// Note: getLengthSync DOESN'T calculate streams length -// As workaround one can calculate file size manually -// and add it as knownLength option -FormData.prototype.getLengthSync = function() { - var knownLength = this._overheadLength + this._valueLength; + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - // Don't get confused, there are 3 "internal" streams for each keyval pair - // so it basically checks if there is any value added to the form - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` - // https://github.com/form-data/form-data/issues/40 - if (!this.hasKnownLength()) { - // Some async length retrievers are present - // therefore synchronous length calculation is false. - // Please use getLength(callback) to get proper length - this._error(new Error('Cannot calculate proper length in synchronous way.')); + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; } - return knownLength; -}; + return buf || (0, _stringify.default)(b); +} -// Public API to check if length of added values is known -// https://github.com/form-data/form-data/issues/196 -// https://github.com/form-data/form-data/issues/262 -FormData.prototype.hasKnownLength = function() { - var hasKnownLength = true; +var _default = v1; +exports["default"] = _default; - if (this._valuesToMeasure.length) { - hasKnownLength = false; - } +/***/ }), - return hasKnownLength; -}; +/***/ 6409: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -FormData.prototype.getLength = function(cb) { - var knownLength = this._overheadLength + this._valueLength; +"use strict"; - if (this._streams.length) { - knownLength += this._lastBoundary().length; - } - if (!this._valuesToMeasure.length) { - process.nextTick(cb.bind(this, null, knownLength)); - return; - } +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { - if (err) { - cb(err); - return; - } +var _v = _interopRequireDefault(__nccwpck_require__(5998)); - values.forEach(function(length) { - knownLength += length; - }); +var _md = _interopRequireDefault(__nccwpck_require__(4569)); - cb(null, knownLength); - }); -}; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -FormData.prototype.submit = function(params, cb) { - var request - , options - , defaults = {method: 'post'} - ; +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; +exports["default"] = _default; - // parse provided url if it's string - // or treat it as options object - if (typeof params == 'string') { +/***/ }), - params = parseUrl(params); - options = populate({ - port: params.port, - path: params.pathname, - host: params.hostname, - protocol: params.protocol - }, defaults); +/***/ 5998: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - // use custom params - } else { +"use strict"; - options = populate(params, defaults); - // if no port provided use default one - if (!options.port) { - options.port = options.protocol == 'https:' ? 443 : 80; - } - } - // put that good code in getHeaders to some use - options.headers = this.getHeaders(params.headers); +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = _default; +exports.URL = exports.DNS = void 0; - // https if specified, fallback to http in any other case - if (options.protocol == 'https:') { - request = https.request(options); - } else { - request = http.request(options); - } +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); - // get content length and fire away - this.getLength(function(err, length) { - if (err) { - this._error(err); - return; - } +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); - // add content length - request.setHeader('Content-Length', length); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - this.pipe(request); - if (cb) { - request.on('error', cb); - request.on('response', cb.bind(this, null)); - } - }.bind(this)); +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape - return request; -}; + const bytes = []; -FormData.prototype._error = function(err) { - if (!this.error) { - this.error = err; - this.pause(); - this.emit('error', err); + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); } -}; - -FormData.prototype.toString = function () { - return '[object FormData]'; -}; + return bytes; +} -/***/ }), +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; -/***/ 3061: -/***/ ((module) => { +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } -// populates missing values -module.exports = function(dst, src) { + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } - Object.keys(src).forEach(function(prop) - { - dst[prop] = dst[prop] || src[prop]; - }); + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` - return dst; -}; + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; -/***/ }), + if (buf) { + offset = offset || 0; -/***/ 3118: -/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } -/*! - * mime-db - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015-2022 Douglas Christopher Wilson - * MIT Licensed - */ + return buf; + } -/** - * Module exports. - */ + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support -module.exports = __nccwpck_require__(9857) + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} /***/ }), -/***/ 4991: +/***/ 5122: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; -/*! - * mime-types - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -/** - * Module dependencies. - * @private - */ - -var db = __nccwpck_require__(3118) -var extname = (__nccwpck_require__(1017).extname) - -/** - * Module variables. - * @private - */ +var _rng = _interopRequireDefault(__nccwpck_require__(807)); -var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/ -var TEXT_TYPE_REGEXP = /^text\//i +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); -/** - * Module exports. - * @public - */ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -exports.charset = charset -exports.charsets = { lookup: charset } -exports.contentType = contentType -exports.extension = extension -exports.extensions = Object.create(null) -exports.lookup = lookup -exports.types = Object.create(null) +function v4(options, buf, offset) { + options = options || {}; -// Populate the extensions/types maps -populateMaps(exports.extensions, exports.types) + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` -/** - * Get the default charset for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ -function charset (type) { - if (!type || typeof type !== 'string') { - return false - } + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - // TODO: use media-typer - var match = EXTRACT_TYPE_REGEXP.exec(type) - var mime = match && db[match[1].toLowerCase()] + if (buf) { + offset = offset || 0; - if (mime && mime.charset) { - return mime.charset - } + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } - // default text/* to utf-8 - if (match && TEXT_TYPE_REGEXP.test(match[1])) { - return 'UTF-8' + return buf; } - return false + return (0, _stringify.default)(rnds); } -/** - * Create a full Content-Type header given a MIME type or extension. - * - * @param {string} str - * @return {boolean|string} - */ +var _default = v4; +exports["default"] = _default; -function contentType (str) { - // TODO: should this even be in this module? - if (!str || typeof str !== 'string') { - return false - } +/***/ }), - var mime = str.indexOf('/') === -1 - ? exports.lookup(str) - : str +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (!mime) { - return false - } +"use strict"; - // TODO: use content-type or other module - if (mime.indexOf('charset') === -1) { - var charset = exports.charset(mime) - if (charset) mime += '; charset=' + charset.toLowerCase() - } - return mime -} +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; -/** - * Get the default extension for a MIME type. - * - * @param {string} type - * @return {boolean|string} - */ +var _v = _interopRequireDefault(__nccwpck_require__(5998)); -function extension (type) { - if (!type || typeof type !== 'string') { - return false - } +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); - // TODO: use media-typer - var match = EXTRACT_TYPE_REGEXP.exec(type) +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // get extensions - var exts = match && exports.extensions[match[1].toLowerCase()] +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; - if (!exts || !exts.length) { - return false - } +/***/ }), - return exts[0] -} +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { -/** - * Lookup the MIME type for a file path/extension. - * - * @param {string} path - * @return {boolean|string} - */ +"use strict"; -function lookup (path) { - if (!path || typeof path !== 'string') { - return false - } - // get the extension ("ext" or ".ext" or full path) - var extension = extname('x.' + path) - .toLowerCase() - .substr(1) +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - if (!extension) { - return false - } +var _regex = _interopRequireDefault(__nccwpck_require__(814)); - return exports.types[extension] || false +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); } -/** - * Populate the extensions and types maps. - * @private - */ +var _default = validate; +exports["default"] = _default; -function populateMaps (extensions, types) { - // source preference (least -> most) - var preference = ['nginx', 'apache', undefined, 'iana'] +/***/ }), - Object.keys(db).forEach(function forEachMimeType (type) { - var mime = db[type] - var exts = mime.extensions +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { - if (!exts || !exts.length) { - return - } +"use strict"; - // mime -> extensions - extensions[type] = exts - // extension -> mime - for (var i = 0; i < exts.length; i++) { - var extension = exts[i] +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; - if (types[extension]) { - var from = preference.indexOf(db[types[extension]].source) - var to = preference.indexOf(mime.source) +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); - if (types[extension] !== 'application/octet-stream' && - (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) { - // skip the remapping - continue - } - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // set the extension -> mime - types[extension] = type - } - }) +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); } +var _default = version; +exports["default"] = _default; /***/ }), @@ -26387,6 +26405,14 @@ module.exports = require("tls"); /***/ }), +/***/ 6224: +/***/ ((module) => { + +"use strict"; +module.exports = require("tty"); + +/***/ }), + /***/ 7310: /***/ ((module) => { @@ -28046,7 +28072,7 @@ module.exports = parseParams /***/ }), -/***/ 9857: +/***/ 3765: /***/ ((module) => { "use strict"; @@ -28112,8 +28138,8 @@ var __webpack_exports__ = {}; */ const core = __nccwpck_require__(2186); -const formData = __nccwpck_require__(5685); -const Mailgun = __nccwpck_require__(5046); +const formData = __nccwpck_require__(4334); +const Mailgun = __nccwpck_require__(4274); const mailgun = new Mailgun(formData); const optionalFields = ['cc', 'text', 'html']; diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 3efe8ace25..b00842b705 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@actions/core": "^1.10.1", - "mailgun.js": "^3.3.0" + "mailgun.js": "^10.1.0" }, "devDependencies": { "@vercel/ncc": "^0.38.1" @@ -51,15 +51,19 @@ "ncc": "dist/ncc/cli.js" } }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/base-64": { @@ -67,321 +71,93 @@ "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.8" } }, - "node_modules/data-uri-to-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", - "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=6" + "node": ">=0.4.0" } }, - "node_modules/fetch-blob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", - "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==", + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { - "node": "^10.17.0 || >=12.3.0" + "node": ">=4.0" }, "peerDependenciesMeta": { - "domexception": { + "debug": { "optional": true } } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { - "isobject": "^3.0.1" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ky": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/ky/-/ky-0.25.1.tgz", - "integrity": "sha512-PjpCEWlIU7VpiMVrTwssahkYXX1by6NCT0fhTUX34F3DTinARlgMpriuroolugFPcMgpPWrOW4mTb984Qm1RXA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky?sponsor=1" - } - }, - "node_modules/ky-universal": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.8.2.tgz", - "integrity": "sha512-xe0JaOH9QeYxdyGLnzUOVGK4Z6FGvDVzcXFTdrYA1f33MZdEa45sUDaMBy98xQMcsd2XIBrTXRrRYnegcSdgVQ==", - "dependencies": { - "abort-controller": "^3.0.0", - "node-fetch": "3.0.0-beta.9" - }, - "engines": { - "node": ">=10.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky-universal?sponsor=1" - }, - "peerDependencies": { - "ky": ">=0.17.0", - "web-streams-polyfill": ">=2.0.0" - }, - "peerDependenciesMeta": { - "web-streams-polyfill": { - "optional": true - } + "node": ">= 6" } }, "node_modules/mailgun.js": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-3.7.3.tgz", - "integrity": "sha512-DHP9v6dNPRM2puOx4HVJVjQKWzgzpQ5Fh1ICW632qaDVgd/QqGRhOjCoHe12JJqrFkhgDvXBhENYeZDHYdkJHQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-10.1.0.tgz", + "integrity": "sha512-j2yP5HGT14xwobySPA+y5IZtKW+XxavNySmFt8A/ztXTCmmgd2OEJMX293femA579iXyphjfymXyTQ/DCP9aAg==", "dependencies": { + "axios": "^1.6.0", "base-64": "^1.0.0", - "bluebird": "^3.7.2", - "ky": "^0.25.1", - "ky-universal": "^0.8.2", - "url": "^0.11.0", - "url-join": "0.0.1", - "web-streams-polyfill": "^3.0.1", - "webpack-merge": "^5.4.0" - } - }, - "node_modules/node-fetch": { - "version": "3.0.0-beta.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0-beta.9.tgz", - "integrity": "sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==", - "dependencies": { - "data-uri-to-buffer": "^3.0.1", - "fetch-blob": "^2.1.1" + "url-join": "^4.0.1" }, "engines": { - "node": "^10.17 || >=12.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" + "node": ">=18.0.0" } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dependencies": { - "side-channel": "^1.0.4" - }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.6" } }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/tunnel": { "version": "0.0.6", @@ -402,19 +178,10 @@ "node": ">=14.0" } }, - "node_modules/url": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", - "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.2" - } - }, "node_modules/url-join": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", - "integrity": "sha512-H6dnQ/yPAAVzMQRvEvyz01hhfQL5qRWSEt7BX8t9DqnPw9BjMb64fjIRq76Uvf1hkHp+mTZvEVJ5guXOT0Xqaw==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" }, "node_modules/uuid": { "version": "8.3.2", @@ -423,32 +190,6 @@ "bin": { "uuid": "dist/bin/uuid" } - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz", - "integrity": "sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" } } } diff --git a/.github/actions/send-email/package.json b/.github/actions/send-email/package.json index 088f74f9ea..69ee369e50 100644 --- a/.github/actions/send-email/package.json +++ b/.github/actions/send-email/package.json @@ -15,7 +15,7 @@ "license": "Apache-2.0", "dependencies": { "@actions/core": "^1.10.1", - "mailgun.js": "^3.3.0" + "mailgun.js": "^10.1.0" }, "devDependencies": { "@vercel/ncc": "^0.38.1" From 4d71f5f1c40fc6ad3dc4e1da83dca09488fa851b Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 8 Feb 2024 09:57:44 -0500 Subject: [PATCH 059/323] [chore] Update Github action workflows to fix node version and `set-output` deprecation warnings (#2431) * [chore]: Update github action workflows to fix node version and deprecation warnings * fix: typo * fix: missed upgrade --- .github/scripts/publish_preflight_check.sh | 13 +++++++------ .github/workflows/ci.yml | 4 ++-- .github/workflows/nightly.yml | 4 ++-- .github/workflows/release.yml | 22 ++++++++-------------- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/.github/scripts/publish_preflight_check.sh b/.github/scripts/publish_preflight_check.sh index fdba60bff8..8d2f4a14cd 100755 --- a/.github/scripts/publish_preflight_check.sh +++ b/.github/scripts/publish_preflight_check.sh @@ -70,7 +70,7 @@ if [[ ! "${RELEASE_VERSION}" =~ ^([0-9]*)\.([0-9]*)\.([0-9]*)$ ]]; then fi echo_info "Extracted release version: ${RELEASE_VERSION}" -echo "::set-output name=version::v${RELEASE_VERSION}" +echo "version=v${RELEASE_VERSION}" >> $GITHUB_OUTPUT echo_info "" @@ -156,12 +156,13 @@ readonly CHANGELOG=`${CURRENT_DIR}/generate_changelog.sh` echo "$CHANGELOG" # Parse and preformat the text to handle multi-line output. -# See https://github.community/t5/GitHub-Actions/set-output-Truncates-Multiline-Strings/td-p/37870 +# See https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-of-a-multiline-string +# and https://github.com/github/docs/issues/21529#issue-1418590935 FILTERED_CHANGELOG=`echo "$CHANGELOG" | grep -v "\\[INFO\\]"` || true -FILTERED_CHANGELOG="${FILTERED_CHANGELOG//'%'/'%25'}" -FILTERED_CHANGELOG="${FILTERED_CHANGELOG//$'\n'/'%0A'}" -FILTERED_CHANGELOG="${FILTERED_CHANGELOG//$'\r'/'%0D'}" -echo "::set-output name=changelog::${FILTERED_CHANGELOG}" +FILTERED_CHANGELOG="${FILTERED_CHANGELOG//$'\''/'"'}" +echo "changelog<> $GITHUB_OUTPUT +echo -e "$FILTERED_CHANGELOG" >> $GITHUB_OUTPUT +echo "CHANGELOGEOF" >> $GITHUB_OUTPUT echo "" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68fd5e2cd1..e4fb651cc4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,9 +12,9 @@ jobs: node-version: [14.x, 16.x] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - name: Install and build diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5ebc0c9ff2..c3edd0b335 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -29,12 +29,12 @@ jobs: steps: - name: Checkout source for staging - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: ref: ${{ github.event.client_payload.ref || github.ref }} - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 14.x diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c01fba6dcf..e183bac114 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,12 +40,12 @@ jobs: # via the 'ref' client parameter. steps: - name: Checkout source for staging - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: ref: ${{ github.event.client_payload.ref || github.ref }} - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 14.x @@ -104,7 +104,7 @@ jobs: steps: - name: Checkout source for publish - uses: actions/checkout@v2 + uses: actions/checkout@v4 # Download the artifacts created by the stage_release job. - name: Download release candidates @@ -114,7 +114,7 @@ jobs: # Node.js and NPM are needed to complete the publish. - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 14.x @@ -122,19 +122,13 @@ jobs: id: preflight run: ./.github/scripts/publish_preflight_check.sh - # We pull this action from a custom fork of a contributor until - # https://github.com/actions/create-release/pull/32 is merged. Also note that v1 of - # this action does not support the "body" parameter. + # See: https://cli.github.com/manual/gh_release_create - name: Create release tag - uses: fleskesvor/create-release@1a72e235c178bf2ae6c51a8ae36febc24568c5fe env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ steps.preflight.outputs.version }} - release_name: Firebase Admin Node.js SDK ${{ steps.preflight.outputs.version }} - body: ${{ steps.preflight.outputs.changelog }} - draft: false - prerelease: false + run: gh release create ${{ steps.preflight.outputs.version }} + --title "Firebase Admin Node.js SDK ${{ steps.preflight.outputs.version }}" + --notes '${{ steps.preflight.outputs.changelog }}' - name: Publish to NPM run: ./.github/scripts/publish_package.sh From 11a9b20df2bf511770b9d01c1df578e458d4f1d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:30:33 -0500 Subject: [PATCH 060/323] build(deps-dev): bump @microsoft/api-extractor from 7.39.4 to 7.40.1 (#2452) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.39.4 to 7.40.1. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.40.1/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5fe3a93dae..85116a2f1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -945,15 +945,15 @@ } }, "@microsoft/api-extractor": { - "version": "7.39.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.39.4.tgz", - "integrity": "sha512-6YvfkpbEqRQ0UPdVBc+lOiq7VlXi9kw8U3w+RcXCFDVc/UljlXU5l9fHEyuBAW1GGO2opUe+yf9OscWhoHANhg==", + "version": "7.40.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.40.1.tgz", + "integrity": "sha512-xHn2Zkh6s5JIjP94SG6VtIlIeRJcASgfZpDKV+bgoddMt1X4ujSZFOz7uEGNYNO7mEtdVOvpNKBpC4CDytD8KQ==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.7", + "@microsoft/api-extractor-model": "7.28.9", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.64.2", + "@rushstack/node-core-library": "3.66.0", "@rushstack/rig-package": "0.5.1", "@rushstack/ts-command-line": "4.17.1", "colors": "~1.2.1", @@ -971,9 +971,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.64.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.64.2.tgz", - "integrity": "sha512-n1S2VYEklONiwKpUyBq/Fym6yAsfsCXrqFabuOMcCuj4C+zW+HyaspSHXJCKqkMxfjviwe/c9+DUqvRWIvSN9Q==", + "version": "3.66.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.66.0.tgz", + "integrity": "sha512-nXyddNe3T9Ph14TrIfjtLZ+GDzC7HL/wF+ZKC18qmRVtz2xXLd1ZzreVgiAgGDwn8ZUWZ/7q//gQJk96iWjSrg==", "dev": true, "requires": { "colors": "~1.2.1", @@ -1012,14 +1012,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.7", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.7.tgz", - "integrity": "sha512-4gCGGEQGHmbQmarnDcEWS2cjj0LtNuD3D6rh3ZcAyAYTkceAugAk2eyQHGdTcGX8w3qMjWCTU1TPb8xHnMM+Kg==", + "version": "7.28.9", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.9.tgz", + "integrity": "sha512-lM77dV+VO46MGp5lu4stUBnO3jyr+CrDzU+DtapcOQEZUqJxPYUoK5zjeD+gRZ9ckgGMZC94ch6FBkpmsjwQgw==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.64.2" + "@rushstack/node-core-library": "3.66.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1029,9 +1029,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.64.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.64.2.tgz", - "integrity": "sha512-n1S2VYEklONiwKpUyBq/Fym6yAsfsCXrqFabuOMcCuj4C+zW+HyaspSHXJCKqkMxfjviwe/c9+DUqvRWIvSN9Q==", + "version": "3.66.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.66.0.tgz", + "integrity": "sha512-nXyddNe3T9Ph14TrIfjtLZ+GDzC7HL/wF+ZKC18qmRVtz2xXLd1ZzreVgiAgGDwn8ZUWZ/7q//gQJk96iWjSrg==", "dev": true, "requires": { "colors": "~1.2.1", From b65b1a8f8bfc7505d9ab5a177ff56ac14e8751cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:37:23 +0000 Subject: [PATCH 061/323] build(deps-dev): bump mocha from 10.2.0 to 10.3.0 (#2454) --- package-lock.json | 57 +++++++++++++++-------------------------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index 85116a2f1c..0a9b6e8735 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6426,9 +6426,9 @@ "dev": true }, "mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", + "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -6438,13 +6438,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -6476,6 +6475,15 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -6511,28 +6519,16 @@ "optional": true }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } + "minimatch": "^5.0.1", + "once": "^1.3.0" } }, "is-binary-path": { @@ -6551,17 +6547,6 @@ "dev": true, "requires": { "brace-expansion": "^2.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - } } }, "ms": { @@ -6653,12 +6638,6 @@ "dev": true, "optional": true }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", From 5fe41189279c0a037db3fb48298a1adc657e9701 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:45:55 +0000 Subject: [PATCH 062/323] build(deps): bump @types/node from 20.11.5 to 20.11.17 (#2455) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a9b6e8735..c2b3cc2f8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1457,9 +1457,9 @@ } }, "@types/node": { - "version": "20.11.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.5.tgz", - "integrity": "sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==", + "version": "20.11.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz", + "integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==", "requires": { "undici-types": "~5.26.4" } From 45b87f2d8756654731a4245985c07337af2dbc96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:37:37 -0500 Subject: [PATCH 063/323] build(deps): bump undici in /.github/actions/send-email (#2459) Bumps [undici](https://github.com/nodejs/undici) from 5.28.2 to 5.28.3. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v5.28.2...v5.28.3) --- updated-dependencies: - dependency-name: undici dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/send-email/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index b00842b705..9882308ff4 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -168,9 +168,9 @@ } }, "node_modules/undici": { - "version": "5.28.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", - "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==", + "version": "5.28.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", + "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", "dependencies": { "@fastify/busboy": "^2.0.0" }, From 86ec221dafeec132fe3279ce02c026147e8b90c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:43:07 +0000 Subject: [PATCH 064/323] build(deps): bump @types/node from 20.11.17 to 20.11.19 (#2464) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2b3cc2f8c..11f8bffead 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1457,9 +1457,9 @@ } }, "@types/node": { - "version": "20.11.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz", - "integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==", + "version": "20.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", + "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", "requires": { "undici-types": "~5.26.4" } From 6d259ccc0fa3e66c0d28ddc9eb992fdede886262 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:48:28 +0000 Subject: [PATCH 065/323] build(deps-dev): bump nock from 13.5.1 to 13.5.3 (#2463) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 11f8bffead..b2be6254ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6726,9 +6726,9 @@ } }, "nock": { - "version": "13.5.1", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.1.tgz", - "integrity": "sha512-+s7b73fzj5KnxbKH4Oaqz07tQ8degcMilU4rrmnKvI//b0JMBU4wEXFQ8zqr+3+L4eWSfU3H/UoIVGUV0tue1Q==", + "version": "13.5.3", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.3.tgz", + "integrity": "sha512-2NlGmHIK2rTeyy7UaY1ZNg0YZfEJMxghXgZi0b4DBsUyoDNTTxZeCSG1nmirAWF44RkkoV8NnegLVQijgVapNQ==", "dev": true, "requires": { "debug": "^4.1.0", From 9955bca47249301aa970679ae99fe01d54adf6a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:52:38 +0000 Subject: [PATCH 066/323] build(deps-dev): bump @microsoft/api-extractor from 7.40.1 to 7.40.3 (#2465) --- package-lock.json | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index b2be6254ac..4aa9560348 100644 --- a/package-lock.json +++ b/package-lock.json @@ -945,17 +945,17 @@ } }, "@microsoft/api-extractor": { - "version": "7.40.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.40.1.tgz", - "integrity": "sha512-xHn2Zkh6s5JIjP94SG6VtIlIeRJcASgfZpDKV+bgoddMt1X4ujSZFOz7uEGNYNO7mEtdVOvpNKBpC4CDytD8KQ==", + "version": "7.40.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.40.3.tgz", + "integrity": "sha512-mh1BTKFxowAcArjUG3ryKN7seUEQt5BawAWCEtVq7nJYT2w2lBRGBmMBy93fnrWUxnvatXdtWgNi++Dl5R+7sQ==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.9", + "@microsoft/api-extractor-model": "7.28.11", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.66.0", - "@rushstack/rig-package": "0.5.1", - "@rushstack/ts-command-line": "4.17.1", + "@rushstack/node-core-library": "4.0.0", + "@rushstack/rig-package": "0.5.2", + "@rushstack/ts-command-line": "4.17.2", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.22.1", @@ -971,9 +971,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.66.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.66.0.tgz", - "integrity": "sha512-nXyddNe3T9Ph14TrIfjtLZ+GDzC7HL/wF+ZKC18qmRVtz2xXLd1ZzreVgiAgGDwn8ZUWZ/7q//gQJk96iWjSrg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.0.tgz", + "integrity": "sha512-4ocU3K2NtpILEWG6LjSMRSwrb0CjvYOioVTzqvIOj6vc5yD0BcscfpVp5dkHGLZxnqdmkBrTKvyg6AmqhWnw1w==", "dev": true, "requires": { "colors": "~1.2.1", @@ -986,9 +986,9 @@ } }, "@rushstack/ts-command-line": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.17.1.tgz", - "integrity": "sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==", + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.17.2.tgz", + "integrity": "sha512-QS2S2nJo9zXq/+9Dk10LmvIFugMizI9IeQUH4jnhIcoaeqYlsv2fK830U+/gMKpI5vomXz19XMXfkUfZzO4R3A==", "dev": true, "requires": { "@types/argparse": "1.0.38", @@ -1012,14 +1012,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.9", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.9.tgz", - "integrity": "sha512-lM77dV+VO46MGp5lu4stUBnO3jyr+CrDzU+DtapcOQEZUqJxPYUoK5zjeD+gRZ9ckgGMZC94ch6FBkpmsjwQgw==", + "version": "7.28.11", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.11.tgz", + "integrity": "sha512-iyYqSH4gI3dFj4GLTTvi4Usgd5bILc9bbB5m2xul5tJ0JQ9G9lc1rY67rSD6O0hU62E1WRHOai9GUUVXMgCTdA==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.66.0" + "@rushstack/node-core-library": "4.0.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1029,9 +1029,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.66.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.66.0.tgz", - "integrity": "sha512-nXyddNe3T9Ph14TrIfjtLZ+GDzC7HL/wF+ZKC18qmRVtz2xXLd1ZzreVgiAgGDwn8ZUWZ/7q//gQJk96iWjSrg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.0.tgz", + "integrity": "sha512-4ocU3K2NtpILEWG6LjSMRSwrb0CjvYOioVTzqvIOj6vc5yD0BcscfpVp5dkHGLZxnqdmkBrTKvyg6AmqhWnw1w==", "dev": true, "requires": { "colors": "~1.2.1", @@ -1201,9 +1201,9 @@ } }, "@rushstack/rig-package": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.1.tgz", - "integrity": "sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", + "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", "dev": true, "requires": { "resolve": "~1.22.1", From d856abe9ab5299c9b3f82f6a527bf55f9dbe3c5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 12:26:25 -0500 Subject: [PATCH 067/323] build(deps-dev): bump nock from 13.5.3 to 13.5.4 (#2475) Bumps [nock](https://github.com/nock/nock) from 13.5.3 to 13.5.4. - [Release notes](https://github.com/nock/nock/releases) - [Changelog](https://github.com/nock/nock/blob/main/CHANGELOG.md) - [Commits](https://github.com/nock/nock/compare/v13.5.3...v13.5.4) --- updated-dependencies: - dependency-name: nock dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4aa9560348..1bdd6bf6ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6726,9 +6726,9 @@ } }, "nock": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.3.tgz", - "integrity": "sha512-2NlGmHIK2rTeyy7UaY1ZNg0YZfEJMxghXgZi0b4DBsUyoDNTTxZeCSG1nmirAWF44RkkoV8NnegLVQijgVapNQ==", + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz", + "integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==", "dev": true, "requires": { "debug": "^4.1.0", From 0ffb8c77f290063bda7fe557e99d0655d8b4cabd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 12:40:55 -0500 Subject: [PATCH 068/323] build(deps-dev): bump eslint from 8.56.0 to 8.57.0 (#2473) Bumps [eslint](https://github.com/eslint/eslint) from 8.56.0 to 8.57.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.56.0...v8.57.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1bdd6bf6ac..e567473744 100644 --- a/package-lock.json +++ b/package-lock.json @@ -450,9 +450,9 @@ } }, "@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true }, "@fastify/busboy": { @@ -3439,16 +3439,16 @@ "dev": true }, "eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -4050,9 +4050,9 @@ } }, "flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "flush-write-stream": { From 156ea00e0f97af7c4787a82e7eb0fab209cdfaa1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 14:34:47 -0500 Subject: [PATCH 069/323] build(deps-dev): bump @microsoft/api-extractor from 7.40.3 to 7.42.0 (#2480) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.40.3 to 7.42.0. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.42.0/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 99 +++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index e567473744..5bccfdb92f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -945,19 +945,20 @@ } }, "@microsoft/api-extractor": { - "version": "7.40.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.40.3.tgz", - "integrity": "sha512-mh1BTKFxowAcArjUG3ryKN7seUEQt5BawAWCEtVq7nJYT2w2lBRGBmMBy93fnrWUxnvatXdtWgNi++Dl5R+7sQ==", + "version": "7.42.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.42.0.tgz", + "integrity": "sha512-PemnV/hXo3o/7Qpw/yxmu1ReyA/SnZ1/x5w6wvEu7W2NpYgo79VctVo5AdDwExOukBDPnsb9b8r6mgKQVyGrqg==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.11", + "@microsoft/api-extractor-model": "7.28.13", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.0.0", + "@rushstack/node-core-library": "4.0.2", "@rushstack/rig-package": "0.5.2", - "@rushstack/ts-command-line": "4.17.2", - "colors": "~1.2.1", + "@rushstack/terminal": "0.10.0", + "@rushstack/ts-command-line": "4.18.0", "lodash": "~4.17.15", + "minimatch": "~3.0.3", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", @@ -971,12 +972,11 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.0.tgz", - "integrity": "sha512-4ocU3K2NtpILEWG6LjSMRSwrb0CjvYOioVTzqvIOj6vc5yD0BcscfpVp5dkHGLZxnqdmkBrTKvyg6AmqhWnw1w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", + "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", "dev": true, "requires": { - "colors": "~1.2.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", "jju": "~1.4.0", @@ -986,22 +986,25 @@ } }, "@rushstack/ts-command-line": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.17.2.tgz", - "integrity": "sha512-QS2S2nJo9zXq/+9Dk10LmvIFugMizI9IeQUH4jnhIcoaeqYlsv2fK830U+/gMKpI5vomXz19XMXfkUfZzO4R3A==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.18.0.tgz", + "integrity": "sha512-iq8+NCtnOhz4BR4hwmFCRzULmFd8hSbDqJWbdGG44t/fXMRsK3Drft1fiDkxWGPuD3V1x3RDYdXxAfJqKU3XpQ==", "dev": true, "requires": { + "@rushstack/terminal": "0.10.0", "@types/argparse": "1.0.38", "argparse": "~1.0.9", - "colors": "~1.2.1", "string-argv": "~0.3.1" } }, - "colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } }, "typescript": { "version": "5.3.3", @@ -1012,14 +1015,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.11", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.11.tgz", - "integrity": "sha512-iyYqSH4gI3dFj4GLTTvi4Usgd5bILc9bbB5m2xul5tJ0JQ9G9lc1rY67rSD6O0hU62E1WRHOai9GUUVXMgCTdA==", + "version": "7.28.13", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", + "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.0.0" + "@rushstack/node-core-library": "4.0.2" }, "dependencies": { "@microsoft/tsdoc": { @@ -1029,12 +1032,11 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.0.tgz", - "integrity": "sha512-4ocU3K2NtpILEWG6LjSMRSwrb0CjvYOioVTzqvIOj6vc5yD0BcscfpVp5dkHGLZxnqdmkBrTKvyg6AmqhWnw1w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", + "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", "dev": true, "requires": { - "colors": "~1.2.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", "jju": "~1.4.0", @@ -1042,12 +1044,6 @@ "semver": "~7.5.4", "z-schema": "~5.0.2" } - }, - "colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true } } }, @@ -1210,6 +1206,41 @@ "strip-json-comments": "~3.1.1" } }, + "@rushstack/terminal": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", + "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", + "dev": true, + "requires": { + "@rushstack/node-core-library": "4.0.2", + "supports-color": "~8.1.1" + }, + "dependencies": { + "@rushstack/node-core-library": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", + "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", + "dev": true, + "requires": { + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "z-schema": "~5.0.2" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "@rushstack/ts-command-line": { "version": "4.15.2", "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz", From e179d7ded5d8f38ca8536dd5259187fc75b5d857 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 14:29:58 -0500 Subject: [PATCH 070/323] build(deps-dev): bump @firebase/app-compat from 0.2.27 to 0.2.28 (#2483) Bumps [@firebase/app-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/app-compat) from 0.2.27 to 0.2.28. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/master/packages/app-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/app-compat@0.2.28/packages/app-compat) --- updated-dependencies: - dependency-name: "@firebase/app-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5bccfdb92f..df110ed38a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -477,9 +477,9 @@ } }, "@firebase/app": { - "version": "0.9.27", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.27.tgz", - "integrity": "sha512-p2Dvl1ge4kRsyK5+wWcmdAIE9MSwZ0pDKAYB51LZgZuz6wciUZk4E1yAEdkfQlRxuHehn+Ol9WP5Qk2XQZiHGg==", + "version": "0.9.28", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.28.tgz", + "integrity": "sha512-MS0+EtNixrwJbVDs5Bt/lhUhzeWGUtUoP6X+zYZck5GAZwI5g4F91noVA9oIXlFlpn6Q1xIbiaHA2GwGk7/7Ag==", "dev": true, "requires": { "@firebase/component": "0.6.5", @@ -516,12 +516,12 @@ "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" }, "@firebase/app-compat": { - "version": "0.2.27", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.27.tgz", - "integrity": "sha512-SYlqocfUDKPHR6MSFC8hree0BTiWFu5o8wbf6zFlYXyG41w7TcHp4wJi4H/EL5V6cM4kxwruXTJtqXX/fRAZtw==", + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.28.tgz", + "integrity": "sha512-Mr2NbeM1Oaayuw5unUAMzt+7/MN+e2uklT1l87D+ZLJl2UvhZAZmMt74GjEI9N3sDYKMeszSbszBqtJ1fGVafQ==", "dev": true, "requires": { - "@firebase/app": "0.9.27", + "@firebase/app": "0.9.28", "@firebase/component": "0.6.5", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.4", From 2b375f13081d8401a1163390b988abb025fdd4d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:35:11 +0000 Subject: [PATCH 071/323] build(deps): bump @types/node from 20.11.19 to 20.11.24 (#2484) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index df110ed38a..9b5a52dbda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1488,9 +1488,9 @@ } }, "@types/node": { - "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "version": "20.11.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", "requires": { "undici-types": "~5.26.4" } From 5a920ef4f938e71f85984accc082ee4d42ded211 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 19:42:16 +0000 Subject: [PATCH 072/323] build(deps-dev): bump @microsoft/api-extractor from 7.42.0 to 7.42.3 (#2485) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b5a52dbda..4dcf9b25da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -945,9 +945,9 @@ } }, "@microsoft/api-extractor": { - "version": "7.42.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.42.0.tgz", - "integrity": "sha512-PemnV/hXo3o/7Qpw/yxmu1ReyA/SnZ1/x5w6wvEu7W2NpYgo79VctVo5AdDwExOukBDPnsb9b8r6mgKQVyGrqg==", + "version": "7.42.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.42.3.tgz", + "integrity": "sha512-JNLJFpGHz6ekjS6bvYXxUBeRGnSHeCMFNvRbCQ+7XXB/ZFrgLSMPwWtEq40AiWAy+oyG5a4RSNwdJTp0B2USvQ==", "dev": true, "requires": { "@microsoft/api-extractor-model": "7.28.13", @@ -956,7 +956,7 @@ "@rushstack/node-core-library": "4.0.2", "@rushstack/rig-package": "0.5.2", "@rushstack/terminal": "0.10.0", - "@rushstack/ts-command-line": "4.18.0", + "@rushstack/ts-command-line": "4.19.1", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -986,9 +986,9 @@ } }, "@rushstack/ts-command-line": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.18.0.tgz", - "integrity": "sha512-iq8+NCtnOhz4BR4hwmFCRzULmFd8hSbDqJWbdGG44t/fXMRsK3Drft1fiDkxWGPuD3V1x3RDYdXxAfJqKU3XpQ==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", + "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", "dev": true, "requires": { "@rushstack/terminal": "0.10.0", From 05203aeef7c0fb6e24a85a332c064c53813e3a81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 14:12:41 -0500 Subject: [PATCH 073/323] build(deps): bump jose from 4.15.4 to 4.15.5 (#2489) Bumps [jose](https://github.com/panva/jose) from 4.15.4 to 4.15.5. - [Release notes](https://github.com/panva/jose/releases) - [Changelog](https://github.com/panva/jose/blob/v4.15.5/CHANGELOG.md) - [Commits](https://github.com/panva/jose/compare/v4.15.4...v4.15.5) --- updated-dependencies: - dependency-name: jose dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4dcf9b25da..06ca73f566 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5654,9 +5654,9 @@ "dev": true }, "jose": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", - "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==" + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==" }, "js-tokens": { "version": "4.0.0", From f6a3ae9909d784b16162683e93e99953dca23f8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:53:29 -0400 Subject: [PATCH 074/323] build(deps): bump @google-cloud/firestore from 7.3.0 to 7.4.0 (#2499) Bumps [@google-cloud/firestore](https://github.com/googleapis/nodejs-firestore) from 7.3.0 to 7.4.0. - [Release notes](https://github.com/googleapis/nodejs-firestore/releases) - [Changelog](https://github.com/googleapis/nodejs-firestore/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-firestore/compare/v7.3.0...v7.4.0) --- updated-dependencies: - dependency-name: "@google-cloud/firestore" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06ca73f566..02b6d27da8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ } }, "@google-cloud/firestore": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.3.0.tgz", - "integrity": "sha512-2IftQLAbCuVp0nTd3neeu+d3OYIegJpV/V9R4USQj51LzJcXPe8h8jZ7j3+svSNhJVGy6JsN0T1QqlJdMDhTwg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.4.0.tgz", + "integrity": "sha512-PRukAUgeBOZu/4pK9NXkAs8ur6QUpG6bBiwcnSO1qsh0FlR93gqU+VtkCx3EJM46S10jzMhHqpA0NoVbnUs5TQ==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -743,13 +743,13 @@ } }, "@grpc/grpc-js": { - "version": "1.9.14", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.14.tgz", - "integrity": "sha512-nOpuzZ2G3IuMFN+UPPpKrC6NsLmWsTqSsm66IRfnBt1D4pwTqE27lmbpcPM+l2Ua4gE7PfjRHI6uedAy7hoXUw==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.3.tgz", + "integrity": "sha512-qiO9MNgYnwbvZ8MK0YLWbnGrNX3zTcj6/Ef7UHu5ZofER3e2nF3Y35GaPo9qNJJ/UJQKa4KL+z/F4Q8Q+uCdUQ==", "optional": true, "requires": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" + "@grpc/proto-loader": "^0.7.10", + "@js-sdsl/ordered-map": "^4.4.2" } }, "@grpc/proto-loader": { @@ -906,6 +906,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "optional": true + }, "@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -4595,17 +4601,17 @@ } }, "google-gax": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.0.tgz", - "integrity": "sha512-SWHX72gbccNfpPoeTkNmZJxmLyKWeLr0+5Ch6qtrf4oAN8KFXnyXe5EixatILnJWufM3L59MRZ4hSJWVJ3IQqw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.1.tgz", + "integrity": "sha512-qpSfslpwqToIgQ+Tf3MjWIDjYK4UFIZ0uz6nLtttlW9N1NQA4PhGf9tlGo6KDYJ4rgL2w4CjXVd0z5yeNpN/Iw==", "optional": true, "requires": { - "@grpc/grpc-js": "~1.9.6", + "@grpc/grpc-js": "~1.10.0", "@grpc/proto-loader": "^0.7.0", "@types/long": "^4.0.0", "abort-controller": "^3.0.0", "duplexify": "^4.0.0", - "google-auth-library": "^9.0.0", + "google-auth-library": "^9.3.0", "node-fetch": "^2.6.1", "object-hash": "^3.0.0", "proto3-json-serializer": "^2.0.0", From 298f92435bd2c8a1b26337f5d7e1474fcbeb7453 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 15:57:27 +0000 Subject: [PATCH 075/323] build(deps): bump follow-redirects in /.github/actions/send-email (#2497) --- .github/actions/send-email/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 9882308ff4..63221bcb45 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -91,9 +91,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", From 742cc96d601258cd3654780af97712c6cdfa9de9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:25:12 +0000 Subject: [PATCH 076/323] build(deps): bump @fastify/busboy from 2.1.0 to 2.1.1 (#2491) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02b6d27da8..28e582b658 100644 --- a/package-lock.json +++ b/package-lock.json @@ -456,9 +456,9 @@ "dev": true }, "@fastify/busboy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", - "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==" }, "@firebase/api-documenter": { "version": "0.4.0", From e42840cafe12423e8c19636173f9c7a0f9284499 Mon Sep 17 00:00:00 2001 From: DyosTheNerd Date: Thu, 21 Mar 2024 17:29:36 +0100 Subject: [PATCH 077/323] issue 2467: add async to send each loop to prevent local validation from throwing in an unknown state (#2469) Co-authored-by: Lahiru Maramba --- src/messaging/messaging.ts | 2 +- test/unit/messaging/messaging.spec.ts | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/messaging/messaging.ts b/src/messaging/messaging.ts index 932b8d8e52..f7a2a14ddf 100644 --- a/src/messaging/messaging.ts +++ b/src/messaging/messaging.ts @@ -294,7 +294,7 @@ export class Messaging { return this.getUrlPath() .then((urlPath) => { - const requests: Promise[] = copy.map((message) => { + const requests: Promise[] = copy.map(async (message) => { validateMessage(message); const request: { message: Message; validate_only?: boolean } = { message }; if (dryRun) { diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index dc978c7866..c343ea319d 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -604,6 +604,19 @@ describe('Messaging', () => { .should.eventually.be.rejectedWith('Exactly one of topic, token or condition is required'); }); + it('should reject a message when it does not pass local validation, but still try the other messages', () => { + const invalidMessage: Message = { token: 'a', notification: { imageUrl: 'abc' } }; + const messageIds = [ + 'projects/projec_id/messages/1', + ]; + messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) + return messaging.sendEach([invalidMessage, validMessage]) + .then((response: BatchResponse) => { + expect(response.successCount).to.equal(1); + expect(response.failureCount).to.equal(1); + }); + }); + const invalidDryRun = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; invalidDryRun.forEach((dryRun) => { it(`should throw given invalid dryRun parameter: ${JSON.stringify(dryRun)}`, () => { From 8142b28b36fa6c0bfa194e9d1681892d2060efcc Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:48:40 -0400 Subject: [PATCH 078/323] [chore] Fixed links to rtdb api docs (#2501) * Fixed links to rtdb api docs * fixed text to reference `database-compat` --- docgen/extras/firebase-admin.database.md | 12 ++++----- src/database/database-namespace.ts | 32 ++++++++++++------------ src/database/database.ts | 4 +-- src/database/index.ts | 8 +++--- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/docgen/extras/firebase-admin.database.md b/docgen/extras/firebase-admin.database.md index 6e1c25770f..0cce501db4 100644 --- a/docgen/extras/firebase-admin.database.md +++ b/docgen/extras/firebase-admin.database.md @@ -4,9 +4,9 @@ The following externally defined APIs are re-exported from this module entry poi | Symbol | Description | | --- | --- | -| [DataSnapshot](https://firebase.google.com/docs/reference/js/database.datasnapshot) | `DataSnapshot` type from the `@firebase/database` package. | -| [EventType](https://firebase.google.com/docs/reference/js/database#eventtype) | `EventType` type from the `@firebase/database` package. | -| [OnDisconnect](https://firebase.google.com/docs/reference/js/database.ondisconnect) | `OnDisconnect` type from the `@firebase/database` package. | -| [Query](https://firebase.google.com/docs/reference/js/database.query) | `Query` type from the `@firebase/database` package. | -| [DatabaseReference](https://firebase.google.com/docs/reference/js/database.databasereference) | `DatabaseReference` type from the `@firebase/database` package. | -| [ThenableReference](https://firebase.google.com/docs/reference/js/database.thenablereference) | `ThenableReference` type from the `@firebase/database` package. | +| [DataSnapshot](https://firebase.google.com/docs/reference/js/v8/firebase.database.DataSnapshot) | `DataSnapshot` type from the `@firebase/database-compat` package. | +| [EventType](https://firebase.google.com/docs/reference/js/v8/firebase.database#eventtype) | `EventType` type from the `@firebase/database-compat` package. | +| [OnDisconnect](https://firebase.google.com/docs/reference/js/v8/firebase.database.OnDisconnect) | `OnDisconnect` type from the `@firebase/database-compat` package. | +| [Query](https://firebase.google.com/docs/reference/js/v8/firebase.database.Query) | `Query` type from the `@firebase/database-compat` package. | +| [Reference](https://firebase.google.com/docs/reference/js/v8/firebase.database.Reference) | `Reference` type from the `@firebase/database-compat` package. | +| [ThenableReference](https://firebase.google.com/docs/reference/js/v8/firebase.database.ThenableReference) | `ThenableReference` type from the `@firebase/database-compat` package. | diff --git a/src/database/database-namespace.ts b/src/database/database-namespace.ts index e59be799db..0bb190bc27 100644 --- a/src/database/database-namespace.ts +++ b/src/database/database-namespace.ts @@ -57,50 +57,50 @@ export namespace database { export type Database = TDatabase; /** - * Type alias to {@link https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot | DataSnapshot} - * type from the `@firebase/database` package. + * Type alias to {@link https://firebase.google.com/docs/reference/js/v8/firebase.database.DataSnapshot | DataSnapshot} + * type from the `@firebase/database-compat` package. */ export type DataSnapshot = rtdb.DataSnapshot; /** - * Type alias to the {@link https://firebase.google.com/docs/reference/js/firebase.database#eventtype | EventType} - * type from the `@firebase/database` package. + * Type alias to the {@link https://firebase.google.com/docs/reference/js/v8/firebase.database#eventtype | EventType} + * type from the `@firebase/database-compat` package. */ export type EventType = rtdb.EventType; /** - * Type alias to {@link https://firebase.google.com/docs/reference/js/firebase.database.OnDisconnect | OnDisconnect} - * type from the `@firebase/database` package. + * Type alias to {@link https://firebase.google.com/docs/reference/js/v8/firebase.database.OnDisconnect | OnDisconnect} + * type from the `@firebase/database-compat` package. */ export type OnDisconnect = rtdb.OnDisconnect; /** - * Type alias to {@link https://firebase.google.com/docs/reference/js/firebase.database.Query | Query} - * type from the `@firebase/database` package. + * Type alias to {@link https://firebase.google.com/docs/reference/js/v8/firebase.database.Query | Query} + * type from the `@firebase/database-compat` package. */ export type Query = rtdb.Query; /** - * Type alias to {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference | Reference} - * type from the `@firebase/database` package. + * Type alias to {@link https://firebase.google.com/docs/reference/js/v8/firebase.database.Reference | Reference} + * type from the `@firebase/database-compat` package. */ export type Reference = rtdb.Reference; /** - * Type alias to {@link https://firebase.google.com/docs/reference/js/firebase.database.ThenableReference | - * ThenableReference} type from the `@firebase/database` package. + * Type alias to {@link https://firebase.google.com/docs/reference/js/v8/firebase.database.ThenableReference | + * ThenableReference} type from the `@firebase/database-compat` package. */ export type ThenableReference = rtdb.ThenableReference; /** - * {@link https://firebase.google.com/docs/reference/js/firebase.database#enablelogging | enableLogging} - * function from the `@firebase/database` package. + * {@link https://firebase.google.com/docs/reference/js/v8/firebase.database#enablelogging | enableLogging} + * function from the `@firebase/database-compat` package. */ export declare const enableLogging: typeof rtdb.enableLogging; /** - * {@link https://firebase.google.com/docs/reference/js/firebase.database.ServerValue | ServerValue} - * constant from the `@firebase/database` package. + * {@link https://firebase.google.com/docs/reference/js/v8/firebase.database.ServerValue | ServerValue} + * constant from the `@firebase/database-compat` package. */ // eslint-disable-next-line @typescript-eslint/naming-convention export declare const ServerValue: rtdb.ServerValue; diff --git a/src/database/database.ts b/src/database/database.ts index 8c79925637..555072f2df 100644 --- a/src/database/database.ts +++ b/src/database/database.ts @@ -29,8 +29,8 @@ import { getSdkVersion } from '../utils/index'; /** * The Firebase Database service interface. Extends the - * {@link https://firebase.google.com/docs/reference/js/firebase.database.Database | Database} - * interface provided by the `@firebase/database` package. + * {@link https://firebase.google.com/docs/reference/js/v8/firebase.database.Database | Database} + * interface provided by the `@firebase/database-compat` package. */ export interface Database extends FirebaseDatabase { /** diff --git a/src/database/index.ts b/src/database/index.ts index 9a5fbfdf5e..d276b27a08 100644 --- a/src/database/index.ts +++ b/src/database/index.ts @@ -43,14 +43,14 @@ export { // TODO: Remove the following any-cast once the typins in @firebase/database-types are fixed. /** - * {@link https://firebase.google.com/docs/reference/js/firebase.database#enablelogging | enableLogging} - * function from the `@firebase/database` package. + * {@link https://firebase.google.com/docs/reference/js/v8/firebase.database#enablelogging | enableLogging} + * function from the `@firebase/database-compat` package. */ export const enableLogging: typeof rtdb.enableLogging = enableLoggingFunc as any; /** - * {@link https://firebase.google.com/docs/reference/js/firebase.database.ServerValue | ServerValue} - * constant from the `@firebase/database` package. + * {@link https://firebase.google.com/docs/reference/js/v8/firebase.database.ServerValue | ServerValue} + * constant from the `@firebase/database-compat` package. */ // eslint-disable-next-line @typescript-eslint/naming-convention export const ServerValue: rtdb.ServerValue = serverValueConst; From 5f683c40e058ed493aa47e82c573ad451728b47b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:12:12 -0400 Subject: [PATCH 079/323] build(deps): bump @types/node from 20.11.24 to 20.11.30 (#2508) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.24 to 20.11.30. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 28e582b658..595a685244 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1494,9 +1494,9 @@ } }, "@types/node": { - "version": "20.11.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", - "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", "requires": { "undici-types": "~5.26.4" } From 09dadb2534f2ae40d20c64518bbe0203ba288ba2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 20:17:29 +0000 Subject: [PATCH 080/323] build(deps-dev): bump @microsoft/api-extractor from 7.42.3 to 7.43.0 (#2511) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 595a685244..9286e0d8da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -951,9 +951,9 @@ } }, "@microsoft/api-extractor": { - "version": "7.42.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.42.3.tgz", - "integrity": "sha512-JNLJFpGHz6ekjS6bvYXxUBeRGnSHeCMFNvRbCQ+7XXB/ZFrgLSMPwWtEq40AiWAy+oyG5a4RSNwdJTp0B2USvQ==", + "version": "7.43.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", + "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", "dev": true, "requires": { "@microsoft/api-extractor-model": "7.28.13", @@ -968,7 +968,7 @@ "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", - "typescript": "5.3.3" + "typescript": "5.4.2" }, "dependencies": { "@microsoft/tsdoc": { @@ -1013,9 +1013,9 @@ } }, "typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true } } From b62d3360e7e960cad6694c34c9c553d823775e7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 20:24:24 +0000 Subject: [PATCH 081/323] build(deps): bump @google-cloud/storage from 7.7.0 to 7.9.0 (#2509) --- package-lock.json | 48 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9286e0d8da..cac7034afc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -710,9 +710,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.7.0.tgz", - "integrity": "sha512-EMCEY+6JiIkx7Dt8NXVGGjy1vRdSGdHkoqZoqjJw7cEBkT7ZkX0c7puedfn1MamnzW5SX4xoa2jVq5u7OWBmkQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.9.0.tgz", + "integrity": "sha512-PlFl7g3r91NmXtZHXsSEfTZES5ysD3SSBWmX4iBdQ2TFH7tN/Vn/IhnVELCHtgh1vc+uYPZ7XvRYaqtDCdghIA==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", @@ -721,11 +721,11 @@ "abort-controller": "^3.0.0", "async-retry": "^1.3.3", "compressible": "^2.0.12", - "duplexify": "^4.0.0", + "duplexify": "^4.1.3", "ent": "^2.2.0", "fast-xml-parser": "^4.3.0", "gaxios": "^6.0.2", - "google-auth-library": "^9.0.0", + "google-auth-library": "^9.6.3", "mime": "^3.0.0", "mime-types": "^2.0.8", "p-limit": "^3.0.1", @@ -734,6 +734,38 @@ "uuid": "^8.0.0" }, "dependencies": { + "duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "google-auth-library": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.7.0.tgz", + "integrity": "sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==", + "optional": true, + "requires": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "optional": true + }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -3850,9 +3882,9 @@ "dev": true }, "fast-xml-parser": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.2.tgz", - "integrity": "sha512-rmrXUXwbJedoXkStenj1kkljNF7ugn5ZjR9FJcwmCfcCbtOMDghPajbc+Tck6vE6F5XsDmx+Pr2le9fw8+pXBg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz", + "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==", "optional": true, "requires": { "strnum": "^1.0.5" From d811a9b0d5e4d4d6b217e6248e60831c6b168ad8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Mar 2024 20:30:58 +0000 Subject: [PATCH 082/323] build(deps-dev): bump @firebase/app-compat from 0.2.28 to 0.2.29 (#2510) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index cac7034afc..0e44ad0cd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -477,9 +477,9 @@ } }, "@firebase/app": { - "version": "0.9.28", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.28.tgz", - "integrity": "sha512-MS0+EtNixrwJbVDs5Bt/lhUhzeWGUtUoP6X+zYZck5GAZwI5g4F91noVA9oIXlFlpn6Q1xIbiaHA2GwGk7/7Ag==", + "version": "0.9.29", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.29.tgz", + "integrity": "sha512-HbKTjfmILklasIu/ij6zKnFf3SgLYXkBDVN7leJfVGmohl+zA7Ig+eXM1ZkT1pyBJ8FTYR+mlOJer/lNEnUCtw==", "dev": true, "requires": { "@firebase/component": "0.6.5", @@ -516,12 +516,12 @@ "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" }, "@firebase/app-compat": { - "version": "0.2.28", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.28.tgz", - "integrity": "sha512-Mr2NbeM1Oaayuw5unUAMzt+7/MN+e2uklT1l87D+ZLJl2UvhZAZmMt74GjEI9N3sDYKMeszSbszBqtJ1fGVafQ==", + "version": "0.2.29", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.29.tgz", + "integrity": "sha512-NqUdegXJfwphx9i/2bOE2CTZ55TC9bbDg+iwkxVShsPBJhD3CzQJkFhoDz4ccfbJaKZGsqjY3fisgX5kbDROnA==", "dev": true, "requires": { - "@firebase/app": "0.9.28", + "@firebase/app": "0.9.29", "@firebase/component": "0.6.5", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.4", From f952c5e3d146dc9aa7d21bcfa099eb2f59f88784 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 14:48:28 -0400 Subject: [PATCH 083/323] build(deps): bump @google-cloud/firestore from 7.4.0 to 7.5.0 (#2517) Bumps [@google-cloud/firestore](https://github.com/googleapis/nodejs-firestore) from 7.4.0 to 7.5.0. - [Release notes](https://github.com/googleapis/nodejs-firestore/releases) - [Changelog](https://github.com/googleapis/nodejs-firestore/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-firestore/compare/v7.4.0...v7.5.0) --- updated-dependencies: - dependency-name: "@google-cloud/firestore" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 49 ++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0e44ad0cd5..9e266b3e59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ } }, "@google-cloud/firestore": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.4.0.tgz", - "integrity": "sha512-PRukAUgeBOZu/4pK9NXkAs8ur6QUpG6bBiwcnSO1qsh0FlR93gqU+VtkCx3EJM46S10jzMhHqpA0NoVbnUs5TQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.5.0.tgz", + "integrity": "sha512-bhFKaCybfK/jzqhVm1Y1o8p3wOHVEo8opj7IJGF2sdqS69xl6QD1zpnrgssi/4HUj9bxIqtcs33Ofz//deV+rg==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -775,9 +775,9 @@ } }, "@grpc/grpc-js": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.3.tgz", - "integrity": "sha512-qiO9MNgYnwbvZ8MK0YLWbnGrNX3zTcj6/Ef7UHu5ZofER3e2nF3Y35GaPo9qNJJ/UJQKa4KL+z/F4Q8Q+uCdUQ==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.4.tgz", + "integrity": "sha512-MqBisuxTkYvPFnEiu+dag3xG/NBUDzSbAFAWlzfkGnQkjVZ6by3h4atbBc+Ikqup1z5BfB4BN18gKWR1YyppNw==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.10", @@ -785,9 +785,9 @@ } }, "@grpc/proto-loader": { - "version": "0.7.10", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", - "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.12.tgz", + "integrity": "sha512-DCVwMxqYzpUCiDMl7hQ384FqP4T3DbNpXU8pt681l3UWCip1WUiD5JrkImUwCB9a7f2cq4CUTmi5r/xIMRPY1Q==", "optional": true, "requires": { "lodash.camelcase": "^4.3.0", @@ -3304,15 +3304,23 @@ } }, "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "optional": true, "requires": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "stream-shift": "^1.0.2" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "optional": true + } } }, "each-props": { @@ -4619,9 +4627,9 @@ } }, "google-auth-library": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.4.1.tgz", - "integrity": "sha512-Chs7cuzDuav8W/BXOoRgSXw4u0zxYtuqAHETDR5Q6dG1RwNwz7NUKjsDDHAsBV3KkiiJBtJqjbzy1XU1L41w1g==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.7.0.tgz", + "integrity": "sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==", "optional": true, "requires": { "base64-js": "^1.3.0", @@ -4633,9 +4641,9 @@ } }, "google-gax": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.1.tgz", - "integrity": "sha512-qpSfslpwqToIgQ+Tf3MjWIDjYK4UFIZ0uz6nLtttlW9N1NQA4PhGf9tlGo6KDYJ4rgL2w4CjXVd0z5yeNpN/Iw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.2.tgz", + "integrity": "sha512-2mw7qgei2LPdtGrmd1zvxQviOcduTnsvAWYzCxhOWXK4IQKmQztHnDQwD0ApB690fBQJemFKSU7DnceAy3RLzw==", "optional": true, "requires": { "@grpc/grpc-js": "~1.10.0", @@ -8953,7 +8961,8 @@ "stream-shift": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true }, "streamfilter": { "version": "3.0.0", From 81deb48a5940822ba917ce4cd1fecd3450a7dac7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 18:53:12 +0000 Subject: [PATCH 084/323] build(deps): bump @types/node from 20.11.30 to 20.12.2 (#2516) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e266b3e59..680b015719 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1526,9 +1526,9 @@ } }, "@types/node": { - "version": "20.11.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", - "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "version": "20.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz", + "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==", "requires": { "undici-types": "~5.26.4" } From e7ea83ef653f67a93427378f31d25098029d2425 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 18:57:44 +0000 Subject: [PATCH 085/323] build(deps-dev): bump mocha from 10.3.0 to 10.4.0 (#2513) --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 680b015719..f69ada475b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6503,9 +6503,9 @@ "dev": true }, "mocha": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", - "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", + "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -6547,9 +6547,9 @@ } }, "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true }, "brace-expansion": { From 837b69b61b3df3dcd8a31ccd16062e1bba236dca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 19:02:38 +0000 Subject: [PATCH 086/323] build(deps-dev): bump @firebase/auth-types from 0.12.0 to 0.12.1 (#2514) --- package-lock.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f69ada475b..d2ab1fd15a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -592,6 +592,12 @@ "tslib": "^2.1.0" }, "dependencies": { + "@firebase/auth-types": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", + "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", + "dev": true + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -609,9 +615,9 @@ "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" }, "@firebase/auth-types": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", - "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.1.tgz", + "integrity": "sha512-B3dhiWRWf/njWosx4zdhSEoD4WHJmr4zbnBw6t20mRG/IZ4u0rWUBlMP1vFjhMstKIow1XmoGhTwD65X5ZXLjw==", "dev": true }, "@firebase/component": { From 34f0ac27e286972995ba92bb1cb381d40d9689ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:11:45 -0400 Subject: [PATCH 087/323] build(deps): bump undici in /.github/actions/send-email (#2521) Bumps [undici](https://github.com/nodejs/undici) from 5.28.3 to 5.28.4. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v5.28.3...v5.28.4) --- updated-dependencies: - dependency-name: undici dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/send-email/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 63221bcb45..7c530a0d4f 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -168,9 +168,9 @@ } }, "node_modules/undici": { - "version": "5.28.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz", - "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==", + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", "dependencies": { "@fastify/busboy": "^2.0.0" }, From fa59e2a21fc46819de1c61a6d5ad7f0214b9e45e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:06:50 -0400 Subject: [PATCH 088/323] build(deps): bump @google-cloud/firestore from 7.5.0 to 7.6.0 (#2528) Bumps [@google-cloud/firestore](https://github.com/googleapis/nodejs-firestore) from 7.5.0 to 7.6.0. - [Release notes](https://github.com/googleapis/nodejs-firestore/releases) - [Changelog](https://github.com/googleapis/nodejs-firestore/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-firestore/compare/v7.5.0...v7.6.0) --- updated-dependencies: - dependency-name: "@google-cloud/firestore" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d2ab1fd15a..7498f49f31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -682,15 +682,15 @@ } }, "@google-cloud/firestore": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.5.0.tgz", - "integrity": "sha512-bhFKaCybfK/jzqhVm1Y1o8p3wOHVEo8opj7IJGF2sdqS69xl6QD1zpnrgssi/4HUj9bxIqtcs33Ofz//deV+rg==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.6.0.tgz", + "integrity": "sha512-WUDbaLY8UnPxgwsyIaxj6uxCtSDAaUyvzWJykNH5rZ9i92/SZCsPNNMN0ajrVpAR81hPIL4amXTaMJ40y5L+Yg==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", - "google-gax": "^4.0.4", - "protobufjs": "^7.2.5" + "google-gax": "^4.3.1", + "protobufjs": "^7.2.6" } }, "@google-cloud/paginator": { @@ -781,9 +781,9 @@ } }, "@grpc/grpc-js": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.4.tgz", - "integrity": "sha512-MqBisuxTkYvPFnEiu+dag3xG/NBUDzSbAFAWlzfkGnQkjVZ6by3h4atbBc+Ikqup1z5BfB4BN18gKWR1YyppNw==", + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.6.tgz", + "integrity": "sha512-xP58G7wDQ4TCmN/cMUHh00DS7SRDv/+lC+xFLrTkMIN8h55X5NhZMLYbvy7dSELP15qlI6hPhNCRWVMtZMwqLA==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.10", From 25b2c68bfefa6539a4af7854b31a98c282ea8e1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 16:11:22 +0000 Subject: [PATCH 089/323] build(deps-dev): bump @firebase/app-compat from 0.2.29 to 0.2.30 (#2527) --- package-lock.json | 72 +++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7498f49f31..916738e964 100644 --- a/package-lock.json +++ b/package-lock.json @@ -477,32 +477,41 @@ } }, "@firebase/app": { - "version": "0.9.29", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.29.tgz", - "integrity": "sha512-HbKTjfmILklasIu/ij6zKnFf3SgLYXkBDVN7leJfVGmohl+zA7Ig+eXM1ZkT1pyBJ8FTYR+mlOJer/lNEnUCtw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.0.tgz", + "integrity": "sha512-bemcsqQD4teEnCM/+FiK8LFjlfoIFewMY3LOIgxa59ISlkk4zlw4ezz1iLY45yQ6ip6WDwky7cx9UruFBAn6iw==", "dev": true, "requires": { - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", + "@firebase/component": "0.6.6", + "@firebase/logger": "0.4.1", + "@firebase/util": "1.9.5", "idb": "7.1.1", "tslib": "^2.1.0" }, "dependencies": { "@firebase/component": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz", - "integrity": "sha512-2tVDk1ixi12sbDmmfITK8lxSjmcb73BMF6Qwc3U44hN/J1Fi1QY/Hnnb6klFlbB9/G16a3J3d4nXykye2EADTw==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.6.tgz", + "integrity": "sha512-pp7sWqHmAAlA3os6ERgoM3k5Cxff510M9RLXZ9Mc8KFKMBc2ct3RkZTWUF7ixJNvMiK/iNgRLPDrLR2gtRJ9iQ==", + "dev": true, + "requires": { + "@firebase/util": "1.9.5", + "tslib": "^2.1.0" + } + }, + "@firebase/logger": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.1.tgz", + "integrity": "sha512-tTIixB5UJbG9ZHSGZSZdX7THr3KWOLrejZ9B7jYsm6fpwgRNngKznQKA2wgYVyvBc1ta7dGFh9NtJ8n7qfiYIw==", "dev": true, "requires": { - "@firebase/util": "1.9.4", "tslib": "^2.1.0" } }, "@firebase/util": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", - "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.5.tgz", + "integrity": "sha512-PP4pAFISDxsf70l3pEy34Mf3GkkUcVQ3MdKp6aSVb7tcpfUQxnsdV7twDd8EkfB6zZylH6wpUAoangQDmCUMqw==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -516,32 +525,41 @@ "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" }, "@firebase/app-compat": { - "version": "0.2.29", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.29.tgz", - "integrity": "sha512-NqUdegXJfwphx9i/2bOE2CTZ55TC9bbDg+iwkxVShsPBJhD3CzQJkFhoDz4ccfbJaKZGsqjY3fisgX5kbDROnA==", + "version": "0.2.30", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.30.tgz", + "integrity": "sha512-S3FI3yx36xq5NYWXv/rqZiEnkQ89QwfGdl26iWZ9skuOGM96DYQUxs/zs7NkfAQcfpXC8f5DuUrE0Rz/0XdTEg==", "dev": true, "requires": { - "@firebase/app": "0.9.29", - "@firebase/component": "0.6.5", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.4", + "@firebase/app": "0.10.0", + "@firebase/component": "0.6.6", + "@firebase/logger": "0.4.1", + "@firebase/util": "1.9.5", "tslib": "^2.1.0" }, "dependencies": { "@firebase/component": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.5.tgz", - "integrity": "sha512-2tVDk1ixi12sbDmmfITK8lxSjmcb73BMF6Qwc3U44hN/J1Fi1QY/Hnnb6klFlbB9/G16a3J3d4nXykye2EADTw==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.6.tgz", + "integrity": "sha512-pp7sWqHmAAlA3os6ERgoM3k5Cxff510M9RLXZ9Mc8KFKMBc2ct3RkZTWUF7ixJNvMiK/iNgRLPDrLR2gtRJ9iQ==", + "dev": true, + "requires": { + "@firebase/util": "1.9.5", + "tslib": "^2.1.0" + } + }, + "@firebase/logger": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.1.tgz", + "integrity": "sha512-tTIixB5UJbG9ZHSGZSZdX7THr3KWOLrejZ9B7jYsm6fpwgRNngKznQKA2wgYVyvBc1ta7dGFh9NtJ8n7qfiYIw==", "dev": true, "requires": { - "@firebase/util": "1.9.4", "tslib": "^2.1.0" } }, "@firebase/util": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.4.tgz", - "integrity": "sha512-WLonYmS1FGHT97TsUmRN3qnTh5TeeoJp1Gg5fithzuAgdZOUtsYECfy7/noQ3llaguios8r5BuXSEiK82+UrxQ==", + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.5.tgz", + "integrity": "sha512-PP4pAFISDxsf70l3pEy34Mf3GkkUcVQ3MdKp6aSVb7tcpfUQxnsdV7twDd8EkfB6zZylH6wpUAoangQDmCUMqw==", "dev": true, "requires": { "tslib": "^2.1.0" From a00de0c266a18fbc04bcbf7c1ef28af936920fb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:34:54 -0400 Subject: [PATCH 090/323] build(deps-dev): bump gulp from 4.0.2 to 5.0.0 (#2526) Bumps [gulp](https://github.com/gulpjs/gulp) from 4.0.2 to 5.0.0. - [Release notes](https://github.com/gulpjs/gulp/releases) - [Changelog](https://github.com/gulpjs/gulp/blob/master/CHANGELOG.md) - [Commits](https://github.com/gulpjs/gulp/compare/v4.0.2...v5.0.0) --- updated-dependencies: - dependency-name: gulp dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 2620 +++++++++------------------------------------ package.json | 2 +- 2 files changed, 522 insertions(+), 2100 deletions(-) diff --git a/package-lock.json b/package-lock.json index 916738e964..8d010bbada 100644 --- a/package-lock.json +++ b/package-lock.json @@ -820,6 +820,21 @@ "yargs": "^17.7.2" } }, + "@gulpjs/messages": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", + "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", + "dev": true + }, + "@gulpjs/to-absolute-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", + "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", + "dev": true, + "requires": { + "is-negated-glob": "^1.0.0" + } + }, "@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -1880,127 +1895,13 @@ "dev": true }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "api-extractor-model-me": { @@ -2148,30 +2049,12 @@ "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -2200,78 +2083,18 @@ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", "dev": true }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true - }, "arraybuffer.prototype.slice": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", @@ -2320,23 +2143,16 @@ "dev": true }, "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", + "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" + "end-of-stream": "^1.4.4", + "once": "^1.4.0", + "stream-exhaust": "^1.0.2" } }, - "async-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", - "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", - "dev": true - }, "async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -2347,12 +2163,12 @@ } }, "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", + "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", "dev": true, "requires": { - "async-done": "^1.2.2" + "async-done": "^2.0.0" } }, "asynckit": { @@ -2360,12 +2176,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, "available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -2385,20 +2195,25 @@ "dev": true }, "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", + "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", "dev": true, "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" + "async-done": "^2.0.0", + "async-settle": "^2.0.0", + "now-and-later": "^3.0.0" + }, + "dependencies": { + "now-and-later": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", + "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + } } }, "balanced-match": { @@ -2407,41 +2222,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "bare-events": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", + "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - } - } + "optional": true }, "base64-js": { "version": "1.5.1", @@ -2474,19 +2260,32 @@ "optional": true }, "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", "dev": true, - "optional": true, "requires": { - "file-uri-to-path": "1.0.0" + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + } } }, "bluebird": { @@ -2560,23 +2359,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, "caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", @@ -2606,12 +2388,6 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", - "dev": true - }, "caniuse-lite": { "version": "1.0.30001566", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", @@ -2688,113 +2464,19 @@ } }, "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" } }, "chownr": { @@ -2803,29 +2485,6 @@ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -2903,33 +2562,6 @@ } } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2976,12 +2608,6 @@ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, - "component-emitter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", - "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", - "dev": true - }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -3062,19 +2688,13 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true - }, "copy-props": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", - "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", + "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", "dev": true, "requires": { - "each-props": "^1.3.2", + "each-props": "^3.0.0", "is-plain-object": "^5.0.0" }, "dependencies": { @@ -3126,16 +2746,6 @@ } } }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -3159,12 +2769,6 @@ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true - }, "deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -3180,23 +2784,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, "default-require-extensions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", @@ -3214,12 +2801,6 @@ } } }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", - "dev": true - }, "define-data-property": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", @@ -3242,28 +2823,6 @@ "object-keys": "^1.1.1" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - } - } - }, "del": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", @@ -3348,13 +2907,21 @@ } }, "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", + "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", "dev": true, "requires": { - "is-plain-object": "^2.0.1", + "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + } } }, "ecc-jsbn": { @@ -3478,56 +3045,12 @@ "is-symbol": "^1.0.2" } }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3717,56 +3240,6 @@ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "optional": true }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -3776,23 +3249,6 @@ "homedir-polyfill": "^1.0.1" } }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "requires": { - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - } - } - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3819,52 +3275,6 @@ } } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - } - } - }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -3888,6 +3298,12 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -3922,6 +3338,12 @@ "strnum": "^1.0.5" } }, + "fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true + }, "fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -3954,13 +3376,6 @@ "flat-cache": "^3.0.4" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -3992,133 +3407,36 @@ } }, "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", + "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", "dev": true, "requires": { "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", + "is-glob": "^4.0.3", + "micromatch": "^4.0.4", "resolve-dir": "^1.0.1" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } } }, "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", + "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", "dev": true, "requires": { "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", + "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" + "object.pick": "^1.3.0", + "parse-filepath": "^1.0.2" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + } } }, "firebase-token-generator": { @@ -4128,9 +3446,9 @@ "dev": true }, "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", + "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", "dev": true }, "flat": { @@ -4270,15 +3588,6 @@ "mime-types": "^2.1.12" } }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, "fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", @@ -4333,15 +3642,11 @@ "dev": true }, "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } + "optional": true }, "function-bind": { "version": "1.1.2", @@ -4463,12 +3768,6 @@ "get-intrinsic": "^1.1.1" } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true - }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -4571,18 +3870,13 @@ } }, "glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", + "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" + "async-done": "^2.0.0", + "chokidar": "^3.5.3" } }, "global-modules": { @@ -4642,12 +3936,12 @@ } }, "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", + "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", "dev": true, "requires": { - "sparkles": "^1.0.0" + "sparkles": "^2.1.0" } }, "google-auth-library": { @@ -4716,141 +4010,203 @@ } }, "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz", + "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==", "dev": true, "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" + "glob-watcher": "^6.0.0", + "gulp-cli": "^3.0.0", + "undertaker": "^2.0.0", + "vinyl-fs": "^4.0.0" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "fs-mkdirp-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", + "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.8", + "streamx": "^2.12.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "glob-stream": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", + "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", + "dev": true, + "requires": { + "@gulpjs/to-absolute-glob": "^4.0.0", + "anymatch": "^3.1.3", + "fastq": "^1.13.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "is-negated-glob": "^1.0.0", + "normalize-path": "^3.0.0", + "streamx": "^2.12.5" + } + }, "gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", + "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "@gulpjs/messages": "^1.1.0", + "chalk": "^4.1.2", + "copy-props": "^4.0.0", + "gulplog": "^2.2.0", + "interpret": "^3.1.1", + "liftoff": "^5.0.0", + "mute-stdout": "^2.0.0", + "replace-homedir": "^2.0.0", + "semver-greatest-satisfied-range": "^2.0.0", + "string-width": "^4.2.3", + "v8flags": "^4.0.0", + "yargs": "^16.2.0" } }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "lead": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", + "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", + "dev": true + }, + "now-and-later": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", + "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "once": "^1.4.0" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true + }, + "resolve-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", + "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "value-or-function": "^4.0.0" } }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "to-through": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", + "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "streamx": "^2.12.5" } }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "value-or-function": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", + "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", "dev": true }, - "yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", + "vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", "dev": true, "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.1" + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" } }, - "yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", + "vinyl-fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", + "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "^2.0.1", + "glob-stream": "^8.0.0", + "graceful-fs": "^4.2.11", + "iconv-lite": "^0.6.3", + "is-valid-glob": "^1.0.0", + "lead": "^4.0.0", + "normalize-path": "3.0.0", + "resolve-options": "^2.0.0", + "stream-composer": "^1.0.2", + "streamx": "^2.14.0", + "to-through": "^3.0.0", + "value-or-function": "^4.0.0", + "vinyl": "^3.0.0", + "vinyl-sourcemap": "^2.0.0" + } + }, + "vinyl-sourcemap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", + "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", "dev": true, "requires": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" + "convert-source-map": "^2.0.0", + "graceful-fs": "^4.2.10", + "now-and-later": "^3.0.0", + "streamx": "^2.12.5", + "vinyl": "^3.0.0", + "vinyl-contents": "^2.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true } } }, @@ -4917,12 +4273,12 @@ } }, "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", + "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", "dev": true, "requires": { - "glogg": "^1.0.0" + "glogg": "^2.2.0" } }, "har-schema": { @@ -5006,58 +4362,6 @@ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", @@ -5173,6 +4477,15 @@ "debug": "4" } }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "idb": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", @@ -5252,15 +4565,9 @@ } }, "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true }, "is-absolute": { @@ -5273,15 +4580,6 @@ "is-windows": "^1.0.1" } }, - "is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, "is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -5309,12 +4607,12 @@ } }, "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "^2.0.0" } }, "is-boolean-object": { @@ -5348,15 +4646,6 @@ "hasown": "^2.0.0" } }, - "is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, "is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -5366,22 +4655,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5873,12 +5146,6 @@ "verror": "1.10.0" } }, - "just-debounce": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", - "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true - }, "just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", @@ -5938,21 +5205,11 @@ "json-buffer": "3.0.1" } }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", + "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", + "dev": true }, "lazystream": { "version": "1.0.1", @@ -5995,15 +5252,6 @@ } } }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, "lead": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", @@ -6024,19 +5272,26 @@ } }, "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", + "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==", "dev": true, "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" + "extend": "^3.0.2", + "findup-sync": "^5.0.0", + "fined": "^2.0.0", + "flagged-respawn": "^2.0.0", + "is-plain-object": "^5.0.0", + "rechoir": "^0.8.0", + "resolve": "^1.20.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + } } }, "limiter": { @@ -6044,19 +5299,6 @@ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -6215,207 +5457,51 @@ "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", "requires": { "pseudomap": "^1.0.1", - "yallist": "^2.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" - } - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true - }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "yallist": "^2.0.0" } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + } + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true + }, + "map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", + "dev": true + }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -6499,27 +5585,6 @@ } } }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -6716,9 +5781,9 @@ } }, "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", + "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", "dev": true }, "mz": { @@ -6732,32 +5797,6 @@ "thenify-all": "^1.0.0" } }, - "nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6770,12 +5809,6 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -7102,12 +6135,6 @@ "set-blocking": "^2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true - }, "nyc": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", @@ -7284,37 +6311,6 @@ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "object-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", @@ -7333,15 +6329,6 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, "object.assign": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", @@ -7366,16 +6353,6 @@ "isobject": "^3.0.0" } }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -7385,16 +6362,6 @@ "isobject": "^3.0.1" } }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -7458,15 +6425,6 @@ } } }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -7531,15 +6489,6 @@ "path-root": "^0.1.1" } }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, "parse-node-version": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", @@ -7552,12 +6501,6 @@ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", "dev": true }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true - }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -7656,27 +6599,6 @@ "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", "dev": true }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -7737,24 +6659,12 @@ "extend-shallow": "^3.0.2" } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -7905,6 +6815,12 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -7914,234 +6830,32 @@ "safe-buffer": "^5.1.0" } }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, "readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { - "resolve": "^1.1.6" + "picomatch": "^2.2.1" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "resolve": "^1.20.0" } }, "regexp.prototype.flags": { @@ -8191,18 +6905,6 @@ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", "dev": true }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true - }, "replace-ext": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", @@ -8210,15 +6912,10 @@ "dev": true }, "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", + "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", + "dev": true }, "request": { "version": "2.88.2", @@ -8293,12 +6990,6 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true - }, "resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -8335,18 +7026,6 @@ "value-or-function": "^3.0.0" } }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, "retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -8523,15 +7202,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -8558,12 +7228,12 @@ } }, "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", + "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", "dev": true, "requires": { - "sver-compat": "^1.5.0" + "sver": "^1.8.3" } }, "serialize-javascript": { @@ -8604,29 +7274,6 @@ "has-property-descriptors": "^1.0.0" } }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8699,144 +7346,16 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", + "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", "dev": true }, "spawn-wrap": { @@ -8896,15 +7415,6 @@ "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", "dev": true }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -8928,33 +7438,6 @@ "tweetnacl": "~0.14.0" } }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -8967,6 +7450,15 @@ "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", "dev": true }, + "stream-composer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", + "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", + "dev": true, + "requires": { + "streamx": "^2.13.2" + } + }, "stream-events": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", @@ -8997,6 +7489,17 @@ "readable-stream": "^3.0.6" } }, + "streamx": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", + "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "dev": true, + "requires": { + "bare-events": "^2.2.0", + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -9073,15 +7576,6 @@ "ansi-regex": "^5.0.1" } }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -9115,14 +7609,22 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", + "sver": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", + "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", "dev": true, "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "optional": true + } } }, "tar": { @@ -9173,6 +7675,15 @@ } } }, + "teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "requires": { + "streamx": "^2.12.5" + } + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -9288,38 +7799,6 @@ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -9419,12 +7898,6 @@ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "dev": true }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9533,35 +8006,32 @@ "dev": true }, "undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", + "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", + "dev": true, + "requires": { + "bach": "^2.0.1", + "fast-levenshtein": "^3.0.0", + "last-run": "^2.0.0", + "undertaker-registry": "^2.0.0" }, "dependencies": { "fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "dev": true, + "requires": { + "fastest-levenshtein": "^1.0.7" + } } } }, "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", + "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", "dev": true }, "undici-types": { @@ -9569,18 +8039,6 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, "unique-stream": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", @@ -9597,52 +8055,6 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, "update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -9662,18 +8074,6 @@ "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -9691,13 +8091,10 @@ "dev": true }, "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", + "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", + "dev": true }, "validate-npm-package-license": { "version": "3.0.4", @@ -9754,6 +8151,37 @@ "replace-ext": "^1.0.0" } }, + "vinyl-contents": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", + "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", + "dev": true, + "requires": { + "bl": "^5.0.0", + "vinyl": "^3.0.0" + }, + "dependencies": { + "replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true + }, + "vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "requires": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + } + } + } + }, "vinyl-fs": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", @@ -9888,12 +8316,6 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true - }, "which-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", diff --git a/package.json b/package.json index 5391d11c81..9ab7e28d19 100644 --- a/package.json +++ b/package.json @@ -240,7 +240,7 @@ "del": "^6.0.0", "eslint": "^8.12.0", "firebase-token-generator": "^2.0.0", - "gulp": "^4.0.2", + "gulp": "^5.0.0", "gulp-filter": "^7.0.0", "gulp-header": "^2.0.9", "gulp-typescript": "^5.0.1", From a833f4e597c4847548942676576fc5d97f4e6ba8 Mon Sep 17 00:00:00 2001 From: Erik Eldridge Date: Mon, 15 Apr 2024 13:46:21 -0700 Subject: [PATCH 091/323] feat(rc): Add server side Remote Config support (#2529) Currently, Remote Config doesn't provide a way for servers to obtain configuration, and the Admin SDK has historically been used only for managing Remote Config. This change updates the Admin SDK with functionality for evaluating a template to produce configuration for a given context. --- etc/firebase-admin.remote-config.api.md | 109 + package-lock.json | 2722 +++++++++-------- package.json | 2 + .../condition-evaluator-internal.ts | 178 ++ src/remote-config/index.ts | 17 + src/remote-config/internal/value-impl.ts | 61 + .../remote-config-api-client-internal.ts | 51 +- src/remote-config/remote-config-api.ts | 359 ++- src/remote-config/remote-config.ts | 233 ++ test/unit/index.spec.ts | 2 + .../remote-config/condition-evaluator.spec.ts | 825 +++++ .../remote-config/internal/value-impl.spec.ts | 75 + .../remote-config-api-client.spec.ts | 36 +- test/unit/remote-config/remote-config.spec.ts | 880 ++++++ 14 files changed, 4253 insertions(+), 1297 deletions(-) create mode 100644 src/remote-config/condition-evaluator-internal.ts create mode 100644 src/remote-config/internal/value-impl.ts create mode 100644 test/unit/remote-config/condition-evaluator.spec.ts create mode 100644 test/unit/remote-config/internal/value-impl.spec.ts diff --git a/etc/firebase-admin.remote-config.api.md b/etc/firebase-admin.remote-config.api.md index fb07bfad76..aeadcbf779 100644 --- a/etc/firebase-admin.remote-config.api.md +++ b/etc/firebase-admin.remote-config.api.md @@ -8,6 +8,21 @@ import { Agent } from 'http'; +// @public +export interface AndCondition { + conditions?: Array; +} + +// @public +export type DefaultConfig = { + [key: string]: string | number | boolean; +}; + +// @public +export type EvaluationContext = { + randomizationId?: string; +}; + // @public export interface ExplicitParameterValue { value: string; @@ -18,11 +33,21 @@ export interface ExplicitParameterValue { // @public export function getRemoteConfig(app?: App): RemoteConfig; +// @public +export interface GetServerTemplateOptions { + defaultConfig?: DefaultConfig; +} + // @public export interface InAppDefaultValue { useInAppDefault: boolean; } +// @public +export interface InitServerTemplateOptions extends GetServerTemplateOptions { + template?: ServerTemplateDataType; +} + // @public export interface ListVersionsOptions { endTime?: Date | string; @@ -38,16 +63,60 @@ export interface ListVersionsResult { versions: Version[]; } +// @public +export interface MicroPercentRange { + microPercentLowerBound?: number; + microPercentUpperBound?: number; +} + +// @public +export interface NamedCondition { + condition: OneOfCondition; + name: string; +} + +// @public +export interface OneOfCondition { + andCondition?: AndCondition; + false?: Record; + orCondition?: OrCondition; + percent?: PercentCondition; + true?: Record; +} + +// @public +export interface OrCondition { + conditions?: Array; +} + // @public export type ParameterValueType = 'STRING' | 'BOOLEAN' | 'NUMBER' | 'JSON'; +// @public +export interface PercentCondition { + microPercent?: number; + microPercentRange?: MicroPercentRange; + percentOperator?: PercentConditionOperator; + seed?: string; +} + +// @public +export enum PercentConditionOperator { + BETWEEN = "BETWEEN", + GREATER_THAN = "GREATER_THAN", + LESS_OR_EQUAL = "LESS_OR_EQUAL", + UNKNOWN = "UNKNOWN" +} + // @public export class RemoteConfig { // (undocumented) readonly app: App; createTemplateFromJSON(json: string): RemoteConfigTemplate; + getServerTemplate(options?: GetServerTemplateOptions): Promise; getTemplate(): Promise; getTemplateAtVersion(versionNumber: number | string): Promise; + initServerTemplate(options?: InitServerTemplateOptions): ServerTemplate; listVersions(options?: ListVersionsOptions): Promise; publishTemplate(template: RemoteConfigTemplate, options?: { force: boolean; @@ -104,9 +173,49 @@ export interface RemoteConfigUser { name?: string; } +// @public +export interface ServerConfig { + getBoolean(key: string): boolean; + getNumber(key: string): number; + getString(key: string): string; + getValue(key: string): Value; +} + +// @public +export interface ServerTemplate { + evaluate(context?: EvaluationContext): ServerConfig; + load(): Promise; + set(template: ServerTemplateDataType): void; + toJSON(): ServerTemplateData; +} + +// @public +export interface ServerTemplateData { + conditions: NamedCondition[]; + readonly etag: string; + parameters: { + [key: string]: RemoteConfigParameter; + }; + version?: Version; +} + +// @public +export type ServerTemplateDataType = ServerTemplateData | string; + // @public export type TagColor = 'BLUE' | 'BROWN' | 'CYAN' | 'DEEP_ORANGE' | 'GREEN' | 'INDIGO' | 'LIME' | 'ORANGE' | 'PINK' | 'PURPLE' | 'TEAL'; +// @public +export interface Value { + asBoolean(): boolean; + asNumber(): number; + asString(): string; + getSource(): ValueSource; +} + +// @public +export type ValueSource = 'static' | 'default' | 'remote'; + // @public export interface Version { description?: string; diff --git a/package-lock.json b/package-lock.json index 8d010bbada..c6324676c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,105 +11,47 @@ "dev": true }, "@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dev": true, "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", + "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", "dev": true }, "@babel/core": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz", - "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", + "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", - "@babel/helper-compilation-targets": "^7.22.15", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.4", + "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.5", - "@babel/parser": "^7.23.5", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5", + "@babel/helpers": "^7.24.4", + "@babel/parser": "^7.24.4", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -117,12 +59,6 @@ "semver": "^6.3.1" }, "dependencies": { - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -132,26 +68,26 @@ } }, "@babel/generator": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", - "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", + "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", "dev": true, "requires": { - "@babel/types": "^7.23.5", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" } }, "@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -205,12 +141,12 @@ } }, "@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", "dev": true, "requires": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.0" } }, "@babel/helper-module-transforms": { @@ -245,9 +181,9 @@ } }, "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", "dev": true }, "@babel/helper-validator-identifier": { @@ -263,25 +199,26 @@ "dev": true }, "@babel/helpers": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz", - "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz", + "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==", "dev": true, "requires": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.5", - "@babel/types": "^7.23.5" + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" } }, "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "dependencies": { "ansi-styles": { @@ -343,37 +280,37 @@ } }, "@babel/parser": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", - "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", "dev": true }, "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" } }, "@babel/traverse": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", - "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.5", + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.5", - "@babel/types": "^7.23.5", - "debug": "^4.1.0", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", "globals": "^11.1.0" }, "dependencies": { @@ -386,9 +323,9 @@ } }, "@babel/types": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", - "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.23.4", @@ -447,6 +384,23 @@ "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "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 + } } }, "@eslint/js": { @@ -477,9 +431,9 @@ } }, "@firebase/app": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.0.tgz", - "integrity": "sha512-bemcsqQD4teEnCM/+FiK8LFjlfoIFewMY3LOIgxa59ISlkk4zlw4ezz1iLY45yQ6ip6WDwky7cx9UruFBAn6iw==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.1.tgz", + "integrity": "sha512-H8hvbSVxNt+QaUQ1O0Gqidksi5ilj6eL8iMYxUNZgsMwZ1yOTgXc2C9zktbPQKokgcMq+EbF0k/t5iouslSkiA==", "dev": true, "requires": { "@firebase/component": "0.6.6", @@ -487,104 +441,72 @@ "@firebase/util": "1.9.5", "idb": "7.1.1", "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/component": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.6.tgz", - "integrity": "sha512-pp7sWqHmAAlA3os6ERgoM3k5Cxff510M9RLXZ9Mc8KFKMBc2ct3RkZTWUF7ixJNvMiK/iNgRLPDrLR2gtRJ9iQ==", - "dev": true, - "requires": { - "@firebase/util": "1.9.5", - "tslib": "^2.1.0" - } - }, - "@firebase/logger": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.1.tgz", - "integrity": "sha512-tTIixB5UJbG9ZHSGZSZdX7THr3KWOLrejZ9B7jYsm6fpwgRNngKznQKA2wgYVyvBc1ta7dGFh9NtJ8n7qfiYIw==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.5.tgz", - "integrity": "sha512-PP4pAFISDxsf70l3pEy34Mf3GkkUcVQ3MdKp6aSVb7tcpfUQxnsdV7twDd8EkfB6zZylH6wpUAoangQDmCUMqw==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - } } }, "@firebase/app-check-interop-types": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz", - "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.1.tgz", + "integrity": "sha512-NILZbe6RH3X1pZmJnfOfY2gLIrlKmrkUMMrrK6VSXHcSE0eQv28xFEcw16D198i9JYZpy5Kwq394My62qCMaIw==" }, "@firebase/app-compat": { - "version": "0.2.30", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.30.tgz", - "integrity": "sha512-S3FI3yx36xq5NYWXv/rqZiEnkQ89QwfGdl26iWZ9skuOGM96DYQUxs/zs7NkfAQcfpXC8f5DuUrE0Rz/0XdTEg==", + "version": "0.2.31", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.31.tgz", + "integrity": "sha512-TP9EwOiqDDL4tsP9EyOJn+RYUTkopS0nCg6TZ0PH8XiUgLlgDAF2waAZNha0+18elUkVjbWoXcudCgJ0iVWEVA==", "dev": true, "requires": { - "@firebase/app": "0.10.0", + "@firebase/app": "0.10.1", "@firebase/component": "0.6.6", "@firebase/logger": "0.4.1", "@firebase/util": "1.9.5", "tslib": "^2.1.0" + } + }, + "@firebase/app-types": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.1.tgz", + "integrity": "sha512-nFGqTYsnDFn1oXf1tCwPAc+hQPxyvBT/QB7qDjwK+IDYThOn63nGhzdUTXxVD9Ca8gUY/e5PQMngeo0ZW/E3uQ==" + }, + "@firebase/auth": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.4.0.tgz", + "integrity": "sha512-SfFXZCHDbY+7oSR52NSwx0U7LjYiA+N8imloxphCf3/F+MFty/+mhdjSXGtrJYd0Gbud/qcyedfn2XnWJeIB/g==", + "dev": true, + "requires": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" }, "dependencies": { "@firebase/component": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.6.tgz", - "integrity": "sha512-pp7sWqHmAAlA3os6ERgoM3k5Cxff510M9RLXZ9Mc8KFKMBc2ct3RkZTWUF7ixJNvMiK/iNgRLPDrLR2gtRJ9iQ==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", + "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", "dev": true, "requires": { - "@firebase/util": "1.9.5", + "@firebase/util": "1.9.3", "tslib": "^2.1.0" } }, "@firebase/logger": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.1.tgz", - "integrity": "sha512-tTIixB5UJbG9ZHSGZSZdX7THr3KWOLrejZ9B7jYsm6fpwgRNngKznQKA2wgYVyvBc1ta7dGFh9NtJ8n7qfiYIw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", "dev": true, "requires": { "tslib": "^2.1.0" } }, "@firebase/util": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.5.tgz", - "integrity": "sha512-PP4pAFISDxsf70l3pEy34Mf3GkkUcVQ3MdKp6aSVb7tcpfUQxnsdV7twDd8EkfB6zZylH6wpUAoangQDmCUMqw==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", + "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", "dev": true, "requires": { "tslib": "^2.1.0" } - } - } - }, - "@firebase/app-types": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", - "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" - }, - "@firebase/auth": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.4.0.tgz", - "integrity": "sha512-SfFXZCHDbY+7oSR52NSwx0U7LjYiA+N8imloxphCf3/F+MFty/+mhdjSXGtrJYd0Gbud/qcyedfn2XnWJeIB/g==", - "dev": true, - "requires": { - "@firebase/component": "0.6.4", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.3", - "node-fetch": "2.6.7", - "tslib": "^2.1.0" - }, - "dependencies": { + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -616,6 +538,25 @@ "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", "dev": true }, + "@firebase/component": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", + "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", + "dev": true, + "requires": { + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", + "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -628,9 +569,9 @@ } }, "@firebase/auth-interop-types": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz", - "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg==" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.2.tgz", + "integrity": "sha512-k3NA28Jfoo0+o391bFjoV9X5QLnUL1WbLhZZRbTQhZdmdGYJfX8ixtNNlHsYQ94bwG0QRbsmvkzDnzuhHrV11w==" }, "@firebase/auth-types": { "version": "0.12.1", @@ -639,62 +580,62 @@ "dev": true }, "@firebase/component": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", - "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.6.tgz", + "integrity": "sha512-pp7sWqHmAAlA3os6ERgoM3k5Cxff510M9RLXZ9Mc8KFKMBc2ct3RkZTWUF7ixJNvMiK/iNgRLPDrLR2gtRJ9iQ==", "requires": { - "@firebase/util": "1.9.3", + "@firebase/util": "1.9.5", "tslib": "^2.1.0" } }, "@firebase/database": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.2.tgz", - "integrity": "sha512-8X6NBJgUQzDz0xQVaCISoOLINKat594N2eBbMR3Mu/MH/ei4WM+aAMlsNzngF22eljXu1SILP5G3evkyvsG3Ng==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.4.tgz", + "integrity": "sha512-k84cXh+dtpzvY6yOhfyr1B+I1vjvSMtmlqotE0lTNVylc8m5nmOohjzpTLEQDrBWvwACX/VP5fEyajAdmnOKqA==", "requires": { - "@firebase/app-check-interop-types": "0.3.0", - "@firebase/auth-interop-types": "0.2.1", - "@firebase/component": "0.6.4", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.3", + "@firebase/app-check-interop-types": "0.3.1", + "@firebase/auth-interop-types": "0.2.2", + "@firebase/component": "0.6.6", + "@firebase/logger": "0.4.1", + "@firebase/util": "1.9.5", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "@firebase/database-compat": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.2.tgz", - "integrity": "sha512-09ryJnXDvuycsxn8aXBzLhBTuCos3HEnCOBWY6hosxfYlNCGnLvG8YMlbSAt5eNhf7/00B095AEfDsdrrLjxqA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.4.tgz", + "integrity": "sha512-GEEDAvsSMAkqy0BIFSVtFzoOIIcKHFfDM4aXHtWL/JCaNn4OOjH7td73jDfN3ALvpIN4hQki0FcxQ89XjqaTjQ==", "requires": { - "@firebase/component": "0.6.4", - "@firebase/database": "1.0.2", - "@firebase/database-types": "1.0.0", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.3", + "@firebase/component": "0.6.6", + "@firebase/database": "1.0.4", + "@firebase/database-types": "1.0.2", + "@firebase/logger": "0.4.1", + "@firebase/util": "1.9.5", "tslib": "^2.1.0" } }, "@firebase/database-types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.0.tgz", - "integrity": "sha512-SjnXStoE0Q56HcFgNQ+9SsmJc0c8TqGARdI/T44KXy+Ets3r6x/ivhQozT66bMnCEjJRywYoxNurRTMlZF8VNg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.2.tgz", + "integrity": "sha512-JRigr5JNLEHqOkI99tAGHDZF47469/cJz1tRAgGs8Feh+3ZmQy/vVChSqwMp2DuVUGp9PlmGsNSlpINJ/hDuIA==", "requires": { - "@firebase/app-types": "0.9.0", - "@firebase/util": "1.9.3" + "@firebase/app-types": "0.9.1", + "@firebase/util": "1.9.5" } }, "@firebase/logger": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", - "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.1.tgz", + "integrity": "sha512-tTIixB5UJbG9ZHSGZSZdX7THr3KWOLrejZ9B7jYsm6fpwgRNngKznQKA2wgYVyvBc1ta7dGFh9NtJ8n7qfiYIw==", "requires": { "tslib": "^2.1.0" } }, "@firebase/util": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", - "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.5.tgz", + "integrity": "sha512-PP4pAFISDxsf70l3pEy34Mf3GkkUcVQ3MdKp6aSVb7tcpfUQxnsdV7twDd8EkfB6zZylH6wpUAoangQDmCUMqw==", "requires": { "tslib": "^2.1.0" } @@ -734,9 +675,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.9.0.tgz", - "integrity": "sha512-PlFl7g3r91NmXtZHXsSEfTZES5ysD3SSBWmX4iBdQ2TFH7tN/Vn/IhnVELCHtgh1vc+uYPZ7XvRYaqtDCdghIA==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.10.0.tgz", + "integrity": "sha512-aBNejLVzHpI7C8eJSMpBpfdq1lxvYuHqG+zy/xvs032RyPRxuu45DLMeXuAbgwyx1VBsxWGYifrPDx+O7hJrmw==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", @@ -744,52 +685,18 @@ "@google-cloud/promisify": "^4.0.0", "abort-controller": "^3.0.0", "async-retry": "^1.3.3", - "compressible": "^2.0.12", "duplexify": "^4.1.3", "ent": "^2.2.0", "fast-xml-parser": "^4.3.0", "gaxios": "^6.0.2", "google-auth-library": "^9.6.3", "mime": "^3.0.0", - "mime-types": "^2.0.8", "p-limit": "^3.0.1", "retry-request": "^7.0.0", "teeny-request": "^9.0.0", "uuid": "^8.0.0" }, "dependencies": { - "duplexify": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", - "optional": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" - } - }, - "google-auth-library": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.7.0.tgz", - "integrity": "sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==", - "optional": true, - "requires": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", - "jws": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "optional": true - }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -853,9 +760,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -939,26 +846,26 @@ "dev": true }, "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true }, "@jridgewell/sourcemap-codec": { @@ -968,9 +875,9 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1022,18 +929,18 @@ } }, "@microsoft/api-extractor": { - "version": "7.43.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.0.tgz", - "integrity": "sha512-GFhTcJpB+MI6FhvXEI9b2K0snulNLWHqC/BbcJtyNYcKUiw7l3Lgis5ApsYncJ0leALX7/of4XfmXk+maT111w==", + "version": "7.43.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.1.tgz", + "integrity": "sha512-ohg40SsvFFgzHFAtYq5wKJc8ZDyY46bphjtnSvhSSlXpPTG7GHwyyXkn48UZiUCBwr2WC7TRC1Jfwz7nreuiyQ==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.13", + "@microsoft/api-extractor-model": "7.28.14", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.0.2", + "@rushstack/node-core-library": "4.1.0", "@rushstack/rig-package": "0.5.2", - "@rushstack/terminal": "0.10.0", - "@rushstack/ts-command-line": "4.19.1", + "@rushstack/terminal": "0.10.1", + "@rushstack/ts-command-line": "4.19.2", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1049,9 +956,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", - "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz", + "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==", "dev": true, "requires": { "fs-extra": "~7.0.1", @@ -1063,24 +970,24 @@ } }, "@rushstack/ts-command-line": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", - "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.2.tgz", + "integrity": "sha512-cqmXXmBEBlzo9WtyUrHtF9e6kl0LvBY7aTSVX4jfnBfXWZQWnPq9JTFPlQZ+L/ZwjZ4HrNwQsOVvhe9oOucZkw==", "dev": true, "requires": { - "@rushstack/terminal": "0.10.0", + "@rushstack/terminal": "0.10.1", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" } }, - "minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "lru-cache": "^6.0.0" } }, "typescript": { @@ -1092,14 +999,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.13", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", - "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", + "version": "7.28.14", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.14.tgz", + "integrity": "sha512-Bery/c8A8SsKPSvA82cTTuy/+OcxZbLRmKhPkk91/AJOQzxZsShcrmHFAGeiEqSIrv1nPZ3tKq9kfMLdCHmsqg==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.0.2" + "@rushstack/node-core-library": "4.1.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1109,9 +1016,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", - "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz", + "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==", "dev": true, "requires": { "fs-extra": "~7.0.1", @@ -1121,6 +1028,15 @@ "semver": "~7.5.4", "z-schema": "~5.0.2" } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -1270,6 +1186,15 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", "dev": true + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -1281,22 +1206,30 @@ "requires": { "resolve": "~1.22.1", "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/terminal": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", - "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.1.tgz", + "integrity": "sha512-C6Vi/m/84IYJTkfzmXr1+W8Wi3MmBjVF/q3za91Gb3VYjKbpALHVxY6FgH625AnDe5Z0Kh4MHKWA3Z7bqgAezA==", "dev": true, "requires": { - "@rushstack/node-core-library": "4.0.2", + "@rushstack/node-core-library": "4.1.0", "supports-color": "~8.1.1" }, "dependencies": { "@rushstack/node-core-library": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", - "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz", + "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==", "dev": true, "requires": { "fs-extra": "~7.0.1", @@ -1307,13 +1240,13 @@ "z-schema": "~5.0.2" } }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "lru-cache": "^6.0.0" } } } @@ -1339,9 +1272,9 @@ } }, "@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -1391,9 +1324,9 @@ "optional": true }, "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "dev": true }, "@tsconfig/node12": { @@ -1450,9 +1383,9 @@ "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" }, "@types/chai": { - "version": "4.3.11", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.11.tgz", - "integrity": "sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==", + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", + "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", "dev": true }, "@types/chai-as-promised": { @@ -1484,9 +1417,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.41", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", - "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -1521,9 +1454,9 @@ } }, "@types/lodash": { - "version": "4.14.202", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", - "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", + "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", "dev": true }, "@types/long": { @@ -1565,17 +1498,17 @@ } }, "@types/node": { - "version": "20.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz", - "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==", + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", "requires": { "undici-types": "~5.26.4" } }, "@types/qs": { - "version": "6.9.10", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", - "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==" + "version": "6.9.14", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", + "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==" }, "@types/range-parser": { "version": "1.2.7", @@ -1604,9 +1537,9 @@ } }, "@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", "dev": true }, "@types/send": { @@ -1619,13 +1552,13 @@ } }, "@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "requires": { "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "@types/node": "*", + "@types/send": "*" } }, "@types/sinon": { @@ -1785,9 +1718,9 @@ } }, "acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-jsx": { @@ -1803,9 +1736,9 @@ "dev": true }, "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "optional": true, "requires": { "debug": "^4.3.4" @@ -2062,13 +1995,13 @@ "dev": true }, "array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" } }, "array-differ": { @@ -2096,17 +2029,18 @@ "dev": true }, "arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, "requires": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", "is-shared-array-buffer": "^1.0.2" } }, @@ -2177,10 +2111,13 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } }, "aws-sign2": { "version": "0.7.0", @@ -2203,17 +2140,6 @@ "async-done": "^2.0.0", "async-settle": "^2.0.0", "now-and-later": "^3.0.0" - }, - "dependencies": { - "now-and-later": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", - "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - } } }, "balanced-match": { @@ -2266,26 +2192,13 @@ "dev": true }, "bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "requires": { - "buffer": "^6.0.3", + "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" - }, - "dependencies": { - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } } }, "bluebird": { @@ -2320,26 +2233,24 @@ "dev": true }, "browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" } }, "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, "buffer-equal": { @@ -2372,14 +2283,16 @@ } }, "call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -2388,10 +2301,16 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, "caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001610", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz", + "integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==", "dev": true }, "caseless": { @@ -2441,6 +2360,17 @@ "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "check-error": { @@ -2480,10 +2410,9 @@ } }, "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "clean-stack": { "version": "2.2.0", @@ -2608,15 +2537,6 @@ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", "dev": true }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "optional": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2683,9 +2603,9 @@ "dev": true }, "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "copy-props": { @@ -2696,14 +2616,6 @@ "requires": { "each-props": "^3.0.0", "is-plain-object": "^5.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } } }, "core-util-is": { @@ -2755,6 +2667,39 @@ "assert-plus": "^1.0.0" } }, + "data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2764,11 +2709,19 @@ } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, "deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", @@ -2778,6 +2731,11 @@ "type-detect": "^4.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2802,14 +2760,14 @@ } }, "define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "requires": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" } }, "define-properties": { @@ -2857,10 +2815,9 @@ "dev": true }, "detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==" }, "diff": { "version": "5.0.0", @@ -2896,14 +2853,6 @@ "inherits": "^2.0.3", "readable-stream": "^3.1.1", "stream-shift": "^1.0.2" - }, - "dependencies": { - "stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "optional": true - } } }, "each-props": { @@ -2914,14 +2863,6 @@ "requires": { "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } } }, "ecc-jsbn": { @@ -2943,9 +2884,9 @@ } }, "electron-to-chromium": { - "version": "1.4.605", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.605.tgz", - "integrity": "sha512-V52j+P5z6cdRqTjPR/bYNxx7ETCHIkm5VIGuyCy3CMrfSnbEpIlLnk5oHmZo7gYvDfh2TfHeanB6rawyQ23ktg==", + "version": "1.4.736", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz", + "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q==", "dev": true }, "emoji-regex": { @@ -2977,61 +2918,92 @@ } }, "es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" + "which-typed-array": "^1.1.15" + } + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" } }, "es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "requires": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" } }, "es-to-primitive": { @@ -3052,9 +3024,9 @@ "dev": true }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" }, "escape-string-regexp": { "version": "4.0.0", @@ -3144,6 +3116,15 @@ "is-glob": "^4.0.3" } }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3240,6 +3221,11 @@ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "optional": true }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -3262,17 +3248,6 @@ "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } } }, "extsprintf": { @@ -3293,6 +3268,15 @@ "time-stamp": "^1.0.0" } }, + "farmhash": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/farmhash/-/farmhash-3.3.0.tgz", + "integrity": "sha512-IZJWJXvX+TZJ4qZrcRZkDqI66s4VxrRD+NsduTSe0PZ9BGEDB53S0cd+e4rTXIWbL5k213W8cN6pMZuPVA+z0Q==", + "requires": { + "node-addon-api": "^5.1.0", + "prebuild-install": "^7.1.1" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3345,9 +3329,9 @@ "dev": true }, "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -3429,14 +3413,6 @@ "object.defaults": "^1.1.0", "object.pick": "^1.3.0", "parse-filepath": "^1.0.2" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } } }, "firebase-token-generator": { @@ -3594,6 +3570,11 @@ "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -3626,13 +3607,13 @@ } }, "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", + "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" + "graceful-fs": "^4.2.8", + "streamx": "^2.12.0" } }, "fs.realpath": { @@ -3696,15 +3677,16 @@ } }, "gaxios": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.1.1.tgz", - "integrity": "sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.5.0.tgz", + "integrity": "sha512-R9QGdv8j4/dlNoQbX3hSaK/S0rkMijqjVvW3YM06CoBdbU/VdKd159j4hePpng0KuE6Lh6JJ7UdmVGJZFcAG1w==", "optional": true, "requires": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", - "node-fetch": "^2.6.9" + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" } }, "gcp-metadata": { @@ -3735,11 +3717,12 @@ "dev": true }, "get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "requires": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", @@ -3759,13 +3742,14 @@ "dev": true }, "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" } }, "getpass": { @@ -3777,6 +3761,11 @@ "assert-plus": "^1.0.0" } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3789,6 +3778,17 @@ "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "glob-parent": { @@ -3801,70 +3801,28 @@ } }, "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", + "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", "dev": true, "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", + "@gulpjs/to-absolute-glob": "^4.0.0", + "anymatch": "^3.1.3", + "fastq": "^1.13.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" + "normalize-path": "^3.0.0", + "streamx": "^2.12.5" }, "dependencies": { "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "is-glob": "^4.0.3" } } } @@ -3945,9 +3903,9 @@ } }, "google-auth-library": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.7.0.tgz", - "integrity": "sha512-I/AvzBiUXDzLOy4iIZ2W+Zq33W4lcukQv1nl7C8WUA6SQwyQwUwu3waNmWNAvzds//FG8SZ+DnKnW/2k6mQS8A==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.8.0.tgz", + "integrity": "sha512-TJJXFzMlVGRlIH27gYZ6XXyPf5Y3OItsKFfefsDAafNNywYRTkei83nEO29IrYj8GtdHWU78YnW+YZdaZaXIJA==", "optional": true, "requires": { "base64-js": "^1.3.0", @@ -4000,9 +3958,9 @@ "dev": true }, "gtoken": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz", - "integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "optional": true, "requires": { "gaxios": "^6.0.0", @@ -4032,47 +3990,6 @@ "wrap-ansi": "^7.0.0" } }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "fs-mkdirp-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", - "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.8", - "streamx": "^2.12.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "glob-stream": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", - "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", - "dev": true, - "requires": { - "@gulpjs/to-absolute-glob": "^4.0.0", - "anymatch": "^3.1.3", - "fastq": "^1.13.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "is-negated-glob": "^1.0.0", - "normalize-path": "^3.0.0", - "streamx": "^2.12.5" - } - }, "gulp-cli": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", @@ -4093,104 +4010,10 @@ "yargs": "^16.2.0" } }, - "lead": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", - "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", - "dev": true - }, - "now-and-later": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", - "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "replace-ext": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", - "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", - "dev": true - }, - "resolve-options": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", - "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", - "dev": true, - "requires": { - "value-or-function": "^4.0.0" - } - }, - "to-through": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", - "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", - "dev": true, - "requires": { - "streamx": "^2.12.5" - } - }, - "value-or-function": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", - "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", - "dev": true - }, - "vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", - "dev": true, - "requires": { - "clone": "^2.1.2", - "clone-stats": "^1.0.0", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" - } - }, - "vinyl-fs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", - "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^2.0.1", - "glob-stream": "^8.0.0", - "graceful-fs": "^4.2.11", - "iconv-lite": "^0.6.3", - "is-valid-glob": "^1.0.0", - "lead": "^4.0.0", - "normalize-path": "3.0.0", - "resolve-options": "^2.0.0", - "stream-composer": "^1.0.2", - "streamx": "^2.14.0", - "to-through": "^3.0.0", - "value-or-function": "^4.0.0", - "vinyl": "^3.0.0", - "vinyl-sourcemap": "^2.0.0" - } - }, - "vinyl-sourcemap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", - "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", - "dev": true, - "requires": { - "convert-source-map": "^2.0.0", - "graceful-fs": "^4.2.10", - "now-and-later": "^3.0.0", - "streamx": "^2.12.5", - "vinyl": "^3.0.0", - "vinyl-contents": "^2.0.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -4254,12 +4077,166 @@ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", "dev": true }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + } + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "requires": { + "once": "^1.3.2" + } + }, + "replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true + }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", + "dev": true, + "requires": { + "value-or-function": "^3.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", @@ -4269,6 +4246,129 @@ "inherits": "^2.0.4", "readable-stream": "2 || 3" } + }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", + "dev": true, + "requires": { + "through2": "^2.0.3" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", + "dev": true + }, + "vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", + "dev": true, + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + } } } }, @@ -4327,18 +4427,18 @@ "dev": true }, "has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "requires": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" } }, "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true }, "has-symbols": { @@ -4348,12 +4448,12 @@ "dev": true }, "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "requires": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" } }, "has-unicode": { @@ -4381,9 +4481,9 @@ } }, "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "requires": { "function-bind": "^1.1.2" @@ -4427,6 +4527,19 @@ "get-prop": "0.0.10", "minimist": "^1.2.0", "stream-buffers": "^3.0.0" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + } } }, "http-parser-js": { @@ -4468,9 +4581,9 @@ } }, "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", "optional": true, "requires": { "agent-base": "^7.0.2", @@ -4495,13 +4608,12 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "import-fresh": { @@ -4550,16 +4662,15 @@ "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "internal-slot": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "requires": { - "get-intrinsic": "^1.2.2", + "es-errors": "^1.3.0", "hasown": "^2.0.0", "side-channel": "^1.0.4" } @@ -4581,14 +4692,13 @@ } }, "is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "requires": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" } }, "is-arrayish": { @@ -4646,6 +4756,15 @@ "hasown": "^2.0.0" } }, + "is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "requires": { + "is-typed-array": "^1.1.13" + } + }, "is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -4655,6 +4774,26 @@ "has-tostringtag": "^1.0.0" } }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + }, + "dependencies": { + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + } + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4682,9 +4821,9 @@ "dev": true }, "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true }, "is-number": { @@ -4721,13 +4860,10 @@ "dev": true }, "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true }, "is-regex": { "version": "1.1.4", @@ -4749,12 +4885,12 @@ } }, "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "requires": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" } }, "is-stream": { @@ -4781,12 +4917,12 @@ } }, "is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "requires": { - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.14" } }, "is-typedarray": { @@ -4966,6 +5102,15 @@ "requires": { "semver": "^7.5.3" } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -4981,9 +5126,9 @@ } }, "istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -5147,9 +5292,9 @@ } }, "just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", "dev": true }, "jwa": { @@ -5177,9 +5322,9 @@ }, "dependencies": { "@types/jsonwebtoken": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", - "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", + "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", "requires": { "@types/node": "*" } @@ -5205,6 +5350,12 @@ "json-buffer": "3.0.1" } }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==", + "dev": true + }, "last-run": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", @@ -5253,13 +5404,10 @@ } }, "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", + "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", + "dev": true }, "levn": { "version": "0.4.1", @@ -5284,14 +5432,6 @@ "is-plain-object": "^5.0.0", "rechoir": "^0.8.0", "resolve": "^1.20.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } } }, "limiter": { @@ -5299,6 +5439,18 @@ "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -5422,8 +5574,7 @@ "long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "optional": true + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "loupe": { "version": "2.3.7", @@ -5543,10 +5694,15 @@ "mime-db": "1.52.0" } }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -5555,8 +5711,7 @@ "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "minipass": { "version": "5.0.0", @@ -5591,6 +5746,11 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "mocha": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", @@ -5625,22 +5785,6 @@ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true - }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -5677,13 +5821,6 @@ "wrap-ansi": "^7.0.0" } }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, "glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -5697,15 +5834,6 @@ "once": "^1.3.0" } }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, "minimatch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", @@ -5721,23 +5849,11 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } + "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 }, "yargs": { "version": "16.2.0", @@ -5797,6 +5913,11 @@ "thenify-all": "^1.0.0" } }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -5816,47 +5937,16 @@ "dev": true }, "nise": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", - "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", "dev": true, "requires": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^10.0.2", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - } - } - } + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" } }, "nock": { @@ -5870,11 +5960,18 @@ "propagate": "^2.0.0" } }, + "node-abi": { + "version": "3.57.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.57.0.tgz", + "integrity": "sha512-Dp+A9JWxRaKuHP35H77I4kCKesDy5HUDEmScia2FyncMTOXASMyg251F5PhFoDA5uqBrDDffiLpbqnrZmNXW+g==", + "requires": { + "semver": "^7.3.5" + } + }, "node-addon-api": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "dev": true + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" }, "node-fetch": { "version": "2.7.0", @@ -5946,12 +6043,12 @@ "dev": true }, "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", + "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", "dev": true, "requires": { - "once": "^1.3.2" + "once": "^1.4.0" } }, "npm-run-all": { @@ -6031,60 +6128,12 @@ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, "semver": { "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", @@ -6106,12 +6155,6 @@ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6187,6 +6230,18 @@ "wrap-ansi": "^6.2.0" } }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -6233,24 +6288,12 @@ "aggregate-error": "^3.0.0" } }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -6489,6 +6532,16 @@ "path-root": "^0.1.1" } }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, "parse-node-version": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", @@ -6540,28 +6593,17 @@ "path-root-regex": "^0.1.0" } }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - } - } + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "dev": true + }, + "path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "dev": true }, "path-type": { "version": "4.0.0", @@ -6599,6 +6641,12 @@ "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", "dev": true }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -6659,6 +6707,31 @@ "extend-shallow": "^3.0.2" } }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true + }, + "prebuild-install": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6733,10 +6806,9 @@ "dev": true }, "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -6765,6 +6837,16 @@ "stream-shift": "^1.0.0" } }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -6830,6 +6912,39 @@ "safe-buffer": "^5.1.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + } + } + }, "readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -6859,14 +6974,15 @@ } }, "regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" } }, "release-zalgo": { @@ -6906,9 +7022,9 @@ "dev": true }, "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", "dev": true }, "replace-homedir": { @@ -6990,6 +7106,12 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -7018,12 +7140,12 @@ "dev": true }, "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", + "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", "dev": true, "requires": { - "value-or-function": "^3.0.0" + "value-or-function": "^4.0.0" } }, "retry": { @@ -7033,13 +7155,12 @@ "optional": true }, "retry-request": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.1.tgz", - "integrity": "sha512-ZI6vJp9rfB71mrZpw+n9p/B6HCsd7QJlSEQftZ+xfJzr3cQ9EPGKw1FF0BnViJ0fYREX6FhymBD2CARpmsFciQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", "optional": true, "requires": { "@types/request": "^2.48.8", - "debug": "^4.1.1", "extend": "^3.0.2", "teeny-request": "^9.0.0" } @@ -7141,12 +7262,6 @@ "kind-of": "^1.1.0" } }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==", - "dev": true - }, "plugin-error": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", @@ -7178,13 +7293,13 @@ } }, "safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -7203,13 +7318,13 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" } }, @@ -7220,9 +7335,9 @@ "dev": true }, "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "requires": { "lru-cache": "^6.0.0" } @@ -7252,26 +7367,29 @@ "dev": true }, "set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "requires": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" } }, "set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "requires": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" } }, "shebang-command": { @@ -7296,14 +7414,15 @@ "dev": true }, "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" } }, "signal-exit": { @@ -7312,6 +7431,21 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, "sinon": { "version": "17.0.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", @@ -7327,10 +7461,19 @@ }, "dependencies": { "diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -7394,9 +7537,9 @@ } }, "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true }, "spdx-expression-parse": { @@ -7410,9 +7553,9 @@ } }, "spdx-license-ids": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", - "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, "sprintf-js": { @@ -7475,10 +7618,9 @@ "dev": true }, "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" }, "streamfilter": { "version": "3.0.0", @@ -7517,47 +7659,49 @@ } }, "string.prototype.padend": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", - "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" } }, "string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" } }, "string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "string_decoder": { @@ -7576,12 +7720,17 @@ "ansi-regex": "^5.0.1" } }, - "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==", + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + }, "strnum": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", @@ -7595,9 +7744,9 @@ "optional": true }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -7628,9 +7777,9 @@ } }, "tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -7639,6 +7788,37 @@ "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + } + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" } }, "teeny-request": { @@ -7762,13 +7942,23 @@ } }, "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.1.0.tgz", + "integrity": "sha512-VhZsTsfrIJjyUi6GeecnwcOJlmoqgIdGFDjqnV5ape+F1DN8GejfPO66XyIhoinxmxGImiUTrq9RwpTN5yszGA==", "dev": true, "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" + "through2": "^4.0.2" + }, + "dependencies": { + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } } }, "time-stamp": { @@ -7809,12 +7999,12 @@ } }, "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", + "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", "dev": true, "requires": { - "through2": "^2.0.3" + "streamx": "^2.12.5" } }, "tough-cookie": { @@ -7887,7 +8077,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -7920,50 +8109,55 @@ "dev": true }, "typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" } }, "typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, "requires": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" } }, "typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" } }, "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "requires": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" } }, "typedarray": { @@ -8113,9 +8307,9 @@ "dev": true }, "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", + "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", "dev": true }, "verror": { @@ -8138,17 +8332,16 @@ } }, "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", "dev": true, "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", + "clone": "^2.1.2", "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" } }, "vinyl-contents": { @@ -8161,108 +8354,63 @@ "vinyl": "^3.0.0" }, "dependencies": { - "replace-ext": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", - "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", - "dev": true + "bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "requires": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } }, - "vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "requires": { - "clone": "^2.1.2", - "clone-stats": "^1.0.0", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } } } }, "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", + "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", "dev": true, "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", + "fs-mkdirp-stream": "^2.0.1", + "glob-stream": "^8.0.0", + "graceful-fs": "^4.2.11", + "iconv-lite": "^0.6.3", "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "lead": "^4.0.0", + "normalize-path": "3.0.0", + "resolve-options": "^2.0.0", + "stream-composer": "^1.0.2", + "streamx": "^2.14.0", + "to-through": "^3.0.0", + "value-or-function": "^4.0.0", + "vinyl": "^3.0.0", + "vinyl-sourcemap": "^2.0.0" } }, "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", + "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", "dev": true, "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } + "convert-source-map": "^2.0.0", + "graceful-fs": "^4.2.10", + "now-and-later": "^3.0.0", + "streamx": "^2.12.5", + "vinyl": "^3.0.0", + "vinyl-contents": "^2.0.0" } }, "webidl-conversions": { @@ -8316,17 +8464,23 @@ "is-symbol": "^1.0.3" } }, + "which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, "which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.2" } }, "wide-align": { @@ -8416,20 +8570,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } } }, "yn": { diff --git a/package.json b/package.json index 9ab7e28d19..e9cf393309 100644 --- a/package.json +++ b/package.json @@ -200,8 +200,10 @@ "@firebase/database-compat": "^1.0.2", "@firebase/database-types": "^1.0.0", "@types/node": "^20.10.3", + "farmhash": "^3.3.0", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.0.1", + "long": "^5.2.3", "node-forge": "^1.3.1", "uuid": "^9.0.0" }, diff --git a/src/remote-config/condition-evaluator-internal.ts b/src/remote-config/condition-evaluator-internal.ts new file mode 100644 index 0000000000..b23958cd77 --- /dev/null +++ b/src/remote-config/condition-evaluator-internal.ts @@ -0,0 +1,178 @@ +/*! + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import { + AndCondition, + OneOfCondition, + EvaluationContext, + NamedCondition, + OrCondition, + PercentCondition, + PercentConditionOperator +} from './remote-config-api'; +import * as farmhash from 'farmhash'; +import long = require('long'); + +/** + * Encapsulates condition evaluation logic to simplify organization and + * facilitate testing. + * + * @internal + */ +export class ConditionEvaluator { + private static MAX_CONDITION_RECURSION_DEPTH = 10; + + public evaluateConditions( + namedConditions: NamedCondition[], + context: EvaluationContext): Map { + // The order of the conditions is significant. + // A JS Map preserves the order of insertion ("Iteration happens in insertion order" + // - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#description). + const evaluatedConditions = new Map(); + + for (const namedCondition of namedConditions) { + evaluatedConditions.set( + namedCondition.name, + this.evaluateCondition(namedCondition.condition, context)); + } + + return evaluatedConditions; + } + + private evaluateCondition( + condition: OneOfCondition, + context: EvaluationContext, + nestingLevel = 0): boolean { + if (nestingLevel >= ConditionEvaluator.MAX_CONDITION_RECURSION_DEPTH) { + // TODO: add logging once we have a wrapped logger. + return false; + } + if (condition.orCondition) { + return this.evaluateOrCondition(condition.orCondition, context, nestingLevel + 1) + } + if (condition.andCondition) { + return this.evaluateAndCondition(condition.andCondition, context, nestingLevel + 1) + } + if (condition.true) { + return true; + } + if (condition.false) { + return false; + } + if (condition.percent) { + return this.evaluatePercentCondition(condition.percent, context); + } + // TODO: add logging once we have a wrapped logger. + return false; + } + + private evaluateOrCondition( + orCondition: OrCondition, + context: EvaluationContext, + nestingLevel: number): boolean { + + const subConditions = orCondition.conditions || []; + + for (const subCondition of subConditions) { + // Recursive call. + const result = this.evaluateCondition( + subCondition, context, nestingLevel + 1); + + // Short-circuit the evaluation result for true. + if (result) { + return result; + } + } + return false; + } + + private evaluateAndCondition( + andCondition: AndCondition, + context: EvaluationContext, + nestingLevel: number): boolean { + + const subConditions = andCondition.conditions || []; + + for (const subCondition of subConditions) { + // Recursive call. + const result = this.evaluateCondition( + subCondition, context, nestingLevel + 1); + + // Short-circuit the evaluation result for false. + if (!result) { + return result; + } + } + return true; + } + + private evaluatePercentCondition( + percentCondition: PercentCondition, + context: EvaluationContext + ): boolean { + if (!context.randomizationId) { + // TODO: add logging once we have a wrapped logger. + return false; + } + + // This is the entry point for processing percent condition data from the response. + // We're not using a proto library, so we can't assume undefined fields have + // default values. + const { seed, percentOperator, microPercent, microPercentRange } = percentCondition; + + if (!percentOperator) { + // TODO: add logging once we have a wrapped logger. + return false; + } + + const normalizedMicroPercent = microPercent || 0; + const normalizedMicroPercentUpperBound = microPercentRange?.microPercentUpperBound || 0; + const normalizedMicroPercentLowerBound = microPercentRange?.microPercentLowerBound || 0; + + const seedPrefix = seed && seed.length > 0 ? `${seed}.` : ''; + const stringToHash = `${seedPrefix}${context.randomizationId}`; + + + // Using a 64-bit long for consistency with the Remote Config fetch endpoint. + let hash64 = long.fromString(farmhash.fingerprint64(stringToHash)); + + // Negate the hash if its value is less than 0. We handle this manually because the + // Long library doesn't provided an absolute value method. + if (hash64.lt(0)) { + hash64 = hash64.negate(); + } + + const instanceMicroPercentile = hash64.mod(100 * 1_000_000); + + switch (percentOperator) { + case PercentConditionOperator.LESS_OR_EQUAL: + return instanceMicroPercentile.lte(normalizedMicroPercent); + case PercentConditionOperator.GREATER_THAN: + return instanceMicroPercentile.gt(normalizedMicroPercent); + case PercentConditionOperator.BETWEEN: + return instanceMicroPercentile.gt(normalizedMicroPercentLowerBound) + && instanceMicroPercentile.lte(normalizedMicroPercentUpperBound); + case PercentConditionOperator.UNKNOWN: + default: + break; + } + + // TODO: add logging once we have a wrapped logger. + return false; + } +} diff --git a/src/remote-config/index.ts b/src/remote-config/index.ts index e4719b2e43..9198284b0e 100644 --- a/src/remote-config/index.ts +++ b/src/remote-config/index.ts @@ -25,18 +25,35 @@ import { FirebaseApp } from '../app/firebase-app'; import { RemoteConfig } from './remote-config'; export { + AndCondition, + DefaultConfig, + EvaluationContext, ExplicitParameterValue, + GetServerTemplateOptions, InAppDefaultValue, + InitServerTemplateOptions, ListVersionsOptions, ListVersionsResult, + MicroPercentRange, + NamedCondition, + OneOfCondition, + OrCondition, ParameterValueType, + PercentConditionOperator, + PercentCondition, RemoteConfigCondition, RemoteConfigParameter, RemoteConfigParameterGroup, RemoteConfigParameterValue, RemoteConfigTemplate, RemoteConfigUser, + ServerConfig, + ServerTemplate, + ServerTemplateData, + ServerTemplateDataType, TagColor, + Value, + ValueSource, Version, } from './remote-config-api'; export { RemoteConfig } from './remote-config'; diff --git a/src/remote-config/internal/value-impl.ts b/src/remote-config/internal/value-impl.ts new file mode 100644 index 0000000000..6d71476538 --- /dev/null +++ b/src/remote-config/internal/value-impl.ts @@ -0,0 +1,61 @@ +/*! + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import { + Value, + ValueSource, +} from '../remote-config-api'; + +/** + * Implements type-safe getters for parameter values. + * + * Visible for testing. + * + * @internal + */ +export class ValueImpl implements Value { + public static readonly DEFAULT_VALUE_FOR_BOOLEAN = false; + public static readonly DEFAULT_VALUE_FOR_STRING = ''; + public static readonly DEFAULT_VALUE_FOR_NUMBER = 0; + public static readonly BOOLEAN_TRUTHY_VALUES = ['1', 'true', 't', 'yes', 'y', 'on']; + constructor( + private readonly source: ValueSource, + private readonly value = ValueImpl.DEFAULT_VALUE_FOR_STRING) { } + asString(): string { + return this.value; + } + asBoolean(): boolean { + if (this.source === 'static') { + return ValueImpl.DEFAULT_VALUE_FOR_BOOLEAN; + } + return ValueImpl.BOOLEAN_TRUTHY_VALUES.indexOf(this.value.toLowerCase()) >= 0; + } + asNumber(): number { + if (this.source === 'static') { + return ValueImpl.DEFAULT_VALUE_FOR_NUMBER; + } + const num = Number(this.value); + if (isNaN(num)) { + return ValueImpl.DEFAULT_VALUE_FOR_NUMBER; + } + return num; + } + getSource(): ValueSource { + return this.source; + } +} diff --git a/src/remote-config/remote-config-api-client-internal.ts b/src/remote-config/remote-config-api-client-internal.ts index b8cfe22fc4..f1a0ad1c10 100644 --- a/src/remote-config/remote-config-api-client-internal.ts +++ b/src/remote-config/remote-config-api-client-internal.ts @@ -21,10 +21,19 @@ import { PrefixedFirebaseError } from '../utils/error'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; import { deepCopy } from '../utils/deep-copy'; -import { ListVersionsOptions, ListVersionsResult, RemoteConfigTemplate } from './remote-config-api'; +import { + ListVersionsOptions, + ListVersionsResult, + RemoteConfigTemplate, + ServerTemplateData +} from './remote-config-api'; // Remote Config backend constants -const FIREBASE_REMOTE_CONFIG_V1_API = 'https://firebaseremoteconfig.googleapis.com/v1'; +/** + * Allows the `FIREBASE_REMOTE_CONFIG_URL_BASE` environment + * variable to override the default API endpoint URL. + */ +const FIREBASE_REMOTE_CONFIG_URL_BASE = process.env.FIREBASE_REMOTE_CONFIG_URL_BASE || 'https://firebaseremoteconfig.googleapis.com'; const FIREBASE_REMOTE_CONFIG_HEADERS = { 'X-Firebase-Client': `fire-admin-node/${utils.getSdkVersion()}`, // There is a known issue in which the ETag is not properly returned in cases where the request @@ -166,6 +175,24 @@ export class RemoteConfigApiClient { }); } + public getServerTemplate(): Promise { + return this.getUrl() + .then((url) => { + const request: HttpRequestConfig = { + method: 'GET', + url: `${url}/namespaces/firebase-server/serverRemoteConfig`, + headers: FIREBASE_REMOTE_CONFIG_HEADERS + }; + return this.httpClient.send(request); + }) + .then((resp) => { + return this.toRemoteConfigServerTemplate(resp); + }) + .catch((err) => { + throw this.toFirebaseError(err); + }); + } + private sendPutRequest(template: RemoteConfigTemplate, etag: string, validateOnly?: boolean): Promise { let path = 'remoteConfig'; if (validateOnly) { @@ -191,7 +218,7 @@ export class RemoteConfigApiClient { private getUrl(): Promise { return this.getProjectIdPrefix() .then((projectIdPrefix) => { - return `${FIREBASE_REMOTE_CONFIG_V1_API}/${projectIdPrefix}`; + return `${FIREBASE_REMOTE_CONFIG_URL_BASE}/v1/${projectIdPrefix}`; }); } @@ -255,6 +282,24 @@ export class RemoteConfigApiClient { }; } + /** + * Creates a RemoteConfigServerTemplate from the API response. + * If provided, customEtag is used instead of the etag returned in the API response. + * + * @param {HttpResponse} resp API response object. + * @param {string} customEtag A custom etag to replace the etag fom the API response (Optional). + */ + private toRemoteConfigServerTemplate(resp: HttpResponse, customEtag?: string): ServerTemplateData { + const etag = (typeof customEtag === 'undefined') ? resp.headers['etag'] : customEtag; + this.validateEtag(etag); + return { + conditions: resp.data.conditions, + parameters: resp.data.parameters, + etag, + version: resp.data.version, + }; + } + /** * Checks if the given RemoteConfigTemplate object is valid. * The object must have valid parameters, parameter groups, conditions, and an etag. diff --git a/src/remote-config/remote-config-api.ts b/src/remote-config/remote-config-api.ts index 90f3bd4970..3ededc58c9 100644 --- a/src/remote-config/remote-config-api.ts +++ b/src/remote-config/remote-config-api.ts @@ -54,6 +54,165 @@ export interface RemoteConfigCondition { tagColor?: TagColor; } +/** + * Represents a Remote Config condition in the dataplane. + * A condition targets a specific group of users. A list of these conditions + * comprise part of a Remote Config template. + */ +export interface NamedCondition { + + /** + * A non-empty and unique name of this condition. + */ + name: string; + + /** + * The logic of this condition. + * See the documentation on + * {@link https://firebase.google.com/docs/remote-config/condition-reference | condition expressions} + * for the expected syntax of this field. + */ + condition: OneOfCondition; +} + +/** + * Represents a condition that may be one of several types. + * Only the first defined field will be processed. + */ +export interface OneOfCondition { + + /** + * Makes this condition an OR condition. + */ + orCondition?: OrCondition; + + /** + * Makes this condition an AND condition. + */ + andCondition?: AndCondition; + + /** + * Makes this condition a constant true. + */ + true?: Record; + + /** + * Makes this condition a constant false. + */ + false?: Record; + + /** + * Makes this condition a percent condition. + */ + percent?: PercentCondition; +} + +/** + * Represents a collection of conditions that evaluate to true if all are true. + */ +export interface AndCondition { + + /** + * The collection of conditions. + */ + conditions?: Array; +} + +/** + * Represents a collection of conditions that evaluate to true if any are true. + */ +export interface OrCondition { + + /** + * The collection of conditions. + */ + conditions?: Array; +} + +/** + * Defines supported operators for percent conditions. + */ +export enum PercentConditionOperator { + + /** + * A catchall error case. + */ + UNKNOWN = 'UNKNOWN', + + /** + * Target percentiles less than or equal to the target percent. + * A condition using this operator must specify microPercent. + */ + LESS_OR_EQUAL = 'LESS_OR_EQUAL', + + /** + * Target percentiles greater than the target percent. + * A condition using this operator must specify microPercent. + */ + GREATER_THAN = 'GREATER_THAN', + + /** + * Target percentiles within an interval defined by a lower bound and an + * upper bound. The lower bound is an exclusive (open) bound and the + * micro_percent_range_upper_bound is an inclusive (closed) bound. + * A condition using this operator must specify microPercentRange. + */ + BETWEEN = 'BETWEEN' +} + +/** + * Represents the limit of percentiles to target in micro-percents. + * The value must be in the range [0 and 100000000] + */ +export interface MicroPercentRange { + + /** + * The lower limit of percentiles to target in micro-percents. + * The value must be in the range [0 and 100000000]. + */ + microPercentLowerBound?: number; + + /** + * The upper limit of percentiles to target in micro-percents. + * The value must be in the range [0 and 100000000]. + */ + microPercentUpperBound?: number; +} + +/** + * Represents a condition that compares the instance pseudo-random + * percentile to a given limit. + */ +export interface PercentCondition { + + /** + * The choice of percent operator to determine how to compare targets + * to percent(s). + */ + percentOperator?: PercentConditionOperator; + + /** + * The limit of percentiles to target in micro-percents when + * using the LESS_OR_EQUAL and GREATER_THAN operators. The value must + * be in the range [0 and 100000000]. + */ + microPercent?: number; + + /** + * The seed used when evaluating the hash function to map an instance to + * a value in the hash space. This is a string which can have 0 - 32 + * characters and can contain ASCII characters [-_.0-9a-zA-Z].The string + * is case-sensitive. + */ + seed?: string; + + /** + * The micro-percent interval to be used with the + * BETWEEN operator. + */ + microPercentRange?: MicroPercentRange; +} + /** * Interface representing an explicit parameter value. */ @@ -135,7 +294,7 @@ export interface RemoteConfigParameterGroup { } /** - * Interface representing a Remote Config template. + * Represents a Remote Config client template. */ export interface RemoteConfigTemplate { /** @@ -167,6 +326,105 @@ export interface RemoteConfigTemplate { version?: Version; } +/** + * Represents the data in a Remote Config server template. + */ +export interface ServerTemplateData { + /** + * A list of conditions in descending order by priority. + */ + conditions: NamedCondition[]; + + /** + * Map of parameter keys to their optional default values and optional conditional values. + */ + parameters: { [key: string]: RemoteConfigParameter }; + + /** + * Current Remote Config template ETag (read-only). + */ + readonly etag: string; + + /** + * Version information for the current Remote Config template. + */ + version?: Version; +} + +/** + * Represents optional arguments that can be used when instantiating {@link ServerTemplate}. + */ +export interface GetServerTemplateOptions { + + /** + * Defines in-app default parameter values, so that your app behaves as + * intended before it connects to the Remote Config backend, and so that + * default values are available if none are set on the backend. + */ + defaultConfig?: DefaultConfig; +} + +/** + * Represents the type of a Remote Config server template that can be set on + * {@link ServerTemplate}. This can either be a {@link ServerTemplateData} object + * or a template JSON string. + */ +export type ServerTemplateDataType = ServerTemplateData | string; + +/** + * Represents optional arguments that can be used when instantiating + * {@link ServerTemplate} synchonously. + */ +export interface InitServerTemplateOptions extends GetServerTemplateOptions { + + /** + * Enables integrations to use template data loaded independently. For + * example, customers can reduce initialization latency by pre-fetching and + * caching template data and then using this option to initialize the SDK with + * that data. + */ + template?: ServerTemplateDataType, +} + +/** + * Represents a stateful abstraction for a Remote Config server template. + */ +export interface ServerTemplate { + /** + * Evaluates the current template to produce a {@link ServerConfig}. + */ + evaluate(context?: EvaluationContext): ServerConfig; + + /** + * Fetches and caches the current active version of the + * project's {@link ServerTemplate}. + */ + load(): Promise; + + /** + * Sets and caches a {@link ServerTemplateData} or a JSON string representing + * the server template + */ + set(template: ServerTemplateDataType): void; + + /** + * Returns a JSON representation of {@link ServerTemplateData} + */ + toJSON(): ServerTemplateData; +} + +/** + * Represents template evaluation input signals. + */ +export type EvaluationContext = { + + /** + * Defines the identifier to use when splitting a group. For example, + * this is used by the percent condition. + */ + randomizationId?: string +}; + /** * Interface representing a Remote Config user. */ @@ -289,3 +547,102 @@ export interface ListVersionsOptions { */ endTime?: Date | string; } + +/** + * Represents the configuration produced by evaluating a server template. + */ +export interface ServerConfig { + + /** + * Gets the value for the given key as a boolean. + * + * Convenience method for calling serverConfig.getValue(key).asBoolean(). + * + * @param key - The name of the parameter. + * + * @returns The value for the given key as a boolean. + */ + getBoolean(key: string): boolean; + + /** + * Gets the value for the given key as a number. + * + * Convenience method for calling serverConfig.getValue(key).asNumber(). + * + * @param key - The name of the parameter. + * + * @returns The value for the given key as a number. + */ + getNumber(key: string): number; + + /** + * Gets the value for the given key as a string. + * Convenience method for calling serverConfig.getValue(key).asString(). + * + * @param key - The name of the parameter. + * + * @returns The value for the given key as a string. + */ + getString(key: string): string; + + /** + * Gets the {@link Value} for the given key. + * + * Ensures application logic will always have a type-safe reference, + * even if the parameter is removed remotely. + * + * @param key - The name of the parameter. + * + * @returns The value for the given key. + */ + getValue(key: string): Value; +} + +/** + * Wraps a parameter value with metadata and type-safe getters. + * + * Type-safe getters insulate application logic from remote + * changes to parameter names and types. + */ +export interface Value { + + /** + * Gets the value as a boolean. + * + * The following values (case insensitive) are interpreted as true: + * "1", "true", "t", "yes", "y", "on". Other values are interpreted as false. + */ + asBoolean(): boolean; + + /** + * Gets the value as a number. Comparable to calling Number(value) || 0. + */ + asNumber(): number; + + /** + * Gets the value as a string. + */ + asString(): string; + + /** + * Gets the {@link ValueSource} for the given key. + */ + getSource(): ValueSource; +} + +/** + * Indicates the source of a value. + * + *
    + *
  • "static" indicates the value was defined by a static constant.
  • + *
  • "default" indicates the value was defined by default config.
  • + *
  • "remote" indicates the value was defined by config produced by + * evaluating a template.
  • + *
+ */ +export type ValueSource = 'static' | 'default' | 'remote'; + +/** + * Defines the format for in-app default parameter values. + */ +export type DefaultConfig = { [key: string]: string | number | boolean }; diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index 27cbd05793..c529501315 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -17,15 +17,30 @@ import { App } from '../app'; import * as validator from '../utils/validator'; import { FirebaseRemoteConfigError, RemoteConfigApiClient } from './remote-config-api-client-internal'; +import { ConditionEvaluator } from './condition-evaluator-internal'; +import { ValueImpl } from './internal/value-impl'; import { ListVersionsOptions, ListVersionsResult, RemoteConfigCondition, RemoteConfigParameter, RemoteConfigParameterGroup, + ServerTemplate, RemoteConfigTemplate, RemoteConfigUser, Version, + ExplicitParameterValue, + InAppDefaultValue, + ServerConfig, + RemoteConfigParameterValue, + EvaluationContext, + ServerTemplateData, + NamedCondition, + Value, + DefaultConfig, + GetServerTemplateOptions, + InitServerTemplateOptions, + ServerTemplateDataType, } from './remote-config-api'; /** @@ -168,6 +183,30 @@ export class RemoteConfig { return new RemoteConfigTemplateImpl(template); } + + /** + * Instantiates {@link ServerTemplate} and then fetches and caches the latest + * template version of the project. + */ + public async getServerTemplate(options?: GetServerTemplateOptions): Promise { + const template = this.initServerTemplate(options); + await template.load(); + return template; + } + + /** + * Synchronously instantiates {@link ServerTemplate}. + */ + public initServerTemplate(options?: InitServerTemplateOptions): ServerTemplate { + const template = new ServerTemplateImpl( + this.client, new ConditionEvaluator(), options?.defaultConfig); + + if (options?.template) { + template.set(options?.template); + } + + return template; + } } /** @@ -254,6 +293,200 @@ class RemoteConfigTemplateImpl implements RemoteConfigTemplate { } } +/** + * Remote Config dataplane template data implementation. + */ +class ServerTemplateImpl implements ServerTemplate { + private cache: ServerTemplateData; + private stringifiedDefaultConfig: {[key: string]: string} = {}; + + constructor( + private readonly apiClient: RemoteConfigApiClient, + private readonly conditionEvaluator: ConditionEvaluator, + public readonly defaultConfig: DefaultConfig = {} + ) { + // RC stores all remote values as string, but it's more intuitive + // to declare default values with specific types, so this converts + // the external declaration to an internal string representation. + for (const key in defaultConfig) { + this.stringifiedDefaultConfig[key] = String(defaultConfig[key]); + } + } + + /** + * Fetches and caches the current active version of the project's {@link ServerTemplate}. + */ + public load(): Promise { + return this.apiClient.getServerTemplate() + .then((template) => { + this.cache = new ServerTemplateDataImpl(template); + }); + } + + /** + * Parses a {@link ServerTemplateDataType} and caches it. + */ + public set(template: ServerTemplateDataType): void { + let parsed; + if (validator.isString(template)) { + try { + parsed = JSON.parse(template); + } catch (e) { + // Transforms JSON parse errors to Firebase error. + throw new FirebaseRemoteConfigError( + 'invalid-argument', + `Failed to parse the JSON string: ${template}. ` + e); + } + } else { + parsed = template; + } + // Throws template parse errors. + this.cache = new ServerTemplateDataImpl(parsed); + } + + /** + * Evaluates the current template in cache to produce a {@link ServerConfig}. + */ + public evaluate(context: EvaluationContext = {}): ServerConfig { + if (!this.cache) { + + // This is the only place we should throw during evaluation, since it's under the + // control of application logic. To preserve forward-compatibility, we should only + // return false in cases where the SDK is unsure how to evaluate the fetched template. + throw new FirebaseRemoteConfigError( + 'failed-precondition', + 'No Remote Config Server template in cache. Call load() before calling evaluate().'); + } + + const evaluatedConditions = this.conditionEvaluator.evaluateConditions( + this.cache.conditions, context); + + const configValues: { [key: string]: Value } = {}; + + // Initializes config Value objects with default values. + for (const key in this.stringifiedDefaultConfig) { + configValues[key] = new ValueImpl('default', this.stringifiedDefaultConfig[key]); + } + + // Overlays config Value objects derived by evaluating the template. + for (const [key, parameter] of Object.entries(this.cache.parameters)) { + const { conditionalValues, defaultValue } = parameter; + + // Supports parameters with no conditional values. + const normalizedConditionalValues = conditionalValues || {}; + + let parameterValueWrapper: RemoteConfigParameterValue | undefined = undefined; + + // Iterates in order over condition list. If there is a value associated + // with a condition, this checks if the condition is true. + for (const [conditionName, conditionEvaluation] of evaluatedConditions) { + if (normalizedConditionalValues[conditionName] && conditionEvaluation) { + parameterValueWrapper = normalizedConditionalValues[conditionName]; + break; + } + } + + if (parameterValueWrapper && (parameterValueWrapper as InAppDefaultValue).useInAppDefault) { + // TODO: add logging once we have a wrapped logger. + continue; + } + + if (parameterValueWrapper) { + const parameterValue = (parameterValueWrapper as ExplicitParameterValue).value; + configValues[key] = new ValueImpl('remote', parameterValue); + continue; + } + + if (!defaultValue) { + // TODO: add logging once we have a wrapped logger. + continue; + } + + if ((defaultValue as InAppDefaultValue).useInAppDefault) { + // TODO: add logging once we have a wrapped logger. + continue; + } + + const parameterDefaultValue = (defaultValue as ExplicitParameterValue).value; + configValues[key] = new ValueImpl('remote', parameterDefaultValue); + } + + return new ServerConfigImpl(configValues); + } + + /** + * @returns JSON representation of the server template + */ + public toJSON(): ServerTemplateData { + return this.cache; + } +} + +class ServerConfigImpl implements ServerConfig { + constructor( + private readonly configValues: { [key: string]: Value }, + ){} + getBoolean(key: string): boolean { + return this.getValue(key).asBoolean(); + } + getNumber(key: string): number { + return this.getValue(key).asNumber(); + } + getString(key: string): string { + return this.getValue(key).asString(); + } + getValue(key: string): Value { + return this.configValues[key] || new ValueImpl('static'); + } +} + +/** + * Remote Config dataplane template data implementation. + */ +class ServerTemplateDataImpl implements ServerTemplateData { + public parameters: { [key: string]: RemoteConfigParameter }; + public parameterGroups: { [key: string]: RemoteConfigParameterGroup }; + public conditions: NamedCondition[]; + public readonly etag: string; + public version?: Version; + + constructor(template: ServerTemplateData) { + if (!validator.isNonNullObject(template) || + !validator.isNonEmptyString(template.etag)) { + throw new FirebaseRemoteConfigError( + 'invalid-argument', + `Invalid Remote Config template: ${JSON.stringify(template)}`); + } + + this.etag = template.etag; + if (typeof template.parameters !== 'undefined') { + if (!validator.isNonNullObject(template.parameters)) { + throw new FirebaseRemoteConfigError( + 'invalid-argument', + 'Remote Config parameters must be a non-null object'); + } + this.parameters = template.parameters; + } else { + this.parameters = {}; + } + + if (typeof template.conditions !== 'undefined') { + if (!validator.isArray(template.conditions)) { + throw new FirebaseRemoteConfigError( + 'invalid-argument', + 'Remote Config conditions must be an array'); + } + this.conditions = template.conditions; + } else { + this.conditions = []; + } + + if (typeof template.version !== 'undefined') { + this.version = new VersionImpl(template.version); + } + } +} + /** * Remote Config Version internal implementation. */ diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index c2ce02ff3f..31efeaf979 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -97,6 +97,8 @@ import './security-rules/security-rules-api-client.spec'; import './remote-config/index.spec'; import './remote-config/remote-config.spec'; import './remote-config/remote-config-api-client.spec'; +import './remote-config/condition-evaluator.spec'; +import './remote-config/internal/value-impl.spec'; // AppCheck import './app-check/app-check.spec'; diff --git a/test/unit/remote-config/condition-evaluator.spec.ts b/test/unit/remote-config/condition-evaluator.spec.ts new file mode 100644 index 0000000000..fbf3ca4979 --- /dev/null +++ b/test/unit/remote-config/condition-evaluator.spec.ts @@ -0,0 +1,825 @@ +/*! + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import * as chai from 'chai'; +import * as sinon from 'sinon'; +import { ConditionEvaluator } from '../../../src/remote-config/condition-evaluator-internal'; +import { + PercentConditionOperator, + PercentCondition +} from '../../../src/remote-config/remote-config-api'; +import { v4 as uuidv4 } from 'uuid'; +import { clone } from 'lodash'; +import * as farmhash from 'farmhash'; + +const expect = chai.expect; + + + +describe('ConditionEvaluator', () => { + let stubs: sinon.SinonStub[] = []; + + afterEach(() => { + for (const stub of stubs) { + stub.restore(); + } + stubs = []; + }); + + describe('evaluateConditions', () => { + it('should evaluate empty OR condition to false', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + } + } + }; + const context = {} + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', false]])); + }); + + it('should evaluate empty OR.AND condition to true', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [ + { + andCondition: { + } + } + ] + } + } + }; + const context = {} + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', true]])); + }); + + it('should evaluate OR.AND.TRUE condition to true', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [ + { + andCondition: { + conditions: [ + { + true: { + } + } + ] + } + } + ] + } + } + }; + const context = {} + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', true]])); + }); + + it('should evaluate OR.AND.FALSE condition to false', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [ + { + andCondition: { + conditions: [ + { + false: { + } + } + ] + } + } + ] + } + } + }; + const context = {} + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', false]])); + }); + + it('should evaluate non-OR top-level condition', () => { + // The server wraps conditions in OR.AND, but the evaluation logic + // is more general. + const condition = { + name: 'is_enabled', + condition: { + true: { + } + } + }; + const context = {} + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', true]])); + }); + + describe('percentCondition', () => { + it('should evaluate an unknown operator to false', () => { + // Verifies future operators won't trigger errors. + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.UNKNOWN + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', false]])); + }); + + it('should evaluate less or equal to max to true', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.LESS_OR_EQUAL, + seed: 'abcdef', + microPercent: 100_000_000 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', true]])); + }); + + it('should evaluate less or equal to min to false', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.LESS_OR_EQUAL, + seed: 'abcdef', + microPercent: 0 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', false]])); + }); + + it('should use zero for undefined microPercent', () => { + // Stubs ID hasher to return a number larger than zero. + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('1'); + stubs.push(stub); + + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.LESS_OR_EQUAL, + // Leaves microPercent undefined + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + + // Evaluates false because 1 is not <= 0 + expect(actual).to.be.false; + }); + + it('should use zeros for undefined microPercentRange', () => { + // Stubs ID hasher to return a number in range. + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('1'); + stubs.push(stub); + + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.BETWEEN, + // Leaves microPercentRange undefined + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + + // Evaluates false because 1 is not in (0,0] + expect(actual).to.be.false; + }); + + it('should use zero for undefined microPercentUpperBound', () => { + // Stubs ID hasher to return a number outside range. + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('1'); + stubs.push(stub); + + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.BETWEEN, + microPercentRange: { + microPercentLowerBound: 0 + // Leaves upper bound undefined + } + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + + // Evaluates false because 1 is not in (0,0] + expect(actual).to.be.false; + }); + + it('should use zero for undefined microPercentLowerBound', () => { + // Stubs ID hasher to return a number in range. + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('1'); + stubs.push(stub); + + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.BETWEEN, + microPercentRange: { + microPercentUpperBound: 1 + // Leaves lower bound undefined + } + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + + // Evaluates true because 1 is in (0,1] + expect(actual).to.be.true; + }); + + it('should evaluate 9 as less or equal to 10', () => { + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('9'); + + stubs.push(stub); + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.LESS_OR_EQUAL, + seed: 'abcdef', + microPercent: 10 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + expect(actual).to.be.true; + }); + + it('should evaluate 10 as less or equal to 10', () => { + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('10'); + + stubs.push(stub); + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.LESS_OR_EQUAL, + seed: 'abcdef', + microPercent: 10 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + expect(actual).to.be.true; + }); + + it('should evaluate 11 as not less or equal to 10', () => { + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('11'); + + stubs.push(stub); + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.LESS_OR_EQUAL, + seed: 'abcdef', + microPercent: 10 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + expect(actual).to.be.false; + }); + + it('should negate -11 to 11 and evaluate as not less or equal to 10', () => { + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('-11'); + + stubs.push(stub); + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.LESS_OR_EQUAL, + seed: 'abcdef', + microPercent: 10 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + expect(actual).to.be.false; + }); + + it('should evaluate greater than min to true', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.GREATER_THAN, + seed: 'abcdef', + microPercent: 0 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', true]])); + }); + + it('should evaluate 11M as greater than 10M', () => { + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('11'); + + stubs.push(stub); + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.GREATER_THAN, + seed: 'abcdef', + microPercent: 10 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + expect(actual).to.be.true; + }); + + it('should evaluate 9 as not greater than 10', () => { + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('9'); + stubs.push(stub); + + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.GREATER_THAN, + seed: 'abcdef', + microPercent: 10 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + expect(actual).to.be.false; + }); + + it('should evaluate greater than max to false', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.GREATER_THAN, + seed: 'abcdef', + microPercent: 100_000_000 + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', false]])); + }); + + it('should evaluate between min and max to true', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.BETWEEN, + seed: 'abcdef', + microPercentRange: { + microPercentLowerBound: 0, + microPercentUpperBound: 100_000_000 + } + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', true]])); + }); + + it('should evaluate 10 as between 9 and 11', () => { + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('10'); + stubs.push(stub); + + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.BETWEEN, + seed: 'abcdef', + microPercentRange: { + microPercentLowerBound: 9, + microPercentUpperBound: 11 + } + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + expect(actual).to.be.true; + }); + + it('should evaluate between equal bounds to false', () => { + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.BETWEEN, + seed: 'abcdef', + microPercentRange: { + microPercentLowerBound: 50000000, + microPercentUpperBound: 50000000 + } + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([['is_enabled', false]])); + }); + + it('should evaluate 12 as not between 9 and 11', () => { + const stub = sinon + .stub(farmhash, 'fingerprint64') + .returns('12'); + stubs.push(stub); + + const condition = { + name: 'is_enabled', + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [{ + percent: { + percentOperator: PercentConditionOperator.BETWEEN, + seed: 'abcdef', + microPercentRange: { + microPercentLowerBound: 9, + microPercentUpperBound: 11 + } + } + }], + } + }] + } + } + }; + const context = { randomizationId: '123' } + const evaluator = new ConditionEvaluator(); + const actual = evaluator.evaluateConditions([condition], context) + .get('is_enabled'); + expect(actual).to.be.false; + }); + + // The following tests are probablistic. They use tolerances based on + // standard deviations to balance accuracy and flakiness. Random IDs will + // hash to the target range + 3 standard deviations 99.7% of the time, + // which minimizes flakiness. + // Use python to calculate standard deviation. For example, for 100k + // trials with 50% probability: + // from scipy.stats import binom + // print(binom.std(100_000, 0.5) * 3) + it('should evaluate less or equal to 10% to approx 10%', () => { + const percentCondition = { + percentOperator: PercentConditionOperator.LESS_OR_EQUAL, + microPercent: 10_000_000 // 10% + }; + const evaluator = new ConditionEvaluator(); + const truthyAssignments = evaluateRandomAssignments(percentCondition, 100_000, evaluator); + // 284 is 3 standard deviations for 100k trials with 10% probability. + const tolerance = 284; + expect(truthyAssignments).to.be.greaterThanOrEqual(10000 - tolerance); + expect(truthyAssignments).to.be.lessThanOrEqual(10000 + tolerance); + }); + + it('should evaluate between 0 to 10% to approx 10%', () => { + const percentCondition = { + percentOperator: PercentConditionOperator.BETWEEN, + microPercentRange: { + microPercentLowerBound: 0, + microPercentUpperBound: 10_000_000 + } + }; + const evaluator = new ConditionEvaluator(); + const truthyAssignments = evaluateRandomAssignments(percentCondition, 100_000, evaluator); + // 284 is 3 standard deviations for 100k trials with 10% probability. + const tolerance = 284; + expect(truthyAssignments).to.be.greaterThanOrEqual(10000 - tolerance); + expect(truthyAssignments).to.be.lessThanOrEqual(10000 + tolerance); + }); + + it('should evaluate greater than 10% to approx 90%', () => { + const percentCondition = { + percentOperator: PercentConditionOperator.GREATER_THAN, + microPercent: 10_000_000 + }; + const evaluator = new ConditionEvaluator(); + const truthyAssignments = evaluateRandomAssignments(percentCondition, 100_000, evaluator); + // 284 is 3 standard deviations for 100k trials with 90% probability. + const tolerance = 284; + expect(truthyAssignments).to.be.greaterThanOrEqual(90000 - tolerance); + expect(truthyAssignments).to.be.lessThanOrEqual(90000 + tolerance); + }); + + it('should evaluate between 40% to 60% to approx 20%', () => { + const percentCondition = { + percentOperator: PercentConditionOperator.BETWEEN, + microPercentRange: { + microPercentLowerBound: 40_000_000, + microPercentUpperBound: 60_000_000 + } + }; + const evaluator = new ConditionEvaluator(); + const truthyAssignments = evaluateRandomAssignments(percentCondition, 100_000, evaluator); + // 379 is 3 standard deviations for 100k trials with 20% probability. + const tolerance = 379; + expect(truthyAssignments).to.be.greaterThanOrEqual(20000 - tolerance); + expect(truthyAssignments).to.be.lessThanOrEqual(20000 + tolerance); + }); + + it('should evaluate between interquartile range to approx 50%', () => { + const percentCondition = { + percentOperator: PercentConditionOperator.BETWEEN, + microPercentRange: { + microPercentLowerBound: 25_000_000, + microPercentUpperBound: 75_000_000 + } + }; + const evaluator = new ConditionEvaluator(); + const truthyAssignments = evaluateRandomAssignments(percentCondition, 100_000, evaluator); + // 474 is 3 standard deviations for 100k trials with 50% probability. + const tolerance = 474; + expect(truthyAssignments).to.be.greaterThanOrEqual(50000 - tolerance); + expect(truthyAssignments).to.be.lessThanOrEqual(50000 + tolerance); + }); + + // Returns the number of assignments which evaluate to true for the specified percent condition. + // This method randomly generates the ids for each assignment for this purpose. + function evaluateRandomAssignments( + condition: PercentCondition, + numOfAssignments: number, + conditionEvaluator: ConditionEvaluator): number { + + let evalTrueCount = 0; + for (let i = 0; i < numOfAssignments; i++) { + const clonedCondition = { + ...clone(condition), + seed: 'seed' + }; + const context = { randomizationId: uuidv4() } + if (conditionEvaluator.evaluateConditions([{ + name: 'is_enabled', + condition: { percent: clonedCondition } + }], context).get('is_enabled') == true) { evalTrueCount++ } + } + return evalTrueCount; + } + }); + }); +}); diff --git a/test/unit/remote-config/internal/value-impl.spec.ts b/test/unit/remote-config/internal/value-impl.spec.ts new file mode 100644 index 0000000000..b344d0c9d1 --- /dev/null +++ b/test/unit/remote-config/internal/value-impl.spec.ts @@ -0,0 +1,75 @@ +/*! + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import * as chai from 'chai'; +import { ValueImpl } from '../../../../src/remote-config/internal/value-impl'; + +const expect = chai.expect; + +describe('ValueImpl', () => { + describe('getSource', () => { + it('returns the source string', () => { + const value = new ValueImpl('static'); + expect(value.getSource()).to.equal('static'); + }); + }); + + describe('asString', () => { + it('returns string value as a string', () => { + const value = new ValueImpl('default', 'shiba'); + expect(value.asString()).to.equal('shiba'); + }); + + it('defaults to empty string', () => { + const value = new ValueImpl('static'); + expect(value.asString()).to.equal(ValueImpl.DEFAULT_VALUE_FOR_STRING); + }); + }); + + describe('asNumber', () => { + it('returns numeric value as a number', () => { + const value = new ValueImpl('default', '123'); + expect(value.asNumber()).to.equal(123); + }); + + it('defaults to zero for non-numeric value', () => { + const value = new ValueImpl('default', 'Hi, NaN!'); + expect(value.asNumber()).to.equal(ValueImpl.DEFAULT_VALUE_FOR_NUMBER); + }); + }); + + describe('asBoolean', () => { + it("returns true for any value in RC's list of truthy values", () => { + for (const truthyValue of ValueImpl.BOOLEAN_TRUTHY_VALUES) { + const value = new ValueImpl('default', truthyValue); + expect(value.asBoolean()).to.be.true; + } + }); + + it('is case-insensitive', () => { + const value = new ValueImpl('default', 'TRUE'); + expect(value.asBoolean()).to.be.true; + }); + + it("returns false for any value not in RC's list of truthy values", () => { + const value = new ValueImpl('default', "I'm falsy"); + expect(value.asBoolean()).to.be.false; + }); + }); +}); + diff --git a/test/unit/remote-config/remote-config-api-client.spec.ts b/test/unit/remote-config/remote-config-api-client.spec.ts index 9c66f78a41..52abb968c1 100644 --- a/test/unit/remote-config/remote-config-api-client.spec.ts +++ b/test/unit/remote-config/remote-config-api-client.spec.ts @@ -33,6 +33,7 @@ import { getSdkVersion } from '../../../src/utils/index'; import { RemoteConfigTemplate, Version, ListVersionsResult, } from '../../../src/remote-config/index'; +import { ServerTemplateData } from '../../../src/remote-config/remote-config-api'; const expect = chai.expect; @@ -661,6 +662,36 @@ describe('RemoteConfigApiClient', () => { }); }); + describe('getServerTemplate', () => { + it('should reject when project id is not available', () => { + return clientWithoutProjectId.getServerTemplate() + .should.eventually.be.rejectedWith(noProjectId); + }); + + // tests for api response validations + runEtagHeaderTests(() => apiClient.getServerTemplate()); + runErrorResponseTests(() => apiClient.getServerTemplate()); + + it('should resolve with the latest template on success', () => { + const stub = sinon + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200, { etag: 'etag-123456789012-1' })); + stubs.push(stub); + return apiClient.getServerTemplate() + .then((resp) => { + expect(resp.conditions).to.deep.equal(TEST_RESPONSE.conditions); + expect(resp.parameters).to.deep.equal(TEST_RESPONSE.parameters); + expect(resp.etag).to.equal('etag-123456789012-1'); + expect(resp.version).to.deep.equal(TEST_RESPONSE.version); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'GET', + url: 'https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig', + headers: EXPECTED_HEADERS, + }); + }); + }); + }); + function runTemplateVersionNumberTests(rcOperation: (v: string | number) => any): void { ['', null, NaN, true, [], {}].forEach((invalidVersion) => { it(`should reject if the versionNumber is: ${invalidVersion}`, () => { @@ -677,7 +708,7 @@ describe('RemoteConfigApiClient', () => { }); } - function runEtagHeaderTests(rcOperation: () => Promise): void { + function runEtagHeaderTests(rcOperation: () => Promise): void { it('should reject when the etag is not present in the response', () => { const stub = sinon .stub(HttpClient.prototype, 'send') @@ -690,7 +721,8 @@ describe('RemoteConfigApiClient', () => { }); } - function runErrorResponseTests(rcOperation: () => Promise): void { + function runErrorResponseTests( + rcOperation: () => Promise): void { it('should reject when a full platform error response is received', () => { const stub = sinon .stub(HttpClient.prototype, 'send') diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index 5459ecd90c..526dc0699e 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -34,6 +34,9 @@ import { RemoteConfigApiClient } from '../../../src/remote-config/remote-config-api-client-internal'; import { deepCopy } from '../../../src/utils/deep-copy'; +import { + NamedCondition, ServerTemplate, ServerTemplateData, Version +} from '../../../src/remote-config/remote-config-api'; const expect = chai.expect; @@ -98,6 +101,44 @@ describe('RemoteConfig', () => { version: VERSION_INFO, }; + const SERVER_REMOTE_CONFIG_RESPONSE: { + // This type is effectively a RemoteConfigServerTemplate, but with mutable fields + // to allow easier use from within the tests. An improvement would be to + // alter this into a helper that creates customized RemoteConfigTemplateContent based + // on the needs of the test, as that would ensure type-safety. + conditions?: Array; + parameters?: object | null; + etag: string; + version?: object; + } = { + conditions: [ + { + name: 'ios', + condition: { + orCondition: { + conditions: [ + { + andCondition: { + conditions: [ + { true: {} } + ] + } + } + ] + } + } + }, + ], + parameters: { + holiday_promo_enabled: { + defaultValue: { value: 'true' }, + conditionalValues: { ios: { useInAppDefault: true } } + }, + }, + etag: 'etag-123456789012-5', + version: VERSION_INFO, + }; + const REMOTE_CONFIG_TEMPLATE: RemoteConfigTemplate = { conditions: [{ name: 'ios', @@ -511,6 +552,845 @@ describe('RemoteConfig', () => { }); }); + describe('getServerTemplate', () => { + const operationName = 'getServerTemplate'; + + it('should propagate API errors', () => { + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .rejects(INTERNAL_ERROR); + stubs.push(stub); + + return remoteConfig.getServerTemplate().should.eventually.be.rejected.and.deep.equal(INTERNAL_ERROR); + }); + + it('should resolve a server template on success', () => { + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(SERVER_REMOTE_CONFIG_RESPONSE as ServerTemplateData); + stubs.push(stub); + + return remoteConfig.getServerTemplate() + .then((template) => { + expect(template.toJSON().conditions.length).to.equal(1); + expect(template.toJSON().conditions[0].name).to.equal('ios'); + expect(template.toJSON().etag).to.equal('etag-123456789012-5'); + + const version = template.toJSON().version!; + expect(version.versionNumber).to.equal('86'); + expect(version.updateOrigin).to.equal('ADMIN_SDK_NODE'); + expect(version.updateType).to.equal('INCREMENTAL_UPDATE'); + expect(version.updateUser).to.deep.equal({ + email: 'firebase-adminsdk@gserviceaccount.com' + }); + expect(version.description).to.equal('production version'); + expect(version.updateTime).to.equal('Mon, 15 Jun 2020 16:45:03 GMT'); + + const key = 'holiday_promo_enabled'; + const p1 = template.toJSON().parameters[key]; + expect(p1.defaultValue).deep.equals({ value: 'true' }); + expect(p1.conditionalValues).deep.equals({ ios: { useInAppDefault: true } }); + + const c = template.toJSON().conditions.find((c) => c.name === 'ios'); + expect(c).to.be.not.undefined; + const cond = c as NamedCondition; + expect(cond.name).to.equal('ios'); + + const parsed = template.toJSON(); + const expectedTemplate = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + const expectedVersion = deepCopy(VERSION_INFO); + expectedVersion.updateTime = new Date(expectedVersion.updateTime).toUTCString(); + expectedTemplate.version = expectedVersion; + expect(parsed).deep.equals(expectedTemplate); + }); + }); + + it('should set defaultConfig when passed', () => { + // Defines template with no parameters to demonstrate + // default config will be used instead, + const template = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + template.parameters = {}; + + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(template); + stubs.push(stub); + + const defaultConfig = { + holiday_promo_enabled: false, + holiday_promo_discount: 20, + }; + + return remoteConfig.getServerTemplate({ defaultConfig }) + .then((template) => { + const config = template.evaluate(); + expect(config.getBoolean('holiday_promo_enabled')).to.equal( + defaultConfig.holiday_promo_enabled); + expect(config.getNumber('holiday_promo_discount')).to.equal( + defaultConfig.holiday_promo_discount); + }); + }); + }); + + describe('initServerTemplate', () => { + it('should set and instantiates template when passed', () => { + const template = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + template.parameters = { + dog_type: { + defaultValue: { + value: 'shiba' + } + } + }; + const initializedTemplate = remoteConfig.initServerTemplate({ template }); + const parsed = initializedTemplate.toJSON(); + const expectedVersion = deepCopy(VERSION_INFO); + expectedVersion.updateTime = new Date(expectedVersion.updateTime).toUTCString(); + template.version = expectedVersion as Version; + expect(parsed).deep.equals(deepCopy(template)); + }); + + it('should set and instantiates template when json string is passed', () => { + const template = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + template.parameters = { + dog_type: { + defaultValue: { + value: 'shiba' + }, + description: 'Type of dog breed', + valueType: 'STRING' + } + }; + const templateJson = JSON.stringify(template); + const initializedTemplate = remoteConfig.initServerTemplate({ template: templateJson }); + const parsed = initializedTemplate.toJSON(); + const expectedVersion = deepCopy(VERSION_INFO); + expectedVersion.updateTime = new Date(expectedVersion.updateTime).toUTCString(); + template.version = expectedVersion as Version; + expect(parsed).deep.equals(deepCopy(template)); + }); + + describe('should throw error if invalid template JSON is passed', () => { + const INVALID_PARAMETERS: any[] = [null, '', 'abc', 1, true, []]; + const INVALID_CONDITIONS: any[] = [null, '', 'abc', 1, true, {}]; + + let sourceTemplate = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + const jsonString = '{invalidJson: null}'; + it('should throw if template is an invalid JSON', () => { + expect(() => remoteConfig.initServerTemplate({ template: jsonString })) + .to.throw(/Failed to parse the JSON string: ([\D\w]*)\./); + }); + + INVALID_PARAMETERS.forEach((invalidParameter) => { + sourceTemplate.parameters = invalidParameter; + const jsonString = JSON.stringify(sourceTemplate); + it(`should throw if the parameters is ${JSON.stringify(invalidParameter)}`, () => { + expect(() => remoteConfig.initServerTemplate({ template: jsonString })) + .to.throw('Remote Config parameters must be a non-null object'); + }); + }); + + sourceTemplate = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + INVALID_CONDITIONS.forEach((invalidConditions) => { + sourceTemplate.conditions = invalidConditions; + const jsonString = JSON.stringify(sourceTemplate); + it(`should throw if the conditions is ${JSON.stringify(invalidConditions)}`, () => { + expect(() => remoteConfig.initServerTemplate({ template: jsonString })) + .to.throw('Remote Config conditions must be an array'); + }); + }); + }); + }); + + describe('RemoteConfigServerTemplate', () => { + const SERVER_REMOTE_CONFIG_RESPONSE_2 = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + SERVER_REMOTE_CONFIG_RESPONSE_2.parameters = { + dog_type: { + defaultValue: { + value: 'corgi' + } + }, + dog_type_enabled: { + defaultValue: { + value: 'true' + } + }, + dog_age: { + defaultValue: { + value: '22' + } + }, + dog_jsonified: { + defaultValue: { + value: '{"name":"Taro","breed":"Corgi","age":1,"fluffiness":100}' + } + }, + dog_use_inapp_default: { + defaultValue: { + useInAppDefault: true + } + }, + dog_no_remote_default_value: { + } + }; + + describe('load', () => { + const operationName = 'getServerTemplate'; + + it('should propagate API errors', () => { + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .rejects(INTERNAL_ERROR); + stubs.push(stub); + + return remoteConfig.getServerTemplate().should.eventually.be.rejected.and.deep.equal(INTERNAL_ERROR); + }); + + it('should reject when API response is invalid', () => { + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(undefined); + stubs.push(stub); + return remoteConfig.getServerTemplate().should.eventually.be.rejected.and.have.property( + 'message', 'Invalid Remote Config template: undefined'); + }); + + it('should reject when API response does not contain an ETag', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + response.etag = ''; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response as ServerTemplateData); + stubs.push(stub); + return remoteConfig.getServerTemplate() + .should.eventually.be.rejected.and.have.property( + 'message', `Invalid Remote Config template: ${JSON.stringify(response)}`); + }); + + it('should reject when API response does not contain valid parameters', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + response.parameters = null; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response as ServerTemplateData); + stubs.push(stub); + return remoteConfig.getServerTemplate() + .should.eventually.be.rejected.and.have.property( + 'message', 'Remote Config parameters must be a non-null object'); + }); + + it('should reject when API response does not contain valid conditions', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + response.conditions = Object(); + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response as ServerTemplateData); + stubs.push(stub); + return remoteConfig.getServerTemplate() + .should.eventually.be.rejected.and.have.property( + 'message', 'Remote Config conditions must be an array'); + }); + + it('should resolve with parameters:{} when no parameters present in the response', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + response.parameters = undefined; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response as ServerTemplateData); + stubs.push(stub); + return remoteConfig.getServerTemplate() + .then((template) => { + // If parameters are not present in the response, we set it to an empty object. + expect(template.toJSON().parameters).deep.equals({}); + }); + }); + + it('should resolve with conditions:[] when no conditions present in the response', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + response.conditions = undefined; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response as ServerTemplateData); + stubs.push(stub); + return remoteConfig.getServerTemplate() + .then((template) => { + // If conditions are not present in the response, we set it to an empty array. + expect(template.toJSON().conditions).deep.equals([]); + }); + }); + + it('should resolve a server template on success', () => { + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(SERVER_REMOTE_CONFIG_RESPONSE as ServerTemplateData); + stubs.push(stub); + + return remoteConfig.getServerTemplate() + .then((template) => { + expect(template.toJSON().conditions.length).to.equal(1); + expect(template.toJSON().conditions[0].name).to.equal('ios'); + expect(template.toJSON().etag).to.equal('etag-123456789012-5'); + + const version = template.toJSON().version!; + expect(version.versionNumber).to.equal('86'); + expect(version.updateOrigin).to.equal('ADMIN_SDK_NODE'); + expect(version.updateType).to.equal('INCREMENTAL_UPDATE'); + expect(version.updateUser).to.deep.equal({ + email: 'firebase-adminsdk@gserviceaccount.com' + }); + expect(version.description).to.equal('production version'); + expect(version.updateTime).to.equal('Mon, 15 Jun 2020 16:45:03 GMT'); + + const key = 'holiday_promo_enabled'; + const p1 = template.toJSON().parameters[key]; + expect(p1.defaultValue).deep.equals({ value: 'true' }); + expect(p1.conditionalValues).deep.equals({ ios: { useInAppDefault: true } }); + + const c = template.toJSON().conditions.find((c) => c.name === 'ios'); + expect(c).to.be.not.undefined; + const cond = c as NamedCondition; + expect(cond.name).to.equal('ios'); + expect(cond.condition).deep.equals({ + 'orCondition': { + 'conditions': [ + { + 'andCondition': { + 'conditions': [ + { + 'true': {} + } + ] + } + } + ] + } + }); + + const parsed = template.toJSON(); + const expectedTemplate = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + const expectedVersion = deepCopy(VERSION_INFO); + expectedVersion.updateTime = new Date(expectedVersion.updateTime).toUTCString(); + expectedTemplate.version = expectedVersion; + expect(parsed).deep.equals(expectedTemplate); + }); + }); + + it('should resolve with template when Version updateTime contains 3 digits in fractional seconds', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + const versionInfo = deepCopy(VERSION_INFO); + versionInfo.updateTime = '2020-10-03T17:14:10.203Z'; + response.version = versionInfo; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response as ServerTemplateData); + stubs.push(stub); + + return remoteConfig.getServerTemplate() + .then((template) => { + expect(template.toJSON().etag).to.equal('etag-123456789012-5'); + + const version = template.toJSON().version!; + expect(version.versionNumber).to.equal('86'); + expect(version.updateOrigin).to.equal('ADMIN_SDK_NODE'); + expect(version.updateType).to.equal('INCREMENTAL_UPDATE'); + expect(version.updateUser).to.deep.equal({ + email: 'firebase-adminsdk@gserviceaccount.com' + }); + expect(version.description).to.equal('production version'); + expect(version.updateTime).to.equal('Sat, 03 Oct 2020 17:14:10 GMT'); + }); + }); + + it('should resolve with template when Version updateTime contains 6 digits in fractional seconds', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + const versionInfo = deepCopy(VERSION_INFO); + versionInfo.updateTime = '2020-08-14T17:01:36.541527Z'; + response.version = versionInfo; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response as ServerTemplateData); + stubs.push(stub); + + return remoteConfig.getServerTemplate() + .then((template) => { + expect(template.toJSON().etag).to.equal('etag-123456789012-5'); + + const version = template.toJSON().version!; + expect(version.versionNumber).to.equal('86'); + expect(version.updateOrigin).to.equal('ADMIN_SDK_NODE'); + expect(version.updateType).to.equal('INCREMENTAL_UPDATE'); + expect(version.updateUser).to.deep.equal({ + email: 'firebase-adminsdk@gserviceaccount.com' + }); + expect(version.description).to.equal('production version'); + expect(version.updateTime).to.equal('Fri, 14 Aug 2020 17:01:36 GMT'); + }); + }); + + it('should resolve with template when Version updateTime contains 9 digits in fractional seconds', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + const versionInfo = deepCopy(VERSION_INFO); + versionInfo.updateTime = '2020-11-15T06:57:26.342763941Z'; + response.version = versionInfo; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response as ServerTemplateData); + stubs.push(stub); + + return remoteConfig.getServerTemplate() + .then((template) => { + expect(template.toJSON().etag).to.equal('etag-123456789012-5'); + + const version = template.toJSON().version!; + expect(version.versionNumber).to.equal('86'); + expect(version.updateOrigin).to.equal('ADMIN_SDK_NODE'); + expect(version.updateType).to.equal('INCREMENTAL_UPDATE'); + expect(version.updateUser).to.deep.equal({ + email: 'firebase-adminsdk@gserviceaccount.com' + }); + expect(version.description).to.equal('production version'); + expect(version.updateTime).to.equal('Sun, 15 Nov 2020 06:57:26 GMT'); + }); + }); + }); + + describe('set', () => { + it('should set template when passed', () => { + const template = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + template.parameters = { + dog_type: { + defaultValue: { + value: 'shiba' + }, + description: 'Type of dog breed', + valueType: 'STRING' + } + }; + template.version = { + ...deepCopy(VERSION_INFO), + updateTime: new Date(VERSION_INFO.updateTime).toUTCString() + } as Version; + const initializedTemplate = remoteConfig.initServerTemplate(); + initializedTemplate.set(template); + const parsed = initializedTemplate.toJSON(); + expect(parsed).deep.equals(template); + }); + + it('should set and instantiates template when json string is passed', () => { + const template = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + template.parameters = { + dog_type: { + defaultValue: { + value: 'shiba' + }, + description: 'Type of dog breed', + valueType: 'STRING' + } + }; + template.version = { + ...deepCopy(VERSION_INFO), + updateTime: new Date(VERSION_INFO.updateTime).toUTCString() + } as Version; + const templateJson = JSON.stringify(template); + const initializedTemplate = remoteConfig.initServerTemplate(); + initializedTemplate.set(templateJson); + const parsed = initializedTemplate.toJSON(); + expect(parsed).deep.equals(template); + }); + + describe('should throw error if there are any JSON or tempalte parsing errors', () => { + const INVALID_PARAMETERS: any[] = [null, '', 'abc', 1, true, []]; + const INVALID_CONDITIONS: any[] = [null, '', 'abc', 1, true, {}]; + + let sourceTemplate = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + const jsonString = '{invalidJson: null}'; + it('should throw if template is an invalid JSON', () => { + expect(() => remoteConfig.initServerTemplate({ template: jsonString })) + .to.throw(/Failed to parse the JSON string: ([\D\w]*)\./); + }); + + INVALID_PARAMETERS.forEach((invalidParameter) => { + sourceTemplate.parameters = invalidParameter; + const jsonString = JSON.stringify(sourceTemplate); + it(`should throw if the template is invalid - parameters is ${JSON.stringify(invalidParameter)}`, () => { + expect(() => remoteConfig.initServerTemplate({ template: jsonString })) + .to.throw('Remote Config parameters must be a non-null object'); + }); + }); + + sourceTemplate = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + INVALID_CONDITIONS.forEach((invalidConditions) => { + sourceTemplate.conditions = invalidConditions; + const jsonString = JSON.stringify(sourceTemplate); + it(`should throw if the template is invalid - conditions is ${JSON.stringify(invalidConditions)}`, () => { + expect(() => remoteConfig.initServerTemplate({ template: jsonString })) + .to.throw('Remote Config conditions must be an array'); + }); + }); + }); + + it('should throw if template is an invalid JSON', () => { + const jsonString = '{invalidJson: null}'; + const initializedTemplate = remoteConfig.initServerTemplate(); + expect(() => initializedTemplate.set(jsonString)) + .to.throw(/Failed to parse the JSON string: ([\D\w]*)\./); + }); + }); + + describe('evaluate', () => { + it('returns a config when template is present in cache', () => { + const stub = sinon + .stub(RemoteConfigApiClient.prototype, 'getServerTemplate') + .resolves(SERVER_REMOTE_CONFIG_RESPONSE_2 as ServerTemplateData); + stubs.push(stub); + return remoteConfig.getServerTemplate() + .then((template: ServerTemplate) => { + const config = template.evaluate!(); + expect(config.getString('dog_type')).to.equal('corgi'); + expect(config.getBoolean('dog_type_enabled')).to.equal(true); + expect(config.getNumber('dog_age')).to.equal(22); + }); + }); + + it('returns conditional value', () => { + const condition = { + name: 'is_true', + condition: { + orCondition: { + conditions: [ + { + andCondition: { + conditions: [ + { + name: '', + true: { + } + } + ] + } + } + ] + } + } + }; + const template = remoteConfig.initServerTemplate({ + template: { + conditions: [condition], + parameters: { + is_enabled: { + defaultValue: { value: 'false' }, + conditionalValues: { is_true: { value: 'true' } } + }, + }, + etag: '123' + } + }); + const config = template.evaluate(); + expect(config.getBoolean('is_enabled')).to.be.true; + }); + + it('honors condition order', () => { + const template = remoteConfig.initServerTemplate({ + template: { + conditions: [ + { + name: 'is_true', + condition: { + orCondition: { + conditions: [ + { + andCondition: { + conditions: [ + { + true: { + } + } + ] + } + } + ] + } + } + }, + { + name: 'is_true_too', + condition: { + orCondition: { + conditions: [ + { + andCondition: { + conditions: [ + { + true: { + } + } + ] + } + } + ] + } + } + }], + parameters: { + dog_type: { + defaultValue: { value: 'chihuahua' }, + conditionalValues: { + // The is_true and is_true_too conditions both return true, + // but is_true is first in the list, so the corresponding + // value is selected. + is_true_too: { value: 'dachshund' }, + is_true: { value: 'corgi' } + } + }, + }, + etag: '123' + } + }); + const config = template.evaluate(); + expect(config.getString('dog_type')).to.eq('corgi'); + }); + + it('uses local default if parameter not in template', () => { + const template = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + template.parameters = {}; + + const stub = sinon + .stub(RemoteConfigApiClient.prototype, 'getServerTemplate') + .resolves(template); + stubs.push(stub); + + const defaultConfig = { + dog_coat: 'blue merle', + }; + + return remoteConfig.getServerTemplate({ defaultConfig }) + .then((template: ServerTemplate) => { + const config = template.evaluate(); + expect(config.getString('dog_coat')).to.equal(defaultConfig.dog_coat); + }); + }); + + it('uses local default when parameter is in template but default value is undefined', () => { + const template = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + template.parameters = { + dog_no_remote_default_value: {} + }; + + const stub = sinon + .stub(RemoteConfigApiClient.prototype, 'getServerTemplate') + .resolves(template); + stubs.push(stub); + + const defaultConfig = { + dog_no_remote_default_value: 'local default' + }; + + return remoteConfig.getServerTemplate({ defaultConfig }) + .then((template: ServerTemplate) => { + const config = template.evaluate!(); + expect(config.getString('dog_no_remote_default_value')).to.equal( + defaultConfig.dog_no_remote_default_value); + }); + }); + + it('uses local default when in-app default value specified', () => { + const template = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + template.parameters = { + dog_no_remote_default_value: {} + }; + + const stub = sinon + .stub(RemoteConfigApiClient.prototype, 'getServerTemplate') + .resolves(template); + stubs.push(stub); + + const defaultConfig = { + dog_use_inapp_default: '🐕' + }; + + return remoteConfig.getServerTemplate({ defaultConfig }) + .then((template: ServerTemplate) => { + const config = template.evaluate!(); + expect(config.getString('dog_use_inapp_default')).to.equal( + defaultConfig.dog_use_inapp_default); + }); + }); + + it('uses local default when in-app default value specified after loading remote values', async () => { + // We had a bug caused by forgetting the first argument to + // Object.assign. This resulted in defaultConfig being overwritten + // by the remote values. So this test asserts we can use in-app + // default after loading remote values. + const template = remoteConfig.initServerTemplate({ + defaultConfig: { + dog_type: 'corgi' + } + }); + + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + + response.parameters = { + dog_type: { + defaultValue: { + value: 'pug' + } + }, + } + + template.set(response as ServerTemplateData); + + let config = template.evaluate(); + + expect(config.getString('dog_type')).to.equal('pug'); + + response.parameters = { + dog_type: { + defaultValue: { + useInAppDefault: true + } + }, + } + + template.set(response as ServerTemplateData); + + config = template.evaluate(); + + expect(config.getString('dog_type')).to.equal('corgi'); + }); + + it('overrides local default when remote value exists', () => { + const response = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); + response.parameters = { + dog_type_enabled: { + defaultValue: { + // Defines remote value + value: 'true' + } + }, + } + + const stub = sinon + .stub(RemoteConfigApiClient.prototype, 'getServerTemplate') + .resolves(response as ServerTemplateData); + stubs.push(stub); + + return remoteConfig.getServerTemplate({ + defaultConfig: { + // Defines local default + dog_type_enabled: false + } + }) + .then((template: ServerTemplate) => { + const config = template.evaluate(); + // Asserts remote value overrides local default. + expect(config.getBoolean('dog_type_enabled')).to.be.true; + }); + }); + }); + }); + + // Note the static source is set in the getValue() method, but the other sources + // are set in the evaluate() method, so these tests span a couple layers. + describe('ServerConfig', () => { + describe('getValue', () => { + it('should return static when default and remote are not defined', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + // Omits remote parameter values. + templateData.parameters = { + }; + // Omits in-app default values. + const template = remoteConfig.initServerTemplate({ template: templateData }); + const config = template.evaluate(); + const value = config.getValue('dog_type'); + expect(value.asString()).to.equal(''); + expect(value.getSource()).to.equal('static'); + }); + + it('should return default value when it is defined', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + // Omits remote parameter values. + templateData.parameters = { + }; + const template = remoteConfig.initServerTemplate({ + template: templateData, + // Defines in-app default values. + defaultConfig: { + dog_type: 'shiba' + } + }); + const config = template.evaluate(); + const value = config.getValue('dog_type'); + expect(value.asString()).to.equal('shiba'); + expect(value.getSource()).to.equal('default'); + }); + + it('should return remote value when it is defined', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + // Defines remote parameter values. + templateData.parameters = { + dog_type: { + defaultValue: { + value: 'pug' + } + } + }; + const template = remoteConfig.initServerTemplate({ + template: templateData, + // Defines in-app default values. + defaultConfig: { + dog_type: 'shiba' + } + }); + const config = template.evaluate(); + const value = config.getValue('dog_type'); + expect(value.asString()).to.equal('pug'); + expect(value.getSource()).to.equal('remote'); + }); + }); + + describe('getString', () => { + it('returns a string value', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + const template = remoteConfig.initServerTemplate({ + template: templateData, + defaultConfig: { + dog_type: 'shiba' + } + }); + const config = template.evaluate(); + expect(config.getString('dog_type')).to.equal('shiba'); + }); + }); + + describe('getNumber', () => { + it('returns a numeric value', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + const template = remoteConfig.initServerTemplate({ + template: templateData, + defaultConfig: { + dog_age: 12 + } + }); + const config = template.evaluate(); + expect(config.getNumber('dog_age')).to.equal(12); + }); + }); + + describe('getBoolean', () => { + it('returns a boolean value', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + const template = remoteConfig.initServerTemplate({ + template: templateData, + defaultConfig: { + dog_is_cute: true + } + }); + const config = template.evaluate(); + expect(config.getBoolean('dog_is_cute')).to.be.true; + }); + }); + }); + function runInvalidResponseTests(rcOperation: () => Promise, operationName: any): void { it('should propagate API errors', () => { From 19c74dc6f7d6e98e7075b18bda980028d8960c76 Mon Sep 17 00:00:00 2001 From: pragatimodi <110490169+pragatimodi@users.noreply.github.com> Date: Mon, 15 Apr 2024 15:34:47 -0700 Subject: [PATCH 092/323] chore: Excluding certain event_types from processing uid (#2370) * adding optional param to token verifier * update _verifyAuthBlockingToken method * fix lint * adding public definitions * add AuthBlockingEventType type * use decoded payload instead * remove debug statement * formatting * add unit tests * unit test * unit test * add comment per code review * Apply suggestions from code review Co-authored-by: Kevin Cheung * fix unit test messages * fix lint --------- Co-authored-by: Kevin Cheung Co-authored-by: Lahiru Maramba --- src/auth/token-verifier.ts | 20 ++++++++----- test/unit/auth/token-verifier.spec.ts | 41 +++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/auth/token-verifier.ts b/src/auth/token-verifier.ts index 05566205b5..73fc8f678c 100644 --- a/src/auth/token-verifier.ts +++ b/src/auth/token-verifier.ts @@ -529,13 +529,19 @@ export class FirebaseTokenVerifier { errorMessage = `${this.tokenInfo.jwtName} has incorrect "iss" (issuer) claim. Expected ` + `"${this.issuer}` + projectId + '" but got "' + payload.iss + '".' + projectIdMatchMessage + verifyJwtTokenDocsMessage; - } else if (typeof payload.sub !== 'string') { - errorMessage = `${this.tokenInfo.jwtName} has no "sub" (subject) claim.` + verifyJwtTokenDocsMessage; - } else if (payload.sub === '') { - errorMessage = `${this.tokenInfo.jwtName} has an empty string "sub" (subject) claim.` + verifyJwtTokenDocsMessage; - } else if (payload.sub.length > 128) { - errorMessage = `${this.tokenInfo.jwtName} has "sub" (subject) claim longer than 128 characters.` + - verifyJwtTokenDocsMessage; + } else if (!(payload.event_type !== undefined && + (payload.event_type === 'beforeSendSms' || payload.event_type === 'beforeSendEmail'))) { + // excluding `beforeSendSms` and `beforeSendEmail` from processing `sub` as there is no user record available. + // `sub` is the same as `uid` which is part of the user record. + if (typeof payload.sub !== 'string') { + errorMessage = `${this.tokenInfo.jwtName} has no "sub" (subject) claim.` + verifyJwtTokenDocsMessage; + } else if (payload.sub === '') { + errorMessage = `${this.tokenInfo.jwtName} has an empty "sub" (subject) claim.` + + verifyJwtTokenDocsMessage; + } else if (payload.sub.length > 128) { + errorMessage = `${this.tokenInfo.jwtName} has a "sub" (subject) claim longer than 128 characters.` + + verifyJwtTokenDocsMessage; + } } if (errorMessage) { throw new FirebaseAuthError(AuthClientErrorCode.INVALID_ARGUMENT, errorMessage); diff --git a/test/unit/auth/token-verifier.spec.ts b/test/unit/auth/token-verifier.spec.ts index 7abda8eb08..2d01678ef7 100644 --- a/test/unit/auth/token-verifier.spec.ts +++ b/test/unit/auth/token-verifier.spec.ts @@ -341,7 +341,8 @@ describe('FirebaseTokenVerifier', () => { }); return tokenVerifier.verifyJWT(mockIdToken) - .should.eventually.be.rejectedWith('Firebase ID token has "sub" (subject) claim longer than 128 characters'); + .should.eventually.be.rejectedWith('Firebase ID token has a "sub" (subject) claim longer than 128 ' + + 'characters'); }); }); @@ -659,7 +660,7 @@ describe('FirebaseTokenVerifier', () => { return authBlockingTokenVerifier._verifyAuthBlockingToken(mockAuthBlockingToken, false, undefined) .should.eventually.be.rejectedWith( - 'Firebase Auth Blocking token has "sub" (subject) claim longer than 128 characters'); + 'Firebase Auth Blocking token has a "sub" (subject) claim longer than 128 characters'); }); }); @@ -780,5 +781,41 @@ describe('FirebaseTokenVerifier', () => { await authBlockingTokenVerifier._verifyAuthBlockingToken(idTokenNoHeader, false, undefined) .should.eventually.be.rejectedWith('Firebase Auth Blocking token has no "kid" claim.'); }); + + const eventTypesWithoutUid = ['beforeSendSms', 'beforeSendEmail']; + eventTypesWithoutUid.forEach((eventType) => { + it('should not throw error on invalid `sub` when event_type is "' + eventType + '"' , async () => { + const verifierStub = sinon.stub(PublicKeySignatureVerifier.prototype, 'verify') + .resolves(); + stubs.push(verifierStub); + + const mockAuthBlockingToken = mocks.generateAuthBlockingToken({ + subject: '' + }, { + event_type: eventType, + }); + return authBlockingTokenVerifier._verifyAuthBlockingToken(mockAuthBlockingToken, false, undefined) + .should.eventually.be.fulfilled; + }); + }); + + const eventTypesWithUid = ['beforeCreate', 'beforeSignIn', undefined]; + eventTypesWithUid.forEach((eventType) => { + it('should not throw error on invalid `sub` when event_type is "' + eventType + '"', async () => { + const verifierStub = sinon.stub(PublicKeySignatureVerifier.prototype, 'verify') + .resolves(); + stubs.push(verifierStub); + + const mockAuthBlockingToken = mocks.generateAuthBlockingToken({ + subject: '' + }, { + event_type: eventType, + }); + return authBlockingTokenVerifier._verifyAuthBlockingToken(mockAuthBlockingToken, false, undefined) + .should.eventually.be.rejectedWith('Firebase Auth Blocking token has an empty "sub" (subject) claim.' + + ' See https://cloud.google.com/identity-platform/docs/blocking-functions for details on how to retrieve an' + + ' Auth Blocking token.'); + }); + }); }); }); From ba207553cf281eb715c94e50e565fcb5bea01509 Mon Sep 17 00:00:00 2001 From: jen_h Date: Tue, 16 Apr 2024 11:50:31 -0500 Subject: [PATCH 093/323] Fix minor typo (#2533) --- src/remote-config/remote-config-api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote-config/remote-config-api.ts b/src/remote-config/remote-config-api.ts index 3ededc58c9..4a9a2cfc4e 100644 --- a/src/remote-config/remote-config-api.ts +++ b/src/remote-config/remote-config-api.ts @@ -373,7 +373,7 @@ export type ServerTemplateDataType = ServerTemplateData | string; /** * Represents optional arguments that can be used when instantiating - * {@link ServerTemplate} synchonously. + * {@link ServerTemplate} synchronously. */ export interface InitServerTemplateOptions extends GetServerTemplateOptions { From 67151e620fbb7bdfc2a017e9a35d51eca035d824 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 16 Apr 2024 13:15:35 -0400 Subject: [PATCH 094/323] [chore] Release 12.1.0 (#2532) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e9cf393309..8ce1736665 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.0.0", + "version": "12.1.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From fb7c13f35ea5dca60a2a6c424aafb2440d13916c Mon Sep 17 00:00:00 2001 From: Erik Eldridge Date: Wed, 17 Apr 2024 11:28:00 -0700 Subject: [PATCH 095/323] Update package.json to use farmhash 3.3.1 (#2534) --- package-lock.json | 28 ++++++++++++++-------------- package.json | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index c6324676c4..02633e47ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.0.0", + "version": "12.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1506,9 +1506,9 @@ } }, "@types/qs": { - "version": "6.9.14", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", - "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==" + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" }, "@types/range-parser": { "version": "1.2.7", @@ -2884,9 +2884,9 @@ } }, "electron-to-chromium": { - "version": "1.4.736", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.736.tgz", - "integrity": "sha512-Rer6wc3ynLelKNM4lOCg7/zPQj8tPOCB2hzD32PX9wd3hgRRi9MxEbmkFCokzcEhRVMiOVLjnL9ig9cefJ+6+Q==", + "version": "1.4.738", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.738.tgz", + "integrity": "sha512-lwKft2CLFztD+vEIpesrOtCrko/TFnEJlHFdRhazU7Y/jx5qc4cqsocfVrBg4So4gGe9lvxnbLIoev47WMpg+A==", "dev": true }, "emoji-regex": { @@ -3269,12 +3269,12 @@ } }, "farmhash": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/farmhash/-/farmhash-3.3.0.tgz", - "integrity": "sha512-IZJWJXvX+TZJ4qZrcRZkDqI66s4VxrRD+NsduTSe0PZ9BGEDB53S0cd+e4rTXIWbL5k213W8cN6pMZuPVA+z0Q==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/farmhash/-/farmhash-3.3.1.tgz", + "integrity": "sha512-XUizHanzlr/v7suBr/o85HSakOoWh6HKXZjFYl5C2+Gj0f0rkw+XTUZzrd9odDsgI9G5tRUcF4wSbKaX04T0DQ==", "requires": { "node-addon-api": "^5.1.0", - "prebuild-install": "^7.1.1" + "prebuild-install": "^7.1.2" } }, "fast-deep-equal": { @@ -5961,9 +5961,9 @@ } }, "node-abi": { - "version": "3.57.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.57.0.tgz", - "integrity": "sha512-Dp+A9JWxRaKuHP35H77I4kCKesDy5HUDEmScia2FyncMTOXASMyg251F5PhFoDA5uqBrDDffiLpbqnrZmNXW+g==", + "version": "3.58.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.58.0.tgz", + "integrity": "sha512-pXY1jnGf5T7b8UNzWzIqf0EkX4bx/w8N2AvwlGnk2SYYA/kzDVPaH0Dh0UG4EwxBB5eKOIZKPr8VAHSHL1DPGg==", "requires": { "semver": "^7.3.5" } diff --git a/package.json b/package.json index 8ce1736665..4db792a913 100644 --- a/package.json +++ b/package.json @@ -200,7 +200,7 @@ "@firebase/database-compat": "^1.0.2", "@firebase/database-types": "^1.0.0", "@types/node": "^20.10.3", - "farmhash": "^3.3.0", + "farmhash": "^3.3.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.0.1", "long": "^5.2.3", From 7463d1cff603ebe3b918e64c0b05328ca5888b05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 19:16:59 +0000 Subject: [PATCH 096/323] build(deps): bump @google-cloud/storage from 7.10.0 to 7.10.1 (#2536) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 02633e47ef..7b0538afe6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -675,9 +675,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.10.0.tgz", - "integrity": "sha512-aBNejLVzHpI7C8eJSMpBpfdq1lxvYuHqG+zy/xvs032RyPRxuu45DLMeXuAbgwyx1VBsxWGYifrPDx+O7hJrmw==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.10.1.tgz", + "integrity": "sha512-sZW14pfxEQZSIbBPs6doFYtcbK31Bs3E4jH5Ly3jJnBkYfkMPX8sXG3ZQXCJa88MKtUNPlgBdMN2OJUzmFe5/g==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", From 685f6c384786ff63340d1f8875bf0b9491ea232f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 16:28:35 -0400 Subject: [PATCH 097/323] build(deps): bump @google-cloud/storage from 7.10.1 to 7.10.2 (#2541) Bumps [@google-cloud/storage](https://github.com/googleapis/nodejs-storage) from 7.10.1 to 7.10.2. - [Release notes](https://github.com/googleapis/nodejs-storage/releases) - [Changelog](https://github.com/googleapis/nodejs-storage/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-storage/compare/v7.10.1...v7.10.2) --- updated-dependencies: - dependency-name: "@google-cloud/storage" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7b0538afe6..b7aa748095 100644 --- a/package-lock.json +++ b/package-lock.json @@ -675,9 +675,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.10.1.tgz", - "integrity": "sha512-sZW14pfxEQZSIbBPs6doFYtcbK31Bs3E4jH5Ly3jJnBkYfkMPX8sXG3ZQXCJa88MKtUNPlgBdMN2OJUzmFe5/g==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.10.2.tgz", + "integrity": "sha512-NaCyhwu0cSqwj6waZO+8WiyzCXUBUfVE7T1fHAGRHEJ+CRy5on2ah/jfC0ZPYXL0q4JoPj98VtMW4bEgtFfKHw==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", From ddcf965511e2f03853bad7658b5c61b85c306580 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 20:33:19 +0000 Subject: [PATCH 098/323] build(deps-dev): bump @firebase/app-compat from 0.2.31 to 0.2.32 (#2540) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index b7aa748095..89094e8135 100644 --- a/package-lock.json +++ b/package-lock.json @@ -431,9 +431,9 @@ } }, "@firebase/app": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.1.tgz", - "integrity": "sha512-H8hvbSVxNt+QaUQ1O0Gqidksi5ilj6eL8iMYxUNZgsMwZ1yOTgXc2C9zktbPQKokgcMq+EbF0k/t5iouslSkiA==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.2.tgz", + "integrity": "sha512-Sk0lQYG0IRIUXkj6Ovaxu0o1E1OdC+IR+UYEYLjXuddr6YjnpFuZ69rTxVja2Ef4TpidJky9o8OoVIaXNjDJ5A==", "dev": true, "requires": { "@firebase/component": "0.6.6", @@ -449,12 +449,12 @@ "integrity": "sha512-NILZbe6RH3X1pZmJnfOfY2gLIrlKmrkUMMrrK6VSXHcSE0eQv28xFEcw16D198i9JYZpy5Kwq394My62qCMaIw==" }, "@firebase/app-compat": { - "version": "0.2.31", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.31.tgz", - "integrity": "sha512-TP9EwOiqDDL4tsP9EyOJn+RYUTkopS0nCg6TZ0PH8XiUgLlgDAF2waAZNha0+18elUkVjbWoXcudCgJ0iVWEVA==", + "version": "0.2.32", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.32.tgz", + "integrity": "sha512-xxfAQKwCmpzwwdBHXT1DTnmilwSeSy6Sa1vThL0q0mq5GPHi52onkm5wl1lrOaiP0uQwQutkZBf/Wy4tDW+5WQ==", "dev": true, "requires": { - "@firebase/app": "0.10.1", + "@firebase/app": "0.10.2", "@firebase/component": "0.6.6", "@firebase/logger": "0.4.1", "@firebase/util": "1.9.5", From f24a7768235d3eb73c51a4b15c43428fe4f72d3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 11:21:36 -0400 Subject: [PATCH 099/323] build(deps): bump @types/node from 20.12.7 to 20.12.10 (#2544) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.7 to 20.12.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 89094e8135..c7834bab77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1498,9 +1498,9 @@ } }, "@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "20.12.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.10.tgz", + "integrity": "sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==", "requires": { "undici-types": "~5.26.4" } From eb1eee60f3818dd1cfb9f5ea729658f395191990 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 15:58:25 +0000 Subject: [PATCH 100/323] build(deps-dev): bump @microsoft/api-extractor from 7.43.1 to 7.43.2 (#2545) --- package-lock.json | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7834bab77..147d24f21d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -929,18 +929,18 @@ } }, "@microsoft/api-extractor": { - "version": "7.43.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.1.tgz", - "integrity": "sha512-ohg40SsvFFgzHFAtYq5wKJc8ZDyY46bphjtnSvhSSlXpPTG7GHwyyXkn48UZiUCBwr2WC7TRC1Jfwz7nreuiyQ==", + "version": "7.43.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.2.tgz", + "integrity": "sha512-5bVGdT/fHTDnBk6XPrw4I/U54LIvEeicOOTcyMtBWq387fad+m6tRk2cP/Lg9bz8+/gJgEkTVhpI8FXV4d79Ng==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.14", + "@microsoft/api-extractor-model": "7.28.15", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.1.0", + "@rushstack/node-core-library": "4.2.0", "@rushstack/rig-package": "0.5.2", - "@rushstack/terminal": "0.10.1", - "@rushstack/ts-command-line": "4.19.2", + "@rushstack/terminal": "0.10.2", + "@rushstack/ts-command-line": "4.19.3", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -956,9 +956,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz", - "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.2.0.tgz", + "integrity": "sha512-y2+m9bbkl1Xe5pt+8gouzRXtXoA2r7B2xkGDT4lpSCpiAU7HNHmhmqxOz+vTmoCamuTj1zqQbgyuoZ1z9cGdag==", "dev": true, "requires": { "fs-extra": "~7.0.1", @@ -970,12 +970,12 @@ } }, "@rushstack/ts-command-line": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.2.tgz", - "integrity": "sha512-cqmXXmBEBlzo9WtyUrHtF9e6kl0LvBY7aTSVX4jfnBfXWZQWnPq9JTFPlQZ+L/ZwjZ4HrNwQsOVvhe9oOucZkw==", + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.3.tgz", + "integrity": "sha512-gWJPWIlr1VC2byK3ZfXMoPLCNT6fFk4qXAb2x2deVRJpq/LQh03galWqissit8QCOS7mOJPyM42uWmT8f4MKRg==", "dev": true, "requires": { - "@rushstack/terminal": "0.10.1", + "@rushstack/terminal": "0.10.2", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -999,14 +999,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.14", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.14.tgz", - "integrity": "sha512-Bery/c8A8SsKPSvA82cTTuy/+OcxZbLRmKhPkk91/AJOQzxZsShcrmHFAGeiEqSIrv1nPZ3tKq9kfMLdCHmsqg==", + "version": "7.28.15", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.15.tgz", + "integrity": "sha512-kAFX0c1+N+2WpZaiksy8H4RZ1sytJb2ZFVEmil5Rt6IK8UExU80f0/4kegXIs1KF8a/YyRW0Pybc7svlT9j/wQ==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.1.0" + "@rushstack/node-core-library": "4.2.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1016,9 +1016,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz", - "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.2.0.tgz", + "integrity": "sha512-y2+m9bbkl1Xe5pt+8gouzRXtXoA2r7B2xkGDT4lpSCpiAU7HNHmhmqxOz+vTmoCamuTj1zqQbgyuoZ1z9cGdag==", "dev": true, "requires": { "fs-extra": "~7.0.1", @@ -1217,19 +1217,19 @@ } }, "@rushstack/terminal": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.1.tgz", - "integrity": "sha512-C6Vi/m/84IYJTkfzmXr1+W8Wi3MmBjVF/q3za91Gb3VYjKbpALHVxY6FgH625AnDe5Z0Kh4MHKWA3Z7bqgAezA==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.2.tgz", + "integrity": "sha512-oMN4uoz6WUeLR9yWHSR4gEEii+8vjIJXPLp7U0k6zccgmOCJXYPKBK30FGpWfDRmqrcCIJi828SKV9V5FB1a0Q==", "dev": true, "requires": { - "@rushstack/node-core-library": "4.1.0", + "@rushstack/node-core-library": "4.2.0", "supports-color": "~8.1.1" }, "dependencies": { "@rushstack/node-core-library": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz", - "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.2.0.tgz", + "integrity": "sha512-y2+m9bbkl1Xe5pt+8gouzRXtXoA2r7B2xkGDT4lpSCpiAU7HNHmhmqxOz+vTmoCamuTj1zqQbgyuoZ1z9cGdag==", "dev": true, "requires": { "fs-extra": "~7.0.1", From 2c717496a286acdadaece5beda1183551a6fbd01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 16:03:51 +0000 Subject: [PATCH 101/323] build(deps): bump @google-cloud/storage from 7.10.2 to 7.11.0 (#2547) --- package-lock.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 147d24f21d..b5ce6c7165 100644 --- a/package-lock.json +++ b/package-lock.json @@ -675,9 +675,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.10.2.tgz", - "integrity": "sha512-NaCyhwu0cSqwj6waZO+8WiyzCXUBUfVE7T1fHAGRHEJ+CRy5on2ah/jfC0ZPYXL0q4JoPj98VtMW4bEgtFfKHw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.11.0.tgz", + "integrity": "sha512-W+OPOCgq7a3aAMANALbJAlEnpMV9fy681JWIm7dYe5W/+nRhq/UvA477TJT5/oPNA5DgiAdMEdiitdoLpZqhJg==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", @@ -686,10 +686,10 @@ "abort-controller": "^3.0.0", "async-retry": "^1.3.3", "duplexify": "^4.1.3", - "ent": "^2.2.0", "fast-xml-parser": "^4.3.0", "gaxios": "^6.0.2", "google-auth-library": "^9.6.3", + "html-entities": "^2.5.2", "mime": "^3.0.0", "p-limit": "^3.0.1", "retry-request": "^7.0.0", @@ -2902,12 +2902,6 @@ "once": "^1.4.0" } }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "optional": true - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4510,6 +4504,12 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, + "html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "optional": true + }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", From 6b558d66ec6bfe7c37eaaa0e450046e3e227ea7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 16:08:37 +0000 Subject: [PATCH 102/323] build(deps-dev): bump @types/lodash from 4.17.0 to 4.17.1 (#2546) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b5ce6c7165..317f22ae95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1454,9 +1454,9 @@ } }, "@types/lodash": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", - "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.1.tgz", + "integrity": "sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==", "dev": true }, "@types/long": { From bde43088d16f7e0c4cd3d13370ef98989d47073b Mon Sep 17 00:00:00 2001 From: Dennis Kugelmann Date: Wed, 8 May 2024 20:15:43 +0000 Subject: [PATCH 103/323] fix: Export error classes (#2151) * Expose error class * Expose more error classes * Expose error codes --------- Co-authored-by: Lahiru Maramba --- src/app/index.ts | 2 ++ src/auth/index.ts | 5 +++++ src/database/index.ts | 2 ++ src/firestore/index.ts | 2 ++ src/installations/index.ts | 2 ++ src/instance-id/index.ts | 2 ++ src/messaging/index.ts | 2 ++ src/project-management/index.ts | 2 ++ 8 files changed, 19 insertions(+) diff --git a/src/app/index.ts b/src/app/index.ts index 02a8509653..5308e414e2 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -29,4 +29,6 @@ export { initializeApp, getApp, getApps, deleteApp } from './lifecycle'; export { Credential, ServiceAccount, GoogleOAuthAccessToken } from './credential'; export { applicationDefault, cert, refreshToken } from './credential-factory'; +export { FirebaseAppError, AppErrorCodes } from '../utils/error'; + export const SDK_VERSION = getSdkVersion(); diff --git a/src/auth/index.ts b/src/auth/index.ts index a559a706f8..f350b28837 100644 --- a/src/auth/index.ts +++ b/src/auth/index.ts @@ -164,3 +164,8 @@ export { UserMetadata, UserRecord, } from './user-record'; + +export { + FirebaseAuthError, + AuthClientErrorCode, +} from '../utils/error'; diff --git a/src/database/index.ts b/src/database/index.ts index d276b27a08..7a17deb751 100644 --- a/src/database/index.ts +++ b/src/database/index.ts @@ -125,3 +125,5 @@ function getDatabaseInstance(options: { url?: string; app?: App }): Database { const dbService = firebaseApp.getOrInitService('database', (app) => new DatabaseService(app)); return dbService.getDatabase(options.url); } + +export { FirebaseDatabaseError } from '../utils/error'; diff --git a/src/firestore/index.ts b/src/firestore/index.ts index ff6954cefa..f906f382e2 100644 --- a/src/firestore/index.ts +++ b/src/firestore/index.ts @@ -220,3 +220,5 @@ export function initializeFirestore( return firestoreService.initializeDatabase(databaseId, settings); } + +export { FirebaseFirestoreError } from '../utils/error'; diff --git a/src/installations/index.ts b/src/installations/index.ts index c790c2c8ce..1d6a39dc35 100644 --- a/src/installations/index.ts +++ b/src/installations/index.ts @@ -61,3 +61,5 @@ export function getInstallations(app?: App): Installations { const firebaseApp: FirebaseApp = app as FirebaseApp; return firebaseApp.getOrInitService('installations', (app) => new Installations(app)); } + +export { FirebaseInstallationsError, InstallationsClientErrorCode } from '../utils/error'; diff --git a/src/instance-id/index.ts b/src/instance-id/index.ts index 6d014aeebb..1a9c06d3bc 100644 --- a/src/instance-id/index.ts +++ b/src/instance-id/index.ts @@ -70,3 +70,5 @@ export function getInstanceId(app?: App): InstanceId { const firebaseApp: FirebaseApp = app as FirebaseApp; return firebaseApp.getOrInitService('instanceId', (app) => new InstanceId(app)); } + +export { FirebaseInstanceIdError, InstanceIdClientErrorCode } from '../utils/error'; diff --git a/src/messaging/index.ts b/src/messaging/index.ts index 2371004e33..298a2d5f10 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -100,3 +100,5 @@ export function getMessaging(app?: App): Messaging { const firebaseApp: FirebaseApp = app as FirebaseApp; return firebaseApp.getOrInitService('messaging', (app) => new Messaging(app)); } + +export { FirebaseMessagingError, MessagingClientErrorCode } from '../utils/error'; diff --git a/src/project-management/index.ts b/src/project-management/index.ts index 3a1f8490e1..cc23066681 100644 --- a/src/project-management/index.ts +++ b/src/project-management/index.ts @@ -62,3 +62,5 @@ export function getProjectManagement(app?: App): ProjectManagement { const firebaseApp: FirebaseApp = app as FirebaseApp; return firebaseApp.getOrInitService('projectManagement', (app) => new ProjectManagement(app)); } + +export { FirebaseProjectManagementError, ProjectManagementErrorCode } from '../utils/error'; From a37eb6cb5ad92d911d0b868f5beb8d11761bcc0a Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 8 May 2024 22:03:00 +0000 Subject: [PATCH 104/323] Fix api extractor issues to expose error types (#2549) --- etc/firebase-admin.app.api.md | 32 ++ etc/firebase-admin.auth.api.md | 480 +++++++++++++++++++ etc/firebase-admin.database.api.md | 6 + etc/firebase-admin.firestore.api.md | 6 + etc/firebase-admin.installations.api.md | 30 ++ etc/firebase-admin.instance-id.api.md | 17 + etc/firebase-admin.messaging.api.md | 105 ++++ etc/firebase-admin.project-management.api.md | 9 + src/utils/error.ts | 159 +++--- 9 files changed, 778 insertions(+), 66 deletions(-) diff --git a/etc/firebase-admin.app.api.md b/etc/firebase-admin.app.api.md index a6ad65cd57..4546fe7824 100644 --- a/etc/firebase-admin.app.api.md +++ b/etc/firebase-admin.app.api.md @@ -14,6 +14,32 @@ export interface App { options: AppOptions; } +// @public +export class AppErrorCodes { + // (undocumented) + static APP_DELETED: string; + // (undocumented) + static DUPLICATE_APP: string; + // (undocumented) + static INTERNAL_ERROR: string; + // (undocumented) + static INVALID_APP_NAME: string; + // (undocumented) + static INVALID_APP_OPTIONS: string; + // (undocumented) + static INVALID_ARGUMENT: string; + // (undocumented) + static INVALID_CREDENTIAL: string; + // (undocumented) + static NETWORK_ERROR: string; + // (undocumented) + static NETWORK_TIMEOUT: string; + // (undocumented) + static NO_APP: string; + // (undocumented) + static UNABLE_TO_PARSE_RESPONSE: string; +} + // @public export function applicationDefault(httpAgent?: Agent): Credential; @@ -39,6 +65,12 @@ export interface Credential { // @public export function deleteApp(app: App): Promise; +// Warning: (ae-forgotten-export) The symbol "PrefixedFirebaseError" needs to be exported by the entry point index.d.ts +// +// @public +export class FirebaseAppError extends PrefixedFirebaseError { +} + // @public export interface FirebaseArrayIndexError { error: FirebaseError; diff --git a/etc/firebase-admin.auth.api.md b/etc/firebase-admin.auth.api.md index 3723abd051..d921458bec 100644 --- a/etc/firebase-admin.auth.api.md +++ b/etc/firebase-admin.auth.api.md @@ -55,6 +55,480 @@ export class Auth extends BaseAuth { tenantManager(): TenantManager; } +// @public +export class AuthClientErrorCode { + // (undocumented) + static AUTH_BLOCKING_TOKEN_EXPIRED: { + code: string; + message: string; + }; + // (undocumented) + static BILLING_NOT_ENABLED: { + code: string; + message: string; + }; + // (undocumented) + static CLAIMS_TOO_LARGE: { + code: string; + message: string; + }; + // (undocumented) + static CONFIGURATION_EXISTS: { + code: string; + message: string; + }; + // (undocumented) + static CONFIGURATION_NOT_FOUND: { + code: string; + message: string; + }; + // (undocumented) + static EMAIL_ALREADY_EXISTS: { + code: string; + message: string; + }; + // (undocumented) + static EMAIL_NOT_FOUND: { + code: string; + message: string; + }; + // (undocumented) + static FORBIDDEN_CLAIM: { + code: string; + message: string; + }; + // (undocumented) + static ID_TOKEN_EXPIRED: { + code: string; + message: string; + }; + // (undocumented) + static ID_TOKEN_REVOKED: { + code: string; + message: string; + }; + // (undocumented) + static INSUFFICIENT_PERMISSION: { + code: string; + message: string; + }; + // (undocumented) + static INTERNAL_ERROR: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_ARGUMENT: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_CLAIMS: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_CONFIG: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_CONTINUE_URI: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_CREATION_TIME: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_CREDENTIAL: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_DISABLED_FIELD: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_DISPLAY_NAME: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_DYNAMIC_LINK_DOMAIN: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_EMAIL: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_EMAIL_VERIFIED: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_ENROLLED_FACTORS: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_ENROLLMENT_TIME: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_HASH_ALGORITHM: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_HASH_BLOCK_SIZE: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_HASH_DERIVED_KEY_LENGTH: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_HASH_KEY: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_HASH_MEMORY_COST: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_HASH_PARALLELIZATION: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_HASH_ROUNDS: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_HASH_SALT_SEPARATOR: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_ID_TOKEN: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_LAST_SIGN_IN_TIME: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_NAME: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_NEW_EMAIL: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_OAUTH_CLIENT_ID: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_OAUTH_RESPONSETYPE: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PAGE_TOKEN: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PASSWORD: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PASSWORD_HASH: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PASSWORD_SALT: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PHONE_NUMBER: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PHOTO_URL: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PROJECT_ID: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PROVIDER_DATA: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PROVIDER_ID: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PROVIDER_UID: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_RECAPTCHA_ACTION: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_RECAPTCHA_ENFORCEMENT_STATE: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_SESSION_COOKIE_DURATION: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_TENANT_ID: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_TENANT_TYPE: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_TESTING_PHONE_NUMBER: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_TOKENS_VALID_AFTER_TIME: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_UID: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_USER_IMPORT: { + code: string; + message: string; + }; + // (undocumented) + static MAXIMUM_TEST_PHONE_NUMBER_EXCEEDED: { + code: string; + message: string; + }; + // (undocumented) + static MAXIMUM_USER_COUNT_EXCEEDED: { + code: string; + message: string; + }; + // (undocumented) + static MISMATCHING_TENANT_ID: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_ANDROID_PACKAGE_NAME: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_CONFIG: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_CONTINUE_URI: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_DISPLAY_NAME: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_EMAIL: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_HASH_ALGORITHM: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_IOS_BUNDLE_ID: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_ISSUER: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_OAUTH_CLIENT_ID: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_OAUTH_CLIENT_SECRET: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_PROVIDER_ID: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_SAML_RELYING_PARTY_CONFIG: { + code: string; + message: string; + }; + // (undocumented) + static MISSING_UID: { + code: string; + message: string; + }; + // (undocumented) + static NOT_FOUND: { + code: string; + message: string; + }; + // (undocumented) + static OPERATION_NOT_ALLOWED: { + code: string; + message: string; + }; + // (undocumented) + static PHONE_NUMBER_ALREADY_EXISTS: { + code: string; + message: string; + }; + // (undocumented) + static PROJECT_NOT_FOUND: { + code: string; + message: string; + }; + // (undocumented) + static QUOTA_EXCEEDED: { + code: string; + message: string; + }; + // (undocumented) + static RECAPTCHA_NOT_ENABLED: { + code: string; + message: string; + }; + // (undocumented) + static SECOND_FACTOR_LIMIT_EXCEEDED: { + code: string; + message: string; + }; + // (undocumented) + static SECOND_FACTOR_UID_ALREADY_EXISTS: { + code: string; + message: string; + }; + // (undocumented) + static SESSION_COOKIE_EXPIRED: { + code: string; + message: string; + }; + // (undocumented) + static SESSION_COOKIE_REVOKED: { + code: string; + message: string; + }; + // (undocumented) + static TENANT_NOT_FOUND: { + code: string; + message: string; + }; + // (undocumented) + static UID_ALREADY_EXISTS: { + code: string; + message: string; + }; + // (undocumented) + static UNAUTHORIZED_DOMAIN: { + code: string; + message: string; + }; + // (undocumented) + static UNSUPPORTED_FIRST_FACTOR: { + code: string; + message: string; + }; + // (undocumented) + static UNSUPPORTED_SECOND_FACTOR: { + code: string; + message: string; + }; + // (undocumented) + static UNSUPPORTED_TENANT_OPERATION: { + code: string; + message: string; + }; + // (undocumented) + static UNVERIFIED_EMAIL: { + code: string; + message: string; + }; + // (undocumented) + static USER_DISABLED: { + code: string; + message: string; + }; + // (undocumented) + static USER_NOT_DISABLED: { + code: string; + message: string; + }; + // (undocumented) + static USER_NOT_FOUND: { + code: string; + message: string; + }; +} + // @public export type AuthFactorType = 'phone'; @@ -249,6 +723,12 @@ export interface EmailSignInProviderConfig { passwordRequired?: boolean; } +// Warning: (ae-forgotten-export) The symbol "PrefixedFirebaseError" needs to be exported by the entry point index.d.ts +// +// @public +export class FirebaseAuthError extends PrefixedFirebaseError { +} + // @public export function getAuth(app?: App): Auth; diff --git a/etc/firebase-admin.database.api.md b/etc/firebase-admin.database.api.md index e2411ce4be..1778f75d51 100644 --- a/etc/firebase-admin.database.api.md +++ b/etc/firebase-admin.database.api.md @@ -30,6 +30,12 @@ export const enableLogging: typeof rtdb.enableLogging; export { EventType } +// Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts +// +// @public +export class FirebaseDatabaseError extends FirebaseError { +} + // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts // // @public diff --git a/etc/firebase-admin.firestore.api.md b/etc/firebase-admin.firestore.api.md index 80c0e5d9c3..8f29baeab3 100644 --- a/etc/firebase-admin.firestore.api.md +++ b/etc/firebase-admin.firestore.api.md @@ -102,6 +102,12 @@ export { FieldValue } export { Filter } +// Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts +// +// @public +export class FirebaseFirestoreError extends FirebaseError { +} + export { Firestore } export { FirestoreDataConverter } diff --git a/etc/firebase-admin.installations.api.md b/etc/firebase-admin.installations.api.md index 4a4d11e06f..56496ef135 100644 --- a/etc/firebase-admin.installations.api.md +++ b/etc/firebase-admin.installations.api.md @@ -8,6 +8,12 @@ import { Agent } from 'http'; +// Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts +// +// @public +export class FirebaseInstallationsError extends FirebaseError { +} + // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts // // @public @@ -19,4 +25,28 @@ export class Installations { deleteInstallation(fid: string): Promise; } +// @public (undocumented) +export class InstallationsClientErrorCode { + // (undocumented) + static API_ERROR: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_ARGUMENT: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_INSTALLATION_ID: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PROJECT_ID: { + code: string; + message: string; + }; +} + ``` diff --git a/etc/firebase-admin.instance-id.api.md b/etc/firebase-admin.instance-id.api.md index 2e2a43f642..9c28852a2c 100644 --- a/etc/firebase-admin.instance-id.api.md +++ b/etc/firebase-admin.instance-id.api.md @@ -8,6 +8,12 @@ import { Agent } from 'http'; +// Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts +// +// @public +export class FirebaseInstanceIdError extends FirebaseError { +} + // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts // // @public @deprecated @@ -19,4 +25,15 @@ export class InstanceId { deleteInstanceId(instanceId: string): Promise; } +// Warning: (ae-forgotten-export) The symbol "InstallationsClientErrorCode" needs to be exported by the entry point index.d.ts +// +// @public (undocumented) +export class InstanceIdClientErrorCode extends InstallationsClientErrorCode { + // (undocumented) + static INVALID_INSTANCE_ID: { + code: string; + message: string; + }; +} + ``` diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index e9465a8e2d..4b8e6c1ed3 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -165,6 +165,12 @@ export interface FcmOptions { analyticsLabel?: string; } +// Warning: (ae-forgotten-export) The symbol "PrefixedFirebaseError" needs to be exported by the entry point index.d.ts +// +// @public +export class FirebaseMessagingError extends PrefixedFirebaseError { +} + // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts // // @public @@ -200,6 +206,105 @@ export class Messaging { unsubscribeFromTopic(registrationTokenOrTokens: string | string[], topic: string): Promise; } +// @public +export class MessagingClientErrorCode { + // (undocumented) + static AUTHENTICATION_ERROR: { + code: string; + message: string; + }; + // (undocumented) + static DEVICE_MESSAGE_RATE_EXCEEDED: { + code: string; + message: string; + }; + // (undocumented) + static INTERNAL_ERROR: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_ARGUMENT: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_DATA_PAYLOAD_KEY: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_OPTIONS: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PACKAGE_NAME: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_PAYLOAD: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_RECIPIENT: { + code: string; + message: string; + }; + // (undocumented) + static INVALID_REGISTRATION_TOKEN: { + code: string; + message: string; + }; + // (undocumented) + static MESSAGE_RATE_EXCEEDED: { + code: string; + message: string; + }; + // (undocumented) + static MISMATCHED_CREDENTIAL: { + code: string; + message: string; + }; + // (undocumented) + static PAYLOAD_SIZE_LIMIT_EXCEEDED: { + code: string; + message: string; + }; + // (undocumented) + static REGISTRATION_TOKEN_NOT_REGISTERED: { + code: string; + message: string; + }; + // (undocumented) + static SERVER_UNAVAILABLE: { + code: string; + message: string; + }; + // (undocumented) + static THIRD_PARTY_AUTH_ERROR: { + code: string; + message: string; + }; + // (undocumented) + static TOO_MANY_TOPICS: { + code: string; + message: string; + }; + // (undocumented) + static TOPICS_MESSAGE_RATE_EXCEEDED: { + code: string; + message: string; + }; + // (undocumented) + static UNKNOWN_ERROR: { + code: string; + message: string; + }; +} + // @public export interface MessagingConditionResponse { messageId: number; diff --git a/etc/firebase-admin.project-management.api.md b/etc/firebase-admin.project-management.api.md index 2b8d28297c..8f59f54642 100644 --- a/etc/firebase-admin.project-management.api.md +++ b/etc/firebase-admin.project-management.api.md @@ -43,6 +43,12 @@ export enum AppPlatform { PLATFORM_UNKNOWN = "PLATFORM_UNKNOWN" } +// Warning: (ae-forgotten-export) The symbol "PrefixedFirebaseError" needs to be exported by the entry point index.d.ts +// +// @public +export class FirebaseProjectManagementError extends PrefixedFirebaseError { +} + // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts // // @public @@ -79,6 +85,9 @@ export class ProjectManagement { shaCertificate(shaHash: string): ShaCertificate; } +// @public (undocumented) +export type ProjectManagementErrorCode = 'already-exists' | 'authentication-error' | 'internal-error' | 'invalid-argument' | 'invalid-project-id' | 'invalid-server-response' | 'not-found' | 'service-unavailable' | 'unknown-error'; + // @public export class ShaCertificate { readonly certType: ('sha1' | 'sha256'); diff --git a/src/utils/error.ts b/src/utils/error.ts index cdb7faef05..772d808a9a 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -35,11 +35,13 @@ interface ServerToClientCode { /** * Firebase error code structure. This extends Error. - * - * @param errorInfo - The error information (code and message). - * @constructor */ export class FirebaseError extends Error implements FirebaseErrorInterface { + /** + * @param errorInfo - The error information (code and message). + * @constructor + * @internal + */ constructor(private errorInfo: ErrorInfo) { super(errorInfo.message); @@ -71,13 +73,15 @@ export class FirebaseError extends Error implements FirebaseErrorInterface { /** * A FirebaseError with a prefix in front of the error code. - * - * @param codePrefix - The prefix to apply to the error code. - * @param code - The error code. - * @param message - The error message. - * @constructor */ export class PrefixedFirebaseError extends FirebaseError { + /** + * @param codePrefix - The prefix to apply to the error code. + * @param code - The error code. + * @param message - The error message. + * @constructor + * @internal + */ constructor(private codePrefix: string, code: string, message: string) { super({ code: `${codePrefix}/${code}`, @@ -105,12 +109,14 @@ export class PrefixedFirebaseError extends FirebaseError { /** * Firebase App error code structure. This extends PrefixedFirebaseError. - * - * @param code - The error code. - * @param message - The error message. - * @constructor */ export class FirebaseAppError extends PrefixedFirebaseError { + /** + * @param code - The error code. + * @param message - The error message. + * @constructor + * @internal + */ constructor(code: string, message: string) { super('app', code, message); @@ -124,11 +130,6 @@ export class FirebaseAppError extends PrefixedFirebaseError { /** * Firebase Auth error code structure. This extends PrefixedFirebaseError. - * - * @param info - The error code info. - * @param [message] The error message. This will override the default - * message if provided. - * @constructor */ export class FirebaseAuthError extends PrefixedFirebaseError { /** @@ -139,6 +140,7 @@ export class FirebaseAuthError extends PrefixedFirebaseError { * if not provided. * @param [rawServerResponse] The error's raw server response. * @returns The corresponding developer-facing error. + * @internal */ public static fromServerError( serverErrorCode: string, @@ -161,7 +163,7 @@ export class FirebaseAuthError extends PrefixedFirebaseError { if (clientCodeKey === 'INTERNAL_ERROR' && typeof rawServerResponse !== 'undefined') { try { - error.message += ` Raw server response: "${ JSON.stringify(rawServerResponse) }"`; + error.message += ` Raw server response: "${JSON.stringify(rawServerResponse)}"`; } catch (e) { // Ignore JSON parsing error. } @@ -170,6 +172,12 @@ export class FirebaseAuthError extends PrefixedFirebaseError { return new FirebaseAuthError(error); } + /** + * @param info - The error code info. + * @param message - The error message. This will override the default message if provided. + * @constructor + * @internal + */ constructor(info: ErrorInfo, message?: string) { // Override default message if custom message provided. super('auth', info.code, message || info.message); @@ -184,13 +192,15 @@ export class FirebaseAuthError extends PrefixedFirebaseError { /** * Firebase Database error code structure. This extends FirebaseError. - * - * @param info - The error code info. - * @param [message] The error message. This will override the default - * message if provided. - * @constructor */ export class FirebaseDatabaseError extends FirebaseError { + /** + * @param info - The error code info. + * @param message - The error message. This will override the default + * message if provided. + * @constructor + * @internal + */ constructor(info: ErrorInfo, message?: string) { // Override default message if custom message provided. super({ code: 'database/' + info.code, message: message || info.message }); @@ -199,13 +209,15 @@ export class FirebaseDatabaseError extends FirebaseError { /** * Firebase Firestore error code structure. This extends FirebaseError. - * - * @param info - The error code info. - * @param [message] The error message. This will override the default - * message if provided. - * @constructor */ export class FirebaseFirestoreError extends FirebaseError { + /** + * @param info - The error code info. + * @param message - The error message. This will override the default + * message if provided. + * @constructor + * @internal + */ constructor(info: ErrorInfo, message?: string) { // Override default message if custom message provided. super({ code: 'firestore/' + info.code, message: message || info.message }); @@ -214,13 +226,16 @@ export class FirebaseFirestoreError extends FirebaseError { /** * Firebase instance ID error code structure. This extends FirebaseError. - * - * @param info - The error code info. - * @param [message] The error message. This will override the default - * message if provided. - * @constructor */ export class FirebaseInstanceIdError extends FirebaseError { + /** + * + * @param info - The error code info. + * @param message - The error message. This will override the default + * message if provided. + * @constructor + * @internal + */ constructor(info: ErrorInfo, message?: string) { // Override default message if custom message provided. super({ code: 'instance-id/' + info.code, message: message || info.message }); @@ -230,13 +245,16 @@ export class FirebaseInstanceIdError extends FirebaseError { /** * Firebase Installations service error code structure. This extends `FirebaseError`. - * - * @param info - The error code info. - * @param message - The error message. This will override the default - * message if provided. - * @constructor */ export class FirebaseInstallationsError extends FirebaseError { + /** + * + * @param info - The error code info. + * @param message - The error message. This will override the default + * message if provided. + * @constructor + * @internal + */ constructor(info: ErrorInfo, message?: string) { // Override default message if custom message provided. super({ code: 'installations/' + info.code, message: message || info.message }); @@ -247,10 +265,6 @@ export class FirebaseInstallationsError extends FirebaseError { /** * Firebase Messaging error code structure. This extends PrefixedFirebaseError. - * - * @param info - The error code info. - * @param [message] The error message. This will override the default message if provided. - * @constructor */ export class FirebaseMessagingError extends PrefixedFirebaseError { /** @@ -261,6 +275,7 @@ export class FirebaseMessagingError extends PrefixedFirebaseError { * if not provided. * @param [rawServerResponse] The error's raw server response. * @returns The corresponding developer-facing error. + * @internal */ public static fromServerError( serverErrorCode: string | null, @@ -277,7 +292,7 @@ export class FirebaseMessagingError extends PrefixedFirebaseError { if (clientCodeKey === 'UNKNOWN_ERROR' && typeof rawServerResponse !== 'undefined') { try { - error.message += ` Raw server response: "${ JSON.stringify(rawServerResponse) }"`; + error.message += ` Raw server response: "${JSON.stringify(rawServerResponse)}"`; } catch (e) { // Ignore JSON parsing error. } @@ -286,6 +301,9 @@ export class FirebaseMessagingError extends PrefixedFirebaseError { return new FirebaseMessagingError(error); } + /** + * @internal + */ public static fromTopicManagementServerError( serverErrorCode: string, message?: string, @@ -298,7 +316,7 @@ export class FirebaseMessagingError extends PrefixedFirebaseError { if (clientCodeKey === 'UNKNOWN_ERROR' && typeof rawServerResponse !== 'undefined') { try { - error.message += ` Raw server response: "${ JSON.stringify(rawServerResponse) }"`; + error.message += ` Raw server response: "${JSON.stringify(rawServerResponse)}"`; } catch (e) { // Ignore JSON parsing error. } @@ -307,6 +325,13 @@ export class FirebaseMessagingError extends PrefixedFirebaseError { return new FirebaseMessagingError(error); } + /** + * + * @param info - The error code info. + * @param message - The error message. This will override the default message if provided. + * @constructor + * @internal + */ constructor(info: ErrorInfo, message?: string) { // Override default message if custom message provided. super('messaging', info.code, message || info.message); @@ -321,12 +346,14 @@ export class FirebaseMessagingError extends PrefixedFirebaseError { /** * Firebase project management error code structure. This extends PrefixedFirebaseError. - * - * @param code - The error code. - * @param message - The error message. - * @constructor */ export class FirebaseProjectManagementError extends PrefixedFirebaseError { + /** + * @param code - The error code. + * @param message - The error message. + * @constructor + * @internal + */ constructor(code: ProjectManagementErrorCode, message: string) { super('project-management', code, message); @@ -442,7 +469,7 @@ export class AuthClientErrorCode { public static INVALID_DYNAMIC_LINK_DOMAIN = { code: 'invalid-dynamic-link-domain', message: 'The provided dynamic link domain is not configured or authorized ' + - 'for the current project.', + 'for the current project.', }; public static INVALID_EMAIL_VERIFIED = { code: 'invalid-email-verified', @@ -467,7 +494,7 @@ export class AuthClientErrorCode { public static INVALID_HASH_ALGORITHM = { code: 'invalid-hash-algorithm', message: 'The hash algorithm must match one of the strings in the list of ' + - 'supported algorithms.', + 'supported algorithms.', }; public static INVALID_HASH_BLOCK_SIZE = { code: 'invalid-hash-block-size', @@ -590,7 +617,7 @@ export class AuthClientErrorCode { public static MISSING_ANDROID_PACKAGE_NAME = { code: 'missing-android-pkg-name', message: 'An Android Package Name must be provided if the Android App is ' + - 'required to be installed.', + 'required to be installed.', }; public static MISSING_CONFIG = { code: 'missing-config', @@ -607,7 +634,7 @@ export class AuthClientErrorCode { public static MISSING_EMAIL = { code: 'missing-email', message: 'The email is required for the specified action. For example, a multi-factor user ' + - 'requires a verified email.', + 'requires a verified email.', }; public static MISSING_IOS_BUNDLE_ID = { code: 'missing-ios-bundle-id', @@ -620,7 +647,7 @@ export class AuthClientErrorCode { public static MISSING_HASH_ALGORITHM = { code: 'missing-hash-algorithm', message: 'Importing users with password hashes requires that the hashing ' + - 'algorithm and its parameters be provided.', + 'algorithm and its parameters be provided.', }; public static MISSING_OAUTH_CLIENT_ID = { code: 'missing-oauth-client-id', @@ -653,8 +680,8 @@ export class AuthClientErrorCode { public static OPERATION_NOT_ALLOWED = { code: 'operation-not-allowed', message: 'The given sign-in provider is disabled for this Firebase project. ' + - 'Enable it in the Firebase console, under the sign-in method tab of the ' + - 'Auth section.', + 'Enable it in the Firebase console, under the sign-in method tab of the ' + + 'Auth section.', }; public static PHONE_NUMBER_ALREADY_EXISTS = { code: 'phone-number-already-exists', @@ -702,7 +729,7 @@ export class AuthClientErrorCode { public static UNAUTHORIZED_DOMAIN = { code: 'unauthorized-continue-uri', message: 'The domain of the continue URL is not whitelisted. Whitelist the domain in the ' + - 'Firebase console.', + 'Firebase console.', }; public static UNSUPPORTED_FIRST_FACTOR = { code: 'unsupported-first-factor', @@ -719,7 +746,7 @@ export class AuthClientErrorCode { public static UNVERIFIED_EMAIL = { code: 'unverified-email', message: 'A verified email is required for the specified action. For example, a multi-factor user ' + - 'requires a verified email.', + 'requires a verified email.', }; public static USER_NOT_FOUND = { code: 'user-not-found', @@ -876,15 +903,15 @@ export class InstanceIdClientErrorCode extends InstallationsClientErrorCode { } export type ProjectManagementErrorCode = - 'already-exists' - | 'authentication-error' - | 'internal-error' - | 'invalid-argument' - | 'invalid-project-id' - | 'invalid-server-response' - | 'not-found' - | 'service-unavailable' - | 'unknown-error'; + 'already-exists' + | 'authentication-error' + | 'internal-error' + | 'invalid-argument' + | 'invalid-project-id' + | 'invalid-server-response' + | 'not-found' + | 'service-unavailable' + | 'unknown-error'; /** @const {ServerToClientCode} Auth server to client enum error codes. */ const AUTH_SERVER_TO_CLIENT_CODE: ServerToClientCode = { From 5ed65e552627b15eb5830c2114da51daa0312047 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 12:32:09 -0400 Subject: [PATCH 105/323] build(deps): bump @google-cloud/firestore from 7.6.0 to 7.7.0 (#2558) Bumps [@google-cloud/firestore](https://github.com/googleapis/nodejs-firestore) from 7.6.0 to 7.7.0. - [Release notes](https://github.com/googleapis/nodejs-firestore/releases) - [Changelog](https://github.com/googleapis/nodejs-firestore/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-firestore/compare/v7.6.0...v7.7.0) --- updated-dependencies: - dependency-name: "@google-cloud/firestore" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 60 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index 317f22ae95..44f191cb8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -641,14 +641,14 @@ } }, "@google-cloud/firestore": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.6.0.tgz", - "integrity": "sha512-WUDbaLY8UnPxgwsyIaxj6uxCtSDAaUyvzWJykNH5rZ9i92/SZCsPNNMN0ajrVpAR81hPIL4amXTaMJ40y5L+Yg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.7.0.tgz", + "integrity": "sha512-41/vBFXOeSYjFI/2mJuJrDwg2umGk+FDrI/SCGzBRUe+UZWDN4GoahIbGZ19YQsY0ANNl6DRiAy4wD6JezK02g==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", - "google-gax": "^4.3.1", + "google-gax": "^4.3.3", "protobufjs": "^7.2.6" } }, @@ -706,24 +706,24 @@ } }, "@grpc/grpc-js": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.6.tgz", - "integrity": "sha512-xP58G7wDQ4TCmN/cMUHh00DS7SRDv/+lC+xFLrTkMIN8h55X5NhZMLYbvy7dSELP15qlI6hPhNCRWVMtZMwqLA==", + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.7.tgz", + "integrity": "sha512-ZMBVjSeDAz3tFSehyO6Pd08xZT1HfIwq3opbeM4cDlBh52gmwp0wVIPcQur53NN0ac68HMZ/7SF2rGRD5KmVmg==", "optional": true, "requires": { - "@grpc/proto-loader": "^0.7.10", + "@grpc/proto-loader": "^0.7.13", "@js-sdsl/ordered-map": "^4.4.2" } }, "@grpc/proto-loader": { - "version": "0.7.12", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.12.tgz", - "integrity": "sha512-DCVwMxqYzpUCiDMl7hQ384FqP4T3DbNpXU8pt681l3UWCip1WUiD5JrkImUwCB9a7f2cq4CUTmi5r/xIMRPY1Q==", + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", "optional": true, "requires": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", - "protobufjs": "^7.2.4", + "protobufjs": "^7.2.5", "yargs": "^17.7.2" } }, @@ -3911,12 +3911,12 @@ } }, "google-gax": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.2.tgz", - "integrity": "sha512-2mw7qgei2LPdtGrmd1zvxQviOcduTnsvAWYzCxhOWXK4IQKmQztHnDQwD0ApB690fBQJemFKSU7DnceAy3RLzw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.3.tgz", + "integrity": "sha512-f4F2Y9X4+mqsrJuLZsuTljYuQpcBnQsCt9ScvZpdM8jGjqrcxyJi5JUiqtq0jtpdHVPzyit0N7f5t07e+kH5EA==", "optional": true, "requires": { - "@grpc/grpc-js": "~1.10.0", + "@grpc/grpc-js": "~1.10.3", "@grpc/proto-loader": "^0.7.0", "@types/long": "^4.0.0", "abort-controller": "^3.0.0", @@ -3928,6 +3928,28 @@ "protobufjs": "7.2.6", "retry-request": "^7.0.0", "uuid": "^9.0.1" + }, + "dependencies": { + "protobufjs": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", + "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "optional": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + } + } } }, "gopd": { @@ -6775,9 +6797,9 @@ } }, "protobufjs": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", - "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.0.tgz", + "integrity": "sha512-YWD03n3shzV9ImZRX3ccbjqLxj7NokGN0V/ESiBV5xWqrommYHYiihuIyavq03pWSGqlyvYUFmfoMKd+1rPA/g==", "optional": true, "requires": { "@protobufjs/aspromise": "^1.1.2", From 26cd8b0677764b3d4da4e83a9fecb6a0390a9434 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 12:43:10 -0400 Subject: [PATCH 106/323] build(deps-dev): bump @firebase/app-compat from 0.2.32 to 0.2.33 (#2555) Bumps [@firebase/app-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/app-compat) from 0.2.32 to 0.2.33. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/master/packages/app-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/app-compat@0.2.33/packages/app-compat) --- updated-dependencies: - dependency-name: "@firebase/app-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 86 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 44f191cb8f..ed03b2473c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -431,16 +431,46 @@ } }, "@firebase/app": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.2.tgz", - "integrity": "sha512-Sk0lQYG0IRIUXkj6Ovaxu0o1E1OdC+IR+UYEYLjXuddr6YjnpFuZ69rTxVja2Ef4TpidJky9o8OoVIaXNjDJ5A==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.3.tgz", + "integrity": "sha512-+pW2wNjijh88aFRjNWhDNlVJI5vB7q1IKYEE79a7ErxwNS/Bo+oh16aAAPvunhT06EF5I8y9gAlNuHNN8u4z8g==", "dev": true, "requires": { - "@firebase/component": "0.6.6", - "@firebase/logger": "0.4.1", - "@firebase/util": "1.9.5", + "@firebase/component": "0.6.7", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.9.6", "idb": "7.1.1", "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/component": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.7.tgz", + "integrity": "sha512-baH1AA5zxfaz4O8w0vDwETByrKTQqB5CDjRls79Sa4eAGAoERw4Tnung7XbMl3jbJ4B/dmmtsMrdki0KikwDYA==", + "dev": true, + "requires": { + "@firebase/util": "1.9.6", + "tslib": "^2.1.0" + } + }, + "@firebase/logger": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", + "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.6.tgz", + "integrity": "sha512-IBr1MZbp4d5MjBCXL3TW1dK/PDXX4yOGbiwRNh1oAbE/+ci5Uuvy9KIrsFYY80as1I0iOaD5oOMA9Q8j4TJWcw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } } }, "@firebase/app-check-interop-types": { @@ -449,16 +479,46 @@ "integrity": "sha512-NILZbe6RH3X1pZmJnfOfY2gLIrlKmrkUMMrrK6VSXHcSE0eQv28xFEcw16D198i9JYZpy5Kwq394My62qCMaIw==" }, "@firebase/app-compat": { - "version": "0.2.32", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.32.tgz", - "integrity": "sha512-xxfAQKwCmpzwwdBHXT1DTnmilwSeSy6Sa1vThL0q0mq5GPHi52onkm5wl1lrOaiP0uQwQutkZBf/Wy4tDW+5WQ==", + "version": "0.2.33", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.33.tgz", + "integrity": "sha512-CLXhYJBtLuHXCUvs894gpXEXhZ7Nhytn2icLLIesH+hPLnyBeBf2CSve6Wjig+TOxTdwOQUzdtYpdjmeeYDfpw==", "dev": true, "requires": { - "@firebase/app": "0.10.2", - "@firebase/component": "0.6.6", - "@firebase/logger": "0.4.1", - "@firebase/util": "1.9.5", + "@firebase/app": "0.10.3", + "@firebase/component": "0.6.7", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.9.6", "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/component": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.7.tgz", + "integrity": "sha512-baH1AA5zxfaz4O8w0vDwETByrKTQqB5CDjRls79Sa4eAGAoERw4Tnung7XbMl3jbJ4B/dmmtsMrdki0KikwDYA==", + "dev": true, + "requires": { + "@firebase/util": "1.9.6", + "tslib": "^2.1.0" + } + }, + "@firebase/logger": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", + "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.6.tgz", + "integrity": "sha512-IBr1MZbp4d5MjBCXL3TW1dK/PDXX4yOGbiwRNh1oAbE/+ci5Uuvy9KIrsFYY80as1I0iOaD5oOMA9Q8j4TJWcw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } } }, "@firebase/app-types": { From 41aea3a7987dabc1532082cd3f5cd6cddd71a643 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 16 May 2024 16:50:53 +0000 Subject: [PATCH 107/323] chore: upgrade firestore to 7.7.0 (#2560) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4db792a913..e3a3cf4dd3 100644 --- a/package.json +++ b/package.json @@ -208,7 +208,7 @@ "uuid": "^9.0.0" }, "optionalDependencies": { - "@google-cloud/firestore": "^7.1.0", + "@google-cloud/firestore": "^7.7.0", "@google-cloud/storage": "^7.7.0" }, "devDependencies": { From f837c234d9bae1fa3eae477b51d1595a12ea7164 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 16:55:41 +0000 Subject: [PATCH 108/323] build(deps-dev): bump @microsoft/api-extractor from 7.43.2 to 7.43.7 (#2559) --- package-lock.json | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed03b2473c..0f56eb87d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -989,18 +989,18 @@ } }, "@microsoft/api-extractor": { - "version": "7.43.2", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.2.tgz", - "integrity": "sha512-5bVGdT/fHTDnBk6XPrw4I/U54LIvEeicOOTcyMtBWq387fad+m6tRk2cP/Lg9bz8+/gJgEkTVhpI8FXV4d79Ng==", + "version": "7.43.7", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.7.tgz", + "integrity": "sha512-t5M8BdnS+TmroUA/Z9HJXExS9iL4pK9I3yGu9PsXVTXPmcVXlBlA1CVI7TjRa1jwm+vusG/+sbX1/t5UkJhQMg==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.15", + "@microsoft/api-extractor-model": "7.28.17", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.2.0", + "@rushstack/node-core-library": "4.3.0", "@rushstack/rig-package": "0.5.2", - "@rushstack/terminal": "0.10.2", - "@rushstack/ts-command-line": "4.19.3", + "@rushstack/terminal": "0.11.0", + "@rushstack/ts-command-line": "4.21.0", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1016,9 +1016,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.2.0.tgz", - "integrity": "sha512-y2+m9bbkl1Xe5pt+8gouzRXtXoA2r7B2xkGDT4lpSCpiAU7HNHmhmqxOz+vTmoCamuTj1zqQbgyuoZ1z9cGdag==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.3.0.tgz", + "integrity": "sha512-JuNZ7lwaYQ4R1TugpryyWBn4lIxK+L7fF+muibFp0by5WklG22nsvH868fuBoZMLo5FqAs6WFOifNos4PJjWSA==", "dev": true, "requires": { "fs-extra": "~7.0.1", @@ -1030,12 +1030,12 @@ } }, "@rushstack/ts-command-line": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.3.tgz", - "integrity": "sha512-gWJPWIlr1VC2byK3ZfXMoPLCNT6fFk4qXAb2x2deVRJpq/LQh03galWqissit8QCOS7mOJPyM42uWmT8f4MKRg==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.21.0.tgz", + "integrity": "sha512-z38FLUCn8M9FQf19gJ9eltdwkvc47PxvJmVZS6aKwbBAa3Pis3r3A+ZcBCVPNb9h/Tbga+i0tHdzoSGUoji9GQ==", "dev": true, "requires": { - "@rushstack/terminal": "0.10.2", + "@rushstack/terminal": "0.11.0", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1059,14 +1059,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.15", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.15.tgz", - "integrity": "sha512-kAFX0c1+N+2WpZaiksy8H4RZ1sytJb2ZFVEmil5Rt6IK8UExU80f0/4kegXIs1KF8a/YyRW0Pybc7svlT9j/wQ==", + "version": "7.28.17", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.17.tgz", + "integrity": "sha512-b2AfLP33oEVtWLeNavSBRdyDa8sKlXjN4pdhBnC4HLontOtjILhL1ERAmZObF4PWSyChnnC2vjb47C9WKCFRGg==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.2.0" + "@rushstack/node-core-library": "4.3.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1076,9 +1076,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.2.0.tgz", - "integrity": "sha512-y2+m9bbkl1Xe5pt+8gouzRXtXoA2r7B2xkGDT4lpSCpiAU7HNHmhmqxOz+vTmoCamuTj1zqQbgyuoZ1z9cGdag==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.3.0.tgz", + "integrity": "sha512-JuNZ7lwaYQ4R1TugpryyWBn4lIxK+L7fF+muibFp0by5WklG22nsvH868fuBoZMLo5FqAs6WFOifNos4PJjWSA==", "dev": true, "requires": { "fs-extra": "~7.0.1", @@ -1277,19 +1277,19 @@ } }, "@rushstack/terminal": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.2.tgz", - "integrity": "sha512-oMN4uoz6WUeLR9yWHSR4gEEii+8vjIJXPLp7U0k6zccgmOCJXYPKBK30FGpWfDRmqrcCIJi828SKV9V5FB1a0Q==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.11.0.tgz", + "integrity": "sha512-LKz7pv0G9Py5uULahNSixK1pTqIIKd103pAGhDW51YfzPojvmO5wfITe0PEUNAJZjuufN/KgeRW83dJo1gL2rQ==", "dev": true, "requires": { - "@rushstack/node-core-library": "4.2.0", + "@rushstack/node-core-library": "4.3.0", "supports-color": "~8.1.1" }, "dependencies": { "@rushstack/node-core-library": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.2.0.tgz", - "integrity": "sha512-y2+m9bbkl1Xe5pt+8gouzRXtXoA2r7B2xkGDT4lpSCpiAU7HNHmhmqxOz+vTmoCamuTj1zqQbgyuoZ1z9cGdag==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.3.0.tgz", + "integrity": "sha512-JuNZ7lwaYQ4R1TugpryyWBn4lIxK+L7fF+muibFp0by5WklG22nsvH868fuBoZMLo5FqAs6WFOifNos4PJjWSA==", "dev": true, "requires": { "fs-extra": "~7.0.1", From ee78c8731c6a63d6d105623fb04f9f82d0ec1d5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 17:00:41 +0000 Subject: [PATCH 109/323] build(deps-dev): bump @firebase/auth-types from 0.12.1 to 0.12.2 (#2556) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f56eb87d1..ef48210506 100644 --- a/package-lock.json +++ b/package-lock.json @@ -634,9 +634,9 @@ "integrity": "sha512-k3NA28Jfoo0+o391bFjoV9X5QLnUL1WbLhZZRbTQhZdmdGYJfX8ixtNNlHsYQ94bwG0QRbsmvkzDnzuhHrV11w==" }, "@firebase/auth-types": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.1.tgz", - "integrity": "sha512-B3dhiWRWf/njWosx4zdhSEoD4WHJmr4zbnBw6t20mRG/IZ4u0rWUBlMP1vFjhMstKIow1XmoGhTwD65X5ZXLjw==", + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", + "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", "dev": true }, "@firebase/component": { From f8f8eb95ba90c4cb29cc4e52e0b6c31e615c21a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 10:34:12 -0400 Subject: [PATCH 110/323] --- (#2569) updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ef48210506..b248a26f9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1514,9 +1514,9 @@ } }, "@types/lodash": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.1.tgz", - "integrity": "sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==", + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ==", "dev": true }, "@types/long": { From 8f622cf24401cd404c078245e3b281702087c892 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 15:11:26 +0000 Subject: [PATCH 111/323] --- (#2567) --- package-lock.json | 20 ++++++++++---------- package.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index b248a26f9c..bf586b49a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6019,9 +6019,9 @@ "dev": true }, "nise": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", - "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", + "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0", @@ -7529,17 +7529,17 @@ } }, "sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", + "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", "dev": true, "requires": { - "@sinonjs/commons": "^3.0.0", + "@sinonjs/commons": "^3.0.1", "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" }, "dependencies": { "diff": { diff --git a/package.json b/package.json index e3a3cf4dd3..2b618f30b6 100644 --- a/package.json +++ b/package.json @@ -257,7 +257,7 @@ "request": "^2.75.0", "request-promise": "^4.1.1", "run-sequence": "^2.2.1", - "sinon": "^17.0.1", + "sinon": "^18.0.0", "sinon-chai": "^3.0.0", "ts-node": "^10.2.0", "typescript": "5.1.6", From 72f0169682c416b573defd3aab9b68290ab75b06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 13:38:10 -0400 Subject: [PATCH 112/323] --- (#2566) updated-dependencies: - dependency-name: "@firebase/app-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index bf586b49a9..90cf0fe0cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -431,9 +431,9 @@ } }, "@firebase/app": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.3.tgz", - "integrity": "sha512-+pW2wNjijh88aFRjNWhDNlVJI5vB7q1IKYEE79a7ErxwNS/Bo+oh16aAAPvunhT06EF5I8y9gAlNuHNN8u4z8g==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.4.tgz", + "integrity": "sha512-oKd5cT+fDbQ22X8Am3tBOrSFdDp8n4NJDqld4uo+H/PL9F+D3ogtTeiPyDWw1lZK7FsMbmtRrPRozlmJFzSKAQ==", "dev": true, "requires": { "@firebase/component": "0.6.7", @@ -479,12 +479,12 @@ "integrity": "sha512-NILZbe6RH3X1pZmJnfOfY2gLIrlKmrkUMMrrK6VSXHcSE0eQv28xFEcw16D198i9JYZpy5Kwq394My62qCMaIw==" }, "@firebase/app-compat": { - "version": "0.2.33", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.33.tgz", - "integrity": "sha512-CLXhYJBtLuHXCUvs894gpXEXhZ7Nhytn2icLLIesH+hPLnyBeBf2CSve6Wjig+TOxTdwOQUzdtYpdjmeeYDfpw==", + "version": "0.2.34", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.34.tgz", + "integrity": "sha512-enteBla1gBYObauvsC9bRRoqHZnOW48ahYABZ+l+FEiWil1rw0gVihl8D4eLqtQp/ci8+fbOBf3ZL19uFq/OCw==", "dev": true, "requires": { - "@firebase/app": "0.10.3", + "@firebase/app": "0.10.4", "@firebase/component": "0.6.7", "@firebase/logger": "0.4.2", "@firebase/util": "1.9.6", From 1754b7ed09e16e61f481dd242def9ad25357aa3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 17:44:07 +0000 Subject: [PATCH 113/323] --- (#2568) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 90cf0fe0cf..82ab704853 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1558,9 +1558,9 @@ } }, "@types/node": { - "version": "20.12.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.10.tgz", - "integrity": "sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "requires": { "undici-types": "~5.26.4" } From 4d4fd39dc0dd13f6d4ebed16efeca053ed4d9b14 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 21 May 2024 18:09:42 +0000 Subject: [PATCH 114/323] build(deps): updgrade jwks-rsa (#2570) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b618f30b6..f2f3938e0f 100644 --- a/package.json +++ b/package.json @@ -202,7 +202,7 @@ "@types/node": "^20.10.3", "farmhash": "^3.3.1", "jsonwebtoken": "^9.0.0", - "jwks-rsa": "^3.0.1", + "jwks-rsa": "^3.1.0", "long": "^5.2.3", "node-forge": "^1.3.1", "uuid": "^9.0.0" From e2515f2b993718b26ac3b497154f73ff4e538c41 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 21 May 2024 18:34:37 +0000 Subject: [PATCH 115/323] [chore] Release 12.1.1 (#2561) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f2f3938e0f..5e73bf3f5b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.1.0", + "version": "12.1.1", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 266adc7ec3c20754ab5125e92a6cbcf17568f152 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 15:20:44 -0400 Subject: [PATCH 116/323] build(deps): bump @google-cloud/storage from 7.11.0 to 7.11.1 (#2579) Bumps [@google-cloud/storage](https://github.com/googleapis/nodejs-storage) from 7.11.0 to 7.11.1. - [Release notes](https://github.com/googleapis/nodejs-storage/releases) - [Changelog](https://github.com/googleapis/nodejs-storage/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-storage/compare/v7.11.0...v7.11.1) --- updated-dependencies: - dependency-name: "@google-cloud/storage" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 82ab704853..ec31811319 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.1.0", + "version": "12.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -713,9 +713,9 @@ } }, "@google-cloud/paginator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.0.tgz", - "integrity": "sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", "optional": true, "requires": { "arrify": "^2.0.0", @@ -735,9 +735,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.11.0.tgz", - "integrity": "sha512-W+OPOCgq7a3aAMANALbJAlEnpMV9fy681JWIm7dYe5W/+nRhq/UvA477TJT5/oPNA5DgiAdMEdiitdoLpZqhJg==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.11.1.tgz", + "integrity": "sha512-tibLSvgw7nDohMyIelt26kBpJ59YGWA2Rzep++DFNzEzKaSuCSp56Se9iM13ZlM3j5nLzR21IBkpRN58CmvCIw==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", @@ -3368,9 +3368,9 @@ "dev": true }, "fast-xml-parser": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz", - "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", + "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", "optional": true, "requires": { "strnum": "^1.0.5" From 59928064bca5ebf8af07ad8604e223f32fba1b69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 19:26:02 +0000 Subject: [PATCH 117/323] build(deps-dev): bump chai-as-promised from 7.1.1 to 7.1.2 (#2578) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ec31811319..336e477f1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2395,9 +2395,9 @@ } }, "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", "dev": true, "requires": { "check-error": "^1.0.2" From fc43337cc0e69d6d6b95b89b1db73f1f603dc1ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 May 2024 19:32:01 +0000 Subject: [PATCH 118/323] build(deps-dev): bump @firebase/app-compat from 0.2.34 to 0.2.35 (#2575) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 336e477f1c..bb108fcfb5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -431,9 +431,9 @@ } }, "@firebase/app": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.4.tgz", - "integrity": "sha512-oKd5cT+fDbQ22X8Am3tBOrSFdDp8n4NJDqld4uo+H/PL9F+D3ogtTeiPyDWw1lZK7FsMbmtRrPRozlmJFzSKAQ==", + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.5.tgz", + "integrity": "sha512-iY/fNot+hWPk9sTX8aHMqlcX9ynRvpGkskWAdUZ2eQQdLo8d1hSFYcYNwPv0Q/frGMasw8udKWMcFOEpC9fG8g==", "dev": true, "requires": { "@firebase/component": "0.6.7", @@ -479,12 +479,12 @@ "integrity": "sha512-NILZbe6RH3X1pZmJnfOfY2gLIrlKmrkUMMrrK6VSXHcSE0eQv28xFEcw16D198i9JYZpy5Kwq394My62qCMaIw==" }, "@firebase/app-compat": { - "version": "0.2.34", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.34.tgz", - "integrity": "sha512-enteBla1gBYObauvsC9bRRoqHZnOW48ahYABZ+l+FEiWil1rw0gVihl8D4eLqtQp/ci8+fbOBf3ZL19uFq/OCw==", + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.35.tgz", + "integrity": "sha512-vgay/WRjeH0r97/Q6L6df2CMx7oyNFDsE5yPQ9oR1G+zx2eT0s8vNNh0WlKqQxUEWaOLRnXhQ8gy7uu0cBgTRg==", "dev": true, "requires": { - "@firebase/app": "0.10.4", + "@firebase/app": "0.10.5", "@firebase/component": "0.6.7", "@firebase/logger": "0.4.2", "@firebase/util": "1.9.6", From d65e68f4633085a28b6c10387d2c4c8f900b6db8 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 28 May 2024 20:00:48 +0000 Subject: [PATCH 119/323] change: Deprecate Node.js 16 support (#2574) * change: Deprecate Node versions that reached EoL * change expected error to regex * update readme.md * update readme.md --- .github/workflows/ci.yml | 2 +- README.md | 4 ++-- test/unit/app/firebase-app.spec.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4fb651cc4..cf3a257871 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x] + node-version: [14.x, 16.x, 18.x, 20.x, 22.x] steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 2d466926a7..4eafa48814 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,8 @@ requests, code review feedback, and also pull requests. ## Supported Environments -We support Node.js 14 and higher. However, Node.js 14 support is deprecated. We strongly encourage -you to use Node.js 16 or higher as we will drop support for Node.js 14 in the next major version. +We support Node.js 14 and higher. However, Node.js 14 and 16 support is deprecated. We strongly encourage +you to use Node.js 18 or higher as we will drop support for Node.js 14 and 16 in the next major version. Please also note that the Admin SDK should only be used in server-side/back-end environments controlled by the app developer. diff --git a/test/unit/app/firebase-app.spec.ts b/test/unit/app/firebase-app.spec.ts index 31301b2b1f..2211f4f457 100644 --- a/test/unit/app/firebase-app.spec.ts +++ b/test/unit/app/firebase-app.spec.ts @@ -182,7 +182,7 @@ describe('FirebaseApp', () => { process.env[FIREBASE_CONFIG_VAR] = '{,,'; expect(() => { firebaseNamespace.initializeApp(); - }).to.throw('Failed to parse app options file: SyntaxError: Unexpected token ,'); + }).to.throw(/Failed to parse app options file: SyntaxError:/); }); it('should throw when the environment variable points to an empty file', () => { From 2efcec97608ca6b07e961c203f66983c398a1ded Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 29 May 2024 18:20:04 +0000 Subject: [PATCH 120/323] fix: Use optional chaining in FirebaseError (#2581) --- src/utils/error.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/error.ts b/src/utils/error.ts index 772d808a9a..ef56431a03 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -54,12 +54,12 @@ export class FirebaseError extends Error implements FirebaseErrorInterface { /** @returns The error code. */ public get code(): string { - return this.errorInfo.code; + return this.errorInfo?.code; } /** @returns The error message. */ public get message(): string { - return this.errorInfo.message; + return this.errorInfo?.message; } /** @returns The object representation of the error. */ From 07cfca83d8efebbe9cfcbbf78cbe2c2405256a71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 15:33:41 -0400 Subject: [PATCH 121/323] build(deps): bump @types/node from 20.12.12 to 20.14.0 (#2585) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.12 to 20.14.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb108fcfb5..fdda4c054b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1558,9 +1558,9 @@ } }, "@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "version": "20.14.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.0.tgz", + "integrity": "sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==", "requires": { "undici-types": "~5.26.4" } From 4070f5bf41f83368ec8f7c4f3136a25dfcdf3e03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 19:39:00 +0000 Subject: [PATCH 122/323] build(deps): bump @google-cloud/firestore from 7.7.0 to 7.8.0 (#2583) --- package-lock.json | 48 +++++++++++++---------------------------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index fdda4c054b..66a1522ea1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -701,9 +701,9 @@ } }, "@google-cloud/firestore": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.7.0.tgz", - "integrity": "sha512-41/vBFXOeSYjFI/2mJuJrDwg2umGk+FDrI/SCGzBRUe+UZWDN4GoahIbGZ19YQsY0ANNl6DRiAy4wD6JezK02g==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.8.0.tgz", + "integrity": "sha512-m21BWVZLz7H7NF8HZ5hCGUSCEJKNwYB5yzQqDTuE9YUzNDRMDei3BwVDht5k4xF636sGlnobyBL+dcbthSGONg==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -766,9 +766,9 @@ } }, "@grpc/grpc-js": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.7.tgz", - "integrity": "sha512-ZMBVjSeDAz3tFSehyO6Pd08xZT1HfIwq3opbeM4cDlBh52gmwp0wVIPcQur53NN0ac68HMZ/7SF2rGRD5KmVmg==", + "version": "1.10.8", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.8.tgz", + "integrity": "sha512-vYVqYzHicDqyKB+NQhAc54I1QWCBLCrYG6unqOIcBTHx+7x8C9lcoLj3KVJXs2VB4lUbpWY+Kk9NipcbXYWmvg==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.13", @@ -3971,9 +3971,9 @@ } }, "google-gax": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.3.tgz", - "integrity": "sha512-f4F2Y9X4+mqsrJuLZsuTljYuQpcBnQsCt9ScvZpdM8jGjqrcxyJi5JUiqtq0jtpdHVPzyit0N7f5t07e+kH5EA==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.5.tgz", + "integrity": "sha512-zXRSGgHp33ottCQMdYlKEFX/MhWkzKVX5P3Vpmx+DW6rtseLILzp3V0YV5Rh4oQzzkM0BH9+nJIyX01EUgmd3g==", "optional": true, "requires": { "@grpc/grpc-js": "~1.10.3", @@ -3985,31 +3985,9 @@ "node-fetch": "^2.6.1", "object-hash": "^3.0.0", "proto3-json-serializer": "^2.0.0", - "protobufjs": "7.2.6", + "protobufjs": "7.3.0", "retry-request": "^7.0.0", "uuid": "^9.0.1" - }, - "dependencies": { - "protobufjs": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.6.tgz", - "integrity": "sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - } - } } }, "gopd": { @@ -6848,9 +6826,9 @@ "dev": true }, "proto3-json-serializer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.1.tgz", - "integrity": "sha512-8awBvjO+FwkMd6gNoGFZyqkHZXCFd54CIYTb6De7dPaufGJ2XNW+QUNqbMr8MaAocMdb+KpsD4rxEOaTBDCffA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", "optional": true, "requires": { "protobufjs": "^7.2.5" From 5f01f63da541cea8ca4ce1f67c5050615a9fb06a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 11:09:53 -0400 Subject: [PATCH 123/323] build(deps-dev): bump @types/lodash from 4.17.4 to 4.17.5 (#2594) Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.4 to 4.17.5. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 66a1522ea1..c2a8d3e6bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1514,9 +1514,9 @@ } }, "@types/lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ==", + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", "dev": true }, "@types/long": { From 54405804a868f6e247a59c7f713382bb1a268887 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:13:57 +0000 Subject: [PATCH 124/323] build(deps): bump @grpc/grpc-js from 1.10.8 to 1.10.9 (#2592) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2a8d3e6bc..de47178580 100644 --- a/package-lock.json +++ b/package-lock.json @@ -766,9 +766,9 @@ } }, "@grpc/grpc-js": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.8.tgz", - "integrity": "sha512-vYVqYzHicDqyKB+NQhAc54I1QWCBLCrYG6unqOIcBTHx+7x8C9lcoLj3KVJXs2VB4lUbpWY+Kk9NipcbXYWmvg==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz", + "integrity": "sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.13", From 07855bfd77d378d7558f091173abf97e1e8115fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:18:04 +0000 Subject: [PATCH 125/323] build(deps-dev): bump braces from 3.0.2 to 3.0.3 (#2595) --- package-lock.json | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index de47178580..6e065350eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2278,12 +2278,23 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" + }, + "dependencies": { + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + } } }, "browser-stdout": { @@ -3414,15 +3425,6 @@ "flat-cache": "^3.0.4" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", From fdde8c3a6f67c23830746065b8467e7bbe42e3df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:22:24 +0000 Subject: [PATCH 126/323] build(deps-dev): bump chai-exclude from 2.1.0 to 2.1.1 (#2593) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6e065350eb..b4ce182654 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2415,9 +2415,9 @@ } }, "chai-exclude": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chai-exclude/-/chai-exclude-2.1.0.tgz", - "integrity": "sha512-IBnm50Mvl3O1YhPpTgbU8MK0Gw7NHcb18WT2TxGdPKOMtdtZVKLHmQwdvOF7mTlHVQStbXuZKFwkevFtbHjpVg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chai-exclude/-/chai-exclude-2.1.1.tgz", + "integrity": "sha512-IHgNmgAFOkyRPnmOtZio9UsOHQ6RnzVr2LOs+5V9urYYqjhV/ERLQapC0Eq2DmID5eDWyngAcBxNUm0ZK0QbrQ==", "dev": true, "requires": { "fclone": "^1.0.11" From 5f0f25330110eb55d077ecc375b8f5afdabb408a Mon Sep 17 00:00:00 2001 From: Rafael Fox <20726634+foxrafa@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:40:16 -0300 Subject: [PATCH 127/323] fix: Make ADC + human account work with firebase-admin (#2553) * Make ADC + human account work with firebase-admin * Update api-request.ts * fix unit tests --------- Co-authored-by: Lahiru Maramba --- src/utils/api-request.ts | 6 ++++++ test/unit/app-check/app-check-api-client-internal.spec.ts | 1 + test/unit/functions/functions-api-client-internal.spec.ts | 3 ++- .../machine-learning/machine-learning-api-client.spec.ts | 1 + test/unit/remote-config/remote-config-api-client.spec.ts | 1 + test/unit/security-rules/security-rules-api-client.spec.ts | 1 + 6 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index 2408e92344..5d1b9ecf4c 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -818,6 +818,12 @@ export class AuthorizedHttpClient extends HttpClient { const authHeader = 'Authorization'; requestCopy.headers[authHeader] = `Bearer ${token}`; + // Fix issue where firebase-admin does not specify quota project that is + // necessary for use when utilizing human account with ADC (RSDF) + if (!requestCopy.headers['x-goog-user-project'] && this.app.options.projectId) { + requestCopy.headers['x-goog-user-project'] = this.app.options.projectId + } + if (!requestCopy.httpAgent && this.app.options.httpAgent) { requestCopy.httpAgent = this.app.options.httpAgent; } diff --git a/test/unit/app-check/app-check-api-client-internal.spec.ts b/test/unit/app-check/app-check-api-client-internal.spec.ts index bd048bd9e4..e5a483d91c 100644 --- a/test/unit/app-check/app-check-api-client-internal.spec.ts +++ b/test/unit/app-check/app-check-api-client-internal.spec.ts @@ -45,6 +45,7 @@ describe('AppCheckApiClient', () => { const EXPECTED_HEADERS = { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'x-goog-user-project': 'test-project', }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' diff --git a/test/unit/functions/functions-api-client-internal.spec.ts b/test/unit/functions/functions-api-client-internal.spec.ts index 138280f287..f000d21c0a 100644 --- a/test/unit/functions/functions-api-client-internal.spec.ts +++ b/test/unit/functions/functions-api-client-internal.spec.ts @@ -44,7 +44,8 @@ describe('FunctionsApiClient', () => { const EXPECTED_HEADERS = { 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'Authorization': 'Bearer mock-token' + 'Authorization': 'Bearer mock-token', + 'x-goog-user-project': 'test-project', }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' diff --git a/test/unit/machine-learning/machine-learning-api-client.spec.ts b/test/unit/machine-learning/machine-learning-api-client.spec.ts index 9fbb94066e..4d6873d200 100644 --- a/test/unit/machine-learning/machine-learning-api-client.spec.ts +++ b/test/unit/machine-learning/machine-learning-api-client.spec.ts @@ -117,6 +117,7 @@ describe('MachineLearningApiClient', () => { const EXPECTED_HEADERS = { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'x-goog-user-project': 'test-project', }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' + 'account credentials, or set project ID as an app option. Alternatively, set the ' diff --git a/test/unit/remote-config/remote-config-api-client.spec.ts b/test/unit/remote-config/remote-config-api-client.spec.ts index 52abb968c1..fa464c089a 100644 --- a/test/unit/remote-config/remote-config-api-client.spec.ts +++ b/test/unit/remote-config/remote-config-api-client.spec.ts @@ -57,6 +57,7 @@ describe('RemoteConfigApiClient', () => { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'Accept-Encoding': 'gzip', + 'x-goog-user-project': 'test-project', }; const VERSION_INFO: Version = { diff --git a/test/unit/security-rules/security-rules-api-client.spec.ts b/test/unit/security-rules/security-rules-api-client.spec.ts index 512bcc9a20..d4139fdb34 100644 --- a/test/unit/security-rules/security-rules-api-client.spec.ts +++ b/test/unit/security-rules/security-rules-api-client.spec.ts @@ -44,6 +44,7 @@ describe('SecurityRulesApiClient', () => { const EXPECTED_HEADERS = { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'x-goog-user-project': 'test-project', }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' + 'account credentials, or set project ID as an app option. Alternatively, set the ' From b890182e73d8f112ef2ad807e27f067fca24ee31 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 19 Jun 2024 17:36:58 +0000 Subject: [PATCH 128/323] fix: Replace `farmhash` with `farmhash-modern` (#2603) * fix: Replace farmhash with farmhash-modern * skip rc farmhash tests on node14 --- package-lock.json | 1150 ++++++++--------- package.json | 2 +- .../condition-evaluator-internal.ts | 4 +- .../remote-config/condition-evaluator.spec.ts | 90 +- 4 files changed, 583 insertions(+), 663 deletions(-) diff --git a/package-lock.json b/package-lock.json index b4ce182654..383ad46596 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,12 +4,6 @@ "lockfileVersion": 1, "requires": true, "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, "@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -21,37 +15,37 @@ } }, "@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "requires": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", - "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", "dev": true }, "@babel/core": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", - "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.4", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.4", - "@babel/parser": "^7.24.4", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -68,25 +62,25 @@ } }, "@babel/generator": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", - "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dev": true, "requires": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.24.7", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" } }, "@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", "dev": true, "requires": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -116,106 +110,110 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "requires": { + "@babel/types": "^7.24.7" + } }, "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" } }, "@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, "requires": { - "@babel/types": "^7.24.0" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" } }, "@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" } }, "@babel/helper-string-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", - "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", "dev": true }, "@babel/helpers": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz", - "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", "dev": true, "requires": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -280,36 +278,36 @@ } }, "@babel/parser": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", - "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "dev": true }, "@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" } }, "@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -323,13 +321,13 @@ } }, "@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" } }, @@ -364,9 +362,9 @@ } }, "@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", "dev": true }, "@eslint/eslintrc": { @@ -386,6 +384,24 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -394,12 +410,6 @@ "requires": { "brace-expansion": "^1.1.7" } - }, - "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 } } }, @@ -441,42 +451,12 @@ "@firebase/util": "1.9.6", "idb": "7.1.1", "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/component": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.7.tgz", - "integrity": "sha512-baH1AA5zxfaz4O8w0vDwETByrKTQqB5CDjRls79Sa4eAGAoERw4Tnung7XbMl3jbJ4B/dmmtsMrdki0KikwDYA==", - "dev": true, - "requires": { - "@firebase/util": "1.9.6", - "tslib": "^2.1.0" - } - }, - "@firebase/logger": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", - "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.9.6", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.6.tgz", - "integrity": "sha512-IBr1MZbp4d5MjBCXL3TW1dK/PDXX4yOGbiwRNh1oAbE/+ci5Uuvy9KIrsFYY80as1I0iOaD5oOMA9Q8j4TJWcw==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - } } }, "@firebase/app-check-interop-types": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.1.tgz", - "integrity": "sha512-NILZbe6RH3X1pZmJnfOfY2gLIrlKmrkUMMrrK6VSXHcSE0eQv28xFEcw16D198i9JYZpy5Kwq394My62qCMaIw==" + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz", + "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "@firebase/app-compat": { "version": "0.2.35", @@ -489,42 +469,12 @@ "@firebase/logger": "0.4.2", "@firebase/util": "1.9.6", "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/component": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.7.tgz", - "integrity": "sha512-baH1AA5zxfaz4O8w0vDwETByrKTQqB5CDjRls79Sa4eAGAoERw4Tnung7XbMl3jbJ4B/dmmtsMrdki0KikwDYA==", - "dev": true, - "requires": { - "@firebase/util": "1.9.6", - "tslib": "^2.1.0" - } - }, - "@firebase/logger": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", - "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.9.6", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.6.tgz", - "integrity": "sha512-IBr1MZbp4d5MjBCXL3TW1dK/PDXX4yOGbiwRNh1oAbE/+ci5Uuvy9KIrsFYY80as1I0iOaD5oOMA9Q8j4TJWcw==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - } } }, "@firebase/app-types": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.1.tgz", - "integrity": "sha512-nFGqTYsnDFn1oXf1tCwPAc+hQPxyvBT/QB7qDjwK+IDYThOn63nGhzdUTXxVD9Ca8gUY/e5PQMngeo0ZW/E3uQ==" + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", + "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==" }, "@firebase/auth": { "version": "1.4.0", @@ -629,9 +579,9 @@ } }, "@firebase/auth-interop-types": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.2.tgz", - "integrity": "sha512-k3NA28Jfoo0+o391bFjoV9X5QLnUL1WbLhZZRbTQhZdmdGYJfX8ixtNNlHsYQ94bwG0QRbsmvkzDnzuhHrV11w==" + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", + "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==" }, "@firebase/auth-types": { "version": "0.12.2", @@ -640,62 +590,62 @@ "dev": true }, "@firebase/component": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.6.tgz", - "integrity": "sha512-pp7sWqHmAAlA3os6ERgoM3k5Cxff510M9RLXZ9Mc8KFKMBc2ct3RkZTWUF7ixJNvMiK/iNgRLPDrLR2gtRJ9iQ==", + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.7.tgz", + "integrity": "sha512-baH1AA5zxfaz4O8w0vDwETByrKTQqB5CDjRls79Sa4eAGAoERw4Tnung7XbMl3jbJ4B/dmmtsMrdki0KikwDYA==", "requires": { - "@firebase/util": "1.9.5", + "@firebase/util": "1.9.6", "tslib": "^2.1.0" } }, "@firebase/database": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.4.tgz", - "integrity": "sha512-k84cXh+dtpzvY6yOhfyr1B+I1vjvSMtmlqotE0lTNVylc8m5nmOohjzpTLEQDrBWvwACX/VP5fEyajAdmnOKqA==", - "requires": { - "@firebase/app-check-interop-types": "0.3.1", - "@firebase/auth-interop-types": "0.2.2", - "@firebase/component": "0.6.6", - "@firebase/logger": "0.4.1", - "@firebase/util": "1.9.5", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.5.tgz", + "integrity": "sha512-cAfwBqMQuW6HbhwI3Cb/gDqZg7aR0OmaJ85WUxlnoYW2Tm4eR0hFl5FEijI3/gYPUiUcUPQvTkGV222VkT7KPw==", + "requires": { + "@firebase/app-check-interop-types": "0.3.2", + "@firebase/auth-interop-types": "0.2.3", + "@firebase/component": "0.6.7", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.9.6", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "@firebase/database-compat": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.4.tgz", - "integrity": "sha512-GEEDAvsSMAkqy0BIFSVtFzoOIIcKHFfDM4aXHtWL/JCaNn4OOjH7td73jDfN3ALvpIN4hQki0FcxQ89XjqaTjQ==", - "requires": { - "@firebase/component": "0.6.6", - "@firebase/database": "1.0.4", - "@firebase/database-types": "1.0.2", - "@firebase/logger": "0.4.1", - "@firebase/util": "1.9.5", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.5.tgz", + "integrity": "sha512-NDSMaDjQ+TZEMDMmzJwlTL05kh1+0Y84C+kVMaOmNOzRGRM7VHi29I6YUhCetXH+/b1Wh4ZZRyp1CuWkd8s6hg==", + "requires": { + "@firebase/component": "0.6.7", + "@firebase/database": "1.0.5", + "@firebase/database-types": "1.0.3", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.9.6", "tslib": "^2.1.0" } }, "@firebase/database-types": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.2.tgz", - "integrity": "sha512-JRigr5JNLEHqOkI99tAGHDZF47469/cJz1tRAgGs8Feh+3ZmQy/vVChSqwMp2DuVUGp9PlmGsNSlpINJ/hDuIA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.3.tgz", + "integrity": "sha512-39V/Riv2R3O/aUjYKh0xypj7NTNXNAK1bcgY5Kx+hdQPRS/aPTS8/5c0CGFYKgVuFbYlnlnhrCTYsh2uNhGwzA==", "requires": { - "@firebase/app-types": "0.9.1", - "@firebase/util": "1.9.5" + "@firebase/app-types": "0.9.2", + "@firebase/util": "1.9.6" } }, "@firebase/logger": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.1.tgz", - "integrity": "sha512-tTIixB5UJbG9ZHSGZSZdX7THr3KWOLrejZ9B7jYsm6fpwgRNngKznQKA2wgYVyvBc1ta7dGFh9NtJ8n7qfiYIw==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", + "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", "requires": { "tslib": "^2.1.0" } }, "@firebase/util": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.5.tgz", - "integrity": "sha512-PP4pAFISDxsf70l3pEy34Mf3GkkUcVQ3MdKp6aSVb7tcpfUQxnsdV7twDd8EkfB6zZylH6wpUAoangQDmCUMqw==", + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.6.tgz", + "integrity": "sha512-IBr1MZbp4d5MjBCXL3TW1dK/PDXX4yOGbiwRNh1oAbE/+ci5Uuvy9KIrsFYY80as1I0iOaD5oOMA9Q8j4TJWcw==", "requires": { "tslib": "^2.1.0" } @@ -735,9 +685,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.11.1.tgz", - "integrity": "sha512-tibLSvgw7nDohMyIelt26kBpJ59YGWA2Rzep++DFNzEzKaSuCSp56Se9iM13ZlM3j5nLzR21IBkpRN58CmvCIw==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.11.2.tgz", + "integrity": "sha512-jJOrKyOdujfrSF8EJODW9yY6hqO4jSTk6eVITEj2gsD43BSXuDlnMlLOaBUQhXL29VGnSkxDgYl5tlFhA6LKSA==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", @@ -989,18 +939,18 @@ } }, "@microsoft/api-extractor": { - "version": "7.43.7", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.7.tgz", - "integrity": "sha512-t5M8BdnS+TmroUA/Z9HJXExS9iL4pK9I3yGu9PsXVTXPmcVXlBlA1CVI7TjRa1jwm+vusG/+sbX1/t5UkJhQMg==", + "version": "7.47.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.0.tgz", + "integrity": "sha512-LT8yvcWNf76EpDC+8/ArTVSYePvuDQ+YbAUrsTcpg3ptiZ93HIcMCozP/JOxDt+rrsFfFHcpfoselKfPyRI0GQ==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.28.17", - "@microsoft/tsdoc": "0.14.2", - "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.3.0", + "@microsoft/api-extractor-model": "7.29.2", + "@microsoft/tsdoc": "~0.15.0", + "@microsoft/tsdoc-config": "~0.17.0", + "@rushstack/node-core-library": "5.4.1", "@rushstack/rig-package": "0.5.2", - "@rushstack/terminal": "0.11.0", - "@rushstack/ts-command-line": "4.21.0", + "@rushstack/terminal": "0.13.0", + "@rushstack/ts-command-line": "4.22.0", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1010,37 +960,51 @@ }, "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==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", "dev": true }, "@rushstack/node-core-library": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.3.0.tgz", - "integrity": "sha512-JuNZ7lwaYQ4R1TugpryyWBn4lIxK+L7fF+muibFp0by5WklG22nsvH868fuBoZMLo5FqAs6WFOifNos4PJjWSA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.4.1.tgz", + "integrity": "sha512-WNnwdS8r9NZ/2K3u29tNoSRldscFa7SxU0RT+82B6Dy2I4Hl2MeCSKm4EXLXPKeNzLGvJ1cqbUhTLviSF8E6iA==", "dev": true, "requires": { + "ajv": "~8.13.0", + "ajv-draft-04": "~1.0.0", + "ajv-formats": "~3.0.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" + "semver": "~7.5.4" } }, "@rushstack/ts-command-line": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.21.0.tgz", - "integrity": "sha512-z38FLUCn8M9FQf19gJ9eltdwkvc47PxvJmVZS6aKwbBAa3Pis3r3A+ZcBCVPNb9h/Tbga+i0tHdzoSGUoji9GQ==", + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.0.tgz", + "integrity": "sha512-Qj28t6MO3HRgAZ72FDeFsrpdE6wBWxF3VENgvrXh7JF2qIT+CrXiOJIesW80VFZB9QwObSpkB1ilx794fGQg6g==", "dev": true, "requires": { - "@rushstack/terminal": "0.11.0", + "@rushstack/terminal": "0.13.0", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" } }, + "ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + } + }, "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -1059,34 +1023,48 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.28.17", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.17.tgz", - "integrity": "sha512-b2AfLP33oEVtWLeNavSBRdyDa8sKlXjN4pdhBnC4HLontOtjILhL1ERAmZObF4PWSyChnnC2vjb47C9WKCFRGg==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.2.tgz", + "integrity": "sha512-hAYajOjQan3uslhKJRwvvHIdLJ+ZByKqdSsJ/dgHFxPtEbdKpzMDO8zuW4K5gkSMYl5D0LbNwxkhxr51P2zsmw==", "dev": true, "requires": { - "@microsoft/tsdoc": "0.14.2", - "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.3.0" + "@microsoft/tsdoc": "~0.15.0", + "@microsoft/tsdoc-config": "~0.17.0", + "@rushstack/node-core-library": "5.4.1" }, "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==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", "dev": true }, "@rushstack/node-core-library": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.3.0.tgz", - "integrity": "sha512-JuNZ7lwaYQ4R1TugpryyWBn4lIxK+L7fF+muibFp0by5WklG22nsvH868fuBoZMLo5FqAs6WFOifNos4PJjWSA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.4.1.tgz", + "integrity": "sha512-WNnwdS8r9NZ/2K3u29tNoSRldscFa7SxU0RT+82B6Dy2I4Hl2MeCSKm4EXLXPKeNzLGvJ1cqbUhTLviSF8E6iA==", "dev": true, "requires": { + "ajv": "~8.13.0", + "ajv-draft-04": "~1.0.0", + "ajv-formats": "~3.0.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" + "semver": "~7.5.4" + } + }, + "ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" } }, "semver": { @@ -1107,32 +1085,22 @@ "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==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz", + "integrity": "sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==", "dev": true, "requires": { - "@microsoft/tsdoc": "0.14.2", - "ajv": "~6.12.6", + "@microsoft/tsdoc": "0.15.0", + "ajv": "~8.12.0", "jju": "~1.4.0", - "resolve": "~1.19.0" + "resolve": "~1.22.2" }, "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==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", "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" - } } } }, @@ -1266,38 +1234,44 @@ "requires": { "resolve": "~1.22.1", "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/terminal": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.11.0.tgz", - "integrity": "sha512-LKz7pv0G9Py5uULahNSixK1pTqIIKd103pAGhDW51YfzPojvmO5wfITe0PEUNAJZjuufN/KgeRW83dJo1gL2rQ==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.13.0.tgz", + "integrity": "sha512-Ou44Q2s81BqJu3dpYedAX54am9vn245F0HzqVrfJCMQk5pGgoKKOBOjkbfZC9QKcGNaECh6pwH2s5noJt7X6ew==", "dev": true, "requires": { - "@rushstack/node-core-library": "4.3.0", + "@rushstack/node-core-library": "5.4.1", "supports-color": "~8.1.1" }, "dependencies": { "@rushstack/node-core-library": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.3.0.tgz", - "integrity": "sha512-JuNZ7lwaYQ4R1TugpryyWBn4lIxK+L7fF+muibFp0by5WklG22nsvH868fuBoZMLo5FqAs6WFOifNos4PJjWSA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.4.1.tgz", + "integrity": "sha512-WNnwdS8r9NZ/2K3u29tNoSRldscFa7SxU0RT+82B6Dy2I4Hl2MeCSKm4EXLXPKeNzLGvJ1cqbUhTLviSF8E6iA==", "dev": true, "requires": { + "ajv": "~8.13.0", + "ajv-draft-04": "~1.0.0", + "ajv-formats": "~3.0.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" + "semver": "~7.5.4" + } + }, + "ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" } }, "semver": { @@ -1443,9 +1417,9 @@ "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" }, "@types/chai": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", - "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", "dev": true }, "@types/chai-as-promised": { @@ -1477,9 +1451,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", - "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz", + "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -1558,9 +1532,9 @@ } }, "@types/node": { - "version": "20.14.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.0.tgz", - "integrity": "sha512-5cHBxFGJx6L4s56Bubp4fglrEpmyJypsqI6RgzMfBHWUJQGWAAi8cWcgetEbZXHYXo9C2Fa4EEds/uSyS4cxmA==", + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", "requires": { "undici-types": "~5.26.4" } @@ -1815,17 +1789,32 @@ } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, + "ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true + }, + "ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, "ansi-colors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", @@ -2186,9 +2175,15 @@ "dev": true }, "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", + "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", + "dev": true + }, + "b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", "dev": true }, "bach": { @@ -2209,9 +2204,9 @@ "dev": true }, "bare-events": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.2.tgz", - "integrity": "sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", + "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", "dev": true, "optional": true }, @@ -2252,11 +2247,12 @@ "dev": true }, "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, "requires": { - "buffer": "^5.5.0", + "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } @@ -2284,17 +2280,6 @@ "dev": true, "requires": { "fill-range": "^7.1.1" - }, - "dependencies": { - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - } } }, "browser-stdout": { @@ -2304,24 +2289,25 @@ "dev": true }, "browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "update-browserslist-db": "^1.0.16" } }, "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, "requires": { "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "ieee754": "^1.2.1" } }, "buffer-equal": { @@ -2379,9 +2365,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001610", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz", - "integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==", + "version": "1.0.30001632", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001632.tgz", + "integrity": "sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==", "dev": true }, "caseless": { @@ -2481,9 +2467,10 @@ } }, "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true }, "clean-stack": { "version": "2.2.0", @@ -2772,9 +2759,9 @@ } }, "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "requires": { "ms": "2.1.2" } @@ -2785,28 +2772,15 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "requires": { - "mimic-response": "^3.1.0" - } - }, "deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, "requires": { "type-detect": "^4.0.0" } }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2888,7 +2862,8 @@ "detect-libc": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==" + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true }, "diff": { "version": "5.0.0", @@ -2955,9 +2930,9 @@ } }, "electron-to-chromium": { - "version": "1.4.738", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.738.tgz", - "integrity": "sha512-lwKft2CLFztD+vEIpesrOtCrko/TFnEJlHFdRhazU7Y/jx5qc4cqsocfVrBg4So4gGe9lvxnbLIoev47WMpg+A==", + "version": "1.4.798", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.798.tgz", + "integrity": "sha512-by9J2CiM9KPGj9qfp5U4FcPSbXJG7FNzqnYaY4WLzX+v2PHieVGmnsA4dxfpGE3QEC7JofpPZmn7Vn1B9NR2+Q==", "dev": true }, "emoji-regex": { @@ -3145,6 +3120,18 @@ "text-table": "^0.2.0" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3181,6 +3168,12 @@ "is-glob": "^4.0.3" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3286,11 +3279,6 @@ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "optional": true }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" - }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -3333,14 +3321,10 @@ "time-stamp": "^1.0.0" } }, - "farmhash": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/farmhash/-/farmhash-3.3.1.tgz", - "integrity": "sha512-XUizHanzlr/v7suBr/o85HSakOoWh6HKXZjFYl5C2+Gj0f0rkw+XTUZzrd9odDsgI9G5tRUcF4wSbKaX04T0DQ==", - "requires": { - "node-addon-api": "^5.1.0", - "prebuild-install": "^7.1.2" - } + "farmhash-modern": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", + "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==" }, "fast-deep-equal": { "version": "3.1.3", @@ -3425,6 +3409,15 @@ "flat-cache": "^3.0.4" } }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -3626,11 +3619,6 @@ "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", "dev": true }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, "fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -3733,9 +3721,9 @@ } }, "gaxios": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.5.0.tgz", - "integrity": "sha512-R9QGdv8j4/dlNoQbX3hSaK/S0rkMijqjVvW3YM06CoBdbU/VdKd159j4hePpng0KuE6Lh6JJ7UdmVGJZFcAG1w==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz", + "integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==", "optional": true, "requires": { "extend": "^3.0.2", @@ -3817,11 +3805,6 @@ "assert-plus": "^1.0.0" } }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3927,12 +3910,13 @@ } }, "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "requires": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" } }, "globby": { @@ -3959,9 +3943,9 @@ } }, "google-auth-library": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.8.0.tgz", - "integrity": "sha512-TJJXFzMlVGRlIH27gYZ6XXyPf5Y3OItsKFfefsDAafNNywYRTkei83nEO29IrYj8GtdHWU78YnW+YZdaZaXIJA==", + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.10.0.tgz", + "integrity": "sha512-ol+oSa5NbcGdDqA+gZ3G3mev59OHBZksBTxY/tYwjtcp1H/scAFwJfSQU9/1RALoyZ7FslNbke8j4i3ipwlyuQ==", "optional": true, "requires": { "base64-js": "^1.3.0", @@ -3973,13 +3957,13 @@ } }, "google-gax": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.5.tgz", - "integrity": "sha512-zXRSGgHp33ottCQMdYlKEFX/MhWkzKVX5P3Vpmx+DW6rtseLILzp3V0YV5Rh4oQzzkM0BH9+nJIyX01EUgmd3g==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.6.tgz", + "integrity": "sha512-z3MR+pE6WqU+tnKtkJl4c723EYY7Il4fcSNgEbehzUJpcNWkca9AyoC2pdBWmEa0cda21VRpUBb4s6VSATiUKg==", "optional": true, "requires": { "@grpc/grpc-js": "~1.10.3", - "@grpc/proto-loader": "^0.7.0", + "@grpc/proto-loader": "^0.7.13", "@types/long": "^4.0.0", "abort-controller": "^3.0.0", "duplexify": "^4.0.0", @@ -4451,6 +4435,26 @@ "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "has-ansi": { @@ -4670,7 +4674,8 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true }, "ignore": { "version": "5.3.1", @@ -4724,7 +4729,8 @@ "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, "internal-slot": { "version": "1.0.7", @@ -5271,9 +5277,9 @@ "dev": true }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "json-stable-stringify-without-jsonify": { @@ -5656,28 +5662,12 @@ } }, "lru-memoizer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.2.0.tgz", - "integrity": "sha512-QfOZ6jNkxCcM/BkIPnFsqDhtrazLRsghi9mBwFAzol5GCvj4EkFT899Za3+QwikCg5sRX8JstioBDwOxEyzaNw==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", "requires": { "lodash.clonedeep": "^4.5.0", - "lru-cache": "~4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", - "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", - "requires": { - "pseudomap": "^1.0.1", - "yallist": "^2.0.0" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" - } + "lru-cache": "6.0.0" } }, "make-dir": { @@ -5728,12 +5718,12 @@ "dev": true }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, "requires": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" } }, @@ -5756,11 +5746,6 @@ "mime-db": "1.52.0" } }, - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" - }, "minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", @@ -5773,7 +5758,8 @@ "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true }, "minipass": { "version": "5.0.0", @@ -5808,11 +5794,6 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, "mocha": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", @@ -5883,6 +5864,23 @@ "wrap-ansi": "^7.0.0" } }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, "glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -5911,12 +5909,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "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 - }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -5975,11 +5967,6 @@ "thenify-all": "^1.0.0" } }, - "napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6022,18 +6009,11 @@ "propagate": "^2.0.0" } }, - "node-abi": { - "version": "3.58.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.58.0.tgz", - "integrity": "sha512-pXY1jnGf5T7b8UNzWzIqf0EkX4bx/w8N2AvwlGnk2SYYA/kzDVPaH0Dh0UG4EwxBB5eKOIZKPr8VAHSHL1DPGg==", - "requires": { - "semver": "^7.3.5" - } - }, "node-addon-api": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "dev": true }, "node-fetch": { "version": "2.7.0", @@ -6476,17 +6456,17 @@ } }, "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" } }, "ordered-read-streams": { @@ -6686,9 +6666,9 @@ "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "picomatch": { @@ -6775,25 +6755,6 @@ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true }, - "prebuild-install": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", - "requires": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - } - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6859,7 +6820,8 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true }, "psl": { "version": "1.9.0", @@ -6868,9 +6830,10 @@ "dev": true }, "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -6899,16 +6862,6 @@ "stream-shift": "^1.0.0" } }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -6974,17 +6927,6 @@ "safe-buffer": "^5.1.0" } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -7168,6 +7110,12 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -7397,12 +7345,9 @@ "dev": true }, "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "requires": { - "lru-cache": "^6.0.0" - } + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==" }, "semver-greatest-satisfied-range": { "version": "2.0.0", @@ -7493,21 +7438,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" - }, - "simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "requires": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "sinon": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", @@ -7615,9 +7545,9 @@ } }, "spdx-license-ids": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", - "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, "sprintf-js": { @@ -7694,14 +7624,15 @@ } }, "streamx": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", - "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", "dev": true, "requires": { "bare-events": "^2.2.0", - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" } }, "string-argv": { @@ -7789,9 +7720,10 @@ "dev": true }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + "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 }, "strnum": { "version": "1.0.5", @@ -7850,37 +7782,6 @@ "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" - }, - "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - } - } - }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" } }, "teeny-request": { @@ -7937,6 +7838,15 @@ "minimatch": "^3.0.4" } }, + "text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "dev": true, + "requires": { + "b4a": "^1.6.4" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8004,23 +7914,13 @@ } }, "through2-filter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.1.0.tgz", - "integrity": "sha512-VhZsTsfrIJjyUi6GeecnwcOJlmoqgIdGFDjqnV5ape+F1DN8GejfPO66XyIhoinxmxGImiUTrq9RwpTN5yszGA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "dev": true, "requires": { - "through2": "^4.0.2" - }, - "dependencies": { - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - } - } + "through2": "~2.0.0", + "xtend": "~4.0.0" } }, "time-stamp": { @@ -8114,9 +8014,9 @@ } }, "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "tsutils": { "version": "3.21.0", @@ -8139,6 +8039,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -8312,13 +8213,13 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "dev": true, "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" } }, "uri-js": { @@ -8363,9 +8264,9 @@ } }, "validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", "dev": true }, "value-or-function": { @@ -8414,29 +8315,6 @@ "requires": { "bl": "^5.0.0", "vinyl": "^3.0.0" - }, - "dependencies": { - "bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } } }, "vinyl-fs": { @@ -8554,6 +8432,12 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true + }, "workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", diff --git a/package.json b/package.json index 5e73bf3f5b..9d5d35e420 100644 --- a/package.json +++ b/package.json @@ -200,7 +200,7 @@ "@firebase/database-compat": "^1.0.2", "@firebase/database-types": "^1.0.0", "@types/node": "^20.10.3", - "farmhash": "^3.3.1", + "farmhash-modern": "^1.1.0", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", "long": "^5.2.3", diff --git a/src/remote-config/condition-evaluator-internal.ts b/src/remote-config/condition-evaluator-internal.ts index b23958cd77..46803f8402 100644 --- a/src/remote-config/condition-evaluator-internal.ts +++ b/src/remote-config/condition-evaluator-internal.ts @@ -25,7 +25,7 @@ import { PercentCondition, PercentConditionOperator } from './remote-config-api'; -import * as farmhash from 'farmhash'; +import * as farmhash from 'farmhash-modern'; import long = require('long'); /** @@ -149,7 +149,7 @@ export class ConditionEvaluator { // Using a 64-bit long for consistency with the Remote Config fetch endpoint. - let hash64 = long.fromString(farmhash.fingerprint64(stringToHash)); + let hash64 = long.fromString(farmhash.fingerprint64(stringToHash).toString()); // Negate the hash if its value is less than 0. We handle this manually because the // Long library doesn't provided an absolute value method. diff --git a/test/unit/remote-config/condition-evaluator.spec.ts b/test/unit/remote-config/condition-evaluator.spec.ts index fbf3ca4979..5bb0f89133 100644 --- a/test/unit/remote-config/condition-evaluator.spec.ts +++ b/test/unit/remote-config/condition-evaluator.spec.ts @@ -25,11 +25,11 @@ import { } from '../../../src/remote-config/remote-config-api'; import { v4 as uuidv4 } from 'uuid'; import { clone } from 'lodash'; -import * as farmhash from 'farmhash'; +import * as farmhash from 'farmhash-modern'; const expect = chai.expect; - +const nodeVersion = process.versions.node; describe('ConditionEvaluator', () => { let stubs: sinon.SinonStub[] = []; @@ -145,7 +145,10 @@ describe('ConditionEvaluator', () => { }); describe('percentCondition', () => { - it('should evaluate an unknown operator to false', () => { + it('should evaluate an unknown operator to false', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } // Verifies future operators won't trigger errors. const condition = { name: 'is_enabled', @@ -169,7 +172,10 @@ describe('ConditionEvaluator', () => { new Map([['is_enabled', false]])); }); - it('should evaluate less or equal to max to true', () => { + it('should evaluate less or equal to max to true', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const condition = { name: 'is_enabled', condition: { @@ -194,7 +200,10 @@ describe('ConditionEvaluator', () => { new Map([['is_enabled', true]])); }); - it('should evaluate less or equal to min to false', () => { + it('should evaluate less or equal to min to false', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const condition = { name: 'is_enabled', condition: { @@ -223,7 +232,7 @@ describe('ConditionEvaluator', () => { // Stubs ID hasher to return a number larger than zero. const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('1'); + .returns(1n); stubs.push(stub); const condition = { @@ -256,7 +265,7 @@ describe('ConditionEvaluator', () => { // Stubs ID hasher to return a number in range. const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('1'); + .returns(1n); stubs.push(stub); const condition = { @@ -289,7 +298,7 @@ describe('ConditionEvaluator', () => { // Stubs ID hasher to return a number outside range. const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('1'); + .returns(1n); stubs.push(stub); const condition = { @@ -325,7 +334,7 @@ describe('ConditionEvaluator', () => { // Stubs ID hasher to return a number in range. const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('1'); + .returns(1n); stubs.push(stub); const condition = { @@ -360,7 +369,7 @@ describe('ConditionEvaluator', () => { it('should evaluate 9 as less or equal to 10', () => { const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('9'); + .returns(9n); stubs.push(stub); const condition = { @@ -391,7 +400,7 @@ describe('ConditionEvaluator', () => { it('should evaluate 10 as less or equal to 10', () => { const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('10'); + .returns(10n); stubs.push(stub); const condition = { @@ -422,7 +431,7 @@ describe('ConditionEvaluator', () => { it('should evaluate 11 as not less or equal to 10', () => { const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('11'); + .returns(11n); stubs.push(stub); const condition = { @@ -453,7 +462,7 @@ describe('ConditionEvaluator', () => { it('should negate -11 to 11 and evaluate as not less or equal to 10', () => { const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('-11'); + .returns(-11n); stubs.push(stub); const condition = { @@ -481,7 +490,10 @@ describe('ConditionEvaluator', () => { expect(actual).to.be.false; }); - it('should evaluate greater than min to true', () => { + it('should evaluate greater than min to true', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const condition = { name: 'is_enabled', condition: { @@ -509,7 +521,7 @@ describe('ConditionEvaluator', () => { it('should evaluate 11M as greater than 10M', () => { const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('11'); + .returns(11n); stubs.push(stub); const condition = { @@ -540,7 +552,7 @@ describe('ConditionEvaluator', () => { it('should evaluate 9 as not greater than 10', () => { const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('9'); + .returns(9n); stubs.push(stub); const condition = { @@ -568,7 +580,10 @@ describe('ConditionEvaluator', () => { expect(actual).to.be.false; }); - it('should evaluate greater than max to false', () => { + it('should evaluate greater than max to false', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const condition = { name: 'is_enabled', condition: { @@ -593,7 +608,10 @@ describe('ConditionEvaluator', () => { new Map([['is_enabled', false]])); }); - it('should evaluate between min and max to true', () => { + it('should evaluate between min and max to true', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const condition = { name: 'is_enabled', condition: { @@ -624,7 +642,7 @@ describe('ConditionEvaluator', () => { it('should evaluate 10 as between 9 and 11', () => { const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('10'); + .returns(10n); stubs.push(stub); const condition = { @@ -655,7 +673,10 @@ describe('ConditionEvaluator', () => { expect(actual).to.be.true; }); - it('should evaluate between equal bounds to false', () => { + it('should evaluate between equal bounds to false', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const condition = { name: 'is_enabled', condition: { @@ -686,7 +707,7 @@ describe('ConditionEvaluator', () => { it('should evaluate 12 as not between 9 and 11', () => { const stub = sinon .stub(farmhash, 'fingerprint64') - .returns('12'); + .returns(12n); stubs.push(stub); const condition = { @@ -717,7 +738,7 @@ describe('ConditionEvaluator', () => { expect(actual).to.be.false; }); - // The following tests are probablistic. They use tolerances based on + // The following tests are probabilistic. They use tolerances based on // standard deviations to balance accuracy and flakiness. Random IDs will // hash to the target range + 3 standard deviations 99.7% of the time, // which minimizes flakiness. @@ -725,7 +746,10 @@ describe('ConditionEvaluator', () => { // trials with 50% probability: // from scipy.stats import binom // print(binom.std(100_000, 0.5) * 3) - it('should evaluate less or equal to 10% to approx 10%', () => { + it('should evaluate less or equal to 10% to approx 10%', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const percentCondition = { percentOperator: PercentConditionOperator.LESS_OR_EQUAL, microPercent: 10_000_000 // 10% @@ -738,7 +762,10 @@ describe('ConditionEvaluator', () => { expect(truthyAssignments).to.be.lessThanOrEqual(10000 + tolerance); }); - it('should evaluate between 0 to 10% to approx 10%', () => { + it('should evaluate between 0 to 10% to approx 10%', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const percentCondition = { percentOperator: PercentConditionOperator.BETWEEN, microPercentRange: { @@ -754,7 +781,10 @@ describe('ConditionEvaluator', () => { expect(truthyAssignments).to.be.lessThanOrEqual(10000 + tolerance); }); - it('should evaluate greater than 10% to approx 90%', () => { + it('should evaluate greater than 10% to approx 90%', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const percentCondition = { percentOperator: PercentConditionOperator.GREATER_THAN, microPercent: 10_000_000 @@ -767,7 +797,10 @@ describe('ConditionEvaluator', () => { expect(truthyAssignments).to.be.lessThanOrEqual(90000 + tolerance); }); - it('should evaluate between 40% to 60% to approx 20%', () => { + it('should evaluate between 40% to 60% to approx 20%', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const percentCondition = { percentOperator: PercentConditionOperator.BETWEEN, microPercentRange: { @@ -783,7 +816,10 @@ describe('ConditionEvaluator', () => { expect(truthyAssignments).to.be.lessThanOrEqual(20000 + tolerance); }); - it('should evaluate between interquartile range to approx 50%', () => { + it('should evaluate between interquartile range to approx 50%', function() { + if (nodeVersion.startsWith('14')) { + this.skip(); + } const percentCondition = { percentOperator: PercentConditionOperator.BETWEEN, microPercentRange: { From f6f7cb9650636be5757b968ae0fe2e21560d5923 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:44:03 -0400 Subject: [PATCH 129/323] build(deps): bump uuid from 9.0.1 to 10.0.0 (#2599) Bumps [uuid](https://github.com/uuidjs/uuid) from 9.0.1 to 10.0.0. - [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md) - [Commits](https://github.com/uuidjs/uuid/compare/v9.0.1...v10.0.0) --- updated-dependencies: - dependency-name: uuid dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 28 +++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 383ad46596..b2d4163260 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3731,6 +3731,14 @@ "is-stream": "^2.0.0", "node-fetch": "^2.6.9", "uuid": "^9.0.1" + }, + "dependencies": { + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "optional": true + } } }, "gcp-metadata": { @@ -3974,6 +3982,14 @@ "protobufjs": "7.3.0", "retry-request": "^7.0.0", "uuid": "^9.0.1" + }, + "dependencies": { + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "optional": true + } } }, "gopd": { @@ -7815,6 +7831,12 @@ "agent-base": "6", "debug": "4" } + }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "optional": true } } }, @@ -8237,9 +8259,9 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==" }, "v8-compile-cache-lib": { "version": "3.0.1", diff --git a/package.json b/package.json index 9d5d35e420..a4bb0b022c 100644 --- a/package.json +++ b/package.json @@ -205,7 +205,7 @@ "jwks-rsa": "^3.1.0", "long": "^5.2.3", "node-forge": "^1.3.1", - "uuid": "^9.0.0" + "uuid": "^10.0.0" }, "optionalDependencies": { "@google-cloud/firestore": "^7.7.0", From 5620e9c6bd59a5db1cad26a64557d8175bbb49f8 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 20 Jun 2024 19:46:39 +0000 Subject: [PATCH 130/323] [chore] Release 12.2.0 (#2605) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a4bb0b022c..743124513c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.1.1", + "version": "12.2.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From f1a1a4487eabb4d04e9cc039d5dc6dbda7f7c7a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:59:56 -0400 Subject: [PATCH 131/323] build(deps): bump @types/node from 20.14.2 to 20.14.8 (#2613) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.2 to 20.14.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b2d4163260..b24cdbb244 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.1.1", + "version": "12.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1532,9 +1532,9 @@ } }, "@types/node": { - "version": "20.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", - "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "version": "20.14.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", + "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", "requires": { "undici-types": "~5.26.4" } From 687bb9a9f8ec14fd70249ef9f86d9f24ab31edbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2024 17:04:39 +0000 Subject: [PATCH 132/323] build(deps-dev): bump @types/uuid from 9.0.8 to 10.0.0 (#2612) --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b24cdbb244..c74f055bb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1626,9 +1626,9 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" }, "@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", "dev": true }, "@typescript-eslint/eslint-plugin": { diff --git a/package.json b/package.json index 743124513c..0771f169df 100644 --- a/package.json +++ b/package.json @@ -230,7 +230,7 @@ "@types/request-promise": "^4.1.41", "@types/sinon": "^17.0.2", "@types/sinon-chai": "^3.0.0", - "@types/uuid": "^9.0.1", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "bcrypt": "^5.0.0", From b5664ead99493a23f60b987aa09164edc9fbc1f4 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 26 Jun 2024 20:38:25 +0000 Subject: [PATCH 133/323] chore: update integration test resources (#2615) --- .../resources/integ-service-account.json.gpg | Bin 1735 -> 1762 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/.github/resources/integ-service-account.json.gpg b/.github/resources/integ-service-account.json.gpg index fbfa5311673e1d3bf0d11a09cf922c8b2943f6aa..7740dccd8bdada2eecc181f75c552c00e912e5c2 100644 GIT binary patch literal 1762 zcmV<81|9i~4Fm}T0)n*iur~xoxnP%@af)-$RhZ&7)3w(?>+$-b1cw>C)uo%^A>P*=<*0iel03 za}Fsg1`ruYzno_!>aY;)OsTkc%h&&pe{$nZw5?@UjcH^%VjHu)VgwEnKQUK4HJk0= zyZ5gIrQ>xo>l)_!-wlcQad@p8gshGgv1xcg_Yjj!nW#U|n*LMBm3Wlbk?i_CZ5Ume zal+1184AaJ?*V#JRCa=MTz1K6B-nEb*&W)}8_{YN|7UTh+U!ds%WR1v?9Hbxk@ z+EogP!glp>+*yB=n_Y5O!Q;p67Vmj%K0Z&IQHoSQT$5HK`B~z1yiX&eY#WwU=~;7S z*R}F3&c9V&rDM=B?(>!Z9}?HjEfYzeD!pR<0+x@F>TU9zk7}`hv#*;%+wZyrU0HEofh5VjbOiejUW3pY z12D!+Wf#4>(VKPmD}rZ71T zja(Co^VJ`de?Q=DM7vMvigtGHs?54vGS7;%Hh%Kgpcm|%^7?KEi%S69Cr3HH;P{#2 zQKW(H3{(*{l=~Bf7Rl-tT)anXQbTFgdpURPL%zy_*wvVIb#5uC(O*IiG}XiMGUA%y z{hDOjK*5$4CjH6|s5_9ya=cleH7`i?@E_&%aD!Azwfl->_ z*G%8=hHUxvc;-w-8SZhmd?W7x5Q>Gdn&TWCqCer@&YB71xG=dZ z)$Q#4CnyByk9+}lQNhr0X%Yl^Z@x^E{?CS9l0qFDy5|%MRx3RMp&FRUbXi#z!svt^ z$1+LBRDKak{r8lR!uG7M$3y`i=mM%I6C;mOE*azp=yC&EjEO@hZAV~%vb<>vw*Tx}<@1-F%E1MJ z&Kx%>OC=ss;A2c#Xs*e!O^%Y!Dj=VPAc>{~z^9u8{@H%2A-4|8w>siL6sFHXXGAGp z6u#;-ci&~<6YWll-R0BZ(9=FJ*d=Z^1zpP&loXySLaK2LILSvW!Dc?^#B&6$r*#Z0VQL=xlo$_b_5MO*>kW6!}M4b=rO4;kC? z7>1#k9x6oenqHJ=>|?M)^;{lP0reAV^DsBc!yt{hJ=)44ze!{NMcolK=)E*z3xPIFQ}^9xIoZ8E2fWR@#G|3UOCwegz@y^#$8?WWnJ zs2>$dD-U!>e@QG8RfQO0o(=0E;V|(Wz7kVeam0oZT7r|6xiFJ zNd8hqdzqJ0-`fL-a@okskU*`zWMi=%n1PPxq!&m!cL|J#l~QZ}A3JebK?T zy$sIEE!|IkVGk9;6HzHA)9Y-IXTCA)$QGOVqdT1OhM%`yYT53qvYtc=4KjLTfqCH9 zgC*H0Jk^%P@UH!391-ApSu$Z{4D#3;W{vq*kO zsL+qpghA`Jm|4{gJrTOb%(>>3vR5{Am*n3SBI9H-+h-WW$}kgTg9MyYUUi*K+#nml Ero6&wRR910 literal 1735 zcmV;&1~~bQ4Fm}T0*lt3hL5UUoBz`40nms^KYd|3GC2Nv;SIs4e#-N_7eRc zBZJY^Z@v!!Jp&HSo8lE8T$|kG=u`x+bbZ~LxiY3N2i+4u6%E+mmA+&TT8rD5fa2&Y z04{Q)7#t5X1VnlNF|fT4On+CJ0f{jbBsQVScY;I?P@6z*->YdG76TWIF{55sYSZze z@=mbxW3xJIh_B7oncSF(E=UH;1~eOt9!Y2GWGBDriD)MX}i>r)j&AjPZlX|IK}FvHb$b4L#qb?!I5j$Lwii_sUa_ zdC@!uya2k%0{YtrT)T!CO?R0fq;$E@9bgk=Tk0K5fqK8x-yVO1aEiaRU3Gb|D+_zz z_5QSdSWj%yLrk<0B=ug>VsYYYh0 z+VKxQF%5O%hqBF^RKvD+sZWNd$(+aCdzV&n)|jf{IOiPNa^gZ2tl%%(hR~8u%P<|e zy2vK)gvz);>S1rmVpyHQT(o$J2lgE>0|%qUVWw{~VTnZ zis+M;@d|GQ-xV(UaL?_B&T*hL0&#~5D+L)>`ccBsIPpT?366d)Z90x4B-@le1XAp@ z?*vrciSfTi&EE%i%O?sZp$t>q?axq!x5$6G25z@^?Ejyy6|ZiazDR4gC5OXW8PwuUzl$JAErz|@3rd*z58FzS%DuqY^oa&Y z2Gd1~gQ0KGvn));7du|e@cpw<>^)+7C?%ud4?ay0Y9WR}@$qW7JE%{cWf0xifa?=7 zXGRUKZWtjf(sTld8uDS&$PqT%Cl(HLnpl3C9_ezx?PVg2CcEKM-8waIJUm^lBfBpq zl;nisY{oux75M^aE^`ar4}OkNXW0rm(CHu8locwC<;Du00{JUBEbBPo=@Q10J|eeC z(#rcwmj`B?a~BR_^KC~D9n~>;d1Vge^FFVc8YZ6%!UzGpelrky`}uPN#{FrU>h%~r z&r{}{y>k{1QtFiPxZ&l_II><;khPr_b31lvS&#H#pqXI}4bIdyxFx)wu%$Y!%?W_M z5@#r3>;Th!7~DrfR*)T78C4T~TcMsZ9Fu+h6x5=|c4U(B` ztGS7;4|U&;8X%6N4j9`@%C~q;zv4Uo0f*n=Vsz5!0V;^uf5WH0I&AqMFjPXP<~>Ku z?wfCy3`mG8tz3Hgw@g0!1Amp+jT}fsO|K1ipTdm>0RNl8^b`+^PWKAKv@F5v|g7W!mtP?VeRJU*(m~sl#tmDiF{D_E+Bq2= zHjf@=Q5f6-nBD^FaPEK9M^3$aQG+wmI#m)fI13DfYN|H@$i92-8T}(#OshQ1&T+!f zB8oH$_usn|Hi-ocee+bQey5mD7#A4R>BlFmulxAAPSWtg Date: Thu, 11 Jul 2024 11:07:42 -0400 Subject: [PATCH 134/323] build(deps-dev): bump nyc from 15.1.0 to 17.0.0 (#2616) Bumps [nyc](https://github.com/istanbuljs/nyc) from 15.1.0 to 17.0.0. - [Release notes](https://github.com/istanbuljs/nyc/releases) - [Changelog](https://github.com/istanbuljs/nyc/blob/main/CHANGELOG.md) - [Commits](https://github.com/istanbuljs/nyc/compare/v15.1.0...nyc-v17.0.0) --- updated-dependencies: - dependency-name: nyc dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 43 ++++++++++++++++++------------------------- package.json | 2 +- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index c74f055bb1..f77ed3d294 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2365,9 +2365,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001632", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001632.tgz", - "integrity": "sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==", + "version": "1.0.30001639", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz", + "integrity": "sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==", "dev": true }, "caseless": { @@ -2930,9 +2930,9 @@ } }, "electron-to-chromium": { - "version": "1.4.798", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.798.tgz", - "integrity": "sha512-by9J2CiM9KPGj9qfp5U4FcPSbXJG7FNzqnYaY4WLzX+v2PHieVGmnsA4dxfpGE3QEC7JofpPZmn7Vn1B9NR2+Q==", + "version": "1.4.816", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz", + "integrity": "sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==", "dev": true }, "emoji-regex": { @@ -5097,23 +5097,16 @@ } }, "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" } }, "istanbul-lib-processinfo": { @@ -6237,9 +6230,9 @@ } }, "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.0.0.tgz", + "integrity": "sha512-ISp44nqNCaPugLLGGfknzQwSwt10SSS5IMoPR7GLoMAyS18Iw5js8U7ga2VF9lYuMZ42gOHr3UddZw4WZltxKg==", "dev": true, "requires": { "@istanbuljs/load-nyc-config": "^1.0.0", @@ -6254,7 +6247,7 @@ "glob": "^7.1.6", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-instrument": "^6.0.2", "istanbul-lib-processinfo": "^2.0.2", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", diff --git a/package.json b/package.json index 0771f169df..6a68c36302 100644 --- a/package.json +++ b/package.json @@ -253,7 +253,7 @@ "mz": "^2.7.0", "nock": "^13.0.0", "npm-run-all": "^4.1.5", - "nyc": "^15.1.0", + "nyc": "^17.0.0", "request": "^2.75.0", "request-promise": "^4.1.1", "run-sequence": "^2.2.1", From 304957516ed3fee3433516ea151853864f40d21b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:12:27 +0000 Subject: [PATCH 135/323] build(deps): bump @google-cloud/firestore from 7.8.0 to 7.9.0 (#2618) --- package-lock.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index f77ed3d294..3f55635f72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -651,9 +651,9 @@ } }, "@google-cloud/firestore": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.8.0.tgz", - "integrity": "sha512-m21BWVZLz7H7NF8HZ5hCGUSCEJKNwYB5yzQqDTuE9YUzNDRMDei3BwVDht5k4xF636sGlnobyBL+dcbthSGONg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.9.0.tgz", + "integrity": "sha512-c4ALHT3G08rV7Zwv8Z2KG63gZh66iKdhCBeDfCpIkLrjX6EAjTD/szMdj14M+FnQuClZLFfW5bAgoOjfNmLtJg==", "optional": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -716,9 +716,9 @@ } }, "@grpc/grpc-js": { - "version": "1.10.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.9.tgz", - "integrity": "sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ==", + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.11.tgz", + "integrity": "sha512-3RaoxOqkHHN2c05bwtBNVJmOf/UwMam0rZYtdl7dsRpsvDwcNpv6LkGgzltQ7xVf822LzBoKEPRvf4D7+xeIDw==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.13", @@ -3965,12 +3965,12 @@ } }, "google-gax": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.6.tgz", - "integrity": "sha512-z3MR+pE6WqU+tnKtkJl4c723EYY7Il4fcSNgEbehzUJpcNWkca9AyoC2pdBWmEa0cda21VRpUBb4s6VSATiUKg==", + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.8.tgz", + "integrity": "sha512-SKAQKtvdjtNW3PMOhmKEqpQP+2C5ZqNKfwWxy70efpSwxvRYuAcgMJs6aRHTBPJjz3SO6ZbiXwM6WIuGYFZ7LQ==", "optional": true, "requires": { - "@grpc/grpc-js": "~1.10.3", + "@grpc/grpc-js": "^1.10.9", "@grpc/proto-loader": "^0.7.13", "@types/long": "^4.0.0", "abort-controller": "^3.0.0", @@ -3978,8 +3978,8 @@ "google-auth-library": "^9.3.0", "node-fetch": "^2.6.1", "object-hash": "^3.0.0", - "proto3-json-serializer": "^2.0.0", - "protobufjs": "7.3.0", + "proto3-json-serializer": "^2.0.2", + "protobufjs": "^7.3.2", "retry-request": "^7.0.0", "uuid": "^9.0.1" }, @@ -6807,9 +6807,9 @@ } }, "protobufjs": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.0.tgz", - "integrity": "sha512-YWD03n3shzV9ImZRX3ccbjqLxj7NokGN0V/ESiBV5xWqrommYHYiihuIyavq03pWSGqlyvYUFmfoMKd+1rPA/g==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", + "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", "optional": true, "requires": { "@protobufjs/aspromise": "^1.1.2", From 36044430aa2044a773025fd9d0a618551e592ad7 Mon Sep 17 00:00:00 2001 From: Erik Eldridge Date: Tue, 16 Jul 2024 14:12:54 -0700 Subject: [PATCH 136/323] Remove Remote Config dependency on Long JS (#2614) The conditional logic used by the Remote Config config fetch endpoint hashes randomization IDs into 64 bit numbers (via an algorithm called Farmhash). JS numbers are limited to 53 bits, so we used the long.js package to emulate the fetch endpoint logic in the Admin SDK. PR 2603 migrated the Admin SDK to use a Farmhash library that produces BigInt, which supports 64 bit numbers natively, so we can remove the long.js dependency. Additionally, the SDK currently converts the BigInt to a string before converting the string to a longjs object, which is clunky; and Long JS broke the SDK's ES6 compatibility. --------- Co-authored-by: Lahiru Maramba --- package-lock.json | 3 +- package.json | 1 - .../condition-evaluator-internal.ts | 37 ++++++---- .../remote-config/condition-evaluator.spec.ts | 73 +++++++++++++++++++ 4 files changed, 97 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f55635f72..604a7fb1b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5651,7 +5651,8 @@ "long": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "optional": true }, "loupe": { "version": "2.3.7", diff --git a/package.json b/package.json index 6a68c36302..a31cc77ae3 100644 --- a/package.json +++ b/package.json @@ -203,7 +203,6 @@ "farmhash-modern": "^1.1.0", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", - "long": "^5.2.3", "node-forge": "^1.3.1", "uuid": "^10.0.0" }, diff --git a/src/remote-config/condition-evaluator-internal.ts b/src/remote-config/condition-evaluator-internal.ts index 46803f8402..2be55ec08d 100644 --- a/src/remote-config/condition-evaluator-internal.ts +++ b/src/remote-config/condition-evaluator-internal.ts @@ -26,7 +26,6 @@ import { PercentConditionOperator } from './remote-config-api'; import * as farmhash from 'farmhash-modern'; -import long = require('long'); /** * Encapsulates condition evaluation logic to simplify organization and @@ -147,26 +146,18 @@ export class ConditionEvaluator { const seedPrefix = seed && seed.length > 0 ? `${seed}.` : ''; const stringToHash = `${seedPrefix}${context.randomizationId}`; + const hash64 = ConditionEvaluator.hashSeededRandomizationId(stringToHash) - // Using a 64-bit long for consistency with the Remote Config fetch endpoint. - let hash64 = long.fromString(farmhash.fingerprint64(stringToHash).toString()); + const instanceMicroPercentile = hash64 % BigInt(100 * 1_000_000); - // Negate the hash if its value is less than 0. We handle this manually because the - // Long library doesn't provided an absolute value method. - if (hash64.lt(0)) { - hash64 = hash64.negate(); - } - - const instanceMicroPercentile = hash64.mod(100 * 1_000_000); - switch (percentOperator) { case PercentConditionOperator.LESS_OR_EQUAL: - return instanceMicroPercentile.lte(normalizedMicroPercent); + return instanceMicroPercentile <= normalizedMicroPercent; case PercentConditionOperator.GREATER_THAN: - return instanceMicroPercentile.gt(normalizedMicroPercent); + return instanceMicroPercentile > normalizedMicroPercent; case PercentConditionOperator.BETWEEN: - return instanceMicroPercentile.gt(normalizedMicroPercentLowerBound) - && instanceMicroPercentile.lte(normalizedMicroPercentUpperBound); + return instanceMicroPercentile > normalizedMicroPercentLowerBound + && instanceMicroPercentile <= normalizedMicroPercentUpperBound; case PercentConditionOperator.UNKNOWN: default: break; @@ -175,4 +166,20 @@ export class ConditionEvaluator { // TODO: add logging once we have a wrapped logger. return false; } + + // Visible for testing + static hashSeededRandomizationId(seededRandomizationId: string): bigint { + // For consistency with the Remote Config fetch endpoint's percent condition behavior + // we use Farmhash's fingerprint64 algorithm and interpret the resulting unsigned value + // as a signed value. + let hash64 = BigInt.asIntN(64, farmhash.fingerprint64(seededRandomizationId)); + + // Manually negate the hash if its value is less than 0, since Math.abs doesn't + // support BigInt. + if (hash64 < 0) { + hash64 = -hash64; + } + + return hash64; + } } diff --git a/test/unit/remote-config/condition-evaluator.spec.ts b/test/unit/remote-config/condition-evaluator.spec.ts index 5bb0f89133..17e524f6d8 100644 --- a/test/unit/remote-config/condition-evaluator.spec.ts +++ b/test/unit/remote-config/condition-evaluator.spec.ts @@ -858,4 +858,77 @@ describe('ConditionEvaluator', () => { } }); }); + + describe('hashSeededRandomizationId', () => { + // The Farmhash algorithm produces a 64 bit unsigned integer, + // which we convert to a signed integer for legacy compatibility. + // This has caused confusion in the past, so we explicitly + // test here. + it('should leave numbers <= 2^63-1 (max signed long) as is', function () { + if (nodeVersion.startsWith('14')) { + this.skip(); + } + + const stub = sinon + .stub(farmhash, 'fingerprint64') + // 2^63-1 = 9223372036854775807. + .returns(BigInt('9223372036854775807')); + stubs.push(stub); + + const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); + + expect(actual).to.equal(BigInt('9223372036854775807')) + }); + + it('should convert 2^63 to negative (min signed long) and then find the absolute value', function () { + if (nodeVersion.startsWith('14')) { + this.skip(); + } + + const stub = sinon + .stub(farmhash, 'fingerprint64') + // 2^63 = 9223372036854775808. + .returns(BigInt('9223372036854775808')); + stubs.push(stub); + + const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); + + // 2^63 is the negation of 2^63-1 + expect(actual).to.equal(BigInt('9223372036854775808')) + }); + + it('should convert 2^63+1 to negative and then find the absolute value', function () { + if (nodeVersion.startsWith('14')) { + this.skip(); + } + + const stub = sinon + .stub(farmhash, 'fingerprint64') + // 2^63+1 9223372036854775809. + .returns(BigInt('9223372036854775809')); + stubs.push(stub); + + const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); + + // 2^63+1 is larger than 2^63, so the absolute value is smaller + expect(actual).to.equal(BigInt('9223372036854775807')) + }); + + it('should handle the value that initially caused confusion', function () { + if (nodeVersion.startsWith('14')) { + this.skip(); + } + + const stub = sinon + .stub(farmhash, 'fingerprint64') + // We were initially confused about the nature of this value ... + .returns(BigInt('16081085603393958147')); + stubs.push(stub); + + const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); + + // ... Now we know it's the unsigned equivalent of this absolute value. + expect(actual).to.equal(BigInt('2365658470315593469')) + }); + }); }); From 78b117d672c2ed274dc7a7978c7ea5ec74ea0adb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:01:07 -0400 Subject: [PATCH 137/323] build(deps-dev): bump @types/lodash from 4.17.5 to 4.17.7 (#2636) Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.5 to 4.17.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 604a7fb1b1..f98e3e2643 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1488,9 +1488,9 @@ } }, "@types/lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", + "version": "4.17.7", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", + "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", "dev": true }, "@types/long": { From 74f114315df06b9560772d2ddc92964d2f2899f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:05:50 +0000 Subject: [PATCH 138/323] build(deps): bump @fastify/busboy from 2.1.1 to 3.0.0 (#2632) --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f98e3e2643..50617c08dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -420,9 +420,9 @@ "dev": true }, "@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.0.0.tgz", + "integrity": "sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==" }, "@firebase/api-documenter": { "version": "0.4.0", diff --git a/package.json b/package.json index a31cc77ae3..c79a443c41 100644 --- a/package.json +++ b/package.json @@ -196,7 +196,7 @@ } }, "dependencies": { - "@fastify/busboy": "^2.1.0", + "@fastify/busboy": "^3.0.0", "@firebase/database-compat": "^1.0.2", "@firebase/database-types": "^1.0.0", "@types/node": "^20.10.3", From 9682e7e3b3e2a5e62a5df7fdf371b8a0bc7db716 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 17:11:30 +0000 Subject: [PATCH 139/323] build(deps-dev): bump mocha and @types/mocha (#2640) --- package-lock.json | 125 +++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 79 deletions(-) diff --git a/package-lock.json b/package-lock.json index 50617c08dc..7ed6cac941 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1517,9 +1517,9 @@ "dev": true }, "@types/mocha": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", - "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", + "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", "dev": true }, "@types/nock": { @@ -2866,9 +2866,9 @@ "dev": true }, "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true }, "dir-glob": { @@ -5805,37 +5805,37 @@ "dev": true }, "mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", - "dev": true, - "requires": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "8.1.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", + "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "dependencies": { "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true }, "brace-expansion": { @@ -5847,22 +5847,6 @@ "balanced-match": "^1.0.0" } }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -5874,23 +5858,6 @@ "wrap-ansi": "^7.0.0" } }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, "glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -5905,9 +5872,9 @@ } }, "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -5935,9 +5902,9 @@ } }, "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } @@ -7369,9 +7336,9 @@ } }, "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -8455,9 +8422,9 @@ "dev": true }, "workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", "dev": true }, "wrap-ansi": { From e5001c1333d7367fb3df194c4979fdcff1e3f9c1 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:34:40 -0400 Subject: [PATCH 140/323] feat(fcm): Add HTTP2 support for `sendEach()` and `sendEachForMulticast()` (#2550) * Refactor `api-requets` to prepare to handle both HTTP/1.1 and HTTP/2 requests * Added HTTP2 support for `sendEach()` and sendEachForMulticast` with integration tests * fix: lint * Added unit tests * Added tests for `Http2Client` and `AuthorizedHttp2Client` * Address api review changes and typos. * TW changes, backticks and typos * fix deprecation note * Reword deprecation note. --- etc/firebase-admin.messaging.api.md | 2 + .../app-check-api-client-internal.ts | 6 +- src/app-check/token-generator.ts | 4 +- src/app/credential-internal.ts | 12 +- src/auth/auth-api-request.ts | 4 +- src/auth/token-generator.ts | 4 +- src/database/database.ts | 6 +- src/eventarc/eventarc-client-internal.ts | 4 +- .../extensions-api-client-internal.ts | 4 +- .../functions-api-client-internal.ts | 8 +- .../installations-request-handler.ts | 4 +- .../machine-learning-api-client.ts | 4 +- src/messaging/batch-request-internal.ts | 6 +- .../messaging-api-request-internal.ts | 64 +- src/messaging/messaging-errors-internal.ts | 10 +- src/messaging/messaging.ts | 48 +- ...project-management-api-request-internal.ts | 6 +- .../remote-config-api-client-internal.ts | 16 +- .../security-rules-api-client-internal.ts | 4 +- src/utils/api-request.ts | 839 +++++--- src/utils/crypto-signer.ts | 4 +- src/utils/jwt.ts | 6 +- test/integration/messaging.spec.ts | 58 +- test/integration/setup.ts | 9 + test/resources/mocks.ts | 89 + test/unit/messaging/batch-requests.spec.ts | 20 +- test/unit/messaging/messaging.spec.ts | 461 ++++- test/unit/utils.ts | 16 +- test/unit/utils/api-request.spec.ts | 1684 +++++++++++++++-- 29 files changed, 2902 insertions(+), 500 deletions(-) diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index 4b8e6c1ed3..84cb3e9b84 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -189,6 +189,8 @@ export type Message = TokenMessage | TopicMessage | ConditionMessage; // @public export class Messaging { get app(): App; + // @deprecated + enableLegacyHttpTransport(): void; send(message: Message, dryRun?: boolean): Promise; // @deprecated sendAll(messages: Message[], dryRun?: boolean): Promise; diff --git a/src/app-check/app-check-api-client-internal.ts b/src/app-check/app-check-api-client-internal.ts index 6e99bc2c64..6e896044f6 100644 --- a/src/app-check/app-check-api-client-internal.ts +++ b/src/app-check/app-check-api-client-internal.ts @@ -18,7 +18,7 @@ import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import { - HttpRequestConfig, HttpClient, HttpError, AuthorizedHttpClient, HttpResponse + HttpRequestConfig, HttpClient, RequestResponseError, AuthorizedHttpClient, RequestResponse } from '../utils/api-request'; import { PrefixedFirebaseError } from '../utils/error'; import * as utils from '../utils/index'; @@ -157,7 +157,7 @@ export class AppCheckApiClient { }); } - private toFirebaseError(err: HttpError): PrefixedFirebaseError { + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { if (err instanceof PrefixedFirebaseError) { return err; } @@ -184,7 +184,7 @@ export class AppCheckApiClient { * @param resp - API response object. * @returns An AppCheckToken instance. */ - private toAppCheckToken(resp: HttpResponse): AppCheckToken { + private toAppCheckToken(resp: RequestResponse): AppCheckToken { const token = resp.data.token; // `ttl` is a string with the suffix "s" preceded by the number of seconds, // with nanoseconds expressed as fractional seconds. diff --git a/src/app-check/token-generator.ts b/src/app-check/token-generator.ts index 2cfe3ca14c..0ae7032d64 100644 --- a/src/app-check/token-generator.ts +++ b/src/app-check/token-generator.ts @@ -24,7 +24,7 @@ import { APP_CHECK_ERROR_CODE_MAPPING, } from './app-check-api-client-internal'; import { AppCheckTokenOptions } from './app-check-api'; -import { HttpError } from '../utils/api-request'; +import { RequestResponseError } from '../utils/api-request'; const ONE_MINUTE_IN_SECONDS = 60; const ONE_MINUTE_IN_MILLIS = ONE_MINUTE_IN_SECONDS * 1000; @@ -147,7 +147,7 @@ export function appCheckErrorFromCryptoSignerError(err: Error): Error { return err; } if (err.code === CryptoSignerErrorCode.SERVER_ERROR && validator.isNonNullObject(err.cause)) { - const httpError = err.cause as HttpError + const httpError = err.cause as RequestResponseError const errorResponse = httpError.response.data; if (errorResponse?.error) { const status = errorResponse.error.status; diff --git a/src/app/credential-internal.ts b/src/app/credential-internal.ts index f6a3d3bc78..94ac1ea844 100644 --- a/src/app/credential-internal.ts +++ b/src/app/credential-internal.ts @@ -22,7 +22,7 @@ import path = require('path'); import { Agent } from 'http'; import { Credential, GoogleOAuthAccessToken } from './credential'; import { AppErrorCodes, FirebaseAppError } from '../utils/error'; -import { HttpClient, HttpRequestConfig, HttpError, HttpResponse } from '../utils/api-request'; +import { HttpClient, HttpRequestConfig, RequestResponseError, RequestResponse } from '../utils/api-request'; import * as util from '../utils/validator'; const GOOGLE_TOKEN_AUDIENCE = 'https://accounts.google.com/o/oauth2/token'; @@ -232,7 +232,8 @@ export class ComputeEngineCredential implements Credential { return this.projectId; }) .catch((err) => { - const detail: string = (err instanceof HttpError) ? getDetailFromResponse(err.response) : err.message; + const detail: string = + (err instanceof RequestResponseError) ? getDetailFromResponse(err.response) : err.message; throw new FirebaseAppError( AppErrorCodes.INVALID_CREDENTIAL, `Failed to determine project ID: ${detail}`); @@ -251,7 +252,8 @@ export class ComputeEngineCredential implements Credential { return this.accountId; }) .catch((err) => { - const detail: string = (err instanceof HttpError) ? getDetailFromResponse(err.response) : err.message; + const detail: string = + (err instanceof RequestResponseError) ? getDetailFromResponse(err.response) : err.message; throw new FirebaseAppError( AppErrorCodes.INVALID_CREDENTIAL, `Failed to determine service account email: ${detail}`); @@ -553,7 +555,7 @@ function requestIDToken(client: HttpClient, request: HttpRequestConfig): Promise * Constructs a human-readable error message from the given Error. */ function getErrorMessage(err: Error): string { - const detail: string = (err instanceof HttpError) ? getDetailFromResponse(err.response) : err.message; + const detail: string = (err instanceof RequestResponseError) ? getDetailFromResponse(err.response) : err.message; return `Error fetching access token: ${detail}`; } @@ -562,7 +564,7 @@ function getErrorMessage(err: Error): string { * the response is JSON-formatted, looks up the error and error_description fields sent by the * Google Auth servers. Otherwise returns the entire response payload as the error detail. */ -function getDetailFromResponse(response: HttpResponse): string { +function getDetailFromResponse(response: RequestResponse): string { if (response.isJson() && response.data.error) { const json = response.data; let detail = json.error; diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 9fd535777c..68975fdae3 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -22,7 +22,7 @@ import { FirebaseApp } from '../app/firebase-app'; import { deepCopy, deepExtend } from '../utils/deep-copy'; import { AuthClientErrorCode, FirebaseAuthError } from '../utils/error'; import { - ApiSettings, AuthorizedHttpClient, HttpRequestConfig, HttpError, + ApiSettings, AuthorizedHttpClient, HttpRequestConfig, RequestResponseError, } from '../utils/api-request'; import * as utils from '../utils/index'; @@ -1933,7 +1933,7 @@ export abstract class AbstractAuthRequestHandler { return response.data; }) .catch((err) => { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { const error = err.response.data; const errorCode = AbstractAuthRequestHandler.getErrorCode(error); if (!errorCode) { diff --git a/src/auth/token-generator.ts b/src/auth/token-generator.ts index 7d3bd8a7c6..ce6e21fbb6 100644 --- a/src/auth/token-generator.ts +++ b/src/auth/token-generator.ts @@ -16,7 +16,7 @@ */ import { AuthClientErrorCode, ErrorInfo, FirebaseAuthError } from '../utils/error'; -import { HttpError } from '../utils/api-request'; +import { RequestResponseError } from '../utils/api-request'; import { CryptoSigner, CryptoSignerError, CryptoSignerErrorCode } from '../utils/crypto-signer'; import * as validator from '../utils/validator'; @@ -213,7 +213,7 @@ export function handleCryptoSignerError(err: Error): Error { } if (err.code === CryptoSignerErrorCode.SERVER_ERROR && validator.isNonNullObject(err.cause)) { const httpError = err.cause; - const errorResponse = (httpError as HttpError).response.data; + const errorResponse = (httpError as RequestResponseError).response.data; if (validator.isNonNullObject(errorResponse) && errorResponse.error) { const errorCode = errorResponse.error.status; const description = 'Please refer to https://firebase.google.com/docs/auth/admin/create-custom-tokens ' + diff --git a/src/database/database.ts b/src/database/database.ts index 555072f2df..144f08d430 100644 --- a/src/database/database.ts +++ b/src/database/database.ts @@ -24,7 +24,7 @@ import { Database as DatabaseImpl } from '@firebase/database-compat/standalone'; import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import * as validator from '../utils/validator'; -import { AuthorizedHttpClient, HttpRequestConfig, HttpError } from '../utils/api-request'; +import { AuthorizedHttpClient, HttpRequestConfig, RequestResponseError } from '../utils/api-request'; import { getSdkVersion } from '../utils/index'; /** @@ -292,7 +292,7 @@ class DatabaseRulesClient { } private handleError(err: Error): Error { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { return new FirebaseDatabaseError({ code: AppErrorCodes.INTERNAL_ERROR, message: this.getErrorMessage(err), @@ -301,7 +301,7 @@ class DatabaseRulesClient { return err; } - private getErrorMessage(err: HttpError): string { + private getErrorMessage(err: RequestResponseError): string { const intro = 'Error while accessing security rules'; try { const body: { error?: string } = err.response.data; diff --git a/src/eventarc/eventarc-client-internal.ts b/src/eventarc/eventarc-client-internal.ts index ce02967c93..3aecbdcc96 100644 --- a/src/eventarc/eventarc-client-internal.ts +++ b/src/eventarc/eventarc-client-internal.ts @@ -20,7 +20,7 @@ import { FirebaseEventarcError, toCloudEventProtoFormat } from './eventarc-utils import { App } from '../app'; import { Channel } from './eventarc'; import { - HttpRequestConfig, HttpClient, HttpError, AuthorizedHttpClient + HttpRequestConfig, HttpClient, RequestResponseError, AuthorizedHttpClient } from '../utils/api-request'; import { FirebaseApp } from '../app/firebase-app'; import * as utils from '../utils'; @@ -117,7 +117,7 @@ export class EventarcApiClient { }); } - private toFirebaseError(err: HttpError): PrefixedFirebaseError { + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { if (err instanceof PrefixedFirebaseError) { return err; } diff --git a/src/extensions/extensions-api-client-internal.ts b/src/extensions/extensions-api-client-internal.ts index 407dd5a82e..a51c001304 100644 --- a/src/extensions/extensions-api-client-internal.ts +++ b/src/extensions/extensions-api-client-internal.ts @@ -17,7 +17,7 @@ import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; -import { AuthorizedHttpClient, HttpClient, HttpError, HttpRequestConfig } from '../utils/api-request'; +import { AuthorizedHttpClient, HttpClient, RequestResponseError, HttpRequestConfig } from '../utils/api-request'; import { FirebaseAppError, PrefixedFirebaseError } from '../utils/error'; import * as validator from '../utils/validator'; import * as utils from '../utils'; @@ -76,7 +76,7 @@ export class ExtensionsApiClient { }/${EXTENSIONS_API_VERSION}/projects/${projectId}/instances/${instanceId}/runtimeData`; } - private toFirebaseError(err: HttpError): PrefixedFirebaseError { + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { if (err instanceof PrefixedFirebaseError) { return err; } diff --git a/src/functions/functions-api-client-internal.ts b/src/functions/functions-api-client-internal.ts index 85a447cf33..a98a599ed0 100644 --- a/src/functions/functions-api-client-internal.ts +++ b/src/functions/functions-api-client-internal.ts @@ -18,7 +18,7 @@ import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import { - HttpRequestConfig, HttpClient, HttpError, AuthorizedHttpClient + HttpRequestConfig, HttpClient, RequestResponseError, AuthorizedHttpClient } from '../utils/api-request'; import { PrefixedFirebaseError } from '../utils/error'; import * as utils from '../utils/index'; @@ -99,7 +99,7 @@ export class FunctionsApiClient { }; await this.httpClient.send(request); } catch (err: unknown) { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { if (err.response.status === 404) { // if no task with the provided ID exists, then ignore the delete. return; @@ -156,7 +156,7 @@ export class FunctionsApiClient { }; await this.httpClient.send(request); } catch (err: unknown) { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { if (err.response.status === 409) { throw new FirebaseFunctionsError('task-already-exists', `A task with ID ${opts?.id} already exists`); } else { @@ -321,7 +321,7 @@ export class FunctionsApiClient { return task; } - private toFirebaseError(err: HttpError): PrefixedFirebaseError { + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { if (err instanceof PrefixedFirebaseError) { return err; } diff --git a/src/installations/installations-request-handler.ts b/src/installations/installations-request-handler.ts index f6043c46d0..5314642d55 100644 --- a/src/installations/installations-request-handler.ts +++ b/src/installations/installations-request-handler.ts @@ -19,7 +19,7 @@ import { App } from '../app/index'; import { FirebaseApp } from '../app/firebase-app'; import { FirebaseInstallationsError, InstallationsClientErrorCode } from '../utils/error'; import { - ApiSettings, AuthorizedHttpClient, HttpRequestConfig, HttpError, + ApiSettings, AuthorizedHttpClient, HttpRequestConfig, RequestResponseError, } from '../utils/api-request'; import * as utils from '../utils/index'; @@ -93,7 +93,7 @@ export class FirebaseInstallationsRequestHandler { // return nothing on success }) .catch((err) => { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { const response = err.response; const errorMessage: string = (response.isJson() && 'error' in response.data) ? response.data.error : response.text; diff --git a/src/machine-learning/machine-learning-api-client.ts b/src/machine-learning/machine-learning-api-client.ts index 7ae1c3436a..c3ea7cee4f 100644 --- a/src/machine-learning/machine-learning-api-client.ts +++ b/src/machine-learning/machine-learning-api-client.ts @@ -17,7 +17,7 @@ import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import { - HttpRequestConfig, HttpClient, HttpError, AuthorizedHttpClient, ExponentialBackoffPoller + HttpRequestConfig, HttpClient, RequestResponseError, AuthorizedHttpClient, ExponentialBackoffPoller } from '../utils/api-request'; import { PrefixedFirebaseError } from '../utils/error'; import * as utils from '../utils/index'; @@ -369,7 +369,7 @@ export class MachineLearningApiClient { }); } - private toFirebaseError(err: HttpError): PrefixedFirebaseError { + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { if (err instanceof PrefixedFirebaseError) { return err; } diff --git a/src/messaging/batch-request-internal.ts b/src/messaging/batch-request-internal.ts index d3f18c9942..7f87d7bde1 100644 --- a/src/messaging/batch-request-internal.ts +++ b/src/messaging/batch-request-internal.ts @@ -15,7 +15,7 @@ */ import { - HttpClient, HttpRequestConfig, HttpResponse, parseHttpResponse, + HttpClient, HttpRequestConfig, RequestResponse, parseHttpResponse, } from '../utils/api-request'; import { FirebaseAppError, AppErrorCodes } from '../utils/error'; @@ -54,12 +54,12 @@ export class BatchRequestClient { /** * Sends the given array of sub requests as a single batch, and parses the results into an array - * of HttpResponse objects. + * of `RequestResponse` objects. * * @param requests - An array of sub requests to send. * @returns A promise that resolves when the send operation is complete. */ - public send(requests: SubRequest[]): Promise { + public send(requests: SubRequest[]): Promise { requests = requests.map((req) => { req.headers = Object.assign({}, this.commonHeaders, req.headers); return req; diff --git a/src/messaging/messaging-api-request-internal.ts b/src/messaging/messaging-api-request-internal.ts index 90be03181f..db1aabcc52 100644 --- a/src/messaging/messaging-api-request-internal.ts +++ b/src/messaging/messaging-api-request-internal.ts @@ -18,7 +18,8 @@ import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import { - HttpMethod, AuthorizedHttpClient, HttpRequestConfig, HttpError, HttpResponse, + HttpMethod, AuthorizedHttpClient, HttpRequestConfig, RequestResponseError, RequestResponse, + AuthorizedHttp2Client, Http2SessionHandler, Http2RequestConfig, } from '../utils/api-request'; import { createFirebaseError, getErrorCode } from './messaging-errors-internal'; import { SubRequest, BatchRequestClient } from './batch-request-internal'; @@ -44,6 +45,7 @@ const LEGACY_FIREBASE_MESSAGING_HEADERS = { */ export class FirebaseMessagingRequestHandler { private readonly httpClient: AuthorizedHttpClient; + private readonly http2Client: AuthorizedHttp2Client; private readonly batchClient: BatchRequestClient; /** @@ -52,6 +54,7 @@ export class FirebaseMessagingRequestHandler { */ constructor(app: App) { this.httpClient = new AuthorizedHttpClient(app as FirebaseApp); + this.http2Client = new AuthorizedHttp2Client(app as FirebaseApp); this.batchClient = new BatchRequestClient( this.httpClient, FIREBASE_MESSAGING_BATCH_URL, FIREBASE_MESSAGING_HEADERS); } @@ -75,20 +78,20 @@ export class FirebaseMessagingRequestHandler { return this.httpClient.send(request).then((response) => { // Send non-JSON responses to the catch() below where they will be treated as errors. if (!response.isJson()) { - throw new HttpError(response); + throw new RequestResponseError(response); } // Check for backend errors in the response. const errorCode = getErrorCode(response.data); if (errorCode) { - throw new HttpError(response); + throw new RequestResponseError(response); } // Return entire response. return response.data; }) .catch((err) => { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { throw createFirebaseError(err); } // Re-throw the error if it already has the proper format. @@ -97,14 +100,16 @@ export class FirebaseMessagingRequestHandler { } /** - * Invokes the request handler with the provided request data. + * Invokes the HTTP/1.1 request handler with the provided request data. * * @param host - The host to which to send the request. * @param path - The path to which to send the request. * @param requestData - The request data. * @returns A promise that resolves with the {@link SendResponse}. */ - public invokeRequestHandlerForSendResponse(host: string, path: string, requestData: object): Promise { + public invokeHttpRequestHandlerForSendResponse( + host: string, path: string, requestData: object + ): Promise { const request: HttpRequestConfig = { method: FIREBASE_MESSAGING_HTTP_METHOD, url: `https://${host}${path}`, @@ -116,7 +121,38 @@ export class FirebaseMessagingRequestHandler { return this.buildSendResponse(response); }) .catch((err) => { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { + return this.buildSendResponseFromError(err); + } + // Re-throw the error if it already has the proper format. + throw err; + }); + } + + /** + * Invokes the HTTP/2 request handler with the provided request data. + * + * @param host - The host to which to send the request. + * @param path - The path to which to send the request. + * @param requestData - The request data. + * @returns A promise that resolves with the {@link SendResponse}. + */ + public invokeHttp2RequestHandlerForSendResponse( + host: string, path: string, requestData: object, http2SessionHandler: Http2SessionHandler + ): Promise { + const request: Http2RequestConfig = { + method: FIREBASE_MESSAGING_HTTP_METHOD, + url: `https://${host}${path}`, + data: requestData, + headers: LEGACY_FIREBASE_MESSAGING_HEADERS, + timeout: FIREBASE_MESSAGING_TIMEOUT, + http2SessionHandler: http2SessionHandler + }; + return this.http2Client.send(request).then((response) => { + return this.buildSendResponse(response); + }) + .catch((err) => { + if (err instanceof RequestResponseError) { return this.buildSendResponseFromError(err); } // Re-throw the error if it already has the proper format. @@ -126,15 +162,15 @@ export class FirebaseMessagingRequestHandler { /** * Sends the given array of sub requests as a single batch to FCM, and parses the result into - * a BatchResponse object. + * a `BatchResponse` object. * * @param requests - An array of sub requests to send. * @returns A promise that resolves when the send operation is complete. */ public sendBatchRequest(requests: SubRequest[]): Promise { return this.batchClient.send(requests) - .then((responses: HttpResponse[]) => { - return responses.map((part: HttpResponse) => { + .then((responses: RequestResponse[]) => { + return responses.map((part: RequestResponse) => { return this.buildSendResponse(part); }); }).then((responses: SendResponse[]) => { @@ -145,7 +181,7 @@ export class FirebaseMessagingRequestHandler { failureCount: responses.length - successCount, }; }).catch((err) => { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { throw createFirebaseError(err); } // Re-throw the error if it already has the proper format. @@ -153,19 +189,19 @@ export class FirebaseMessagingRequestHandler { }); } - private buildSendResponse(response: HttpResponse): SendResponse { + private buildSendResponse(response: RequestResponse): SendResponse { const result: SendResponse = { success: response.status === 200, }; if (result.success) { result.messageId = response.data.name; } else { - result.error = createFirebaseError(new HttpError(response)); + result.error = createFirebaseError(new RequestResponseError(response)); } return result; } - private buildSendResponseFromError(err: HttpError): SendResponse { + private buildSendResponseFromError(err: RequestResponseError): SendResponse { return { success: false, error: createFirebaseError(err) diff --git a/src/messaging/messaging-errors-internal.ts b/src/messaging/messaging-errors-internal.ts index a9dd8794af..a04e4cfb2b 100644 --- a/src/messaging/messaging-errors-internal.ts +++ b/src/messaging/messaging-errors-internal.ts @@ -14,18 +14,18 @@ * limitations under the License. */ -import { HttpError } from '../utils/api-request'; +import { RequestResponseError } from '../utils/api-request'; import { FirebaseMessagingError, MessagingClientErrorCode } from '../utils/error'; import * as validator from '../utils/validator'; /** - * Creates a new FirebaseMessagingError by extracting the error code, message and other relevant - * details from an HTTP error response. + * Creates a new `FirebaseMessagingError` by extracting the error code, message and other relevant + * details from a `RequestResponseError` response. * - * @param err - The HttpError to convert into a Firebase error + * @param err - The `RequestResponseError` to convert into a Firebase error * @returns A Firebase error that can be returned to the user. */ -export function createFirebaseError(err: HttpError): FirebaseMessagingError { +export function createFirebaseError(err: RequestResponseError): FirebaseMessagingError { if (err.response.isJson()) { // For JSON responses, map the server response to a client-side error. const json = err.response.data; diff --git a/src/messaging/messaging.ts b/src/messaging/messaging.ts index f7a2a14ddf..ad78783fb9 100644 --- a/src/messaging/messaging.ts +++ b/src/messaging/messaging.ts @@ -41,6 +41,7 @@ import { NotificationMessagePayload, SendResponse, } from './messaging-api'; +import { Http2SessionHandler } from '../utils/api-request'; // FCM endpoints const FCM_SEND_HOST = 'fcm.googleapis.com'; @@ -103,11 +104,11 @@ const MESSAGING_CONDITION_RESPONSE_KEYS_MAP = { }; /** - * Maps a raw FCM server response to a MessagingDevicesResponse object. + * Maps a raw FCM server response to a `MessagingDevicesResponse` object. * * @param response - The raw FCM server response to map. * - * @returns The mapped MessagingDevicesResponse object. + * @returns The mapped `MessagingDevicesResponse` object. */ function mapRawResponseToDevicesResponse(response: object): MessagingDevicesResponse { // Rename properties on the server response @@ -130,11 +131,11 @@ function mapRawResponseToDevicesResponse(response: object): MessagingDevicesResp } /** - * Maps a raw FCM server response to a MessagingDeviceGroupResponse object. + * Maps a raw FCM server response to a `MessagingDeviceGroupResponse` object. * * @param response - The raw FCM server response to map. * - * @returns The mapped MessagingDeviceGroupResponse object. + * @returns The mapped `MessagingDeviceGroupResponse` object. */ function mapRawResponseToDeviceGroupResponse(response: object): MessagingDeviceGroupResponse { // Rename properties on the server response @@ -148,11 +149,11 @@ function mapRawResponseToDeviceGroupResponse(response: object): MessagingDeviceG } /** - * Maps a raw FCM server response to a MessagingTopicManagementResponse object. + * Maps a raw FCM server response to a `MessagingTopicManagementResponse` object. * * @param {object} response The raw FCM server response to map. * - * @returns {MessagingTopicManagementResponse} The mapped MessagingTopicManagementResponse object. + * @returns {MessagingTopicManagementResponse} The mapped `MessagingTopicManagementResponse` object. */ function mapRawResponseToTopicManagementResponse(response: object): MessagingTopicManagementResponse { // Add the success and failure counts. @@ -192,6 +193,7 @@ export class Messaging { private urlPath: string; private readonly appInternal: App; private readonly messagingRequestHandler: FirebaseMessagingRequestHandler; + private useLegacyTransport = false; /** * @internal @@ -221,6 +223,23 @@ export class Messaging { return this.appInternal; } + /** + * Enables the use of legacy HTTP/1.1 transport for `sendEach()` and `sendEachForMulticast()`. + * + * @example + * ```javascript + * const messaging = getMessaging(app); + * messaging.enableLegacyTransport(); + * messaging.sendEach(messages); + * ``` + * + * @deprecated This will be removed when the HTTP/2 transport implementation reaches the same + * stability as the legacy HTTP/1.1 implementation. + */ + public enableLegacyHttpTransport(): void { + this.useLegacyTransport = true; + } + /** * Sends the given message via FCM. * @@ -292,6 +311,8 @@ export class Messaging { MessagingClientErrorCode.INVALID_ARGUMENT, 'dryRun must be a boolean'); } + const http2SessionHandler = this.useLegacyTransport ? undefined : new Http2SessionHandler(`https://${FCM_SEND_HOST}`) + return this.getUrlPath() .then((urlPath) => { const requests: Promise[] = copy.map(async (message) => { @@ -300,10 +321,16 @@ export class Messaging { if (dryRun) { request.validate_only = true; } - return this.messagingRequestHandler.invokeRequestHandlerForSendResponse(FCM_SEND_HOST, urlPath, request); + + if (http2SessionHandler){ + return this.messagingRequestHandler.invokeHttp2RequestHandlerForSendResponse( + FCM_SEND_HOST, urlPath, request, http2SessionHandler); + } + return this.messagingRequestHandler.invokeHttpRequestHandlerForSendResponse(FCM_SEND_HOST, urlPath, request); }); return Promise.allSettled(requests); - }).then((results) => { + }) + .then((results) => { const responses: SendResponse[] = []; results.forEach(result => { if (result.status === 'fulfilled') { @@ -318,6 +345,11 @@ export class Messaging { successCount, failureCount: responses.length - successCount, }; + }) + .finally(() => { + if (http2SessionHandler){ + http2SessionHandler.close() + } }); } diff --git a/src/project-management/project-management-api-request-internal.ts b/src/project-management/project-management-api-request-internal.ts index d7e597d50d..d4a38cb2bc 100644 --- a/src/project-management/project-management-api-request-internal.ts +++ b/src/project-management/project-management-api-request-internal.ts @@ -17,7 +17,7 @@ import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import { - AuthorizedHttpClient, HttpError, HttpMethod, HttpRequestConfig, ExponentialBackoffPoller, + AuthorizedHttpClient, RequestResponseError, HttpMethod, HttpRequestConfig, ExponentialBackoffPoller, } from '../utils/api-request'; import { FirebaseProjectManagementError, ProjectManagementErrorCode } from '../utils/error'; import { getSdkVersion } from '../utils/index'; @@ -322,13 +322,13 @@ export class ProjectManagementRequestHandler { .then((response) => { // Send non-JSON responses to the catch() below, where they will be treated as errors. if (!response.isJson()) { - throw new HttpError(response); + throw new RequestResponseError(response); } return response.data; }) .catch((err) => { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { ProjectManagementRequestHandler.wrapAndRethrowHttpError( err.response.status, err.response.text); } diff --git a/src/remote-config/remote-config-api-client-internal.ts b/src/remote-config/remote-config-api-client-internal.ts index f1a0ad1c10..30a0b10a54 100644 --- a/src/remote-config/remote-config-api-client-internal.ts +++ b/src/remote-config/remote-config-api-client-internal.ts @@ -16,7 +16,9 @@ import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; -import { HttpRequestConfig, HttpClient, HttpError, AuthorizedHttpClient, HttpResponse } from '../utils/api-request'; +import { + HttpRequestConfig, HttpClient, RequestResponseError, AuthorizedHttpClient,RequestResponse +} from '../utils/api-request'; import { PrefixedFirebaseError } from '../utils/error'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; @@ -193,7 +195,11 @@ export class RemoteConfigApiClient { }); } - private sendPutRequest(template: RemoteConfigTemplate, etag: string, validateOnly?: boolean): Promise { + private sendPutRequest( + template: RemoteConfigTemplate, + etag: string, + validateOnly?: boolean + ): Promise { let path = 'remoteConfig'; if (validateOnly) { path += '?validate_only=true'; @@ -242,7 +248,7 @@ export class RemoteConfigApiClient { }); } - private toFirebaseError(err: HttpError): PrefixedFirebaseError { + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { if (err instanceof PrefixedFirebaseError) { return err; } @@ -270,7 +276,7 @@ export class RemoteConfigApiClient { * @param {HttpResponse} resp API response object. * @param {string} customEtag A custom etag to replace the etag fom the API response (Optional). */ - private toRemoteConfigTemplate(resp: HttpResponse, customEtag?: string): RemoteConfigTemplate { + private toRemoteConfigTemplate(resp: RequestResponse, customEtag?: string): RemoteConfigTemplate { const etag = (typeof customEtag === 'undefined') ? resp.headers['etag'] : customEtag; this.validateEtag(etag); return { @@ -289,7 +295,7 @@ export class RemoteConfigApiClient { * @param {HttpResponse} resp API response object. * @param {string} customEtag A custom etag to replace the etag fom the API response (Optional). */ - private toRemoteConfigServerTemplate(resp: HttpResponse, customEtag?: string): ServerTemplateData { + private toRemoteConfigServerTemplate(resp: RequestResponse, customEtag?: string): ServerTemplateData { const etag = (typeof customEtag === 'undefined') ? resp.headers['etag'] : customEtag; this.validateEtag(etag); return { diff --git a/src/security-rules/security-rules-api-client-internal.ts b/src/security-rules/security-rules-api-client-internal.ts index 6d089b4475..7f10a27b93 100644 --- a/src/security-rules/security-rules-api-client-internal.ts +++ b/src/security-rules/security-rules-api-client-internal.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { HttpRequestConfig, HttpClient, HttpError, AuthorizedHttpClient } from '../utils/api-request'; +import { HttpRequestConfig, HttpClient, RequestResponseError, AuthorizedHttpClient } from '../utils/api-request'; import { PrefixedFirebaseError } from '../utils/error'; import { FirebaseSecurityRulesError, SecurityRulesErrorCode } from './security-rules-internal'; import * as utils from '../utils/index'; @@ -283,7 +283,7 @@ export class SecurityRulesApiClient { }); } - private toFirebaseError(err: HttpError): PrefixedFirebaseError { + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { if (err instanceof PrefixedFirebaseError) { return err; } diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index 5d1b9ecf4c..69406c27ea 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -21,6 +21,7 @@ import * as validator from './validator'; import http = require('http'); import https = require('https'); +import http2 = require('http2'); import url = require('url'); import { EventEmitter } from 'events'; import { Readable } from 'stream'; @@ -32,9 +33,9 @@ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD'; export type ApiCallbackFunction = (data: object) => void; /** - * Configuration for constructing a new HTTP request. + * Base configuration for constructing a new request. */ -export interface HttpRequestConfig { +export interface BaseRequestConfig { method: HttpMethod; /** Target URL of the request. Should be a well-formed URL including protocol, hostname, port and path. */ url: string; @@ -42,13 +43,28 @@ export interface HttpRequestConfig { data?: string | object | Buffer | null; /** Connect and read timeout (in milliseconds) for the outgoing request. */ timeout?: number; +} + +/** + * Configuration for constructing a new HTTP request. + */ +export interface HttpRequestConfig extends BaseRequestConfig { httpAgent?: http.Agent; } /** - * Represents an HTTP response received from a remote server. + * Configuration for constructing a new HTTP/2 request. + */ +export interface Http2RequestConfig extends BaseRequestConfig { + http2SessionHandler: Http2SessionHandler; +} + +type RequestConfig = HttpRequestConfig | Http2RequestConfig + +/** + * Represents an HTTP or HTTP/2 response received from a remote server. */ -export interface HttpResponse { +export interface RequestResponse { readonly status: number; readonly headers: any; /** Response data as a raw string. */ @@ -64,23 +80,47 @@ export interface HttpResponse { isJson(): boolean; } -interface LowLevelResponse { +interface BaseLowLevelResponse { status: number; - headers: http.IncomingHttpHeaders; - request: http.ClientRequest | null; data?: string; multipart?: Buffer[]; - config: HttpRequestConfig; } -interface LowLevelError extends Error { +interface LowLevelHttpResponse extends BaseLowLevelResponse { + headers: http.IncomingHttpHeaders; + request: http.ClientRequest | null; config: HttpRequestConfig; +} + +type IncomingHttp2Headers = http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader + +interface LowLevelHttp2Response extends BaseLowLevelResponse { + headers: IncomingHttp2Headers + request: http2.ClientHttp2Stream | null; + config: Http2RequestConfig; +} + +type LowLevelResponse = LowLevelHttpResponse | LowLevelHttp2Response + +interface BaseLowLevelError extends Error { code?: string; +} + +interface LowLevelHttpError extends BaseLowLevelError { + config: HttpRequestConfig; request?: http.ClientRequest; - response?: LowLevelResponse; + response?: LowLevelHttpResponse; +} + +interface LowLevelHttp2Error extends BaseLowLevelError { + config: Http2RequestConfig; + request?: http2.ClientHttp2Stream; + response?: LowLevelHttp2Response; } -class DefaultHttpResponse implements HttpResponse { +type LowLevelError = LowLevelHttpError | LowLevelHttp2Error + +class DefaultRequestResponse implements RequestResponse { public readonly status: number; public readonly headers: any; @@ -91,7 +131,7 @@ class DefaultHttpResponse implements HttpResponse { private readonly request: string; /** - * Constructs a new HttpResponse from the given LowLevelResponse. + * Constructs a new `RequestResponse` from the given `LowLevelResponse`. */ constructor(resp: LowLevelResponse) { this.status = resp.status; @@ -127,10 +167,10 @@ class DefaultHttpResponse implements HttpResponse { } /** - * Represents a multipart HTTP response. Parts that constitute the response body can be accessed + * Represents a multipart HTTP or HTTP/2 response. Parts that constitute the response body can be accessed * via the multipart getter. Getters for text and data throw errors. */ -class MultipartHttpResponse implements HttpResponse { +class MultipartRequestResponse implements RequestResponse { public readonly status: number; public readonly headers: any; @@ -161,23 +201,23 @@ class MultipartHttpResponse implements HttpResponse { } } -export class HttpError extends Error { - constructor(public readonly response: HttpResponse) { +export class RequestResponseError extends Error { + constructor(public readonly response: RequestResponse) { super(`Server responded with status ${response.status}.`); // Set the prototype so that instanceof checks will work correctly. // See: https://github.com/Microsoft/TypeScript/issues/13965 - Object.setPrototypeOf(this, HttpError.prototype); + Object.setPrototypeOf(this, RequestResponseError.prototype); } } /** - * Specifies how failing HTTP requests should be retried. + * Specifies how failing HTTP and HTTP/2 requests should be retried. */ export interface RetryConfig { /** Maximum number of times to retry a given request. */ maxRetries: number; - /** HTTP status codes that should be retried. */ + /** Response status codes that should be retried. */ statusCodes?: number[]; /** Low-level I/O error codes that should be retried. */ @@ -185,8 +225,8 @@ export interface RetryConfig { /** * The multiplier for exponential back off. The retry delay is calculated in seconds using the formula - * `(2^n) * backOffFactor`, where n is the number of retries performed so far. When the backOffFactor is set - * to 0, retries are not delayed. When the backOffFactor is 1, retry duration is doubled each iteration. + * `(2^n) * backOffFactor`, where n is the number of retries performed so far. When the `backOffFactor` is set + * to 0, retries are not delayed. When the `backOffFactor` is 1, retry duration is doubled each iteration. */ backOffFactor?: number; @@ -195,8 +235,8 @@ export interface RetryConfig { } /** - * Default retry configuration for HTTP requests. Retries up to 4 times on connection reset and timeout errors - * as well as HTTP 503 errors. Exposed as a function to ensure that every HttpClient gets its own RetryConfig + * Default retry configuration for HTTP and HTTP/2 requests. Retries up to 4 times on connection reset and timeout + * errors as well as 503 errors. Exposed as a function to ensure that every `RequestClient` gets its own `RetryConfig` * instance. */ export function defaultRetryConfig(): RetryConfig { @@ -210,7 +250,7 @@ export function defaultRetryConfig(): RetryConfig { } /** - * Ensures that the given RetryConfig object is valid. + * Ensures that the given `RetryConfig` object is valid. * * @param retry - The configuration to be validated. */ @@ -241,76 +281,24 @@ function validateRetryConfig(retry: RetryConfig): void { } } -export class HttpClient { +export class RequestClient { + protected readonly retry: RetryConfig; - constructor(private readonly retry: RetryConfig | null = defaultRetryConfig()) { - if (this.retry) { + constructor(retry: RetryConfig | null = defaultRetryConfig()) { + if (retry) { + this.retry = retry validateRetryConfig(this.retry); } } - /** - * Sends an HTTP request to a remote server. If the server responds with a successful response (2xx), the returned - * promise resolves with an HttpResponse. If the server responds with an error (3xx, 4xx, 5xx), the promise rejects - * with an HttpError. In case of all other errors, the promise rejects with a FirebaseAppError. If a request fails - * due to a low-level network error, transparently retries the request once before rejecting the promise. - * - * If the request data is specified as an object, it will be serialized into a JSON string. The application/json - * content-type header will also be automatically set in this case. For all other payload types, the content-type - * header should be explicitly set by the caller. To send a JSON leaf value (e.g. "foo", 5), parse it into JSON, - * and pass as a string or a Buffer along with the appropriate content-type header. - * - * @param config - HTTP request to be sent. - * @returns A promise that resolves with the response details. - */ - public send(config: HttpRequestConfig): Promise { - return this.sendWithRetry(config); - } - - /** - * Sends an HTTP request. In the event of an error, retries the HTTP request according to the - * RetryConfig set on the HttpClient. - * - * @param config - HTTP request to be sent. - * @param retryAttempts - Number of retries performed up to now. - * @returns A promise that resolves with the response details. - */ - private sendWithRetry(config: HttpRequestConfig, retryAttempts = 0): Promise { - return AsyncHttpCall.invoke(config) - .then((resp) => { - return this.createHttpResponse(resp); - }) - .catch((err: LowLevelError) => { - const [delayMillis, canRetry] = this.getRetryDelayMillis(retryAttempts, err); - if (canRetry && this.retry && delayMillis <= this.retry.maxDelayInMillis) { - return this.waitForRetry(delayMillis).then(() => { - return this.sendWithRetry(config, retryAttempts + 1); - }); - } - - if (err.response) { - throw new HttpError(this.createHttpResponse(err.response)); - } - - if (err.code === 'ETIMEDOUT') { - throw new FirebaseAppError( - AppErrorCodes.NETWORK_TIMEOUT, - `Error while making request: ${err.message}.`); - } - throw new FirebaseAppError( - AppErrorCodes.NETWORK_ERROR, - `Error while making request: ${err.message}. Error code: ${err.code}`); - }); - } - - private createHttpResponse(resp: LowLevelResponse): HttpResponse { + protected createRequestResponse(resp: LowLevelResponse): RequestResponse { if (resp.multipart) { - return new MultipartHttpResponse(resp); + return new MultipartRequestResponse(resp); } - return new DefaultHttpResponse(resp); + return new DefaultRequestResponse(resp); } - private waitForRetry(delayMillis: number): Promise { + protected waitForRetry(delayMillis: number): Promise { if (delayMillis > 0) { return new Promise((resolve) => { setTimeout(resolve, delayMillis); @@ -328,7 +316,7 @@ export class HttpClient { * @returns A 2-tuple where the 1st element is the duration to wait before another retry, and the * 2nd element is a boolean indicating whether the request is eligible for a retry or not. */ - private getRetryDelayMillis(retryAttempts: number, err: LowLevelError): [number, boolean] { + protected getRetryDelayMillis(retryAttempts: number, err: LowLevelError): [number, boolean] { if (!this.isRetryEligible(retryAttempts, err)) { return [0, false]; } @@ -344,7 +332,7 @@ export class HttpClient { return [this.backOffDelayMillis(retryAttempts), true]; } - private isRetryEligible(retryAttempts: number, err: LowLevelError): boolean { + protected isRetryEligible(retryAttempts: number, err: LowLevelError): boolean { if (!this.retry) { return false; } @@ -366,11 +354,11 @@ export class HttpClient { return false; } - /** - * Parses the Retry-After HTTP header as a milliseconds value. Return value is negative if the Retry-After header + /**??? + * Parses the Retry-After header as a milliseconds value. Return value is negative if the Retry-After header * contains an expired timestamp or otherwise malformed. */ - private parseRetryAfterIntoMillis(retryAfter: string): number { + protected parseRetryAfterIntoMillis(retryAfter: string): number { const delaySeconds: number = parseInt(retryAfter, 10); if (!isNaN(delaySeconds)) { return delaySeconds * 1000; @@ -383,7 +371,7 @@ export class HttpClient { return -1; } - private backOffDelayMillis(retryAttempts: number): number { + protected backOffDelayMillis(retryAttempts: number): number { if (retryAttempts === 0) { return 0; } @@ -398,15 +386,139 @@ export class HttpClient { } } +export class HttpClient extends RequestClient { + + constructor(retry?: RetryConfig | null) { + super(retry) + } + + /** + * Sends an HTTP request to a remote server. If the server responds with a successful response (2xx), the returned + * promise resolves with an `RequestResponse`. If the server responds with an error (3xx, 4xx, 5xx), the promise + * rejects with an `RequestResponseError`. In case of all other errors, the promise rejects with a `FirebaseAppError`. + * If a request fails due to a low-level network error, the client transparently retries the request once before + * rejecting the promise. + * + * If the request data is specified as an object, it will be serialized into a JSON string. The application/json + * content-type header will also be automatically set in this case. For all other payload types, the content-type + * header should be explicitly set by the caller. To send a JSON leaf value (e.g. "foo", 5), parse it into JSON, + * and pass as a string or a Buffer along with the appropriate content-type header. + * + * @param config - HTTP request to be sent. + * @returns A promise that resolves with the response details. + */ + public send(config: HttpRequestConfig): Promise { + return this.sendWithRetry(config); + } + + /** + * Sends an HTTP request. In the event of an error, retries the HTTP request according to the + * `RetryConfig` set on the `HttpClient`. + * + * @param config - HTTP request to be sent. + * @param retryAttempts - Number of retries performed up to now. + * @returns A promise that resolves with the response details. + */ + private sendWithRetry(config: HttpRequestConfig, retryAttempts = 0): Promise { + return AsyncHttpCall.invoke(config) + .then((resp) => { + return this.createRequestResponse(resp); + }) + .catch((err: LowLevelError) => { + const [delayMillis, canRetry] = this.getRetryDelayMillis(retryAttempts, err); + if (canRetry && this.retry && delayMillis <= this.retry.maxDelayInMillis) { + return this.waitForRetry(delayMillis).then(() => { + return this.sendWithRetry(config, retryAttempts + 1); + }); + } + + if (err.response) { + throw new RequestResponseError(this.createRequestResponse(err.response)); + } + + if (err.code === 'ETIMEDOUT') { + throw new FirebaseAppError( + AppErrorCodes.NETWORK_TIMEOUT, + `Error while making request: ${err.message}.`); + } + throw new FirebaseAppError( + AppErrorCodes.NETWORK_ERROR, + `Error while making request: ${err.message}. Error code: ${err.code}`); + }); + } +} + +export class Http2Client extends RequestClient { + + constructor(retry: RetryConfig | null = defaultRetryConfig()) { + super(retry); + } + + /** + * Sends an HTTP/2 request to a remote server. If the server responds with a successful response (2xx), the returned + * promise resolves with an `RequestResponse`. If the server responds with an error (3xx, 4xx, 5xx), the promise + * rejects with an `RequestResponseError`. In case of all other errors, the promise rejects with a `FirebaseAppError`. + * If a request fails due to a low-level network error, the client transparently retries the request once before + * rejecting the promise. + * + * If the request data is specified as an object, it will be serialized into a JSON string. The application/json + * content-type header will also be automatically set in this case. For all other payload types, the content-type + * header should be explicitly set by the caller. To send a JSON leaf value (e.g. "foo", 5), parse it into JSON, + * and pass as a string or a Buffer along with the appropriate content-type header. + * + * @param config - HTTP/2 request to be sent. + * @returns A promise that resolves with the response details. + */ + public send(config: Http2RequestConfig): Promise { + return this.sendWithRetry(config); + } + + /** + * Sends an HTTP/2 request. In the event of an error, retries the HTTP/2 request according to the + * `RetryConfig` set on the `Http2Client`. + * + * @param config - HTTP/2 request to be sent. + * @param retryAttempts - Number of retries performed up to now. + * @returns A promise that resolves with the response details. + */ + private sendWithRetry(config: Http2RequestConfig, retryAttempts = 0): Promise { + return AsyncHttp2Call.invoke(config) + .then((resp) => { + return this.createRequestResponse(resp); + }) + .catch((err: LowLevelError) => { + const [delayMillis, canRetry] = this.getRetryDelayMillis(retryAttempts, err); + if (canRetry && this.retry && delayMillis <= this.retry.maxDelayInMillis) { + return this.waitForRetry(delayMillis).then(() => { + return this.sendWithRetry(config, retryAttempts + 1); + }); + } + + if (err.response) { + throw new RequestResponseError(this.createRequestResponse(err.response)); + } + + if (err.code === 'ETIMEDOUT') { + throw new FirebaseAppError( + AppErrorCodes.NETWORK_TIMEOUT, + `Error while making request: ${err.message}.`); + } + throw new FirebaseAppError( + AppErrorCodes.NETWORK_ERROR, + `Error while making request: ${err.message}. Error code: ${err.code}`); + }); + } +} + /** - * Parses a full HTTP response message containing both a header and a body. + * Parses a full HTTP or HTTP/2 response message containing both a header and a body. * - * @param response - The HTTP response to be parsed. - * @param config - The request configuration that resulted in the HTTP response. - * @returns An object containing the parsed HTTP status, headers and the body. + * @param response - The HTTP or HTTP/2 response to be parsed. + * @param config - The request configuration that resulted in the HTTP or HTTP/2 response. + * @returns An object containing the response's parsed status, headers and the body. */ export function parseHttpResponse( - response: string | Buffer, config: HttpRequestConfig): HttpResponse { + response: string | Buffer, config: RequestConfig): RequestResponse { const responseText: string = validator.isBuffer(response) ? response.toString('utf-8') : response as string; @@ -442,101 +554,21 @@ export function parseHttpResponse( if (!validator.isNumber(lowLevelResponse.status)) { throw new FirebaseAppError(AppErrorCodes.INTERNAL_ERROR, 'Malformed HTTP status line.'); } - return new DefaultHttpResponse(lowLevelResponse); + return new DefaultRequestResponse(lowLevelResponse); } /** - * A helper class for sending HTTP requests over the wire. This is a wrapper around the standard - * http and https packages of Node.js, providing content processing, timeouts and error handling. + * A helper class for common functionality needed to send requests over the wire. * It also wraps the callback API of the Node.js standard library in a more flexible Promise API. */ -class AsyncHttpCall { - - private readonly config: HttpRequestConfigImpl; - private readonly options: https.RequestOptions; - private readonly entity: Buffer | undefined; - private readonly promise: Promise; - - private resolve: (_: any) => void; - private reject: (_: any) => void; - - /** - * Sends an HTTP request based on the provided configuration. - */ - public static invoke(config: HttpRequestConfig): Promise { - return new AsyncHttpCall(config).promise; - } - - private constructor(config: HttpRequestConfig) { - try { - this.config = new HttpRequestConfigImpl(config); - this.options = this.config.buildRequestOptions(); - this.entity = this.config.buildEntity(this.options.headers!); - this.promise = new Promise((resolve, reject) => { - this.resolve = resolve; - this.reject = reject; - this.execute(); - }); - } catch (err) { - this.promise = Promise.reject(this.enhanceError(err, null)); - } - } - - private execute(): void { - const transport: any = this.options.protocol === 'https:' ? https : http; - const req: http.ClientRequest = transport.request(this.options, (res: http.IncomingMessage) => { - this.handleResponse(res, req); - }); - - // Handle errors - req.on('error', (err) => { - if (req.aborted) { - return; - } - this.enhanceAndReject(err, null, req); - }); - - const timeout: number | undefined = this.config.timeout; - const timeoutCallback: () => void = () => { - req.abort(); - this.rejectWithError(`timeout of ${timeout}ms exceeded`, 'ETIMEDOUT', req); - }; - if (timeout) { - // Listen to timeouts and throw an error. - req.setTimeout(timeout, timeoutCallback); - } - - // Send the request - req.end(this.entity); - } - - private handleResponse(res: http.IncomingMessage, req: http.ClientRequest): void { - if (req.aborted) { - return; - } +class AsyncRequestCall { + protected resolve: (_: any) => void; + protected reject: (_: any) => void; + protected options: https.RequestOptions; + protected entity: Buffer | undefined; + protected promise: Promise; - if (!res.statusCode) { - throw new FirebaseAppError( - AppErrorCodes.INTERNAL_ERROR, - 'Expected a statusCode on the response from a ClientRequest'); - } - - const response: LowLevelResponse = { - status: res.statusCode, - headers: res.headers, - request: req, - data: undefined, - config: this.config, - }; - const boundary = this.getMultipartBoundary(res.headers); - const respStream: Readable = this.uncompressResponse(res); - - if (boundary) { - this.handleMultipartResponse(response, respStream, boundary); - } else { - this.handleRegularResponse(response, respStream); - } - } + constructor(private readonly configImpl: HttpRequestConfigImpl | Http2RequestConfigImpl) {} /** * Extracts multipart boundary from the HTTP header. The content-type header of a multipart @@ -545,7 +577,7 @@ class AsyncHttpCall { * If the content-type header does not exist, or does not start with * 'multipart/', then null will be returned. */ - private getMultipartBoundary(headers: http.IncomingHttpHeaders): string | null { + protected getMultipartBoundary(headers: http.IncomingHttpHeaders): string | null { const contentType = headers['content-type']; if (!contentType || !contentType.startsWith('multipart/')) { return null; @@ -568,21 +600,7 @@ class AsyncHttpCall { return headerParams.boundary; } - private uncompressResponse(res: http.IncomingMessage): Readable { - // Uncompress the response body transparently if required. - let respStream: Readable = res; - const encodings = ['gzip', 'compress', 'deflate']; - if (res.headers['content-encoding'] && encodings.indexOf(res.headers['content-encoding']) !== -1) { - // Add the unzipper to the body stream processing pipeline. - const zlib: typeof zlibmod = require('zlib'); // eslint-disable-line @typescript-eslint/no-var-requires - respStream = respStream.pipe(zlib.createUnzip()); - // Remove the content-encoding in order to not confuse downstream operations. - delete res.headers['content-encoding']; - } - return respStream; - } - - private handleMultipartResponse( + protected handleMultipartResponse( response: LowLevelResponse, respStream: Readable, boundary: string): void { const busboy = require('@fastify/busboy'); // eslint-disable-line @typescript-eslint/no-var-requires @@ -609,15 +627,15 @@ class AsyncHttpCall { respStream.pipe(multipartParser); } - private handleRegularResponse(response: LowLevelResponse, respStream: Readable): void { + protected handleRegularResponse(response: LowLevelResponse, respStream: Readable): void { const responseBuffer: Buffer[] = []; respStream.on('data', (chunk: Buffer) => { responseBuffer.push(chunk); }); respStream.on('error', (err) => { - const req: http.ClientRequest | null = response.request; - if (req && req.aborted) { + const req = response.request; + if (req && req.destroyed) { return; } this.enhanceAndReject(err, null, req); @@ -630,10 +648,10 @@ class AsyncHttpCall { } /** - * Finalizes the current HTTP call in-flight by either resolving or rejecting the associated + * Finalizes the current request call in-flight by either resolving or rejecting the associated * promise. In the event of an error, adds additional useful information to the returned error. */ - private finalizeResponse(response: LowLevelResponse): void { + protected finalizeResponse(response: LowLevelResponse): void { if (response.status >= 200 && response.status < 300) { this.resolve(response); } else { @@ -648,38 +666,38 @@ class AsyncHttpCall { /** * Creates a new error from the given message, and enhances it with other information available. - * Then the promise associated with this HTTP call is rejected with the resulting error. + * Then the promise associated with this request call is rejected with the resulting error. */ - private rejectWithError( + protected rejectWithError( message: string, code?: string | null, - request?: http.ClientRequest | null, + request?: http.ClientRequest | http2.ClientHttp2Stream | null, response?: LowLevelResponse): void { const error = new Error(message); this.enhanceAndReject(error, code, request, response); } - private enhanceAndReject( + protected enhanceAndReject( error: any, code?: string | null, - request?: http.ClientRequest | null, + request?: http.ClientRequest | http2.ClientHttp2Stream | null, response?: LowLevelResponse): void { this.reject(this.enhanceError(error, code, request, response)); } /** - * Enhances the given error by adding more information to it. Specifically, the HttpRequestConfig, + * Enhances the given error by adding more information to it. Specifically, the request config, * the underlying request and response will be attached to the error. */ - private enhanceError( + protected enhanceError( error: any, code?: string | null, - request?: http.ClientRequest | null, + request?: http.ClientRequest | http2.ClientHttp2Stream | null, response?: LowLevelResponse): LowLevelError { - error.config = this.config; + error.config = this.configImpl; if (code) { error.code = code; } @@ -690,12 +708,220 @@ class AsyncHttpCall { } /** - * An adapter class for extracting options and entity data from an HttpRequestConfig. + * A helper class for sending HTTP requests over the wire. This is a wrapper around the standard + * http and https packages of Node.js, providing content processing, timeouts and error handling. + * It also wraps the callback API of the Node.js standard library in a more flexible Promise API. */ -class HttpRequestConfigImpl implements HttpRequestConfig { +class AsyncHttpCall extends AsyncRequestCall { + private readonly httpConfigImpl: HttpRequestConfigImpl; + + /** + * Sends an HTTP request based on the provided configuration. + */ + public static invoke(config: HttpRequestConfig): Promise { + return new AsyncHttpCall(config).promise; + } + + private constructor(config: HttpRequestConfig) { + const httpConfigImpl = new HttpRequestConfigImpl(config); + super(httpConfigImpl) + try { + this.httpConfigImpl = httpConfigImpl; + this.options = this.httpConfigImpl.buildRequestOptions(); + this.entity = this.httpConfigImpl.buildEntity(this.options.headers!); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + this.execute(); + }); + } catch (err) { + this.promise = Promise.reject(this.enhanceError(err, null)); + } + } + + private execute(): void { + const transport: any = this.options.protocol === 'https:' ? https : http; + const req: http.ClientRequest = transport.request(this.options, (res: http.IncomingMessage) => { + this.handleResponse(res, req); + }); + + // Handle errors + req.on('error', (err) => { + if (req.aborted) { + return; + } + this.enhanceAndReject(err, null, req); + }); - constructor(private readonly config: HttpRequestConfig) { + const timeout: number | undefined = this.httpConfigImpl.timeout; + const timeoutCallback: () => void = () => { + req.destroy(); + this.rejectWithError(`timeout of ${timeout}ms exceeded`, 'ETIMEDOUT', req); + }; + if (timeout) { + // Listen to timeouts and throw an error. + req.setTimeout(timeout, timeoutCallback); + } + // Send the request + req.end(this.entity); + } + + private handleResponse(res: http.IncomingMessage, req: http.ClientRequest): void { + if (req.aborted) { + return; + } + + if (!res.statusCode) { + throw new FirebaseAppError( + AppErrorCodes.INTERNAL_ERROR, + 'Expected a statusCode on the response from a ClientRequest'); + } + + const response: LowLevelResponse = { + status: res.statusCode, + headers: res.headers, + request: req, + data: undefined, + config: this.httpConfigImpl, + }; + const boundary = this.getMultipartBoundary(res.headers); + const respStream: Readable = this.uncompressResponse(res); + + if (boundary) { + this.handleMultipartResponse(response, respStream, boundary); + } else { + this.handleRegularResponse(response, respStream); + } + } + + private uncompressResponse(res: http.IncomingMessage): Readable { + // Uncompress the response body transparently if required. + let respStream: Readable = res; + const encodings = ['gzip', 'compress', 'deflate']; + if (res.headers['content-encoding'] && encodings.indexOf(res.headers['content-encoding']) !== -1) { + // Add the unzipper to the body stream processing pipeline. + const zlib: typeof zlibmod = require('zlib'); // eslint-disable-line @typescript-eslint/no-var-requires + respStream = respStream.pipe(zlib.createUnzip()); + // Remove the content-encoding in order to not confuse downstream operations. + delete res.headers['content-encoding']; + } + return respStream; + } +} + +class AsyncHttp2Call extends AsyncRequestCall { + private readonly http2ConfigImpl: Http2RequestConfigImpl + + /** + * Sends an HTTP2 request based on the provided configuration. + */ + public static invoke(config: Http2RequestConfig): Promise { + return new AsyncHttp2Call(config).promise; + } + + private constructor(config: Http2RequestConfig) { + const http2ConfigImpl = new Http2RequestConfigImpl(config); + super(http2ConfigImpl) + try { + this.http2ConfigImpl = http2ConfigImpl; + this.options = this.http2ConfigImpl.buildRequestOptions(); + this.entity = this.http2ConfigImpl.buildEntity(this.options.headers!); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + this.execute(); + }); + } catch (err) { + this.promise = Promise.reject(this.enhanceError(err, null)); + } + } + + private execute(): void { + const req = this.http2ConfigImpl.http2SessionHandler.session.request({ + ':method': this.options.method, + ':scheme': this.options.protocol!, + ':path': this.options.path!, + ...this.options.headers + }); + + req.on('response', (headers: IncomingHttp2Headers) => { + this.handleHttp2Response(headers, req); + }); + + // Handle errors + req.on('error', (err: any) => { + if (req.aborted) { + return; + } + this.enhanceAndReject(err, null, req); + }); + + const timeout: number | undefined = this.http2ConfigImpl.timeout; + const timeoutCallback: () => void = () => { + req.destroy(); + this.rejectWithError(`timeout of ${timeout}ms exceeded`, 'ETIMEDOUT', req); + }; + + if (timeout) { + // Listen to timeouts and throw an error. + req.setTimeout(timeout, timeoutCallback); + } + + req.end(this.entity); + } + + private handleHttp2Response(headers: IncomingHttp2Headers, stream: http2.ClientHttp2Stream): void{ + if (stream.aborted) { + return; + } + + if (!headers[':status']) { + throw new FirebaseAppError( + AppErrorCodes.INTERNAL_ERROR, + 'Expected a statusCode on the response from a ClientRequest'); + } + + const response: LowLevelHttp2Response = { + status: headers[':status'], + headers: headers, + request: stream, + data: undefined, + config: this.http2ConfigImpl, + }; + + const boundary = this.getMultipartBoundary(headers); + const respStream: Readable = this.uncompressResponse(headers, stream); + + if (boundary) { + this.handleMultipartResponse(response, respStream, boundary); + } else { + this.handleRegularResponse(response, respStream); + } + } + + private uncompressResponse(headers: IncomingHttp2Headers, stream: http2.ClientHttp2Stream): Readable { + // Uncompress the response body transparently if required. + let respStream: Readable = stream; + const encodings = ['gzip', 'compress', 'deflate']; + if (headers['content-encoding'] && encodings.indexOf(headers['content-encoding']) !== -1) { + // Add the unzipper to the body stream processing pipeline. + const zlib: typeof zlibmod = require('zlib'); // eslint-disable-line @typescript-eslint/no-var-requires + respStream = respStream.pipe(zlib.createUnzip()); + // Remove the content-encoding in order to not confuse downstream operations. + delete headers['content-encoding']; + } + return respStream; + } +} + +/** + * An adapter class with common functionality needed to extract options and entity data from a `RequestConfig`. + */ +class BaseRequestConfigImpl implements BaseRequestConfig { + + constructor(protected readonly config: RequestConfig) { + this.config = config } get method(): HttpMethod { @@ -718,36 +944,11 @@ class HttpRequestConfigImpl implements HttpRequestConfig { return this.config.timeout; } - get httpAgent(): http.Agent | undefined { - return this.config.httpAgent; - } - - public buildRequestOptions(): https.RequestOptions { - const parsed = this.buildUrl(); - const protocol = parsed.protocol; - let port: string | null = parsed.port; - if (!port) { - const isHttps = protocol === 'https:'; - port = isHttps ? '443' : '80'; - } - - return { - protocol, - hostname: parsed.hostname, - port, - path: parsed.path, - method: this.method, - agent: this.httpAgent, - headers: Object.assign({}, this.headers), - }; - } - public buildEntity(headers: http.OutgoingHttpHeaders): Buffer | undefined { let data: Buffer | undefined; if (!this.hasEntity() || !this.isEntityEnclosingRequest()) { return data; } - if (validator.isBuffer(this.data)) { data = this.data as Buffer; } else if (validator.isObject(this.data)) { @@ -760,22 +961,19 @@ class HttpRequestConfigImpl implements HttpRequestConfig { } else { throw new Error('Request data must be a string, a Buffer or a json serializable object'); } - // Add Content-Length header if data exists. headers['Content-Length'] = data.length.toString(); return data; } - private buildUrl(): url.UrlWithStringQuery { + protected buildUrl(): url.UrlWithStringQuery { const fullUrl: string = this.urlWithProtocol(); if (!this.hasEntity() || this.isEntityEnclosingRequest()) { return url.parse(fullUrl); } - if (!validator.isObject(this.data)) { throw new Error(`${this.method} requests cannot have a body`); } - // Parse URL and append data to query string. const parsedUrl = new url.URL(fullUrl); const dataObj = this.data as {[key: string]: string}; @@ -784,11 +982,10 @@ class HttpRequestConfigImpl implements HttpRequestConfig { parsedUrl.searchParams.append(key, dataObj[key]); } } - return url.parse(parsedUrl.toString()); } - private urlWithProtocol(): string { + protected urlWithProtocol(): string { const fullUrl: string = this.url; if (fullUrl.startsWith('http://') || fullUrl.startsWith('https://')) { return fullUrl; @@ -796,22 +993,83 @@ class HttpRequestConfigImpl implements HttpRequestConfig { return `https://${fullUrl}`; } - private hasEntity(): boolean { + protected hasEntity(): boolean { return !!this.data; } - private isEntityEnclosingRequest(): boolean { + protected isEntityEnclosingRequest(): boolean { // GET and HEAD requests do not support entity (body) in request. return this.method !== 'GET' && this.method !== 'HEAD'; } } +/** + * An adapter class for extracting options and entity data from an `HttpRequestConfig`. + */ +class HttpRequestConfigImpl extends BaseRequestConfigImpl implements HttpRequestConfig { + + constructor(private readonly httpConfig: HttpRequestConfig) { + super(httpConfig) + } + + get httpAgent(): http.Agent | undefined { + return this.httpConfig.httpAgent; + } + + public buildRequestOptions(): https.RequestOptions { + const parsed = this.buildUrl(); + const protocol = parsed.protocol; + let port: string | null = parsed.port; + if (!port) { + const isHttps = protocol === 'https:'; + port = isHttps ? '443' : '80'; + } + + return { + protocol, + hostname: parsed.hostname, + port, + path: parsed.path, + method: this.method, + agent: this.httpAgent, + headers: Object.assign({}, this.headers), + }; + } +} + +/** + * An adapter class for extracting options and entity data from an `Http2RequestConfig`. + */ +class Http2RequestConfigImpl extends BaseRequestConfigImpl implements Http2RequestConfig { + + constructor(private readonly http2Config: Http2RequestConfig) { + super(http2Config) + } + + get http2SessionHandler(): Http2SessionHandler { + return this.http2Config.http2SessionHandler; + } + + public buildRequestOptions(): https.RequestOptions { + const parsed = this.buildUrl(); + const protocol = parsed.protocol; + + return { + protocol, + path: parsed.path, + method: this.method, + headers: Object.assign({}, this.headers), + }; + } +} + export class AuthorizedHttpClient extends HttpClient { + constructor(private readonly app: FirebaseApp) { super(); } - public send(request: HttpRequestConfig): Promise { + public send(request: HttpRequestConfig): Promise { return this.getToken().then((token) => { const requestCopy = Object.assign({}, request); requestCopy.headers = Object.assign({}, request.headers); @@ -833,9 +1091,30 @@ export class AuthorizedHttpClient extends HttpClient { protected getToken(): Promise { return this.app.INTERNAL.getToken() - .then((accessTokenObj) => { - return accessTokenObj.accessToken; - }); + .then((accessTokenObj) => accessTokenObj.accessToken); + } +} + +export class AuthorizedHttp2Client extends Http2Client { + + constructor(private readonly app: FirebaseApp) { + super(); + } + + public send(request: Http2RequestConfig): Promise { + return this.getToken().then((token) => { + const requestCopy = Object.assign({}, request); + requestCopy.headers = Object.assign({}, request.headers); + const authHeader = 'Authorization'; + requestCopy.headers[authHeader] = `Bearer ${token}`; + + return super.send(requestCopy); + }); + } + + protected getToken(): Promise { + return this.app.INTERNAL.getToken() + .then((accessTokenObj) => accessTokenObj.accessToken); } } @@ -843,7 +1122,7 @@ export class AuthorizedHttpClient extends HttpClient { * Class that defines all the settings for the backend API endpoint. * * @param endpoint - The Firebase Auth backend endpoint. - * @param httpMethod - The http method for that endpoint. + * @param httpMethod - The HTTP method for that endpoint. * @constructor */ export class ApiSettings { @@ -1013,3 +1292,51 @@ export class ExponentialBackoffPoller extends EventEmitter { } } } + +export class Http2SessionHandler { + + private http2Session: http2.ClientHttp2Session + + constructor(url: string){ + this.http2Session = this.createSession(url) + } + + public createSession(url: string): http2.ClientHttp2Session { + if (!this.http2Session || this.isClosed ) { + const opts: http2.SecureClientSessionOptions = { + // Set local max concurrent stream limit to respect backend limit + peerMaxConcurrentStreams: 100, + ALPNProtocols: ['h2'] + } + const http2Session = http2.connect(url, opts) + + http2Session.on('goaway', (errorCode, _, opaqueData) => { + throw new FirebaseAppError( + AppErrorCodes.NETWORK_ERROR, + `Error while making requests: GOAWAY - ${opaqueData.toString()}, Error code: ${errorCode}` + ); + }) + + http2Session.on('error', (error) => { + throw new FirebaseAppError( + AppErrorCodes.NETWORK_ERROR, + `Error while making requests: ${error}` + ); + }) + return http2Session + } + return this.http2Session + } + + get session(): http2.ClientHttp2Session { + return this.http2Session + } + + get isClosed(): boolean { + return this.http2Session.closed + } + + public close(): void { + this.http2Session.close() + } +} \ No newline at end of file diff --git a/src/utils/crypto-signer.ts b/src/utils/crypto-signer.ts index ec33a3a714..3123cee209 100644 --- a/src/utils/crypto-signer.ts +++ b/src/utils/crypto-signer.ts @@ -18,7 +18,7 @@ import { App } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import { ServiceAccountCredential } from '../app/credential-internal'; -import { AuthorizedHttpClient, HttpRequestConfig, HttpClient, HttpError } from './api-request'; +import { AuthorizedHttpClient, HttpRequestConfig, HttpClient, RequestResponseError } from './api-request'; import { Algorithm } from 'jsonwebtoken'; import { ErrorInfo } from '../utils/error'; @@ -138,7 +138,7 @@ export class IAMSigner implements CryptoSigner { // Response from IAM is base64 encoded. Decode it into a buffer and return. return Buffer.from(response.data.signedBlob, 'base64'); }).catch((err) => { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { throw new CryptoSignerError({ code: CryptoSignerErrorCode.SERVER_ERROR, message: err.message, diff --git a/src/utils/jwt.ts b/src/utils/jwt.ts index acd1038d2f..5d8f88344f 100644 --- a/src/utils/jwt.ts +++ b/src/utils/jwt.ts @@ -17,7 +17,7 @@ import * as validator from './validator'; import * as jwt from 'jsonwebtoken'; import * as jwks from 'jwks-rsa'; -import { HttpClient, HttpRequestConfig, HttpError } from '../utils/api-request'; +import { HttpClient, HttpRequestConfig, RequestResponseError } from '../utils/api-request'; import { Agent } from 'http'; export const ALGORITHM_RS256: jwt.Algorithm = 'RS256' as const; @@ -140,7 +140,7 @@ export class UrlKeyFetcher implements KeyFetcher { if (!resp.isJson() || resp.data.error) { // Treat all non-json messages and messages with an 'error' field as // error responses. - throw new HttpError(resp); + throw new RequestResponseError(resp); } // reset expire at from previous set of keys. this.publicKeysExpireAt = 0; @@ -158,7 +158,7 @@ export class UrlKeyFetcher implements KeyFetcher { this.publicKeys = resp.data; return resp.data; }).catch((err) => { - if (err instanceof HttpError) { + if (err instanceof RequestResponseError) { let errorMessage = 'Error fetching public keys for Google certs: '; const resp = err.response; if (resp.isJson() && resp.data.error) { diff --git a/test/integration/messaging.spec.ts b/test/integration/messaging.spec.ts index 0a17a2d750..d11b035861 100644 --- a/test/integration/messaging.spec.ts +++ b/test/integration/messaging.spec.ts @@ -17,6 +17,7 @@ import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import { Message, MulticastMessage, getMessaging } from '../../lib/messaging/index'; +import { legacyTransportApp } from './setup'; chai.should(); chai.use(chaiAsPromised); @@ -101,6 +102,11 @@ const options = { }; describe('admin.messaging', () => { + + before(() => { + getMessaging(legacyTransportApp).enableLegacyHttpTransport() + }) + it('send(message, dryRun) returns a message ID', () => { return getMessaging().send(message, true) .then((name) => { @@ -110,7 +116,7 @@ describe('admin.messaging', () => { it('sendEach()', () => { const messages: Message[] = [message, message, message]; - return getMessaging().sendEach(messages, true) + return getMessaging(legacyTransportApp).sendEach(messages, true) .then((response) => { expect(response.responses.length).to.equal(messages.length); expect(response.successCount).to.equal(messages.length); @@ -123,6 +129,37 @@ describe('admin.messaging', () => { }); it('sendEach(500)', () => { + const messages: Message[] = []; + for (let i = 0; i < 500; i++) { + messages.push({ topic: `foo-bar-${i % 10}` }); + } + return getMessaging(legacyTransportApp).sendEach(messages, true) + .then((response) => { + expect(response.responses.length).to.equal(messages.length); + expect(response.successCount).to.equal(messages.length); + expect(response.failureCount).to.equal(0); + response.responses.forEach((resp) => { + expect(resp.success).to.be.true; + expect(resp.messageId).matches(/^projects\/.*\/messages\/.*$/); + }); + }); + }); + + it('sendEach() using HTTP2', () => { + const messages: Message[] = [message, message, message]; + return getMessaging().sendEach(messages, true) + .then((response) => { + expect(response.responses.length).to.equal(messages.length); + expect(response.successCount).to.equal(messages.length); + expect(response.failureCount).to.equal(0); + response.responses.forEach((resp) => { + expect(resp.success).to.be.true; + expect(resp.messageId).matches(/^projects\/.*\/messages\/.*$/); + }); + }); + }); + + it('sendEach(500) using HTTP2', () => { const messages: Message[] = []; for (let i = 0; i < 500; i++) { messages.push({ topic: `foo-bar-${i % 10}` }); @@ -171,6 +208,25 @@ describe('admin.messaging', () => { }); it('sendEachForMulticast()', () => { + const multicastMessage: MulticastMessage = { + data: message.data, + android: message.android, + tokens: ['not-a-token', 'also-not-a-token'], + }; + return getMessaging(legacyTransportApp).sendEachForMulticast(multicastMessage, true) + .then((response) => { + expect(response.responses.length).to.equal(2); + expect(response.successCount).to.equal(0); + expect(response.failureCount).to.equal(2); + response.responses.forEach((resp) => { + expect(resp.success).to.be.false; + expect(resp.messageId).to.be.undefined; + expect(resp.error).to.have.property('code', 'messaging/invalid-argument'); + }); + }); + }); + + it('sendEachForMulticast() using HTTP2', () => { const multicastMessage: MulticastMessage = { data: message.data, android: message.android, diff --git a/test/integration/setup.ts b/test/integration/setup.ts index fa217120f2..8c700d4c41 100644 --- a/test/integration/setup.ts +++ b/test/integration/setup.ts @@ -31,6 +31,7 @@ export let projectId: string; export let apiKey: string; export let defaultApp: App; +export let legacyTransportApp: App; export let nullApp: App; export let nonNullApp: App; export let noServiceAccountApp: App; @@ -92,6 +93,13 @@ before(() => { storageBucket, }); + legacyTransportApp = initializeApp({ + ...getCredential(), + projectId, + databaseURL: databaseUrl, + storageBucket, + }, 'legacyTransport'); + nullApp = initializeApp({ ...getCredential(), projectId, @@ -127,6 +135,7 @@ before(() => { after(() => { return Promise.all([ deleteApp(defaultApp), + deleteApp(legacyTransportApp), deleteApp(nullApp), deleteApp(nonNullApp), deleteApp(noServiceAccountApp), diff --git a/test/resources/mocks.ts b/test/resources/mocks.ts index a528dd5497..626e9663cb 100644 --- a/test/resources/mocks.ts +++ b/test/resources/mocks.ts @@ -21,9 +21,11 @@ import path = require('path'); import events = require('events'); import stream = require('stream'); +import http2 = require('http2'); import * as _ from 'lodash'; import * as jwt from 'jsonwebtoken'; +import * as sinon from 'sinon'; import { AppOptions } from '../../src/firebase-namespace-api'; import { FirebaseApp } from '../../src/app/firebase-app'; @@ -310,6 +312,93 @@ export class MockStream extends stream.PassThrough { public abort: () => void = () => undefined; } +export interface MockHttp2Request { + headers: http2.OutgoingHttpHeaders, + data: any +} + +export interface MockHttp2Response { + headers: http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader, + data: Buffer, + delay?: number, + error?: any +} + +export class Http2Mocker { + private connectStub: sinon.SinonStub | null; + private originalConnect = http2.connect; + private timeouts: NodeJS.Timeout[] = []; + private mockResponses: MockHttp2Response[] = []; + public requests: MockHttp2Request[] = []; + + public http2Stub(mockResponses: MockHttp2Response[]): void { + this.mockResponses = mockResponses + this.connectStub = sinon.stub(http2, 'connect'); + this.connectStub.callsFake((_target: any, options: any) => { + const session = this.originalConnect('https://www.example.com', options); + session.request = this.createMockRequest() + return session; + }) + } + + private createMockRequest() { + return (requestHeaders: http2.OutgoingHttpHeaders) => { + // Create a mock ClientHttp2Stream to return + const mockStream = new stream.Readable({ + // eslint-disable-next-line @typescript-eslint/no-empty-function + read() {} + }) as http2.ClientHttp2Stream; + + mockStream.end = (data: any) => { + this.requests.push({ headers: requestHeaders, data: data }) + return mockStream + }; + + mockStream.setTimeout = (timeout, callback: () => void) => { + this.timeouts.push(setTimeout(callback, timeout)) + } + + const mockRes = this.mockResponses.shift(); + if (mockRes) { + this.timeouts.push(setTimeout(() => { + if (mockRes.error) { + mockStream.emit('error', mockRes.error) + } + else { + mockStream.emit('response', mockRes.headers); + mockStream.emit('data', mockRes.data); + mockStream.emit('end'); + } + }, mockRes.delay)) + } + else { + throw Error('A mock request response was expected but not found.') + } + return mockStream; + } + } + + public done(): void { + // Clear timeouts + this.timeouts.forEach((timeout) => { + clearTimeout(timeout) + }) + + // Remove stub + if (this.connectStub) { + this.connectStub.restore(); + this.connectStub = null; + } + + // Check if all mock requests responces were used + if (this.mockResponses.length > 0) { + throw Error('A extra mock request was provided but not used.') + } + + this.requests = [] + } +} + /** * MESSAGING */ diff --git a/test/unit/messaging/batch-requests.spec.ts b/test/unit/messaging/batch-requests.spec.ts index fdde0c37f6..4f3b09957d 100644 --- a/test/unit/messaging/batch-requests.spec.ts +++ b/test/unit/messaging/batch-requests.spec.ts @@ -23,7 +23,7 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as utils from '../utils'; -import { HttpClient, HttpResponse, HttpRequestConfig, HttpError } from '../../../src/utils/api-request'; +import { HttpClient, RequestResponse, HttpRequestConfig, RequestResponseError } from '../../../src/utils/api-request'; import { SubRequest, BatchRequestClient } from '../../../src/messaging/batch-request-internal'; chai.should(); @@ -47,7 +47,7 @@ function getParsedPartData(obj: object): string { + `${json}`; } -function createMultipartResponse(success: object[], failures: object[] = []): HttpResponse { +function createMultipartResponse(success: object[], failures: object[] = []): RequestResponse { const multipart: Buffer[] = []; success.forEach((part) => { let payload = ''; @@ -97,7 +97,7 @@ describe('BatchRequestClient', () => { ]; const batch = new BatchRequestClient(httpClient, batchUrl); - const responses: HttpResponse[] = await batch.send(requests); + const responses: RequestResponse[] = await batch.send(requests); expect(responses.length).to.equal(1); expect(responses[0].status).to.equal(200); @@ -116,7 +116,7 @@ describe('BatchRequestClient', () => { ]; const batch = new BatchRequestClient(httpClient, batchUrl); - const responses: HttpResponse[] = await batch.send(requests); + const responses: RequestResponse[] = await batch.send(requests); expect(responses.length).to.equal(3); responses.forEach((response) => { @@ -137,7 +137,7 @@ describe('BatchRequestClient', () => { ]; const batch = new BatchRequestClient(httpClient, batchUrl); - const responses: HttpResponse[] = await batch.send(requests); + const responses: RequestResponse[] = await batch.send(requests); expect(responses.length).to.equal(3); responses.forEach((response, idx) => { @@ -163,8 +163,8 @@ describe('BatchRequestClient', () => { await batch.send(requests); sinon.assert.fail('No error thrown for HTTP error'); } catch (err) { - expect(err).to.be.instanceOf(HttpError); - expect((err as HttpError).response.status).to.equal(500); + expect(err).to.be.instanceOf(RequestResponseError); + expect((err as RequestResponseError).response.status).to.equal(500); checkOutgoingRequest(stub, requests); } }); @@ -180,7 +180,7 @@ describe('BatchRequestClient', () => { const commonHeaders = { 'X-Custom-Header': 'value' }; const batch = new BatchRequestClient(httpClient, batchUrl, commonHeaders); - const responses: HttpResponse[] = await batch.send(requests); + const responses: RequestResponse[] = await batch.send(requests); expect(responses.length).to.equal(1); expect(stub).to.have.been.calledOnce; @@ -205,7 +205,7 @@ describe('BatchRequestClient', () => { ]; const batch = new BatchRequestClient(httpClient, batchUrl); - const responses: HttpResponse[] = await batch.send(requests); + const responses: RequestResponse[] = await batch.send(requests); expect(responses.length).to.equal(1); expect(stub).to.have.been.calledOnce; @@ -229,7 +229,7 @@ describe('BatchRequestClient', () => { const commonHeaders = { 'X-Custom-Header': 'value' }; const batch = new BatchRequestClient(httpClient, batchUrl, commonHeaders); - const responses: HttpResponse[] = await batch.send(requests); + const responses: RequestResponse[] = await batch.send(requests); expect(responses.length).to.equal(1); expect(stub).to.have.been.calledOnce; diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index c343ea319d..a56767c123 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -80,6 +80,15 @@ function mockSendRequest(messageId = 'projects/projec_id/messages/message_id'): }); } +function mockHttp2SendRequestResponse(messageId = 'projects/projec_id/messages/message_id'): mocks.MockHttp2Response { + return { + headers: { + ':status': 200, + }, + data: Buffer.from(JSON.stringify({ name: `${messageId}` })), + } as mocks.MockHttp2Response +} + function mockBatchRequest(ids: string[]): nock.Scope { return mockBatchRequestWithErrors(ids); } @@ -127,6 +136,31 @@ function mockSendError( '/v1/projects/project_id/messages:send', statusCode, errorFormat, responseOverride); } +function mockHttp2SendRequestError( + statusCode: number, + errorFormat: 'json' | 'text', + responseOverride?: any, +): mocks.MockHttp2Response { + + let response; + let contentType: string; + if (errorFormat === 'json') { + response = Buffer.from(JSON.stringify(responseOverride || mockServerErrorResponse.json)); + contentType = 'application/json; charset=UTF-8'; + } else { + response = responseOverride || mockServerErrorResponse.text; + contentType = 'text/html; charset=UTF-8'; + } + + return { + headers: { + ':status': statusCode, + 'content-type': contentType + }, + data: Buffer.from(response) + } as mocks.MockHttp2Response +} + function mockBatchError( statusCode: number, errorFormat: 'json' | 'text', @@ -308,7 +342,10 @@ class CustomArray extends Array { } describe('Messaging', () => { let mockApp: FirebaseApp; let messaging: Messaging; + let legacyMessaging: Messaging; let mockedRequests: nock.Scope[] = []; + let mockedHttp2Responses: mocks.MockHttp2Response[] = [] + const http2Mocker: mocks.Http2Mocker = new mocks.Http2Mocker(); let httpsRequestStub: sinon.SinonStub; let getTokenStub: sinon.SinonStub; let nullAccessTokenMessaging: Messaging; @@ -332,6 +369,8 @@ describe('Messaging', () => { mockApp = mocks.app(); getTokenStub = utils.stubGetAccessToken(mockAccessToken, mockApp); messaging = new Messaging(mockApp); + legacyMessaging = new Messaging(mockApp); + legacyMessaging.enableLegacyHttpTransport(); nullAccessTokenMessaging = new Messaging(mocks.appReturningNullAccessToken()); messagingService = messaging; nullAccessTokenMessagingService = nullAccessTokenMessaging; @@ -343,6 +382,8 @@ describe('Messaging', () => { if (httpsRequestStub && httpsRequestStub.restore) { httpsRequestStub.restore(); } + http2Mocker.done() + mockedHttp2Responses = []; getTokenStub.restore(); return mockApp.delete(); }); @@ -610,7 +651,7 @@ describe('Messaging', () => { 'projects/projec_id/messages/1', ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) - return messaging.sendEach([invalidMessage, validMessage]) + return legacyMessaging.sendEach([invalidMessage, validMessage]) .then((response: BatchResponse) => { expect(response.successCount).to.equal(1); expect(response.failureCount).to.equal(1); @@ -633,7 +674,7 @@ describe('Messaging', () => { 'projects/projec_id/messages/3', ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) - return messaging.sendEach([validMessage, validMessage, validMessage]) + return legacyMessaging.sendEach([validMessage, validMessage, validMessage]) .then((response: BatchResponse) => { expect(response.successCount).to.equal(3); expect(response.failureCount).to.equal(0); @@ -667,7 +708,7 @@ describe('Messaging', () => { // for more context. arrayLike.constructor = CustomArray; - return messaging.sendEach(arrayLike) + return legacyMessaging.sendEach(arrayLike) .then((response: BatchResponse) => { expect(response.successCount).to.equal(3); expect(response.failureCount).to.equal(0); @@ -686,7 +727,7 @@ describe('Messaging', () => { 'projects/projec_id/messages/3', ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) - return messaging.sendEach([validMessage, validMessage, validMessage], true) + return legacyMessaging.sendEach([validMessage, validMessage, validMessage], true) .then((response: BatchResponse) => { expect(response.successCount).to.equal(3); expect(response.failureCount).to.equal(0); @@ -712,7 +753,7 @@ describe('Messaging', () => { ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) errors.forEach(error => mockedRequests.push(mockSendError(400, 'json', error))) - return messaging.sendEach([validMessage, validMessage, validMessage], true) + return legacyMessaging.sendEach([validMessage, validMessage, validMessage], true) .then((response: BatchResponse) => { expect(response.successCount).to.equal(2); expect(response.failureCount).to.equal(1); @@ -726,7 +767,7 @@ describe('Messaging', () => { }); }); - it('should be fulfilled with a BatchResponse for all failures given an app which' + + it('should be fulfilled with a BatchResponse for all failures given an app which ' + 'returns null access tokens', () => { return nullAccessTokenMessaging.sendEach( [validMessage, validMessage], @@ -757,7 +798,7 @@ describe('Messaging', () => { ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) errors.forEach(error => mockedRequests.push(mockSendError(404, 'json', error))) - return messaging.sendEach([validMessage, validMessage], true) + return legacyMessaging.sendEach([validMessage, validMessage], true) .then((response: BatchResponse) => { expect(response.successCount).to.equal(1); expect(response.failureCount).to.equal(1); @@ -780,7 +821,7 @@ describe('Messaging', () => { mockedRequests.push(mockSendError(404, 'json', error)); mockedRequests.push(mockSendError(400, 'json', { error: 'test error message' })); mockedRequests.push(mockSendError(400, 'text', 'foo bar')); - return messaging.sendEach( + return legacyMessaging.sendEach( [validMessage, validMessage, validMessage], ).then((response: BatchResponse) => { expect(response.failureCount).to.equal(3); @@ -805,8 +846,222 @@ describe('Messaging', () => { messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) - return messaging.sendEach(messages) + return legacyMessaging.sendEach(messages) + .then((response: BatchResponse) => { + expect(response.successCount).to.equal(3); + expect(response.failureCount).to.equal(0); + response.responses.forEach((resp, idx) => { + expect(resp.success).to.be.true; + expect(resp.messageId).to.equal(messageIds[idx]); + expect(resp.error).to.be.undefined; + }); + }); + }); + + it('should be fulfilled with a BatchResponse given valid messages using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + 'projects/projec_id/messages/2', + 'projects/projec_id/messages/3', + ]; + + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + http2Mocker.http2Stub(mockedHttp2Responses) + + return messaging.sendEach([validMessage, validMessage, validMessage], false) .then((response: BatchResponse) => { + expect(http2Mocker.requests.length).to.equal(3); + expect(response.successCount).to.equal(3); + expect(response.failureCount).to.equal(0); + expect(response.responses.length).to.equal(3); + response.responses.forEach((resp, idx) => { + checkSendResponseSuccess(resp, messageIds[idx]); + }); + }); + }); + + it('should be fulfilled with a BatchResponse given array-like (issue #566) using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + 'projects/projec_id/messages/2', + 'projects/projec_id/messages/3', + ]; + + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + http2Mocker.http2Stub(mockedHttp2Responses) + + const message = { + token: 'a', + android: { + ttl: 3600, + }, + }; + const arrayLike = new CustomArray(); + arrayLike.push(message); + arrayLike.push(message); + arrayLike.push(message); + // Explicitly patch the constructor so that down compiling to ES5 doesn't affect the test. + // See https://github.com/firebase/firebase-admin-node/issues/566#issuecomment-501974238 + // for more context. + arrayLike.constructor = CustomArray; + + return messaging.sendEach(arrayLike, false) + .then((response: BatchResponse) => { + expect(http2Mocker.requests.length).to.equal(3); + expect(response.successCount).to.equal(3); + expect(response.failureCount).to.equal(0); + response.responses.forEach((resp, idx) => { + expect(resp.success).to.be.true; + expect(resp.messageId).to.equal(messageIds[idx]); + expect(resp.error).to.be.undefined; + }); + }); + }); + + it('should be fulfilled with a BatchResponse given valid messages in dryRun mode using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + 'projects/projec_id/messages/2', + 'projects/projec_id/messages/3', + ]; + + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + http2Mocker.http2Stub(mockedHttp2Responses) + + return messaging.sendEach([validMessage, validMessage, validMessage], true) + .then((response: BatchResponse) => { + expect(http2Mocker.requests.length).to.equal(3); + expect(response.successCount).to.equal(3); + expect(response.failureCount).to.equal(0); + expect(response.responses.length).to.equal(3); + response.responses.forEach((resp, idx) => { + checkSendResponseSuccess(resp, messageIds[idx]); + }); + }); + }); + + it('should be fulfilled with a BatchResponse for partial failures using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + 'projects/projec_id/messages/2', + ]; + const errors = [ + { + error: { + status: 'INVALID_ARGUMENT', + message: 'test error message', + }, + }, + ]; + + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + errors.forEach(error => mockedHttp2Responses.push(mockHttp2SendRequestError(400, 'json', error))) + http2Mocker.http2Stub(mockedHttp2Responses) + + return messaging.sendEach([validMessage, validMessage, validMessage], true) + .then((response: BatchResponse) => { + expect(http2Mocker.requests.length).to.equal(3); + expect(response.successCount).to.equal(2); + expect(response.failureCount).to.equal(1); + expect(response.responses.length).to.equal(3); + + const responses = response.responses; + checkSendResponseSuccess(responses[0], messageIds[0]); + checkSendResponseSuccess(responses[1], messageIds[1]); + checkSendResponseFailure( + responses[2], 'messaging/invalid-argument', 'test error message'); + }); + }); + + it('should be fulfilled with a BatchResponse for all failures given an app which ' + + 'returns null access tokens using HTTP/2', () => { + return nullAccessTokenMessaging.sendEach( + [validMessage, validMessage], false).then((response: BatchResponse) => { + expect(response.failureCount).to.equal(2); + response.responses.forEach(resp => checkSendResponseFailure( + resp, 'app/invalid-credential')); + }); + }); + + it('should expose the FCM error code in a detailed error via BatchResponse using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + ]; + const errors = [ + { + error: { + ':status': 'INVALID_ARGUMENT', + message: 'test error message', + details: [ + { + '@type': 'type.googleapis.com/google.firebase.fcm.v1.FcmError', + 'errorCode': 'UNREGISTERED', + }, + ], + }, + }, + ]; + + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + errors.forEach(error => mockedHttp2Responses.push(mockHttp2SendRequestError(400, 'json', error))) + http2Mocker.http2Stub(mockedHttp2Responses) + + return messaging.sendEach([validMessage, validMessage], true) + .then((response: BatchResponse) => { + expect(http2Mocker.requests.length).to.equal(2); + expect(response.successCount).to.equal(1); + expect(response.failureCount).to.equal(1); + expect(response.responses.length).to.equal(2); + + const responses = response.responses; + checkSendResponseSuccess(responses[0], messageIds[0]); + checkSendResponseFailure( + responses[1], 'messaging/registration-token-not-registered'); + }); + }); + + it('should map server error code to client-side error using HTTP/2', () => { + const error = { + error: { + status: 'NOT_FOUND', + message: 'test error message1', + } + }; + mockedHttp2Responses.push(mockHttp2SendRequestError(404, 'json', error)); + mockedHttp2Responses.push(mockHttp2SendRequestError(400, 'json', { error: 'test error message2' })); + mockedHttp2Responses.push(mockHttp2SendRequestError(400, 'text', 'foo bar')); + http2Mocker.http2Stub(mockedHttp2Responses) + + return messaging.sendEach( + [validMessage, validMessage, validMessage], false + ).then((response: BatchResponse) => { + expect(http2Mocker.requests.length).to.equal(3); + expect(response.failureCount).to.equal(3); + const responses = response.responses; + checkSendResponseFailure(responses[0], 'messaging/registration-token-not-registered'); + checkSendResponseFailure(responses[1], 'messaging/unknown-error'); + checkSendResponseFailure(responses[2], 'messaging/invalid-argument'); + }); + }); + + // This test was added to also verify https://github.com/firebase/firebase-admin-node/issues/1146 + it('should be fulfilled when called with different message types using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + 'projects/projec_id/messages/2', + 'projects/projec_id/messages/3', + ]; + const tokenMessage: TokenMessage = { token: 'test' }; + const topicMessage: TopicMessage = { topic: 'test' }; + const conditionMessage: ConditionMessage = { condition: 'test' }; + const messages: Message[] = [tokenMessage, topicMessage, conditionMessage]; + + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + http2Mocker.http2Stub(mockedHttp2Responses) + + return messaging.sendEach(messages, false) + .then ((response: BatchResponse) => { + expect(http2Mocker.requests.length).to.equal(3); expect(response.successCount).to.equal(3); expect(response.failureCount).to.equal(0); response.responses.forEach((resp, idx) => { @@ -831,6 +1086,21 @@ describe('Messaging', () => { let stub: sinon.SinonStub | null; + function checkSendResponseSuccess(response: SendResponse, messageId: string): void { + expect(response.success).to.be.true; + expect(response.messageId).to.equal(messageId); + expect(response.error).to.be.undefined; + } + + function checkSendResponseFailure(response: SendResponse, code: string, msg?: string): void { + expect(response.success).to.be.false; + expect(response.messageId).to.be.undefined; + expect(response.error).to.have.property('code', code); + if (msg) { + expect(response.error!.toString()).to.contain(msg); + } + } + afterEach(() => { if (stub) { stub.restore(); @@ -869,6 +1139,7 @@ describe('Messaging', () => { }); }); + it('should create multiple messages using the empty multicast payload', () => { stub = sinon.stub(messaging, 'sendEach').resolves(mockResponse); const tokens = ['a', 'b', 'c']; @@ -879,6 +1150,7 @@ describe('Messaging', () => { const messages: Message[] = stub!.args[0][0]; expect(messages.length).to.equal(3); expect(stub!.args[0][1]).to.be.undefined; + expect(stub!.args[0][2]).to.be.undefined; messages.forEach((message, idx) => { expect((message as TokenMessage).token).to.equal(tokens[idx]); expect(message.android).to.be.undefined; @@ -909,6 +1181,7 @@ describe('Messaging', () => { const messages: Message[] = stub!.args[0][0]; expect(messages.length).to.equal(3); expect(stub!.args[0][1]).to.be.undefined; + expect(stub!.args[0][2]).to.be.undefined; messages.forEach((message, idx) => { expect((message as TokenMessage).token).to.equal(tokens[idx]); expect(message.android).to.deep.equal(multicast.android); @@ -929,6 +1202,7 @@ describe('Messaging', () => { expect(response).to.deep.equal(mockResponse); expect(stub).to.have.been.calledOnce; expect(stub!.args[0][1]).to.be.true; + expect(stub!.args[0][2]).to.be.undefined; }); }); @@ -939,7 +1213,7 @@ describe('Messaging', () => { 'projects/projec_id/messages/3', ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) - return messaging.sendEachForMulticast({ + return legacyMessaging.sendEachForMulticast({ tokens: ['a', 'b', 'c'], android: { ttl: 100 }, apns: { payload: { aps: { badge: 42 } } }, @@ -964,7 +1238,7 @@ describe('Messaging', () => { 'projects/projec_id/messages/3', ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) - return messaging.sendEachForMulticast({ + return legacyMessaging.sendEachForMulticast({ tokens: ['a', 'b', 'c'], android: { ttl: 100 }, apns: { payload: { aps: { badge: 42 } } }, @@ -996,7 +1270,7 @@ describe('Messaging', () => { ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) errors.forEach(err => mockedRequests.push(mockSendError(400, 'json', err))) - return messaging.sendEachForMulticast({ tokens: ['a', 'b', 'c'] }) + return legacyMessaging.sendEachForMulticast({ tokens: ['a', 'b', 'c'] }) .then((response: BatchResponse) => { expect(response.successCount).to.equal(2); expect(response.failureCount).to.equal(1); @@ -1041,7 +1315,7 @@ describe('Messaging', () => { ]; messageIds.forEach(id => mockedRequests.push(mockSendRequest(id))) errors.forEach(err => mockedRequests.push(mockSendError(400, 'json', err))) - return messaging.sendEachForMulticast({ tokens: ['a', 'b'] }) + return legacyMessaging.sendEachForMulticast({ tokens: ['a', 'b'] }) .then((response: BatchResponse) => { expect(response.successCount).to.equal(1); expect(response.failureCount).to.equal(1); @@ -1064,7 +1338,7 @@ describe('Messaging', () => { mockedRequests.push(mockSendError(404, 'json', error)); mockedRequests.push(mockSendError(400, 'json', { error: 'test error message' })); mockedRequests.push(mockSendError(400, 'text', 'foo bar')); - return messaging.sendEachForMulticast( + return legacyMessaging.sendEachForMulticast( { tokens: ['a', 'a', 'a'] }, ).then((response: BatchResponse) => { expect(response.failureCount).to.equal(3); @@ -1075,20 +1349,153 @@ describe('Messaging', () => { }); }); - function checkSendResponseSuccess(response: SendResponse, messageId: string): void { - expect(response.success).to.be.true; - expect(response.messageId).to.equal(messageId); - expect(response.error).to.be.undefined; - } + it('should be fulfilled with a BatchResponse given valid message using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + 'projects/projec_id/messages/2', + 'projects/projec_id/messages/3', + ]; + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + http2Mocker.http2Stub(mockedHttp2Responses) + return messaging.sendEachForMulticast({ + tokens: ['a', 'b', 'c'], + android: { ttl: 100 }, + apns: { payload: { aps: { badge: 42 } } }, + data: { key: 'value' }, + notification: { title: 'test title' }, + webpush: { data: { webKey: 'webValue' } }, + }, false).then((response: BatchResponse) => { + expect(response.successCount).to.equal(3); + expect(response.failureCount).to.equal(0); + response.responses.forEach((resp, idx) => { + expect(resp.success).to.be.true; + expect(resp.messageId).to.equal(messageIds[idx]); + expect(resp.error).to.be.undefined; + }); + }); + }); - function checkSendResponseFailure(response: SendResponse, code: string, msg?: string): void { - expect(response.success).to.be.false; - expect(response.messageId).to.be.undefined; - expect(response.error).to.have.property('code', code); - if (msg) { - expect(response.error!.toString()).to.contain(msg); - } - } + it('should be fulfilled with a BatchResponse given valid message in dryRun mode using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + 'projects/projec_id/messages/2', + 'projects/projec_id/messages/3', + ]; + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + http2Mocker.http2Stub(mockedHttp2Responses) + return messaging.sendEachForMulticast({ + tokens: ['a', 'b', 'c'], + android: { ttl: 100 }, + apns: { payload: { aps: { badge: 42 } } }, + data: { key: 'value' }, + notification: { title: 'test title' }, + webpush: { data: { webKey: 'webValue' } }, + }, true).then((response: BatchResponse) => { + expect(response.successCount).to.equal(3); + expect(response.failureCount).to.equal(0); + expect(response.responses.length).to.equal(3); + response.responses.forEach((resp, idx) => { + checkSendResponseSuccess(resp, messageIds[idx]); + }); + }); + }); + + it('should be fulfilled with a BatchResponse for partial failures using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + 'projects/projec_id/messages/2', + ]; + const errors = [ + { + error: { + status: 'INVALID_ARGUMENT', + message: 'test error message', + }, + }, + ]; + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + errors.forEach(error => mockedHttp2Responses.push(mockHttp2SendRequestError(400, 'json', error))) + http2Mocker.http2Stub(mockedHttp2Responses) + return messaging.sendEachForMulticast({ tokens: ['a', 'b', 'c'] }, false) + .then((response: BatchResponse) => { + expect(response.successCount).to.equal(2); + expect(response.failureCount).to.equal(1); + expect(response.responses.length).to.equal(3); + + const responses = response.responses; + checkSendResponseSuccess(responses[0], messageIds[0]); + checkSendResponseSuccess(responses[1], messageIds[1]); + checkSendResponseFailure( + responses[2], 'messaging/invalid-argument', 'test error message'); + }); + }); + + it('should be fulfilled with a BatchResponse for all failures given an app which ' + + 'returns null access tokens using HTTP/2', () => { + return nullAccessTokenMessaging.sendEachForMulticast( + { tokens: ['a', 'a'] }, false + ).then((response: BatchResponse) => { + expect(response.failureCount).to.equal(2); + response.responses.forEach(resp => checkSendResponseFailure( + resp, 'app/invalid-credential')); + }); + }); + + it('should expose the FCM error code in a detailed error via BatchResponse using HTTP/2', () => { + const messageIds = [ + 'projects/projec_id/messages/1', + ]; + const errors = [ + { + error: { + status: 'INVALID_ARGUMENT', + message: 'test error message', + details: [ + { + '@type': 'type.googleapis.com/google.firebase.fcm.v1.FcmError', + 'errorCode': 'UNREGISTERED', + }, + ], + }, + }, + ]; + messageIds.forEach(id => mockedHttp2Responses.push(mockHttp2SendRequestResponse(id))) + errors.forEach(error => mockedHttp2Responses.push(mockHttp2SendRequestError(400, 'json', error))) + http2Mocker.http2Stub(mockedHttp2Responses) + return messaging.sendEachForMulticast({ tokens: ['a', 'b'] }, false) + .then((response: BatchResponse) => { + expect(response.successCount).to.equal(1); + expect(response.failureCount).to.equal(1); + expect(response.responses.length).to.equal(2); + + const responses = response.responses; + checkSendResponseSuccess(responses[0], messageIds[0]); + checkSendResponseFailure( + responses[1], 'messaging/registration-token-not-registered'); + }); + }); + + it('should map server error code to client-side error using HTTP/2', () => { + const error = { + error: { + status: 'NOT_FOUND', + message: 'test error message', + } + }; + mockedHttp2Responses.push(mockHttp2SendRequestError(404, 'json', error)); + mockedHttp2Responses.push(mockHttp2SendRequestError(400, 'json', { error: 'test error message2' })); + mockedHttp2Responses.push(mockHttp2SendRequestError(400, 'text', 'foo bar')); + http2Mocker.http2Stub(mockedHttp2Responses) + return messaging.sendEachForMulticast( + { tokens: ['a', 'a', 'a'] }, false + ).then((response: BatchResponse) => { + expect(response.failureCount).to.equal(3); + const responses = response.responses; + checkSendResponseFailure(responses[0], 'messaging/registration-token-not-registered'); + checkSendResponseFailure(responses[1], 'messaging/unknown-error'); + checkSendResponseFailure(responses[2], 'messaging/invalid-argument'); + }); + }); }); describe('sendAll()', () => { diff --git a/test/unit/utils.ts b/test/unit/utils.ts index 2eb608397e..6ff00d5e26 100644 --- a/test/unit/utils.ts +++ b/test/unit/utils.ts @@ -20,13 +20,13 @@ import * as sinon from 'sinon'; import * as mocks from '../resources/mocks'; import { AppOptions } from '../../src/firebase-namespace-api'; import { FirebaseApp, FirebaseAppInternals, FirebaseAccessToken } from '../../src/app/firebase-app'; -import { HttpError, HttpResponse } from '../../src/utils/api-request'; +import { RequestResponseError, RequestResponse } from '../../src/utils/api-request'; /** - * Returns a new FirebaseApp instance with the provided options. + * Returns a new `FirebaseApp` instance with the provided options. * - * @param options The options for the FirebaseApp instance to create. - * @return A new FirebaseApp instance with the provided options. + * @param options The options for the `FirebaseApp` instance to create. + * @return A new `FirebaseApp` instance with the provided options. */ export function createAppWithOptions(options: object): FirebaseApp { return new FirebaseApp(options as AppOptions, mocks.appName); @@ -39,7 +39,7 @@ export function generateRandomAccessToken(): string { } /** - * Creates a stub for retrieving an access token from a FirebaseApp. All services should use this + * Creates a stub for retrieving an access token from a `FirebaseApp`. All services should use this * method for stubbing the OAuth2 flow during unit tests. * * @param {string} accessToken The access token string to return. @@ -69,7 +69,7 @@ export function stubGetAccessToken(accessToken?: string, app?: FirebaseApp): sin * @param {*=} headers HTTP headers to be included in the ersponse. * @return {HttpResponse} An HTTP response object. */ -export function responseFrom(data: object | string, status = 200, headers: any = {}): HttpResponse { +export function responseFrom(data: object | string, status = 200, headers: any = {}): RequestResponse { let responseData: any; let responseText: string; if (typeof data === 'object') { @@ -92,6 +92,6 @@ export function responseFrom(data: object | string, status = 200, headers: any = }; } -export function errorFrom(data: any, status = 500): HttpError { - return new HttpError(responseFrom(data, status)); +export function errorFrom(data: any, status = 500): RequestResponseError { + return new RequestResponseError(responseFrom(data, status)); } diff --git a/test/unit/utils/api-request.spec.ts b/test/unit/utils/api-request.spec.ts index fd92a9c191..4fcb5a397b 100644 --- a/test/unit/utils/api-request.spec.ts +++ b/test/unit/utils/api-request.spec.ts @@ -28,8 +28,9 @@ import * as mocks from '../../resources/mocks'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { - ApiSettings, HttpClient, HttpError, AuthorizedHttpClient, ApiCallbackFunction, HttpRequestConfig, - HttpResponse, parseHttpResponse, RetryConfig, defaultRetryConfig, + ApiSettings, HttpClient, Http2Client, AuthorizedHttpClient, ApiCallbackFunction, HttpRequestConfig, + parseHttpResponse, RetryConfig, defaultRetryConfig, Http2SessionHandler, Http2RequestConfig, + RequestResponseError, RequestResponse, AuthorizedHttp2Client, } from '../../../src/utils/api-request'; import { deepCopy } from '../../../src/utils/deep-copy'; import { Agent } from 'http'; @@ -43,7 +44,8 @@ const expect = chai.expect; const mockHost = 'www.example.com'; const mockPath = '/foo/bar'; -const mockUrl = `https://${mockHost}${mockPath}`; +const mockHostUrl = `https://${mockHost}`; +const mockUrl = `${mockHostUrl}${mockPath}`; const mockErrorResponse = { error: { @@ -93,6 +95,55 @@ function mockRequestWithError(err: any): nock.Scope { .replyWithError(err); } +function mockHttp2SendRequestResponse( + statusCode: number, + headers: any, + response:any, + delay?: number +): mocks.MockHttp2Response { + if (headers['content-type'] === 'application/json') { + response = JSON.stringify(response) + } + + return { + headers: { + ':status': statusCode, + ...headers + }, + data: Buffer.from(response), + delay: delay + } as mocks.MockHttp2Response +} + +function mockHttp2SendRequestError( + statusCode = 400, + headers: any, + response: any = mockErrorResponse, + delay?: number +): mocks.MockHttp2Response { + if (headers['content-type'] === 'application/json') { + response = JSON.stringify(response) + } + else if (headers['content-type'] === 'text/html') { + response = mockTextErrorResponse; + } + + return { + headers: { + ':status': statusCode, + ...headers + }, + data: Buffer.from(response), + delay: delay + } as mocks.MockHttp2Response +} + +function mockHttp2Error(err: any): mocks.MockHttp2Response { + return { + error: err + } as mocks.MockHttp2Response +} + /** * Returns a new RetryConfig instance for testing. This is same as the default * RetryConfig, with the backOffFactor set to 0 to avoid delays. @@ -625,7 +676,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 400.'); const resp = err.response; expect(resp.status).to.equal(400); @@ -642,7 +693,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 500.'); const resp = err.response; expect(resp.status).to.equal(500); @@ -663,7 +714,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 500.'); const resp = err.response; expect(resp.status).to.equal(500); @@ -757,7 +808,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 503.'); const resp = err.response; expect(resp.status).to.equal(503); @@ -889,7 +940,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 503.'); const resp = err.response; expect(resp.status).to.equal(503); @@ -915,7 +966,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 503.'); const resp = err.response; expect(resp.status).to.equal(503); @@ -939,7 +990,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 503.'); const resp = err.response; expect(resp.status).to.equal(503); @@ -970,7 +1021,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 503.'); const resp = err.response; expect(resp.status).to.equal(503); @@ -1000,7 +1051,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).catch((err: HttpError) => { + }).catch((err: RequestResponseError) => { expect(err.message).to.equal('Server responded with status 503.'); const resp = err.response; expect(resp.status).to.equal(503); @@ -1035,7 +1086,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).then((resp: HttpResponse) => { + }).then((resp: RequestResponse) => { expect(resp.status).to.equal(200); expect(resp.headers['content-type']).to.equal('application/json'); expect(resp.data).to.deep.equal(respData); @@ -1071,7 +1122,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).then((resp: HttpResponse) => { + }).then((resp: RequestResponse) => { expect(resp.status).to.equal(200); expect(resp.headers['content-type']).to.equal('application/json'); expect(resp.data).to.deep.equal(respData); @@ -1105,7 +1156,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).then((resp: HttpResponse) => { + }).then((resp: RequestResponse) => { expect(resp.status).to.equal(200); expect(resp.headers['content-type']).to.equal('application/json'); expect(resp.data).to.deep.equal(respData); @@ -1137,7 +1188,7 @@ describe('HttpClient', () => { return client.send({ method: 'GET', url: mockUrl, - }).then((resp: HttpResponse) => { + }).then((resp: RequestResponse) => { expect(resp.status).to.equal(200); expect(resp.headers['content-type']).to.equal('application/json'); expect(resp.data).to.deep.equal(respData); @@ -1193,155 +1244,1411 @@ describe('HttpClient', () => { }); }); -describe('AuthorizedHttpClient', () => { - let mockApp: FirebaseApp; - let mockedRequests: nock.Scope[] = []; - let getTokenStub: sinon.SinonStub; +describe('Http2Client', () => { + let mockedHttp2Responses: mocks.MockHttp2Response[] = []; + const http2Mocker: mocks.Http2Mocker = new mocks.Http2Mocker(); + let http2SessionHandler: Http2SessionHandler; + let delayStub: sinon.SinonStub | null = null; + let clock: sinon.SinonFakeTimers | null = null; - const mockAccessToken: string = utils.generateRandomAccessToken(); - const requestHeaders = { - reqheaders: { - Authorization: `Bearer ${mockAccessToken}`, - }, - }; + const sampleMultipartData = '--boundary\r\n' + + 'Content-type: application/json\r\n\r\n' + + '{"foo": 1}\r\n' + + '--boundary\r\n' + + 'Content-type: text/plain\r\n\r\n' + + 'foo bar\r\n' + + '--boundary--\r\n'; - before(() => { - getTokenStub = utils.stubGetAccessToken(mockAccessToken); + afterEach(() => { + if ( http2SessionHandler) { + http2SessionHandler.close() + } + if (delayStub) { + delayStub.restore(); + delayStub = null; + } + if (clock) { + clock.restore(); + clock = null; + } + http2Mocker.done() + mockedHttp2Responses = []; }); - after(() => { - getTokenStub.restore(); + const invalidNumbers: any[] = ['string', null, undefined, {}, [], true, false, NaN, -1]; + const invalidArrays: any[] = ['string', null, {}, true, false, NaN, 0, 1]; + + invalidNumbers.forEach((maxRetries: any) => { + it(`should throw when maxRetries is: ${maxRetries}`, () => { + expect(() => { + new Http2Client({ maxRetries } as any); + }).to.throw('maxRetries must be a non-negative integer'); + }); }); - beforeEach(() => { - mockApp = mocks.app(); + invalidNumbers.forEach((backOffFactor: any) => { + if (typeof backOffFactor !== 'undefined') { + it(`should throw when backOffFactor is: ${backOffFactor}`, () => { + expect(() => { + new Http2Client({ maxRetries: 1, backOffFactor } as any); + }).to.throw('backOffFactor must be a non-negative number'); + }); + } }); - afterEach(() => { - mockedRequests.forEach((mockedRequest) => mockedRequest.done()); - mockedRequests = []; - return mockApp.delete(); + invalidNumbers.forEach((maxDelayInMillis: any) => { + it(`should throw when maxDelayInMillis is: ${maxDelayInMillis}`, () => { + expect(() => { + new Http2Client({ maxRetries: 1, maxDelayInMillis } as any); + }).to.throw('maxDelayInMillis must be a non-negative integer'); + }); + }); + + invalidArrays.forEach((ioErrorCodes: any) => { + it(`should throw when ioErrorCodes is: ${ioErrorCodes}`, () => { + expect(() => { + new HttpClient({ maxRetries: 1, maxDelayInMillis: 10000, ioErrorCodes } as any); + }).to.throw('ioErrorCodes must be an array'); + }); + }); + + invalidArrays.forEach((statusCodes: any) => { + it(`should throw when statusCodes is: ${statusCodes}`, () => { + expect(() => { + new HttpClient({ maxRetries: 1, maxDelayInMillis: 10000, statusCodes } as any); + }).to.throw('statusCodes must be an array'); + }); }); it('should be fulfilled for a 2xx response with a json payload', () => { const respData = { foo: 'bar' }; - const scope = nock('https://' + mockHost, requestHeaders) - .get(mockPath) - .reply(200, respData, { - 'content-type': 'application/json', - }); - mockedRequests.push(scope); - const client = new AuthorizedHttpClient(mockApp); + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + return client.send({ method: 'GET', url: mockUrl, + http2SessionHandler: http2SessionHandler, }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); expect(resp.status).to.equal(200); expect(resp.headers['content-type']).to.equal('application/json'); expect(resp.text).to.equal(JSON.stringify(respData)); expect(resp.data).to.deep.equal(respData); + expect(resp.multipart).to.be.undefined; + expect(resp.isJson()).to.be.true; }); }); - describe('HTTP Agent', () => { - let transportSpy: sinon.SinonSpy | null = null; - let mockAppWithAgent: FirebaseApp; - let agentForApp: Agent; + it('should be fulfilled for a 2xx response with a text payload', () => { + const respData = 'foo bar'; + const headers = { 'content-type': 'text/plain' }; - beforeEach(() => { - const options = mockApp.options; - options.httpAgent = new Agent(); + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); - // eslint-disable-next-line @typescript-eslint/no-var-requires - const https = require('https'); - transportSpy = sinon.spy(https, 'request'); - mockAppWithAgent = mocks.appWithOptions(options); - agentForApp = options.httpAgent; + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('text/plain'); + expect(resp.text).to.equal(respData); + expect(() => { resp.data; }).to.throw('Error while parsing response data'); + expect(resp.multipart).to.be.undefined; + expect(resp.isJson()).to.be.false; }); + }); - afterEach(() => { - transportSpy!.restore(); - transportSpy = null; - return mockAppWithAgent.delete(); + it('should be fulfilled for a 2xx response with an empty multipart payload', () => { + const respData = '--boundary--\r\n'; + const headers = { 'content-type': 'multipart/mixed; boundary=boundary' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('multipart/mixed; boundary=boundary'); + expect(resp.multipart).to.not.be.undefined; + expect(resp.multipart!.length).to.equal(0); + expect(() => { resp.text; }).to.throw('Unable to parse multipart payload as text'); + expect(() => { resp.data; }).to.throw('Unable to parse multipart payload as JSON'); + expect(resp.isJson()).to.be.false; }); + }); - it('should use the HTTP agent set in request', () => { - const respData = { success: true }; - const scope = nock('https://' + mockHost, requestHeaders) - .get(mockPath) - .reply(200, respData, { - 'content-type': 'application/json', - }); - mockedRequests.push(scope); - const client = new AuthorizedHttpClient(mockAppWithAgent); - const httpAgent = new Agent(); - return client.send({ - method: 'GET', - url: mockUrl, - httpAgent, - }).then((resp) => { - expect(resp.status).to.equal(200); - expect(transportSpy!.callCount).to.equal(1); - const options = transportSpy!.args[0][0]; - expect(options.agent).to.equal(httpAgent); - }); + it('should be fulfilled for a 2xx response with a multipart payload', () => { + const headers = { 'content-type': 'multipart/mixed; boundary=boundary' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, sampleMultipartData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('multipart/mixed; boundary=boundary'); + expect(resp.multipart).to.exist; + expect(resp.multipart!.map((buffer) => buffer.toString('utf-8'))).to.deep.equal(['{"foo": 1}', 'foo bar']); + expect(() => { resp.text; }).to.throw('Unable to parse multipart payload as text'); + expect(() => { resp.data; }).to.throw('Unable to parse multipart payload as JSON'); + expect(resp.isJson()).to.be.false; }); + }); - it('should use the HTTP agent set in AppOptions', () => { - const respData = { success: true }; - const scope = nock('https://' + mockHost, requestHeaders) - .get(mockPath) - .reply(200, respData, { - 'content-type': 'application/json', - }); - mockedRequests.push(scope); - const client = new AuthorizedHttpClient(mockAppWithAgent); - return client.send({ - method: 'GET', - url: mockUrl, - }).then((resp) => { - expect(resp.status).to.equal(200); - expect(transportSpy!.callCount).to.equal(1); - const options = transportSpy!.args[0][0]; - expect(options.agent).to.equal(agentForApp); - }); + it('should be fulfilled for a 2xx response with any multipart payload', () => { + const headers = { 'content-type': 'multipart/something; boundary=boundary' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, sampleMultipartData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('multipart/something; boundary=boundary'); + expect(resp.multipart).to.exist; + expect(resp.multipart!.map((buffer) => buffer.toString('utf-8'))).to.deep.equal(['{"foo": 1}', 'foo bar']); + expect(() => { resp.text; }).to.throw('Unable to parse multipart payload as text'); + expect(() => { resp.data; }).to.throw('Unable to parse multipart payload as JSON'); + expect(resp.isJson()).to.be.false; }); }); - it('should make a POST request with the provided headers and data', () => { - const reqData = { request: 'data' }; - const respData = { success: true }; - const options = { - reqheaders: { - 'Content-Type': (header: string) => { - return header.startsWith('application/json'); // auto-inserted - }, - 'My-Custom-Header': 'CustomValue', - }, - }; - Object.assign(options.reqheaders, requestHeaders.reqheaders); - const scope = nock('https://' + mockHost, options) - .post(mockPath, reqData) - .reply(200, respData, { - 'content-type': 'application/json', - }); - mockedRequests.push(scope); - const client = new AuthorizedHttpClient(mockApp); + it('should handle as a text response when boundary not present', () => { + const respData = 'foo bar'; + const headers = { 'content-type': 'multipart/mixed' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + return client.send({ - method: 'POST', + method: 'GET', url: mockUrl, - headers: { - 'My-Custom-Header': 'CustomValue', - }, - data: reqData, + http2SessionHandler: http2SessionHandler, }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); expect(resp.status).to.equal(200); - expect(resp.headers['content-type']).to.equal('application/json'); - expect(resp.data).to.deep.equal(respData); + expect(resp.headers['content-type']).to.equal('multipart/mixed'); + expect(resp.multipart).to.be.undefined; + expect(resp.text).to.equal(respData); + expect(() => { resp.data; }).to.throw('Error while parsing response data'); + expect(resp.isJson()).to.be.false; }); }); - it('should not mutate the arguments', () => { + it('should be fulfilled for a 2xx response with a compressed payload', () => { + const deflated: Buffer = zlib.deflateSync('foo bar'); + const headers = { 'content-type': 'text/plain', 'content-encoding': 'deflate' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, deflated)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('text/plain'); + expect(resp.headers['content-encoding']).to.be.undefined; + expect(resp.multipart).to.be.undefined; + expect(resp.text).to.equal('foo bar'); + expect(() => { resp.data; }).to.throw('Error while parsing response data'); + expect(resp.isJson()).to.be.false; + }); + }); + + it('should use the default RetryConfig', () => { + const client = new Http2Client(); + const config = (client as any).retry as RetryConfig; + expect(defaultRetryConfig()).to.deep.equal(config); + }); + + it('should make a POST request with the provided headers and data', () => { + const reqData = { request: 'data' }; + const respData = { success: true }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'POST', + url: mockUrl, + headers: { + 'authorization': 'Bearer token', + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('POST'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(JSON.parse(http2Mocker.requests[0].data)).to.deep.equal(reqData); + expect(http2Mocker.requests[0].headers.authorization).to.equal('Bearer token'); + expect(http2Mocker.requests[0].headers['content-type']).to.contain('application/json'); + expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue'); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should use the specified content-type header for the body', () => { + const reqData = { request: 'data' }; + const respData = { success: true }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'POST', + url: mockUrl, + headers: { + 'content-type': 'custom/type', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('POST'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(JSON.parse(http2Mocker.requests[0].data)).to.deep.equal(reqData); + expect(http2Mocker.requests[0].headers['content-type']).to.contain('custom/type'); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should not mutate the arguments', () => { + const reqData = { request: 'data' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse( + 200, + { 'content-type': 'application/json' }, + { success: true } + )); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + const request: Http2RequestConfig = { + method: 'POST', + url: mockUrl, + headers: { + 'authorization': 'Bearer token', + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }; + const requestCopy = deepCopy(request); + + return client.send(request).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('POST'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(JSON.parse(http2Mocker.requests[0].data)).to.deep.equal(reqData); + expect(http2Mocker.requests[0].headers['content-type']).to.contain('application/json'); + expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue'); + expect(http2Mocker.requests[0].headers.authorization).to.equal('Bearer token'); + expect(resp.status).to.equal(200); + expect(request).to.deep.equal(requestCopy); + }); + }); + + it('should make a GET request with the provided headers and data', () => { + const reqData = { key1: 'value1', key2: 'value2' }; + const respData = { success: true }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + headers: { + 'authorization': 'Bearer token', + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(`${mockPath}?key1=value1&key2=value2`); + expect(http2Mocker.requests[0].headers.authorization).to.equal('Bearer token'); + expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue'); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should merge query parameters in URL with data', () => { + const reqData = { key1: 'value1', key2: 'value2' }; + const respData = { success: true }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl + '?key3=value3', + data: reqData, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(`${mockPath}?key3=value3&key1=value1&key2=value2`); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should urlEncode query parameters in URL', () => { + const reqData = { key1: 'value 1!', key2: 'value 2!' }; + const respData = { success: true }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl + '?key3=value+3%21', + data: reqData, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']) + .to.equal(`${mockPath}?key3=value+3%21&key1=value+1%21&key2=value+2%21`); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should default to https when protocol not specified', () => { + const respData = { foo: 'bar' }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl.substring('https://'.length), + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.text).to.equal(JSON.stringify(respData)); + expect(resp.data).to.deep.equal(respData); + expect(resp.multipart).to.be.undefined; + expect(resp.isJson()).to.be.true; + }); + }); + + it('should fail with a GET request containing non-object data', () => { + const err = 'GET requests cannot have a body.'; + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + timeout: 50, + data: 'non-object-data', + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error'); + }); + + it('should make a HEAD request with the provided headers and data', () => { + const reqData = { key1: 'value1', key2: 'value2' }; + const respData = { success: true }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'HEAD', + url: mockUrl, + headers: { + 'authorization': 'Bearer token', + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('HEAD'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(`${mockPath}?key1=value1&key2=value2`); + expect(http2Mocker.requests[0].headers.authorization).to.equal('Bearer token'); + expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue'); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should fail with a HEAD request containing non-object data', () => { + const err = 'HEAD requests cannot have a body.'; + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'HEAD', + url: mockUrl, + timeout: 50, + data: 'non-object-data', + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error'); + }); + + it('should fail with an HttpError for a 4xx response', () => { + const data = { error: 'data' }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestError(400, headers, data)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(err.message).to.equal('Server responded with status 400.'); + const resp = err.response; + expect(resp.status).to.equal(400); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(data); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should fail with an HttpError for a 5xx response', () => { + const data = { error: 'data' }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestError(500, headers, data)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(err.message).to.equal('Server responded with status 500.'); + const resp = err.response; + expect(resp.status).to.equal(500); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(data); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should fail for an error response with a multipart payload', () => { + const headers = { 'content-type': 'multipart/mixed; boundary=boundary' }; + + mockedHttp2Responses.push(mockHttp2SendRequestError(500, headers, sampleMultipartData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(err.message).to.equal('Server responded with status 500.'); + const resp = err.response; + expect(resp.status).to.equal(500); + expect(resp.headers['content-type']).to.equal('multipart/mixed; boundary=boundary'); + expect(resp.multipart).to.exist; + expect(resp.multipart!.map((buffer) => buffer.toString('utf-8'))).to.deep.equal(['{"foo": 1}', 'foo bar']); + expect(() => { resp.text; }).to.throw('Unable to parse multipart payload as text'); + expect(() => { resp.data; }).to.throw('Unable to parse multipart payload as JSON'); + expect(resp.isJson()).to.be.false; + }); + }); + + it('should fail with a FirebaseAppError for a network error', () => { + const err = 'Error while making request: test error. Error code: AWFUL_ERROR'; + + mockedHttp2Responses.push(mockHttp2Error({ message: 'test error', code: 'AWFUL_ERROR' })); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error') + .then(() => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + }); + }); + + it('should timeout when the response is repeatedly delayed', () => { + const err = 'Error while making request: timeout of 50ms exceeded.'; + const respData = { foo: 'bar' }; + const headers = { 'content-type': 'application/json' }; + + for (let i = 0; i < 5; i++) { + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData, 2000)); + } + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(testRetryConfig()); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + timeout: 50, + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-timeout') + .then(() => { + expect(http2Mocker.requests.length).to.equal(5); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + }); + }); + + it('should be rejected, after 4 retries, on multiple network errors', () => { + const err = 'Error while making request: connection reset 5'; + + for (let i = 0; i < 5; i++) { + mockedHttp2Responses.push(mockHttp2Error({ message: `connection reset ${i + 1}`, code: 'ECONNRESET' })); + } + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(testRetryConfig()); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + timeout: 50, + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error') + .then(() => { + expect(http2Mocker.requests.length).to.equal(5); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + }); + }); + + it('should be rejected, after 4 retries, on multiple 503 errors', () => { + const headers = { 'content-type': 'application/json' }; + + for (let i = 0; i < 5; i++) { + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers, {})); + } + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(testRetryConfig()); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(5); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(err.message).to.equal('Server responded with status 503.'); + const resp = err.response; + expect(resp.status).to.equal(503); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal({}); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should succeed, after 1 retry, on a single network error', () => { + const respData = { foo: 'bar' }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2Error({ message: 'connection reset 1', code: 'ECONNRESET' })); + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(defaultRetryConfig()); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(2); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(resp.status).to.equal(200); + expect(resp.data).to.deep.equal(respData); + }); + }); + + it('should not retry when RetryConfig is explicitly null', () => { + const err = 'Error while making request: connection reset 1'; + + mockedHttp2Responses.push(mockHttp2Error({ message: 'connection reset 1', code: 'ECONNRESET' })); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(null); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error') + .then(() => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + }); + }); + + it('should not retry when maxRetries is set to 0', () => { + const err = 'Error while making request: connection reset 1'; + + mockedHttp2Responses.push(mockHttp2Error({ message: 'connection reset 1', code: 'ECONNRESET' })); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client({ + maxRetries: 0, + ioErrorCodes: ['ECONNRESET'], + maxDelayInMillis: 10000, + }); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error') + .then(() => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + }); + }); + + it('should not retry when error codes are not configured', () => { + const err = 'Error while making request: connection reset 1'; + + mockedHttp2Responses.push(mockHttp2Error({ message: 'connection reset 1', code: 'ECONNRESET' })); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client({ + maxRetries: 1, + maxDelayInMillis: 10000, + }); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error') + .then(() => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + }); + }); + + it('should succeed after a retry on a configured I/O error', () => { + const respData = { foo: 'bar' }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2Error({ message: 'connection reset 1', code: 'ETESTCODE' })); + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client({ + maxRetries: 1, + maxDelayInMillis: 1000, + ioErrorCodes: ['ETESTCODE'], + }); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(2); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(resp.status).to.equal(200); + expect(resp.data).to.deep.equal(respData); + }); + }); + + it('should succeed after a retry on a configured HTTP error', () => { + const respData = { foo: 'bar' }; + const headers = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers, {})); + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(testRetryConfig()); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(2); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(resp.status).to.equal(200); + expect(resp.data).to.deep.equal(respData); + }); + }); + + it('should not retry more than maxRetries', () => { + const headers = { 'content-type': 'application/json' }; + + // simulate 2 low-level errors + mockedHttp2Responses.push(mockHttp2Error({ message: 'connection reset 1', code: 'ECONNRESET' })); + mockedHttp2Responses.push(mockHttp2Error({ message: 'connection reset 2', code: 'ECONNRESET' })); + // followed by 3 HTTP errors + for (let i = 0; i < 3; i++) { + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers, {})); + } + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(testRetryConfig()); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(5); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(err.message).to.equal('Server responded with status 503.'); + const resp = err.response; + expect(resp.status).to.equal(503); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal({}); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should not retry when retry-after exceeds maxDelayInMillis', () => { + const headers = { 'content-type': 'application/json', 'retry-after': '61' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers, {})); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client({ + maxRetries: 1, + maxDelayInMillis: 60 * 1000, + statusCodes: [503], + }); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(err.message).to.equal('Server responded with status 503.'); + const resp = err.response; + expect(resp.status).to.equal(503); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal({}); + expect(resp.isJson()).to.be.true; + }); + }); + + it('should retry with exponential back off', () => { + const headers = { 'content-type': 'application/json' }; + + for (let i = 0; i < 5; i++) { + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers, {})); + } + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(defaultRetryConfig()); + delayStub = sinon.stub(client as any, 'waitForRetry').resolves(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(5); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(err.message).to.equal('Server responded with status 503.'); + const resp = err.response; + expect(resp.status).to.equal(503); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal({}); + expect(resp.isJson()).to.be.true; + expect(delayStub!.callCount).to.equal(4); + const delays = delayStub!.args.map((args) => args[0]); + expect(delays).to.deep.equal([0, 1000, 2000, 4000]); + }); + }); + + it('delay should not exceed maxDelayInMillis', () => { + const headers = { 'content-type': 'application/json' }; + + for (let i = 0; i < 5; i++) { + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers, {})); + } + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client({ + maxRetries: 4, + backOffFactor: 1, + maxDelayInMillis: 4 * 1000, + statusCodes: [503], + }); + delayStub = sinon.stub(client as any, 'waitForRetry').resolves(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(5); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(err.message).to.equal('Server responded with status 503.'); + const resp = err.response; + expect(resp.status).to.equal(503); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal({}); + expect(resp.isJson()).to.be.true; + expect(delayStub!.callCount).to.equal(4); + const delays = delayStub!.args.map((args) => args[0]); + expect(delays).to.deep.equal([0, 2000, 4000, 4000]); + }); + }); + + it('should retry without delays when backOffFactor is not set', () => { + const headers = { 'content-type': 'application/json' }; + + for (let i = 0; i < 5; i++) { + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers, {})); + } + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client({ + maxRetries: 4, + maxDelayInMillis: 60 * 1000, + statusCodes: [503], + }); + delayStub = sinon.stub(client as any, 'waitForRetry').resolves(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler + }).catch((err: RequestResponseError) => { + expect(http2Mocker.requests.length).to.equal(5); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(err.message).to.equal('Server responded with status 503.'); + const resp = err.response; + expect(resp.status).to.equal(503); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal({}); + expect(resp.isJson()).to.be.true; + expect(delayStub!.callCount).to.equal(4); + const delays = delayStub!.args.map((args) => args[0]); + expect(delays).to.deep.equal([0, 0, 0, 0]); + }); + }); + + it('should wait when retry-after expressed as seconds', () => { + const respData = { foo: 'bar' }; + const headers1 = { 'content-type': 'application/json', 'retry-after': '30' }; + const headers2 = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers1, {})); + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers2, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(defaultRetryConfig()); + delayStub = sinon.stub(client as any, 'waitForRetry').resolves(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler + }).then((resp: RequestResponse) => { + expect(http2Mocker.requests.length).to.equal(2); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + expect(delayStub!.callCount).to.equal(1); + expect(delayStub!.args[0][0]).to.equal(30 * 1000); + }); + }); + + it('should wait when retry-after expressed as a timestamp', () => { + clock = sinon.useFakeTimers({ toFake: ['Date'] }); + clock.setSystemTime(1000); + + const timestamp = new Date(clock.now + 30 * 1000); + const respData = { foo: 'bar' }; + const headers1 = { 'content-type': 'application/json', 'retry-after': timestamp }; + const headers2 = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers1, {})); + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers2, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(defaultRetryConfig()); + delayStub = sinon.stub(client as any, 'waitForRetry').resolves(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler + }).then((resp: RequestResponse) => { + expect(http2Mocker.requests.length).to.equal(2); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + expect(delayStub!.callCount).to.equal(1); + expect(delayStub!.args[0][0]).to.equal(30 * 1000); + }); + }); + + it('should not wait when retry-after timestamp is expired', () => { + const timestamp = new Date(Date.now() - 30 * 1000); + const respData = { foo: 'bar' }; + const headers1 = { 'content-type': 'application/json', 'retry-after': timestamp.toUTCString() }; + const headers2 = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers1, {})); + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers2, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(defaultRetryConfig()); + delayStub = sinon.stub(client as any, 'waitForRetry').resolves(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler + }).then((resp: RequestResponse) => { + expect(http2Mocker.requests.length).to.equal(2); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + expect(delayStub!.callCount).to.equal(1); + expect(delayStub!.args[0][0]).to.equal(0); + }); + }); + + it('should not wait when retry-after is malformed', () => { + const respData = { foo: 'bar' }; + const headers1 = { 'content-type': 'application/json', 'retry-after': 'invalid' }; + const headers2 = { 'content-type': 'application/json' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(503, headers1, {})); + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers2, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(defaultRetryConfig()); + delayStub = sinon.stub(client as any, 'waitForRetry').resolves(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler + }).then((resp: RequestResponse) => { + expect(http2Mocker.requests.length).to.equal(2); + http2Mocker.requests.forEach(request => { + expect(request.headers[':method']).to.equal('GET'); + expect(request.headers[':scheme']).to.equal('https:'); + expect(request.headers[':path']).to.equal(mockPath); + }); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + expect(resp.isJson()).to.be.true; + expect(delayStub!.callCount).to.equal(1); + expect(delayStub!.args[0][0]).to.equal(0); + }); + }); + + it('should reject if the request payload is invalid', () => { + const err = 'Error while making request: Request data must be a string, a Buffer ' + + 'or a json serializable object'; + + const client = new Http2Client(defaultRetryConfig()); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'POST', + url: mockUrl, + data: 1 as any, + http2SessionHandler: http2SessionHandler + }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error'); + }); +}); + +describe('AuthorizedHttpClient', () => { + let mockApp: FirebaseApp; + let mockedRequests: nock.Scope[] = []; + let getTokenStub: sinon.SinonStub; + + const mockAccessToken: string = utils.generateRandomAccessToken(); + const requestHeaders = { + reqheaders: { + Authorization: `Bearer ${mockAccessToken}`, + }, + }; + + before(() => { + getTokenStub = utils.stubGetAccessToken(mockAccessToken); + }); + + after(() => { + getTokenStub.restore(); + }); + + beforeEach(() => { + mockApp = mocks.app(); + }); + + afterEach(() => { + mockedRequests.forEach((mockedRequest) => mockedRequest.done()); + mockedRequests = []; + return mockApp.delete(); + }); + + it('should be fulfilled for a 2xx response with a json payload', () => { + const respData = { foo: 'bar' }; + const scope = nock('https://' + mockHost, requestHeaders) + .get(mockPath) + .reply(200, respData, { + 'content-type': 'application/json', + }); + mockedRequests.push(scope); + const client = new AuthorizedHttpClient(mockApp); + return client.send({ + method: 'GET', + url: mockUrl, + }).then((resp) => { + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.text).to.equal(JSON.stringify(respData)); + expect(resp.data).to.deep.equal(respData); + }); + }); + + describe('HTTP Agent', () => { + let transportSpy: sinon.SinonSpy | null = null; + let mockAppWithAgent: FirebaseApp; + let agentForApp: Agent; + + beforeEach(() => { + const options = mockApp.options; + options.httpAgent = new Agent(); + + // eslint-disable-next-line @typescript-eslint/no-var-requires + const https = require('https'); + transportSpy = sinon.spy(https, 'request'); + mockAppWithAgent = mocks.appWithOptions(options); + agentForApp = options.httpAgent; + }); + + afterEach(() => { + transportSpy!.restore(); + transportSpy = null; + return mockAppWithAgent.delete(); + }); + + it('should use the HTTP agent set in request', () => { + const respData = { success: true }; + const scope = nock('https://' + mockHost, requestHeaders) + .get(mockPath) + .reply(200, respData, { + 'content-type': 'application/json', + }); + mockedRequests.push(scope); + const client = new AuthorizedHttpClient(mockAppWithAgent); + const httpAgent = new Agent(); + return client.send({ + method: 'GET', + url: mockUrl, + httpAgent, + }).then((resp) => { + expect(resp.status).to.equal(200); + expect(transportSpy!.callCount).to.equal(1); + const options = transportSpy!.args[0][0]; + expect(options.agent).to.equal(httpAgent); + }); + }); + + it('should use the HTTP agent set in AppOptions', () => { + const respData = { success: true }; + const scope = nock('https://' + mockHost, requestHeaders) + .get(mockPath) + .reply(200, respData, { + 'content-type': 'application/json', + }); + mockedRequests.push(scope); + const client = new AuthorizedHttpClient(mockAppWithAgent); + return client.send({ + method: 'GET', + url: mockUrl, + }).then((resp) => { + expect(resp.status).to.equal(200); + expect(transportSpy!.callCount).to.equal(1); + const options = transportSpy!.args[0][0]; + expect(options.agent).to.equal(agentForApp); + }); + }); + }); + + it('should make a POST request with the provided headers and data', () => { + const reqData = { request: 'data' }; + const respData = { success: true }; + const options = { + reqheaders: { + 'Content-Type': (header: string) => { + return header.startsWith('application/json'); // auto-inserted + }, + 'My-Custom-Header': 'CustomValue', + }, + }; + Object.assign(options.reqheaders, requestHeaders.reqheaders); + const scope = nock('https://' + mockHost, options) + .post(mockPath, reqData) + .reply(200, respData, { + 'content-type': 'application/json', + }); + mockedRequests.push(scope); + const client = new AuthorizedHttpClient(mockApp); + return client.send({ + method: 'POST', + url: mockUrl, + headers: { + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + }).then((resp) => { + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + }); + }); + + it('should not mutate the arguments', () => { const reqData = { request: 'data' }; const options = { reqheaders: { @@ -1375,6 +2682,135 @@ describe('AuthorizedHttpClient', () => { }); }); +describe('AuthorizedHttp2Client', () => { + let mockedHttp2Responses: mocks.MockHttp2Response[] = []; + const http2Mocker: mocks.Http2Mocker = new mocks.Http2Mocker(); + let http2SessionHandler: Http2SessionHandler; + let mockApp: FirebaseApp; + let getTokenStub: sinon.SinonStub; + + const mockAccessToken: string = utils.generateRandomAccessToken(); + + before(() => { + getTokenStub = utils.stubGetAccessToken(mockAccessToken); + }); + + after(() => { + getTokenStub.restore(); + }); + + beforeEach(() => { + mockApp = mocks.app(); + }); + + afterEach(() => { + if ( http2SessionHandler) { + http2SessionHandler.close() + } + http2Mocker.done() + mockedHttp2Responses = []; + return mockApp.delete(); + }); + + it('should be fulfilled for a 2xx response with a json payload', () => { + const respData = { foo: 'bar' }; + const headers = { 'content-type': 'application/json', 'Authorization': `Bearer ${mockAccessToken}` }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new AuthorizedHttp2Client(mockApp); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'GET', + url: mockUrl, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('GET'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.text).to.equal(JSON.stringify(respData)); + expect(resp.data).to.deep.equal(respData); + }); + }); + + it('should make a POST request with the provided headers and data', () => { + const reqData = { request: 'data' }; + const respData = { success: true }; + const headers = { 'content-type': 'application/json', 'Authorization': `Bearer ${mockAccessToken}` }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse(200, headers, respData)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new AuthorizedHttp2Client(mockApp); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + return client.send({ + method: 'POST', + url: mockUrl, + headers: { + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('POST'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(JSON.parse(http2Mocker.requests[0].data)).to.deep.equal(reqData); + expect(http2Mocker.requests[0].headers['content-type']).to.contain('application/json'); + expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue'); + expect(http2Mocker.requests[0].headers['Authorization']).to.contain('access_token_'); + expect(resp.status).to.equal(200); + expect(resp.headers['content-type']).to.equal('application/json'); + expect(resp.data).to.deep.equal(respData); + }); + }); + + it('should not mutate the arguments', () => { + const reqData = { request: 'data' }; + + mockedHttp2Responses.push(mockHttp2SendRequestResponse( + 200, + { 'content-type': 'application/json', 'Authorization': `Bearer ${mockAccessToken}` }, + { success: true } + )); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new AuthorizedHttp2Client(mockApp); + http2SessionHandler = new Http2SessionHandler(mockHostUrl); + + const request: Http2RequestConfig = { + method: 'POST', + url: mockUrl, + headers: { + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }; + const requestCopy = deepCopy(request); + + return client.send(request).then((resp) => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('POST'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(JSON.parse(http2Mocker.requests[0].data)).to.deep.equal(reqData); + expect(http2Mocker.requests[0].headers['content-type']).to.contain('application/json'); + expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue'); + expect(http2Mocker.requests[0].headers['Authorization']).to.contain('access_token_'); + expect(resp.status).to.equal(200); + expect(request).to.deep.equal(requestCopy); + }); + }); +}); + describe('ApiSettings', () => { describe('Constructor', () => { it('should succeed with a specified endpoint and a default http method', () => { From 83866940b00c54a7d1f714a0d7a1b79103235f29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:41:51 +0000 Subject: [PATCH 141/323] build(deps): bump @google-cloud/storage from 7.11.2 to 7.12.0 (#2643) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ed6cac941..eedef56d78 100644 --- a/package-lock.json +++ b/package-lock.json @@ -685,9 +685,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.11.2.tgz", - "integrity": "sha512-jJOrKyOdujfrSF8EJODW9yY6hqO4jSTk6eVITEj2gsD43BSXuDlnMlLOaBUQhXL29VGnSkxDgYl5tlFhA6LKSA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.12.0.tgz", + "integrity": "sha512-122Ui67bhnf8MkRnxQAC5lf7wPGkPP5hL3+J5s9HHDw2J9RpaMmnV8iahn+RUn9BH70W6uRe6nMZLXiRaJM/3g==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", From b8f284db92c947b1446f72a36dac9877c6ffc2c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:48:54 +0000 Subject: [PATCH 142/323] build(deps-dev): bump @microsoft/api-extractor from 7.47.0 to 7.47.2 (#2642) --- package-lock.json | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index eedef56d78..0ba6b6b185 100644 --- a/package-lock.json +++ b/package-lock.json @@ -939,18 +939,18 @@ } }, "@microsoft/api-extractor": { - "version": "7.47.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.0.tgz", - "integrity": "sha512-LT8yvcWNf76EpDC+8/ArTVSYePvuDQ+YbAUrsTcpg3ptiZ93HIcMCozP/JOxDt+rrsFfFHcpfoselKfPyRI0GQ==", + "version": "7.47.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.2.tgz", + "integrity": "sha512-YWE2HGrSTZaPPSr7xiNizSuViZpC7Jsa7+DwRW5rYVgrMXNbfX/PpBOoSkl5uaz9I2sv2JKLJ75kVNt64BvS3g==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.29.2", + "@microsoft/api-extractor-model": "7.29.3", "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.4.1", + "@rushstack/node-core-library": "5.5.0", "@rushstack/rig-package": "0.5.2", - "@rushstack/terminal": "0.13.0", - "@rushstack/ts-command-line": "4.22.0", + "@rushstack/terminal": "0.13.2", + "@rushstack/ts-command-line": "4.22.2", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -966,9 +966,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.4.1.tgz", - "integrity": "sha512-WNnwdS8r9NZ/2K3u29tNoSRldscFa7SxU0RT+82B6Dy2I4Hl2MeCSKm4EXLXPKeNzLGvJ1cqbUhTLviSF8E6iA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.0.tgz", + "integrity": "sha512-Cl3MYQ74Je5Y/EngMxcA3SpHjGZ/022nKbAO1aycGfQ+7eKyNCBu0oywj5B1f367GCzuHBgy+3BlVLKysHkXZw==", "dev": true, "requires": { "ajv": "~8.13.0", @@ -982,12 +982,12 @@ } }, "@rushstack/ts-command-line": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.0.tgz", - "integrity": "sha512-Qj28t6MO3HRgAZ72FDeFsrpdE6wBWxF3VENgvrXh7JF2qIT+CrXiOJIesW80VFZB9QwObSpkB1ilx794fGQg6g==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.2.tgz", + "integrity": "sha512-xkvrGd6D9dPlI3I401Thc640WNsEPB1sGEmy12a2VJaPQPwhE6Ik0gEVPZJ/2G1w213eaCAdxUY1xpiTulsmpA==", "dev": true, "requires": { - "@rushstack/terminal": "0.13.0", + "@rushstack/terminal": "0.13.2", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1023,14 +1023,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.2.tgz", - "integrity": "sha512-hAYajOjQan3uslhKJRwvvHIdLJ+ZByKqdSsJ/dgHFxPtEbdKpzMDO8zuW4K5gkSMYl5D0LbNwxkhxr51P2zsmw==", + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.3.tgz", + "integrity": "sha512-kEWjLr2ygL3ku9EGyjeTnL2S5IxyH9NaF1k1UoI0Nzwr4xEJBSWCVsWuF2+0lPUrRPA6mTY95fR264SJ5ETKQA==", "dev": true, "requires": { "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.4.1" + "@rushstack/node-core-library": "5.5.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1040,9 +1040,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.4.1.tgz", - "integrity": "sha512-WNnwdS8r9NZ/2K3u29tNoSRldscFa7SxU0RT+82B6Dy2I4Hl2MeCSKm4EXLXPKeNzLGvJ1cqbUhTLviSF8E6iA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.0.tgz", + "integrity": "sha512-Cl3MYQ74Je5Y/EngMxcA3SpHjGZ/022nKbAO1aycGfQ+7eKyNCBu0oywj5B1f367GCzuHBgy+3BlVLKysHkXZw==", "dev": true, "requires": { "ajv": "~8.13.0", @@ -1237,19 +1237,19 @@ } }, "@rushstack/terminal": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.13.0.tgz", - "integrity": "sha512-Ou44Q2s81BqJu3dpYedAX54am9vn245F0HzqVrfJCMQk5pGgoKKOBOjkbfZC9QKcGNaECh6pwH2s5noJt7X6ew==", + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.13.2.tgz", + "integrity": "sha512-t8i0PsGvBHmFBY8pryO3badqFlxQsm2rw3KYrzjcmVkG/WGklKg1qVkr9beAS1Oe8XWDRgj6SkoHkpNjs7aaNw==", "dev": true, "requires": { - "@rushstack/node-core-library": "5.4.1", + "@rushstack/node-core-library": "5.5.0", "supports-color": "~8.1.1" }, "dependencies": { "@rushstack/node-core-library": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.4.1.tgz", - "integrity": "sha512-WNnwdS8r9NZ/2K3u29tNoSRldscFa7SxU0RT+82B6Dy2I4Hl2MeCSKm4EXLXPKeNzLGvJ1cqbUhTLviSF8E6iA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.0.tgz", + "integrity": "sha512-Cl3MYQ74Je5Y/EngMxcA3SpHjGZ/022nKbAO1aycGfQ+7eKyNCBu0oywj5B1f367GCzuHBgy+3BlVLKysHkXZw==", "dev": true, "requires": { "ajv": "~8.13.0", From f26ad1dbbc9b271cce4dfde0fa96ebc662274d2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:54:11 +0000 Subject: [PATCH 143/323] build(deps): bump @types/node from 20.14.8 to 20.14.11 (#2641) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0ba6b6b185..ac8846a9b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1532,9 +1532,9 @@ } }, "@types/node": { - "version": "20.14.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.8.tgz", - "integrity": "sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", "requires": { "undici-types": "~5.26.4" } From 500bb81e1d5cfb5f17b1392ba17ee604ae912ae3 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:29:44 -0400 Subject: [PATCH 144/323] [chore] Release 12.3.0 (#2644) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c79a443c41..228f86ea8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.2.0", + "version": "12.3.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 9d033953158b6ff43d9513e9a5eb36d1912d5c76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:37:02 -0400 Subject: [PATCH 145/323] build(deps): bump fast-xml-parser from 4.4.0 to 4.4.1 (#2654) Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 4.4.0 to 4.4.1. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.4.0...v4.4.1) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac8846a9b3..264f5491ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.2.0", + "version": "12.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3363,9 +3363,9 @@ "dev": true }, "fast-xml-parser": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", - "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", "optional": true, "requires": { "strnum": "^1.0.5" From 5a6630210425530d2bf597448b7c94c56c9b056e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 18:41:33 +0000 Subject: [PATCH 146/323] build(deps-dev): bump @firebase/app-compat from 0.2.35 to 0.2.37 (#2653) --- package-lock.json | 64 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 264f5491ac..38baf720d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -441,16 +441,37 @@ } }, "@firebase/app": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.5.tgz", - "integrity": "sha512-iY/fNot+hWPk9sTX8aHMqlcX9ynRvpGkskWAdUZ2eQQdLo8d1hSFYcYNwPv0Q/frGMasw8udKWMcFOEpC9fG8g==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.7.tgz", + "integrity": "sha512-7OCd53B+wnk/onbMLn/vM10pDjw97zzWUD8m3swtLYKJIrL+gDZ7HZ4xcbBLw7OB8ikzu8k1ORNjRe2itgAy4g==", "dev": true, "requires": { - "@firebase/component": "0.6.7", + "@firebase/component": "0.6.8", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.6", + "@firebase/util": "1.9.7", "idb": "7.1.1", "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/component": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.8.tgz", + "integrity": "sha512-LcNvxGLLGjBwB0dJUsBGCej2fqAepWyBubs4jt1Tiuns7QLbXHuyObZ4aMeBjZjWx4m8g1LoVI9QFpSaq/k4/g==", + "dev": true, + "requires": { + "@firebase/util": "1.9.7", + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.7.tgz", + "integrity": "sha512-fBVNH/8bRbYjqlbIhZ+lBtdAAS4WqZumx03K06/u7fJSpz1TGjEMm1ImvKD47w+xaFKIP2ori6z8BrbakRfjJA==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } } }, "@firebase/app-check-interop-types": { @@ -459,16 +480,37 @@ "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "@firebase/app-compat": { - "version": "0.2.35", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.35.tgz", - "integrity": "sha512-vgay/WRjeH0r97/Q6L6df2CMx7oyNFDsE5yPQ9oR1G+zx2eT0s8vNNh0WlKqQxUEWaOLRnXhQ8gy7uu0cBgTRg==", + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.37.tgz", + "integrity": "sha512-yiQLYT9LYQHuJGu/msuBLFtdWWTJ3Pz04E9gSeWykSB+8s0XXJJqfqQlghH7CcQ3KnJZR+Wuc3zSMcY3a+dn6Q==", "dev": true, "requires": { - "@firebase/app": "0.10.5", - "@firebase/component": "0.6.7", + "@firebase/app": "0.10.7", + "@firebase/component": "0.6.8", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.6", + "@firebase/util": "1.9.7", "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/component": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.8.tgz", + "integrity": "sha512-LcNvxGLLGjBwB0dJUsBGCej2fqAepWyBubs4jt1Tiuns7QLbXHuyObZ4aMeBjZjWx4m8g1LoVI9QFpSaq/k4/g==", + "dev": true, + "requires": { + "@firebase/util": "1.9.7", + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.7.tgz", + "integrity": "sha512-fBVNH/8bRbYjqlbIhZ+lBtdAAS4WqZumx03K06/u7fJSpz1TGjEMm1ImvKD47w+xaFKIP2ori6z8BrbakRfjJA==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } } }, "@firebase/app-types": { From 87ed6e60801439b579895adbeeae239f51e147a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 18:46:57 +0000 Subject: [PATCH 147/323] build(deps-dev): bump chai from 4.4.1 to 4.5.0 (#2650) --- package-lock.json | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 38baf720d0..d39a05625b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2419,9 +2419,9 @@ "dev": true }, "chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "requires": { "assertion-error": "^1.1.0", @@ -2430,7 +2430,15 @@ "get-func-name": "^2.0.2", "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" + }, + "dependencies": { + "type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true + } } }, "chai-as-promised": { From d09e3bd1be630e42dccd1fffa84fb92e8a10c2ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 18:53:31 +0000 Subject: [PATCH 148/323] build(deps): bump @types/node from 20.14.11 to 22.0.1 (#2657) --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d39a05625b..4149ecb8a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1574,11 +1574,11 @@ } }, "@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "version": "22.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.1.tgz", + "integrity": "sha512-RVKWL+s4ax6syie/ev3FXFIs38mke4ZsCDPBcLF2Gu6MbQXKe9Fo9iU0EPUxDB1mDVvC0vCgkV3lKa2f6xIuHg==", "requires": { - "undici-types": "~5.26.4" + "undici-types": "~6.11.1" } }, "@types/qs": { @@ -8225,9 +8225,9 @@ "dev": true }, "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", + "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==" }, "unique-stream": { "version": "2.3.1", diff --git a/package.json b/package.json index 228f86ea8c..3d18be58e0 100644 --- a/package.json +++ b/package.json @@ -199,7 +199,7 @@ "@fastify/busboy": "^3.0.0", "@firebase/database-compat": "^1.0.2", "@firebase/database-types": "^1.0.0", - "@types/node": "^20.10.3", + "@types/node": "^22.0.1", "farmhash-modern": "^1.1.0", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", From 745c22e4b97e9047d1064f3c1bc1c7fbd816f70c Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 1 Aug 2024 10:27:21 -0400 Subject: [PATCH 149/323] fix: `getToken()` returns existing promise to a token if one exists instead of a new token. (#2648) * fix: returns existing promise to a token if one exists instead of a new token. * fix: lint --- src/app/firebase-app.ts | 17 ++++++++++++----- test/integration/messaging.spec.ts | 2 +- test/unit/app/firebase-app.spec.ts | 10 ++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/app/firebase-app.ts b/src/app/firebase-app.ts index 4dd97cb33d..a0ee93e1fe 100644 --- a/src/app/firebase-app.ts +++ b/src/app/firebase-app.ts @@ -39,19 +39,21 @@ export interface FirebaseAccessToken { */ export class FirebaseAppInternals { private cachedToken_: FirebaseAccessToken; + private promiseToCachedToken_: Promise; private tokenListeners_: Array<(token: string) => void>; + private isRefreshing: boolean; // eslint-disable-next-line @typescript-eslint/naming-convention constructor(private credential_: Credential) { this.tokenListeners_ = []; + this.isRefreshing = false; } public getToken(forceRefresh = false): Promise { if (forceRefresh || this.shouldRefresh()) { - return this.refreshToken(); + this.promiseToCachedToken_ = this.refreshToken(); } - - return Promise.resolve(this.cachedToken_); + return this.promiseToCachedToken_ } public getCachedToken(): FirebaseAccessToken | null { @@ -59,6 +61,7 @@ export class FirebaseAppInternals { } private refreshToken(): Promise { + this.isRefreshing = true; return Promise.resolve(this.credential_.getAccessToken()) .then((result) => { // Since the developer can provide the credential implementation, we want to weakly verify @@ -108,11 +111,15 @@ export class FirebaseAppInternals { } throw new FirebaseAppError(AppErrorCodes.INVALID_CREDENTIAL, errorMessage); - }); + }) + .finally(() => { + this.isRefreshing = false; + }) } private shouldRefresh(): boolean { - return !this.cachedToken_ || (this.cachedToken_.expirationTime - Date.now()) <= TOKEN_EXPIRY_THRESHOLD_MILLIS; + return (!this.cachedToken_ || (this.cachedToken_.expirationTime - Date.now()) <= TOKEN_EXPIRY_THRESHOLD_MILLIS) + && !this.isRefreshing; } /** diff --git a/test/integration/messaging.spec.ts b/test/integration/messaging.spec.ts index d11b035861..d564e06f66 100644 --- a/test/integration/messaging.spec.ts +++ b/test/integration/messaging.spec.ts @@ -278,7 +278,7 @@ describe('admin.messaging', () => { }); }); - xit('sendToDeviceGroup() returns a response with success count', () => { + it('sendToDeviceGroup() returns a response with success count', () => { return getMessaging().sendToDeviceGroup(notificationKey, payload, options) .then((response) => { expect(typeof response.successCount).to.equal('number'); diff --git a/test/unit/app/firebase-app.spec.ts b/test/unit/app/firebase-app.spec.ts index 2211f4f457..df4fc84a67 100644 --- a/test/unit/app/firebase-app.spec.ts +++ b/test/unit/app/firebase-app.spec.ts @@ -808,6 +808,16 @@ describe('FirebaseApp', () => { }); }); + it('only refreshes the token once for concurrent calls', () => { + const promise1 = mockApp.INTERNAL.getToken(); + const promise2 = mockApp.INTERNAL.getToken(); + expect(getTokenStub).to.have.been.calledOnce; + return Promise.all([promise1, promise2]).then((tokens) => { + expect(tokens[0]).to.equal(tokens[1]); + expect(getTokenStub).to.have.been.calledOnce; + }) + }); + it('Includes the original error in exception', () => { getTokenStub.restore(); const mockError = new FirebaseAppError( From 24a469e41c47fb47af3aacbe0eb7606e1fe2652f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 10:43:55 -0400 Subject: [PATCH 150/323] build(deps-dev): bump @firebase/app-compat from 0.2.37 to 0.2.38 (#2664) Bumps [@firebase/app-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/app-compat) from 0.2.37 to 0.2.38. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/main/packages/app-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/app-compat@0.2.38/packages/app-compat) --- updated-dependencies: - dependency-name: "@firebase/app-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4149ecb8a7..3854b71d53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -441,9 +441,9 @@ } }, "@firebase/app": { - "version": "0.10.7", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.7.tgz", - "integrity": "sha512-7OCd53B+wnk/onbMLn/vM10pDjw97zzWUD8m3swtLYKJIrL+gDZ7HZ4xcbBLw7OB8ikzu8k1ORNjRe2itgAy4g==", + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.8.tgz", + "integrity": "sha512-xSLmW0/RShcnUEXH7l+wC0AFWaUtty4tUFF2loIgbtXTRmra0UH/SqYDf/IcfreUninRrCsusNmvoTidGkXJPw==", "dev": true, "requires": { "@firebase/component": "0.6.8", @@ -480,12 +480,12 @@ "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "@firebase/app-compat": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.37.tgz", - "integrity": "sha512-yiQLYT9LYQHuJGu/msuBLFtdWWTJ3Pz04E9gSeWykSB+8s0XXJJqfqQlghH7CcQ3KnJZR+Wuc3zSMcY3a+dn6Q==", + "version": "0.2.38", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.38.tgz", + "integrity": "sha512-36ZrSvkYLW7QR01Sii2X+IY18ErMpRg6e2B2f/DVTtJBolthwXOnNBps+wvaVBvegdvdVPspgDXZUV0ppqh45w==", "dev": true, "requires": { - "@firebase/app": "0.10.7", + "@firebase/app": "0.10.8", "@firebase/component": "0.6.8", "@firebase/logger": "0.4.2", "@firebase/util": "1.9.7", From ed004baafb075390239aec5892889f8959af456f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:49:07 +0000 Subject: [PATCH 151/323] build(deps): bump @types/node from 22.0.1 to 22.1.0 (#2663) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3854b71d53..a05f8713f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1574,11 +1574,11 @@ } }, "@types/node": { - "version": "22.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.1.tgz", - "integrity": "sha512-RVKWL+s4ax6syie/ev3FXFIs38mke4ZsCDPBcLF2Gu6MbQXKe9Fo9iU0EPUxDB1mDVvC0vCgkV3lKa2f6xIuHg==", + "version": "22.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", + "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", "requires": { - "undici-types": "~6.11.1" + "undici-types": "~6.13.0" } }, "@types/qs": { @@ -8225,9 +8225,9 @@ "dev": true }, "undici-types": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz", - "integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==" + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" }, "unique-stream": { "version": "2.3.1", From 3e9fd595235419a0499f68ababb392a1cb8ff3eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 14:53:48 +0000 Subject: [PATCH 152/323] build(deps-dev): bump @microsoft/api-extractor from 7.47.2 to 7.47.5 (#2661) --- package-lock.json | 64 +++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index a05f8713f0..83cd2847d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -981,18 +981,18 @@ } }, "@microsoft/api-extractor": { - "version": "7.47.2", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.2.tgz", - "integrity": "sha512-YWE2HGrSTZaPPSr7xiNizSuViZpC7Jsa7+DwRW5rYVgrMXNbfX/PpBOoSkl5uaz9I2sv2JKLJ75kVNt64BvS3g==", + "version": "7.47.5", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.5.tgz", + "integrity": "sha512-edKt4dFO2t25xmI2FX2rsP5liIgwKW1yuQImA0JM+5YGHCoo51GEQ7j+On17SvVpRJnuqLE/QVgtjIQ1Hpg98w==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.29.3", + "@microsoft/api-extractor-model": "7.29.4", "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.5.0", - "@rushstack/rig-package": "0.5.2", - "@rushstack/terminal": "0.13.2", - "@rushstack/ts-command-line": "4.22.2", + "@rushstack/node-core-library": "5.5.1", + "@rushstack/rig-package": "0.5.3", + "@rushstack/terminal": "0.13.3", + "@rushstack/ts-command-line": "4.22.4", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1008,9 +1008,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.0.tgz", - "integrity": "sha512-Cl3MYQ74Je5Y/EngMxcA3SpHjGZ/022nKbAO1aycGfQ+7eKyNCBu0oywj5B1f367GCzuHBgy+3BlVLKysHkXZw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.1.tgz", + "integrity": "sha512-ZutW56qIzH8xIOlfyaLQJFx+8IBqdbVCZdnj+XT1MorQ1JqqxHse8vbCpEM+2MjsrqcbxcgDIbfggB1ZSQ2A3g==", "dev": true, "requires": { "ajv": "~8.13.0", @@ -1024,12 +1024,12 @@ } }, "@rushstack/ts-command-line": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.2.tgz", - "integrity": "sha512-xkvrGd6D9dPlI3I401Thc640WNsEPB1sGEmy12a2VJaPQPwhE6Ik0gEVPZJ/2G1w213eaCAdxUY1xpiTulsmpA==", + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.4.tgz", + "integrity": "sha512-QoyhbWfyF9Ixg5DWdPzxO3h2RmJ7i5WH9b7qLzD5h5WFya/ZqicjdPrVwQiGtrFvAbBj8jhcC9DhbzU9xAk78g==", "dev": true, "requires": { - "@rushstack/terminal": "0.13.2", + "@rushstack/terminal": "0.13.3", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1065,14 +1065,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.3.tgz", - "integrity": "sha512-kEWjLr2ygL3ku9EGyjeTnL2S5IxyH9NaF1k1UoI0Nzwr4xEJBSWCVsWuF2+0lPUrRPA6mTY95fR264SJ5ETKQA==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.4.tgz", + "integrity": "sha512-LHOMxmT8/tU1IiiiHOdHFF83Qsi+V8d0kLfscG4EvQE9cafiR8blOYr8SfkQKWB1wgEilQgXJX3MIA4vetDLZw==", "dev": true, "requires": { "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.5.0" + "@rushstack/node-core-library": "5.5.1" }, "dependencies": { "@microsoft/tsdoc": { @@ -1082,9 +1082,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.0.tgz", - "integrity": "sha512-Cl3MYQ74Je5Y/EngMxcA3SpHjGZ/022nKbAO1aycGfQ+7eKyNCBu0oywj5B1f367GCzuHBgy+3BlVLKysHkXZw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.1.tgz", + "integrity": "sha512-ZutW56qIzH8xIOlfyaLQJFx+8IBqdbVCZdnj+XT1MorQ1JqqxHse8vbCpEM+2MjsrqcbxcgDIbfggB1ZSQ2A3g==", "dev": true, "requires": { "ajv": "~8.13.0", @@ -1269,9 +1269,9 @@ } }, "@rushstack/rig-package": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", - "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", + "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", "dev": true, "requires": { "resolve": "~1.22.1", @@ -1279,19 +1279,19 @@ } }, "@rushstack/terminal": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.13.2.tgz", - "integrity": "sha512-t8i0PsGvBHmFBY8pryO3badqFlxQsm2rw3KYrzjcmVkG/WGklKg1qVkr9beAS1Oe8XWDRgj6SkoHkpNjs7aaNw==", + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.13.3.tgz", + "integrity": "sha512-fc3zjXOw8E0pXS5t9vTiIPx9gHA0fIdTXsu9mT4WbH+P3mYvnrX0iAQ5a6NvyK1+CqYWBTw/wVNx7SDJkI+WYQ==", "dev": true, "requires": { - "@rushstack/node-core-library": "5.5.0", + "@rushstack/node-core-library": "5.5.1", "supports-color": "~8.1.1" }, "dependencies": { "@rushstack/node-core-library": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.0.tgz", - "integrity": "sha512-Cl3MYQ74Je5Y/EngMxcA3SpHjGZ/022nKbAO1aycGfQ+7eKyNCBu0oywj5B1f367GCzuHBgy+3BlVLKysHkXZw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.1.tgz", + "integrity": "sha512-ZutW56qIzH8xIOlfyaLQJFx+8IBqdbVCZdnj+XT1MorQ1JqqxHse8vbCpEM+2MjsrqcbxcgDIbfggB1ZSQ2A3g==", "dev": true, "requires": { "ajv": "~8.13.0", From d01584ec388cfd5f9714ed769f127c63f1d325d5 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 7 Aug 2024 11:09:26 -0400 Subject: [PATCH 153/323] chore: Skip sendToDeviceGroup integration test (#2666) --- test/integration/messaging.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/messaging.spec.ts b/test/integration/messaging.spec.ts index d564e06f66..8292637faf 100644 --- a/test/integration/messaging.spec.ts +++ b/test/integration/messaging.spec.ts @@ -278,7 +278,7 @@ describe('admin.messaging', () => { }); }); - it('sendToDeviceGroup() returns a response with success count', () => { + it.skip('sendToDeviceGroup() returns a response with success count', () => { return getMessaging().sendToDeviceGroup(notificationKey, payload, options) .then((response) => { expect(typeof response.successCount).to.equal('number'); From 5d475295d69cebb4e8db1d443cd7c0834ce13dd3 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 8 Aug 2024 11:15:45 -0400 Subject: [PATCH 154/323] [chore] Release 12.3.1 (#2667) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3d18be58e0..987bad1e48 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.3.0", + "version": "12.3.1", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 8d11961cb1e15eec17ae0a2151b8ea776d2de005 Mon Sep 17 00:00:00 2001 From: Garrett Burroughs Date: Thu, 8 Aug 2024 14:49:50 -0400 Subject: [PATCH 155/323] Reroute Cloud Tasks to emulator when it is running (#2649) * Redirect Task Enqueue Requests to emulator if it is running * Reroute Task Queue requests to emulator when it is running * Add tests for emulator redirection * Bypass service account check for tasks when running within the emulator * use fake service account when running in emulated mode and service account credentials are not provided * restore package-lock.json --- .../functions-api-client-internal.ts | 49 +++++++--- .../functions-api-client-internal.spec.ts | 93 +++++++++++++++++++ 2 files changed, 130 insertions(+), 12 deletions(-) diff --git a/src/functions/functions-api-client-internal.ts b/src/functions/functions-api-client-internal.ts index a98a599ed0..6696f18da3 100644 --- a/src/functions/functions-api-client-internal.ts +++ b/src/functions/functions-api-client-internal.ts @@ -29,6 +29,7 @@ import { ComputeEngineCredential } from '../app/credential-internal'; const CLOUD_TASKS_API_RESOURCE_PATH = 'projects/{projectId}/locations/{locationId}/queues/{resourceId}/tasks'; const CLOUD_TASKS_API_URL_FORMAT = 'https://cloudtasks.googleapis.com/v2/' + CLOUD_TASKS_API_RESOURCE_PATH; const FIREBASE_FUNCTION_URL_FORMAT = 'https://{locationId}-{projectId}.cloudfunctions.net/{resourceId}'; +export const EMULATED_SERVICE_ACCOUNT_DEFAULT = 'emulated-service-acct@email.com'; const FIREBASE_FUNCTIONS_CONFIG_HEADERS = { 'X-Firebase-Client': `fire-admin-node/${utils.getSdkVersion()}` @@ -69,8 +70,8 @@ export class FunctionsApiClient { } if (!validator.isTaskId(id)) { throw new FirebaseFunctionsError( - 'invalid-argument', 'id can contain only letters ([A-Za-z]), numbers ([0-9]), ' - + 'hyphens (-), or underscores (_). The maximum length is 500 characters.'); + 'invalid-argument', 'id can contain only letters ([A-Za-z]), numbers ([0-9]), ' + + 'hyphens (-), or underscores (_). The maximum length is 500 characters.'); } let resources: utils.ParsedResource; @@ -91,7 +92,8 @@ export class FunctionsApiClient { } try { - const serviceUrl = await this.getUrl(resources, CLOUD_TASKS_API_URL_FORMAT.concat('/', id)); + const serviceUrl = tasksEmulatorUrl(resources, functionName)?.concat('/', id) + ?? await this.getUrl(resources, CLOUD_TASKS_API_URL_FORMAT.concat('/', id)); const request: HttpRequestConfig = { method: 'DELETE', url: serviceUrl, @@ -144,7 +146,10 @@ export class FunctionsApiClient { const task = this.validateTaskOptions(data, resources, opts); try { - const serviceUrl = await this.getUrl(resources, CLOUD_TASKS_API_URL_FORMAT); + const serviceUrl = + tasksEmulatorUrl(resources, functionName) ?? + await this.getUrl(resources, CLOUD_TASKS_API_URL_FORMAT); + const taskPayload = await this.updateTaskPayload(task, resources, extensionId); const request: HttpRequestConfig = { method: 'POST', @@ -237,7 +242,7 @@ export class FunctionsApiClient { serviceAccountEmail: '', }, body: Buffer.from(JSON.stringify({ data })).toString('base64'), - headers: { + headers: { 'Content-Type': 'application/json', ...opts?.headers, } @@ -252,7 +257,7 @@ export class FunctionsApiClient { if ('scheduleTime' in opts && 'scheduleDelaySeconds' in opts) { throw new FirebaseFunctionsError( 'invalid-argument', 'Both scheduleTime and scheduleDelaySeconds are provided. ' - + 'Only one value should be set.'); + + 'Only one value should be set.'); } if ('scheduleTime' in opts && typeof opts.scheduleTime !== 'undefined') { if (!(opts.scheduleTime instanceof Date)) { @@ -275,7 +280,7 @@ export class FunctionsApiClient { || opts.dispatchDeadlineSeconds > 1800) { throw new FirebaseFunctionsError( 'invalid-argument', 'dispatchDeadlineSeconds must be a non-negative duration in seconds ' - + 'and must be in the range of 15s to 30 mins.'); + + 'and must be in the range of 15s to 30 mins.'); } task.dispatchDeadline = `${opts.dispatchDeadlineSeconds}s`; } @@ -283,7 +288,7 @@ export class FunctionsApiClient { if (!validator.isTaskId(opts.id)) { throw new FirebaseFunctionsError( 'invalid-argument', 'id can contain only letters ([A-Za-z]), numbers ([0-9]), ' - + 'hyphens (-), or underscores (_). The maximum length is 500 characters.'); + + 'hyphens (-), or underscores (_). The maximum length is 500 characters.'); } const resourcePath = utils.formatString(CLOUD_TASKS_API_RESOURCE_PATH, { projectId: resources.projectId, @@ -304,9 +309,14 @@ export class FunctionsApiClient { } private async updateTaskPayload(task: Task, resources: utils.ParsedResource, extensionId?: string): Promise { - const functionUrl = validator.isNonEmptyString(task.httpRequest.url) - ? task.httpRequest.url + const defaultUrl = process.env.CLOUD_TASKS_EMULATOR_HOST ? + '' : await this.getUrl(resources, FIREBASE_FUNCTION_URL_FORMAT); + + const functionUrl = validator.isNonEmptyString(task.httpRequest.url) + ? task.httpRequest.url + : defaultUrl; + task.httpRequest.url = functionUrl; // When run from a deployed extension, we should be using ComputeEngineCredentials if (validator.isNonEmptyString(extensionId) && this.app.options.credential instanceof ComputeEngineCredential) { @@ -315,8 +325,16 @@ export class FunctionsApiClient { // Don't send httpRequest.oidcToken if we set Authorization header, or Cloud Tasks will overwrite it. delete task.httpRequest.oidcToken; } else { - const account = await this.getServiceAccount(); - task.httpRequest.oidcToken = { serviceAccountEmail: account }; + try { + const account = await this.getServiceAccount(); + task.httpRequest.oidcToken = { serviceAccountEmail: account }; + } catch (e) { + if (process.env.CLOUD_TASKS_EMULATOR_HOST) { + task.httpRequest.oidcToken = { serviceAccountEmail: EMULATED_SERVICE_ACCOUNT_DEFAULT }; + } else { + throw e; + } + } } return task; } @@ -417,3 +435,10 @@ export class FirebaseFunctionsError extends PrefixedFirebaseError { (this as any).__proto__ = FirebaseFunctionsError.prototype; } } + +function tasksEmulatorUrl(resources: utils.ParsedResource, functionName: string): string | undefined { + if (process.env.CLOUD_TASKS_EMULATOR_HOST) { + return `http://${process.env.CLOUD_TASKS_EMULATOR_HOST}/projects/${resources.projectId}/locations/${resources.locationId}/queues/${functionName}/tasks`; + } + return undefined; +} diff --git a/test/unit/functions/functions-api-client-internal.spec.ts b/test/unit/functions/functions-api-client-internal.spec.ts index f000d21c0a..bb1ae0bfbd 100644 --- a/test/unit/functions/functions-api-client-internal.spec.ts +++ b/test/unit/functions/functions-api-client-internal.spec.ts @@ -29,6 +29,7 @@ import { FirebaseFunctionsError, FunctionsApiClient, Task } from '../../../src/f import { HttpClient } from '../../../src/utils/api-request'; import { FirebaseAppError } from '../../../src/utils/error'; import { deepCopy } from '../../../src/utils/deep-copy'; +import { EMULATED_SERVICE_ACCOUNT_DEFAULT } from '../../../src/functions/functions-api-client-internal'; const expect = chai.expect; @@ -90,6 +91,10 @@ describe('FunctionsApiClient', () => { const CLOUD_TASKS_URL_FULL_RESOURCE = `https://cloudtasks.googleapis.com/v2/projects/${CUSTOM_PROJECT_ID}/locations/${CUSTOM_REGION}/queues/${FUNCTION_NAME}/tasks`; const CLOUD_TASKS_URL_PARTIAL_RESOURCE = `https://cloudtasks.googleapis.com/v2/projects/${mockOptions.projectId}/locations/${CUSTOM_REGION}/queues/${FUNCTION_NAME}/tasks`; + + const CLOUD_TASKS_EMULATOR_HOST = '127.0.0.1:9499'; + + const CLOUD_TASKS_URL_EMULATOR = `http://${CLOUD_TASKS_EMULATOR_HOST}/projects/${mockOptions.projectId}/locations/${DEFAULT_REGION}/queues/${FUNCTION_NAME}/tasks`; const clientWithoutProjectId = new FunctionsApiClient(mocks.mockCredentialApp()); @@ -106,6 +111,9 @@ describe('FunctionsApiClient', () => { afterEach(() => { _.forEach(stubs, (stub) => stub.restore()); stubs = []; + if (process.env.CLOUD_TASKS_EMULATOR_HOST) { + delete process.env.CLOUD_TASKS_EMULATOR_HOST; + } return app.delete(); }); @@ -477,8 +485,79 @@ describe('FunctionsApiClient', () => { }); }); }); + + it('should redirect to the emulator when CLOUD_TASKS_EMULATOR_HOST is set', () => { + const expectedPayload = deepCopy(TEST_TASK_PAYLOAD); + const stub = sinon + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom({}, 200)); + stubs.push(stub); + process.env.CLOUD_TASKS_EMULATOR_HOST = CLOUD_TASKS_EMULATOR_HOST; + return apiClient.enqueue({}, FUNCTION_NAME, '', { uri: TEST_TASK_PAYLOAD.httpRequest.url }) + .then(() => { + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: CLOUD_TASKS_URL_EMULATOR, + headers: EXPECTED_HEADERS, + data: { + task: expectedPayload + } + }); + }); + }); + + it('should leave empty urls alone when CLOUD_TASKS_EMULATOR_HOST is set', () => { + const expectedPayload = deepCopy(TEST_TASK_PAYLOAD); + expectedPayload.httpRequest.url = ''; + const stub = sinon + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom({}, 200)); + stubs.push(stub); + process.env.CLOUD_TASKS_EMULATOR_HOST = CLOUD_TASKS_EMULATOR_HOST; + return apiClient.enqueue({}, FUNCTION_NAME) + .then(() => { + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: CLOUD_TASKS_URL_EMULATOR, + headers: EXPECTED_HEADERS, + data: { + task: expectedPayload + } + }); + }); + }); + + it('should use a fake service account if the emulator is running and no service account is defined', () => { + app = mocks.appWithOptions({ + credential: new mocks.MockCredential(), + projectId: 'test-project', + serviceAccountId: '' + }); + apiClient = new FunctionsApiClient(app); + + const expectedPayload = deepCopy(TEST_TASK_PAYLOAD); + expectedPayload.httpRequest.oidcToken = { serviceAccountEmail: EMULATED_SERVICE_ACCOUNT_DEFAULT }; + const stub = sinon + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom({}, 200)); + stubs.push(stub); + process.env.CLOUD_TASKS_EMULATOR_HOST = CLOUD_TASKS_EMULATOR_HOST; + return apiClient.enqueue({}, FUNCTION_NAME, '', { uri: TEST_TASK_PAYLOAD.httpRequest.url }) + .then(() => { + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: CLOUD_TASKS_URL_EMULATOR, + headers: EXPECTED_HEADERS, + data: { + task: expectedPayload + } + }); + }); + }) + }); + describe('delete', () => { for (const invalidTaskId of [1234, 'task!', 'id:0', '[1234]', '(1234)']) { it(`should throw given an invalid task ID: ${invalidTaskId}`, () => { @@ -514,6 +593,20 @@ describe('FunctionsApiClient', () => { expect(apiClient.delete('nonexistent-task', FUNCTION_NAME)).to.eventually.not.throw(utils.errorFrom({}, 404)); }); + it('should redirect to the emulator when CLOUD_TASKS_EMULATOR_HOST is set', async () => { + process.env.CLOUD_TASKS_EMULATOR_HOST = CLOUD_TASKS_EMULATOR_HOST; + const stub = sinon + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom({}, 200)); + stubs.push(stub); + await apiClient.delete('mock-task', FUNCTION_NAME); + expect(stub).to.have.been.calledWith({ + method: 'DELETE', + url: CLOUD_TASKS_URL_EMULATOR.concat('/', 'mock-task'), + headers: EXPECTED_HEADERS, + }); + }); + it('should throw on non-404 HTTP errors', () => { const stub = sinon .stub(HttpClient.prototype, 'send') From 8a83bdfb0928f5ebe1849585cb86089ac9f82f76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 16:03:16 -0400 Subject: [PATCH 156/323] build(deps-dev): bump @microsoft/api-extractor from 7.47.5 to 7.47.6 (#2671) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.47.5 to 7.47.6. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.47.6/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index 83cd2847d0..42849267a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.3.0", + "version": "12.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -981,18 +981,18 @@ } }, "@microsoft/api-extractor": { - "version": "7.47.5", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.5.tgz", - "integrity": "sha512-edKt4dFO2t25xmI2FX2rsP5liIgwKW1yuQImA0JM+5YGHCoo51GEQ7j+On17SvVpRJnuqLE/QVgtjIQ1Hpg98w==", + "version": "7.47.6", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.6.tgz", + "integrity": "sha512-saI7n319+PdJ8PAePr14LWeIPOW2fHSr3KZfYFqJ2VUpIc1TTSh6ATFZfLPWI1LK7eZHun8+FpNsuxonyvxTgQ==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.29.4", + "@microsoft/api-extractor-model": "7.29.5", "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.5.1", + "@rushstack/node-core-library": "5.6.0", "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.13.3", - "@rushstack/ts-command-line": "4.22.4", + "@rushstack/terminal": "0.13.4", + "@rushstack/ts-command-line": "4.22.5", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1008,9 +1008,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.1.tgz", - "integrity": "sha512-ZutW56qIzH8xIOlfyaLQJFx+8IBqdbVCZdnj+XT1MorQ1JqqxHse8vbCpEM+2MjsrqcbxcgDIbfggB1ZSQ2A3g==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.6.0.tgz", + "integrity": "sha512-3ixIcEHseqU1sbnvoQkvxvfTYWbi1IIhnq/vexJcex7j6D8lnQCiYnd/E2oXbUH0Zv48CjtfslC/2MVFd71mpg==", "dev": true, "requires": { "ajv": "~8.13.0", @@ -1024,12 +1024,12 @@ } }, "@rushstack/ts-command-line": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.4.tgz", - "integrity": "sha512-QoyhbWfyF9Ixg5DWdPzxO3h2RmJ7i5WH9b7qLzD5h5WFya/ZqicjdPrVwQiGtrFvAbBj8jhcC9DhbzU9xAk78g==", + "version": "4.22.5", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.5.tgz", + "integrity": "sha512-eFm+5DJboPHAy3epLNQtmG+hDlBzS950g26nZPbciMQeXmZ5shGGNe6ERjV77wnr5IuxfLhYGJ4ZjPy8Z56MBA==", "dev": true, "requires": { - "@rushstack/terminal": "0.13.3", + "@rushstack/terminal": "0.13.4", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1065,14 +1065,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.29.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.4.tgz", - "integrity": "sha512-LHOMxmT8/tU1IiiiHOdHFF83Qsi+V8d0kLfscG4EvQE9cafiR8blOYr8SfkQKWB1wgEilQgXJX3MIA4vetDLZw==", + "version": "7.29.5", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.5.tgz", + "integrity": "sha512-axMwj4pgtYH6/IclP9ly33laSwTym1kBwSUcoHElc2LYAE5NNlhGT78ucEpIZtqEZaGgA8yxGXIyS17XCC2Iuw==", "dev": true, "requires": { "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.5.1" + "@rushstack/node-core-library": "5.6.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1082,9 +1082,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.1.tgz", - "integrity": "sha512-ZutW56qIzH8xIOlfyaLQJFx+8IBqdbVCZdnj+XT1MorQ1JqqxHse8vbCpEM+2MjsrqcbxcgDIbfggB1ZSQ2A3g==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.6.0.tgz", + "integrity": "sha512-3ixIcEHseqU1sbnvoQkvxvfTYWbi1IIhnq/vexJcex7j6D8lnQCiYnd/E2oXbUH0Zv48CjtfslC/2MVFd71mpg==", "dev": true, "requires": { "ajv": "~8.13.0", @@ -1279,19 +1279,19 @@ } }, "@rushstack/terminal": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.13.3.tgz", - "integrity": "sha512-fc3zjXOw8E0pXS5t9vTiIPx9gHA0fIdTXsu9mT4WbH+P3mYvnrX0iAQ5a6NvyK1+CqYWBTw/wVNx7SDJkI+WYQ==", + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.13.4.tgz", + "integrity": "sha512-h7g2RuffpqBCDKOijlUmvQ0b2O9kpIOK9TWCX9IR+2kvudp6MdtCYDu29zeqweWwCSWUnuAaUfB5HT88s0YCiw==", "dev": true, "requires": { - "@rushstack/node-core-library": "5.5.1", + "@rushstack/node-core-library": "5.6.0", "supports-color": "~8.1.1" }, "dependencies": { "@rushstack/node-core-library": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.5.1.tgz", - "integrity": "sha512-ZutW56qIzH8xIOlfyaLQJFx+8IBqdbVCZdnj+XT1MorQ1JqqxHse8vbCpEM+2MjsrqcbxcgDIbfggB1ZSQ2A3g==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.6.0.tgz", + "integrity": "sha512-3ixIcEHseqU1sbnvoQkvxvfTYWbi1IIhnq/vexJcex7j6D8lnQCiYnd/E2oXbUH0Zv48CjtfslC/2MVFd71mpg==", "dev": true, "requires": { "ajv": "~8.13.0", From b865eb717f4637515b233d7b33321f5370bb6c7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:06:48 +0000 Subject: [PATCH 157/323] build(deps): bump axios in /.github/actions/send-email (#2673) --- .github/actions/send-email/package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 7c530a0d4f..2963ba307e 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -57,11 +57,11 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", - "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } From 96351695926aa0f1d6ea659f3e7840ab32a7ebea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:13:19 +0000 Subject: [PATCH 158/323] build(deps): bump @google-cloud/storage from 7.12.0 to 7.12.1 (#2669) --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 42849267a2..f876bb5e75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -727,9 +727,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.12.0.tgz", - "integrity": "sha512-122Ui67bhnf8MkRnxQAC5lf7wPGkPP5hL3+J5s9HHDw2J9RpaMmnV8iahn+RUn9BH70W6uRe6nMZLXiRaJM/3g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.12.1.tgz", + "integrity": "sha512-Z3ZzOnF3YKLuvpkvF+TjQ6lztxcAyTILp+FjKonmVpEwPa9vFvxpZjubLR4sB6bf19i/8HL2AXRjA0YFgHFRmQ==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", @@ -738,7 +738,7 @@ "abort-controller": "^3.0.0", "async-retry": "^1.3.3", "duplexify": "^4.1.3", - "fast-xml-parser": "^4.3.0", + "fast-xml-parser": "^4.4.1", "gaxios": "^6.0.2", "google-auth-library": "^9.6.3", "html-entities": "^2.5.2", From fcd7f2779931090d5cea399f88779310acc1ac83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:18:48 +0000 Subject: [PATCH 159/323] build(deps-dev): bump mocha from 10.7.0 to 10.7.3 (#2670) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f876bb5e75..92d631b58e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5855,9 +5855,9 @@ "dev": true }, "mocha": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", - "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "dev": true, "requires": { "ansi-colors": "^4.1.3", From 3a97552125a8982e43efa89a4549c55a48b03bc0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:24:07 +0000 Subject: [PATCH 160/323] build(deps): bump @types/node from 22.1.0 to 22.3.0 (#2675) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 92d631b58e..f4ec885b28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1574,11 +1574,11 @@ } }, "@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", "requires": { - "undici-types": "~6.13.0" + "undici-types": "~6.18.2" } }, "@types/qs": { @@ -8225,9 +8225,9 @@ "dev": true }, "undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" }, "unique-stream": { "version": "2.3.1", From a0cc4864346b66a454155c059f58965b38fb02ca Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 22 Aug 2024 18:03:47 +0000 Subject: [PATCH 161/323] chore: Deprecate sendToTopic and Condition (#2683) --- etc/firebase-admin.messaging.api.md | 2 + src/messaging/messaging.ts | 4 + test/integration/messaging.spec.ts | 192 +--------------------------- 3 files changed, 8 insertions(+), 190 deletions(-) diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index 84cb3e9b84..78cb17c5ce 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -198,11 +198,13 @@ export class Messaging { sendEachForMulticast(message: MulticastMessage, dryRun?: boolean): Promise; // @deprecated sendMulticast(message: MulticastMessage, dryRun?: boolean): Promise; + // @deprecated sendToCondition(condition: string, payload: MessagingPayload, options?: MessagingOptions): Promise; // @deprecated sendToDevice(registrationTokenOrTokens: string | string[], payload: MessagingPayload, options?: MessagingOptions): Promise; // @deprecated sendToDeviceGroup(notificationKey: string, payload: MessagingPayload, options?: MessagingOptions): Promise; + // @deprecated sendToTopic(topic: string, payload: MessagingPayload, options?: MessagingOptions): Promise; subscribeToTopic(registrationTokenOrTokens: string | string[], topic: string): Promise; unsubscribeFromTopic(registrationTokenOrTokens: string | string[], topic: string): Promise; diff --git a/src/messaging/messaging.ts b/src/messaging/messaging.ts index ad78783fb9..38c6edcc42 100644 --- a/src/messaging/messaging.ts +++ b/src/messaging/messaging.ts @@ -686,6 +686,8 @@ export class Messaging { * * @returns A promise fulfilled with the server's response after the message * has been sent. + * + * @deprecated Use {@link Messaging.send} instead. */ public sendToTopic( topic: string, @@ -737,6 +739,8 @@ export class Messaging { * * @returns A promise fulfilled with the server's response after the message * has been sent. + * + * @deprecated Use {@link Messaging.send} instead. */ public sendToCondition( condition: string, diff --git a/test/integration/messaging.spec.ts b/test/integration/messaging.spec.ts index 8292637faf..dc6d662f0b 100644 --- a/test/integration/messaging.spec.ts +++ b/test/integration/messaging.spec.ts @@ -17,25 +17,20 @@ import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import { Message, MulticastMessage, getMessaging } from '../../lib/messaging/index'; -import { legacyTransportApp } from './setup'; chai.should(); chai.use(chaiAsPromised); const expect = chai.expect; -// The registration token and notification key have the proper format, but are not guaranteed to +// The registration token have the proper format, but are not guaranteed to // work. The intention of these integration tests is that the endpoints returns the proper payload, // but it is hard to ensure these tokens will always be valid. The tests below should still pass // even if they are rotated or invalid. const registrationToken = 'fGw0qy4TGgk:APA91bGtWGjuhp4WRhHXgbabIYp1jxEKI08ofj_v1bKhWAGJQ4e3arRCW' + 'zeTfHaLz83mBnDh0aPWB1AykXAVUUGl2h1wT4XI6XazWpvY7RBUSYfoxtqSWGIm2nvWh2BOP1YG501SsRoE'; -const notificationKey = 'APA91bFYr4cWCkDs_H9VY2Ai6Erw1ABup1NEYqBjz70O8SzxjpALp_bN913XJMlOepaVv9e' + - 'Qs2QrtqX_RZ6cVVv4czgTQXg62qicITR6tQDizaFilDnlVf0'; -const registrationTokens = [registrationToken + '0', registrationToken + '1', registrationToken + '2']; const topic = 'mock-topic'; -const condition = '"test0" in topics || ("test1" in topics && "test2" in topics)'; const invalidTopic = 'topic-$%#^'; @@ -83,30 +78,7 @@ const message: Message = { topic: 'foo-bar', }; -const payload = { - data: { - foo: 'bar', - }, - notification: { - title: 'Message title', - body: 'Message body', - }, -}; - -const invalidPayload: any = { - foo: 'bar', -}; - -const options = { - timeToLive: 60, -}; - describe('admin.messaging', () => { - - before(() => { - getMessaging(legacyTransportApp).enableLegacyHttpTransport() - }) - it('send(message, dryRun) returns a message ID', () => { return getMessaging().send(message, true) .then((name) => { @@ -115,37 +87,6 @@ describe('admin.messaging', () => { }); it('sendEach()', () => { - const messages: Message[] = [message, message, message]; - return getMessaging(legacyTransportApp).sendEach(messages, true) - .then((response) => { - expect(response.responses.length).to.equal(messages.length); - expect(response.successCount).to.equal(messages.length); - expect(response.failureCount).to.equal(0); - response.responses.forEach((resp) => { - expect(resp.success).to.be.true; - expect(resp.messageId).matches(/^projects\/.*\/messages\/.*$/); - }); - }); - }); - - it('sendEach(500)', () => { - const messages: Message[] = []; - for (let i = 0; i < 500; i++) { - messages.push({ topic: `foo-bar-${i % 10}` }); - } - return getMessaging(legacyTransportApp).sendEach(messages, true) - .then((response) => { - expect(response.responses.length).to.equal(messages.length); - expect(response.successCount).to.equal(messages.length); - expect(response.failureCount).to.equal(0); - response.responses.forEach((resp) => { - expect(resp.success).to.be.true; - expect(resp.messageId).matches(/^projects\/.*\/messages\/.*$/); - }); - }); - }); - - it('sendEach() using HTTP2', () => { const messages: Message[] = [message, message, message]; return getMessaging().sendEach(messages, true) .then((response) => { @@ -159,7 +100,7 @@ describe('admin.messaging', () => { }); }); - it('sendEach(500) using HTTP2', () => { + it('sendEach(500)', () => { const messages: Message[] = []; for (let i = 0; i < 500; i++) { messages.push({ topic: `foo-bar-${i % 10}` }); @@ -176,57 +117,7 @@ describe('admin.messaging', () => { }); }); - it('sendAll()', () => { - const messages: Message[] = [message, message, message]; - return getMessaging().sendAll(messages, true) - .then((response) => { - expect(response.responses.length).to.equal(messages.length); - expect(response.successCount).to.equal(messages.length); - expect(response.failureCount).to.equal(0); - response.responses.forEach((resp) => { - expect(resp.success).to.be.true; - expect(resp.messageId).matches(/^projects\/.*\/messages\/.*$/); - }); - }); - }); - - it('sendAll(500)', () => { - const messages: Message[] = []; - for (let i = 0; i < 500; i++) { - messages.push({ topic: `foo-bar-${i % 10}` }); - } - return getMessaging().sendAll(messages, true) - .then((response) => { - expect(response.responses.length).to.equal(messages.length); - expect(response.successCount).to.equal(messages.length); - expect(response.failureCount).to.equal(0); - response.responses.forEach((resp) => { - expect(resp.success).to.be.true; - expect(resp.messageId).matches(/^projects\/.*\/messages\/.*$/); - }); - }); - }); - it('sendEachForMulticast()', () => { - const multicastMessage: MulticastMessage = { - data: message.data, - android: message.android, - tokens: ['not-a-token', 'also-not-a-token'], - }; - return getMessaging(legacyTransportApp).sendEachForMulticast(multicastMessage, true) - .then((response) => { - expect(response.responses.length).to.equal(2); - expect(response.successCount).to.equal(0); - expect(response.failureCount).to.equal(2); - response.responses.forEach((resp) => { - expect(resp.success).to.be.false; - expect(resp.messageId).to.be.undefined; - expect(resp.error).to.have.property('code', 'messaging/invalid-argument'); - }); - }); - }); - - it('sendEachForMulticast() using HTTP2', () => { const multicastMessage: MulticastMessage = { data: message.data, android: message.android, @@ -245,85 +136,6 @@ describe('admin.messaging', () => { }); }); - it('sendMulticast()', () => { - const multicastMessage: MulticastMessage = { - data: message.data, - android: message.android, - tokens: ['not-a-token', 'also-not-a-token'], - }; - return getMessaging().sendMulticast(multicastMessage, true) - .then((response) => { - expect(response.responses.length).to.equal(2); - expect(response.successCount).to.equal(0); - expect(response.failureCount).to.equal(2); - response.responses.forEach((resp) => { - expect(resp.success).to.be.false; - expect(resp.messageId).to.be.undefined; - expect(resp.error).to.have.property('code', 'messaging/invalid-argument'); - }); - }); - }); - - it('sendToDevice(token) returns a response with multicast ID', () => { - return getMessaging().sendToDevice(registrationToken, payload, options) - .then((response) => { - expect(typeof response.multicastId).to.equal('number'); - }); - }); - - it('sendToDevice(token-list) returns a response with multicat ID', () => { - return getMessaging().sendToDevice(registrationTokens, payload, options) - .then((response) => { - expect(typeof response.multicastId).to.equal('number'); - }); - }); - - it.skip('sendToDeviceGroup() returns a response with success count', () => { - return getMessaging().sendToDeviceGroup(notificationKey, payload, options) - .then((response) => { - expect(typeof response.successCount).to.equal('number'); - }); - }); - - it('sendToTopic() returns a response with message ID', () => { - return getMessaging().sendToTopic(topic, payload, options) - .then((response) => { - expect(typeof response.messageId).to.equal('number'); - }); - }); - - it('sendToCondition() returns a response with message ID', () => { - return getMessaging().sendToCondition(condition, payload, options) - .then((response) => { - expect(typeof response.messageId).to.equal('number'); - }); - }); - - it('sendToDevice(token) fails when called with invalid payload', () => { - return getMessaging().sendToDevice(registrationToken, invalidPayload, options) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('sendToDevice(token-list) fails when called with invalid payload', () => { - return getMessaging().sendToDevice(registrationTokens, invalidPayload, options) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('sendToDeviceGroup() fails when called with invalid payload', () => { - return getMessaging().sendToDeviceGroup(notificationKey, invalidPayload, options) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('sendToTopic() fails when called with invalid payload', () => { - return getMessaging().sendToTopic(topic, invalidPayload, options) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('sendToCondition() fails when called with invalid payload', () => { - return getMessaging().sendToCondition(condition, invalidPayload, options) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - it('subscribeToTopic() returns a response with success count', () => { return getMessaging().subscribeToTopic(registrationToken, topic) .then((response) => { From 22924d8424b9d2e91ad1a84c26dfa4c7e8778505 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:10:06 +0000 Subject: [PATCH 162/323] build(deps-dev): bump @firebase/app-compat from 0.2.38 to 0.2.39 (#2677) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index f4ec885b28..a811d0c732 100644 --- a/package-lock.json +++ b/package-lock.json @@ -441,9 +441,9 @@ } }, "@firebase/app": { - "version": "0.10.8", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.8.tgz", - "integrity": "sha512-xSLmW0/RShcnUEXH7l+wC0AFWaUtty4tUFF2loIgbtXTRmra0UH/SqYDf/IcfreUninRrCsusNmvoTidGkXJPw==", + "version": "0.10.9", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.9.tgz", + "integrity": "sha512-AmGlPg/4SoDhwCdvVDeZsN5Yn+czYD/m/NAEOOCOhwn3Cz1xmEFKAKcyZKKahLrh5QPmge5Adyw+sk3cBTubBg==", "dev": true, "requires": { "@firebase/component": "0.6.8", @@ -480,12 +480,12 @@ "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "@firebase/app-compat": { - "version": "0.2.38", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.38.tgz", - "integrity": "sha512-36ZrSvkYLW7QR01Sii2X+IY18ErMpRg6e2B2f/DVTtJBolthwXOnNBps+wvaVBvegdvdVPspgDXZUV0ppqh45w==", + "version": "0.2.39", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.39.tgz", + "integrity": "sha512-NnTFywe+M/jxZn751NIEhidgDePiDvlcfabvGxBy4YbU1E+b0TpEuJUnm3L6YDZtaZLVEz8ieoq9wbJkgGZ2rg==", "dev": true, "requires": { - "@firebase/app": "0.10.8", + "@firebase/app": "0.10.9", "@firebase/component": "0.6.8", "@firebase/logger": "0.4.2", "@firebase/util": "1.9.7", From d88c3fb234f4990df16a5d636147881c529601f8 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 22 Aug 2024 22:11:07 +0000 Subject: [PATCH 163/323] [chore] Release 12.4.0 (#2674) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 987bad1e48..95060f94b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.3.1", + "version": "12.4.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 6b0a4c5c6567c5fb2cb154e29326dd282b133c8a Mon Sep 17 00:00:00 2001 From: Brian Peiris <79419+brianpeiris@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:28:03 -0400 Subject: [PATCH 164/323] Create CHANGELOG.md (#2626) Add a CHANGELOG.md that just redirects people to the GitHub release notes. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..c26063174b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +# Firebase Admin Changelog + +For detailed version notes and breaking changes, see our release notes on GitHub: +https://github.com/firebase/firebase-admin-node/releases From 3e06bab55b64b2b68b137dd6cc19e86c38f27840 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 10:49:37 -0400 Subject: [PATCH 165/323] build(deps): bump actions/download-artifact in /.github/workflows (#2694) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 1 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v1...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e183bac114..16626cf7f9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -108,7 +108,7 @@ jobs: # Download the artifacts created by the stage_release job. - name: Download release candidates - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: dist From 2fb4a27f024864ff7acd94e716ae0edc77dc853f Mon Sep 17 00:00:00 2001 From: Herman Ho Date: Wed, 4 Sep 2024 15:53:01 +0100 Subject: [PATCH 166/323] fix: support httpAgent in JwksFetcher (#2689) Co-authored-by: Lahiru Maramba --- src/app-check/token-verifier.ts | 2 +- src/utils/jwt.ts | 7 ++++--- test/unit/app-check/token-verifier.spec.ts | 20 ++++++++++++++++++++ test/unit/utils/jwt.spec.ts | 11 +++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/app-check/token-verifier.ts b/src/app-check/token-verifier.ts index 6c6503f05d..cde4878a42 100644 --- a/src/app-check/token-verifier.ts +++ b/src/app-check/token-verifier.ts @@ -37,7 +37,7 @@ export class AppCheckTokenVerifier { private readonly signatureVerifier: SignatureVerifier; constructor(private readonly app: App) { - this.signatureVerifier = PublicKeySignatureVerifier.withJwksUrl(JWKS_URL); + this.signatureVerifier = PublicKeySignatureVerifier.withJwksUrl(JWKS_URL, app.options.httpAgent); } /** diff --git a/src/utils/jwt.ts b/src/utils/jwt.ts index 5d8f88344f..1b1fea6af9 100644 --- a/src/utils/jwt.ts +++ b/src/utils/jwt.ts @@ -53,7 +53,7 @@ export class JwksFetcher implements KeyFetcher { private publicKeysExpireAt = 0; private client: jwks.JwksClient; - constructor(jwksUrl: string) { + constructor(jwksUrl: string, httpAgent?: Agent) { if (!validator.isURL(jwksUrl)) { throw new Error('The provided JWKS URL is not a valid URL.'); } @@ -61,6 +61,7 @@ export class JwksFetcher implements KeyFetcher { this.client = jwks({ jwksUri: jwksUrl, cache: false, // disable jwks-rsa LRU cache as the keys are always cached for 6 hours. + requestAgent: httpAgent, }); } @@ -190,8 +191,8 @@ export class PublicKeySignatureVerifier implements SignatureVerifier { return new PublicKeySignatureVerifier(new UrlKeyFetcher(clientCertUrl, httpAgent)); } - public static withJwksUrl(jwksUrl: string): PublicKeySignatureVerifier { - return new PublicKeySignatureVerifier(new JwksFetcher(jwksUrl)); + public static withJwksUrl(jwksUrl: string, httpAgent?: Agent): PublicKeySignatureVerifier { + return new PublicKeySignatureVerifier(new JwksFetcher(jwksUrl, httpAgent)); } public verify(token: string): Promise { diff --git a/test/unit/app-check/token-verifier.spec.ts b/test/unit/app-check/token-verifier.spec.ts index c6cf897c05..ecc664783b 100644 --- a/test/unit/app-check/token-verifier.spec.ts +++ b/test/unit/app-check/token-verifier.spec.ts @@ -22,6 +22,7 @@ import * as chai from 'chai'; import * as sinon from 'sinon'; import * as mocks from '../../resources/mocks'; import * as nock from 'nock'; +import { Agent } from 'http'; import { AppCheckTokenVerifier } from '../../../src/app-check/token-verifier'; import { JwtError, JwtErrorCode, PublicKeySignatureVerifier } from '../../../src/utils/jwt'; @@ -55,6 +56,25 @@ describe('AppCheckTokenVerifier', () => { } }); + describe('Constructor', () => { + it('AppOptions.httpAgent should be passed to PublicKeySignatureVerifier.withJwksUrl', () => { + const mockAppWithAgent = mocks.appWithOptions({ + httpAgent: new Agent() + }); + const agentForApp = mockAppWithAgent.options.httpAgent; + const verifierSpy = sinon.spy(PublicKeySignatureVerifier, 'withJwksUrl'); + + expect(verifierSpy.args).to.be.empty; + + new AppCheckTokenVerifier( + mockAppWithAgent + ); + + expect(verifierSpy.args[0][1]).to.equal(agentForApp); + verifierSpy.restore(); + }); + }); + describe('verifyJWT()', () => { let mockedRequests: nock.Scope[] = []; let stubs: sinon.SinonStub[] = []; diff --git a/test/unit/utils/jwt.spec.ts b/test/unit/utils/jwt.spec.ts index 18cff06ff7..8dd49dfaf6 100644 --- a/test/unit/utils/jwt.spec.ts +++ b/test/unit/utils/jwt.spec.ts @@ -17,6 +17,7 @@ 'use strict'; // Use untyped import syntax for Node built-ins +import http = require('http'); import https = require('https'); import * as _ from 'lodash'; @@ -380,6 +381,16 @@ describe('PublicKeySignatureVerifier', () => { expect(verifier).to.be.an.instanceOf(PublicKeySignatureVerifier); expect((verifier as any).keyFetcher).to.be.an.instanceOf(JwksFetcher); }); + + it('should return a PublicKeySignatureVerifier instance with a JwksFetcher when a ' + + 'valid jwks url and httpAgent is provided', () => { + const mockHttpAgent = sinon.createStubInstance(http.Agent); + const verifier = PublicKeySignatureVerifier.withJwksUrl('https://www.example.com/publicKeys', mockHttpAgent); + expect(verifier).to.be.an.instanceOf(PublicKeySignatureVerifier); + expect((verifier as any).keyFetcher).to.be.an.instanceOf(JwksFetcher); + expect((verifier as any).keyFetcher.client.options.requestAgent).to.be.an.instanceOf(http.Agent); + expect((verifier as any).keyFetcher.client.options.requestAgent).to.eq(mockHttpAgent); + }); }); describe('verify', () => { From 2a6ca8ee18670d94c07a260b93261e65086951c9 Mon Sep 17 00:00:00 2001 From: Kevin Elko Date: Thu, 5 Sep 2024 14:51:56 -0400 Subject: [PATCH 167/323] feat(rc): SSRC targeting (#2665) * Initial set up and evaluation logic for server side custom signals (#2628) initial skeleton for custom signal evaluation logic --------- Co-authored-by: Kevin Elko * Add logic for remaining custom signal operators (#2633) * initial skeleton for custom signal evaluation logic * adjust some formatting * remove extra curly brace * run lint * Run apidocs * Split EvaluationContext into UserProvidedSignals and PredefinedSignals * rerun apidocs * add logic for remaining custom signal operators * more test cases * test cases for numeric operators * update tests to be way more robust and implement handling for a few edge cases * update some comments --------- Co-authored-by: Kevin Elko * Ssrc targeting numeric version fixes (#2656) * refactor numeric version parsing logic and add more test cases * run lint * test cases for max num segments * run lint on tests --------- Co-authored-by: Kevin Elko * fix test ordering * Export signal types and rerun apidocs * update docstrings * uber minor comment fix --------- Co-authored-by: Kevin Elko --- etc/firebase-admin.remote-config.api.md | 43 ++- .../condition-evaluator-internal.ts | 154 ++++++++- src/remote-config/index.ts | 4 + src/remote-config/remote-config-api.ts | 135 +++++++- .../remote-config/condition-evaluator.spec.ts | 295 +++++++++++++++++- 5 files changed, 615 insertions(+), 16 deletions(-) diff --git a/etc/firebase-admin.remote-config.api.md b/etc/firebase-admin.remote-config.api.md index aeadcbf779..ea0fddd63c 100644 --- a/etc/firebase-admin.remote-config.api.md +++ b/etc/firebase-admin.remote-config.api.md @@ -13,15 +13,41 @@ export interface AndCondition { conditions?: Array; } +// @public +export interface CustomSignalCondition { + customSignalKey?: string; + customSignalOperator?: CustomSignalOperator; + targetCustomSignalValues?: string[]; +} + +// @public +export enum CustomSignalOperator { + NUMERIC_EQUAL = "NUMERIC_EQUAL", + NUMERIC_GREATER_EQUAL = "NUMERIC_GREATER_EQUAL", + NUMERIC_GREATER_THAN = "NUMERIC_GREATER_THAN", + NUMERIC_LESS_EQUAL = "NUMERIC_LESS_EQUAL", + NUMERIC_LESS_THAN = "NUMERIC_LESS_THAN", + NUMERIC_NOT_EQUAL = "NUMERIC_NOT_EQUAL", + SEMANTIC_VERSION_EQUAL = "SEMANTIC_VERSION_EQUAL", + SEMANTIC_VERSION_GREATER_EQUAL = "SEMANTIC_VERSION_GREATER_EQUAL", + SEMANTIC_VERSION_GREATER_THAN = "SEMANTIC_VERSION_GREATER_THAN", + SEMANTIC_VERSION_LESS_EQUAL = "SEMANTIC_VERSION_LESS_EQUAL", + SEMANTIC_VERSION_LESS_THAN = "SEMANTIC_VERSION_LESS_THAN", + SEMANTIC_VERSION_NOT_EQUAL = "SEMANTIC_VERSION_NOT_EQUAL", + STRING_CONTAINS = "STRING_CONTAINS", + STRING_CONTAINS_REGEX = "STRING_CONTAINS_REGEX", + STRING_DOES_NOT_CONTAIN = "STRING_DOES_NOT_CONTAIN", + STRING_EXACTLY_MATCHES = "STRING_EXACTLY_MATCHES", + UNKNOWN = "UNKNOWN" +} + // @public export type DefaultConfig = { [key: string]: string | number | boolean; }; // @public -export type EvaluationContext = { - randomizationId?: string; -}; +export type EvaluationContext = UserProvidedSignals & PredefinedSignals; // @public export interface ExplicitParameterValue { @@ -78,6 +104,7 @@ export interface NamedCondition { // @public export interface OneOfCondition { andCondition?: AndCondition; + customSignal?: CustomSignalCondition; false?: Record; orCondition?: OrCondition; percent?: PercentCondition; @@ -108,6 +135,11 @@ export enum PercentConditionOperator { UNKNOWN = "UNKNOWN" } +// @public +export type PredefinedSignals = { + randomizationId?: string; +}; + // @public export class RemoteConfig { // (undocumented) @@ -205,6 +237,11 @@ export type ServerTemplateDataType = ServerTemplateData | string; // @public export type TagColor = 'BLUE' | 'BROWN' | 'CYAN' | 'DEEP_ORANGE' | 'GREEN' | 'INDIGO' | 'LIME' | 'ORANGE' | 'PINK' | 'PURPLE' | 'TEAL'; +// @public +export type UserProvidedSignals = { + [key: string]: string | number; +}; + // @public export interface Value { asBoolean(): boolean; diff --git a/src/remote-config/condition-evaluator-internal.ts b/src/remote-config/condition-evaluator-internal.ts index 2be55ec08d..2e5c68371f 100644 --- a/src/remote-config/condition-evaluator-internal.ts +++ b/src/remote-config/condition-evaluator-internal.ts @@ -23,7 +23,9 @@ import { NamedCondition, OrCondition, PercentCondition, - PercentConditionOperator + PercentConditionOperator, + CustomSignalCondition, + CustomSignalOperator, } from './remote-config-api'; import * as farmhash from 'farmhash-modern'; @@ -76,6 +78,9 @@ export class ConditionEvaluator { if (condition.percent) { return this.evaluatePercentCondition(condition.percent, context); } + if (condition.customSignal) { + return this.evaluateCustomSignalCondition(condition.customSignal, context); + } // TODO: add logging once we have a wrapped logger. return false; } @@ -167,7 +172,6 @@ export class ConditionEvaluator { return false; } - // Visible for testing static hashSeededRandomizationId(seededRandomizationId: string): bigint { // For consistency with the Remote Config fetch endpoint's percent condition behavior // we use Farmhash's fingerprint64 algorithm and interpret the resulting unsigned value @@ -182,4 +186,150 @@ export class ConditionEvaluator { return hash64; } + + private evaluateCustomSignalCondition( + customSignalCondition: CustomSignalCondition, + context: EvaluationContext + ): boolean { + const { + customSignalOperator, + customSignalKey, + targetCustomSignalValues, + } = customSignalCondition; + + if (!customSignalOperator || !customSignalKey || !targetCustomSignalValues) { + // TODO: add logging once we have a wrapped logger. + return false; + } + + if (!targetCustomSignalValues.length) { + return false; + } + + // Extract the value of the signal from the evaluation context. + const actualCustomSignalValue = context[customSignalKey]; + + if (actualCustomSignalValue == undefined) { + return false + } + + switch (customSignalOperator) { + case CustomSignalOperator.STRING_CONTAINS: + return compareStrings( + targetCustomSignalValues, + actualCustomSignalValue, + (target, actual) => actual.includes(target), + ); + case CustomSignalOperator.STRING_DOES_NOT_CONTAIN: + return !compareStrings( + targetCustomSignalValues, + actualCustomSignalValue, + (target, actual) => actual.includes(target), + ); + case CustomSignalOperator.STRING_EXACTLY_MATCHES: + return compareStrings( + targetCustomSignalValues, + actualCustomSignalValue, + (target, actual) => actual.trim() === target.trim(), + ); + case CustomSignalOperator.STRING_CONTAINS_REGEX: + return compareStrings( + targetCustomSignalValues, + actualCustomSignalValue, + (target, actual) => new RegExp(target).test(actual), + ); + + // For numeric operators only one target value is allowed. + case CustomSignalOperator.NUMERIC_LESS_THAN: + return compareNumbers(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r < 0); + case CustomSignalOperator.NUMERIC_LESS_EQUAL: + return compareNumbers(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r <= 0); + case CustomSignalOperator.NUMERIC_EQUAL: + return compareNumbers(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r === 0); + case CustomSignalOperator.NUMERIC_NOT_EQUAL: + return compareNumbers(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r !== 0); + case CustomSignalOperator.NUMERIC_GREATER_THAN: + return compareNumbers(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r > 0); + case CustomSignalOperator.NUMERIC_GREATER_EQUAL: + return compareNumbers(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r >= 0); + + // For semantic operators only one target value is allowed. + case CustomSignalOperator.SEMANTIC_VERSION_LESS_THAN: + return compareSemanticVersions(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r < 0); + case CustomSignalOperator.SEMANTIC_VERSION_LESS_EQUAL: + return compareSemanticVersions(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r <= 0); + case CustomSignalOperator.SEMANTIC_VERSION_EQUAL: + return compareSemanticVersions(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r === 0); + case CustomSignalOperator.SEMANTIC_VERSION_NOT_EQUAL: + return compareSemanticVersions(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r !== 0); + case CustomSignalOperator.SEMANTIC_VERSION_GREATER_THAN: + return compareSemanticVersions(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r > 0); + case CustomSignalOperator.SEMANTIC_VERSION_GREATER_EQUAL: + return compareSemanticVersions(actualCustomSignalValue, targetCustomSignalValues[0], (r) => r >= 0); + } + + // TODO: add logging once we have a wrapped logger. + return false; + } +} + +// Compares the actual string value of a signal against a list of target +// values. If any of the target values are a match, returns true. +function compareStrings( + targetValues: Array, + actualValue: string|number, + predicateFn: (target: string, actual: string) => boolean +): boolean { + const actual = String(actualValue); + return targetValues.some((target) => predicateFn(target, actual)); +} + +// Compares two numbers against each other. +// Calls the predicate function with -1, 0, 1 if actual is less than, equal to, or greater than target. +function compareNumbers( + actualValue: string|number, + targetValue: string, + predicateFn: (result: number) => boolean +): boolean { + const target = Number(targetValue); + const actual = Number(actualValue); + if (isNaN(target) || isNaN(actual)) { + return false; + } + return predicateFn(actual < target ? -1 : actual > target ? 1 : 0); +} + +// Max number of segments a numeric version can have. This is enforced by the server as well. +const MAX_LENGTH = 5; + +// Compares semantic version strings against each other. +// Calls the predicate function with -1, 0, 1 if actual is less than, equal to, or greater than target. +function compareSemanticVersions( + actualValue: string|number, + targetValue: string, + predicateFn: (result: number) => boolean +): boolean { + const version1 = String(actualValue).split('.').map(Number); + const version2 = targetValue.split('.').map(Number); + + for (let i = 0; i < MAX_LENGTH; i++) { + // Check to see if segments are present. Note that these may be present and be NaN. + const version1HasSegment = version1[i] !== undefined; + const version2HasSegment = version2[i] !== undefined; + + // If both are undefined, we've consumed everything and they're equal. + if (!version1HasSegment && !version2HasSegment) return predicateFn(0) + + // Insert zeros if undefined for easier comparison. + if (!version1HasSegment) version1[i] = 0; + if (!version2HasSegment) version2[i] = 0; + + // At this point, if either segment is NaN, we return false directly. + if (isNaN(version1[i]) || isNaN(version2[i])) return false; + + // Check if we have a difference in segments. Otherwise continue to next segment. + if (version1[i] < version2[i]) return predicateFn(-1); + if (version1[i] > version2[i]) return predicateFn(1); + } + return false; } diff --git a/src/remote-config/index.ts b/src/remote-config/index.ts index 9198284b0e..7b66c44ee9 100644 --- a/src/remote-config/index.ts +++ b/src/remote-config/index.ts @@ -26,6 +26,8 @@ import { RemoteConfig } from './remote-config'; export { AndCondition, + CustomSignalCondition, + CustomSignalOperator, DefaultConfig, EvaluationContext, ExplicitParameterValue, @@ -41,6 +43,7 @@ export { ParameterValueType, PercentConditionOperator, PercentCondition, + PredefinedSignals, RemoteConfigCondition, RemoteConfigParameter, RemoteConfigParameterGroup, @@ -52,6 +55,7 @@ export { ServerTemplateData, ServerTemplateDataType, TagColor, + UserProvidedSignals, Value, ValueSource, Version, diff --git a/src/remote-config/remote-config-api.ts b/src/remote-config/remote-config-api.ts index 4a9a2cfc4e..4dfa1da023 100644 --- a/src/remote-config/remote-config-api.ts +++ b/src/remote-config/remote-config-api.ts @@ -105,6 +105,11 @@ export interface OneOfCondition { * Makes this condition a percent condition. */ percent?: PercentCondition; + + /** + * Makes this condition a custom signal condition. + */ + customSignal?: CustomSignalCondition; } /** @@ -213,6 +218,122 @@ export interface PercentCondition { microPercentRange?: MicroPercentRange; } +/** + * Defines supported operators for custom signal conditions. + */ +export enum CustomSignalOperator { + + /** + * A catchall error case. + */ + UNKNOWN = 'UNKNOWN', + + /** + * Matches a numeric value less than the target value. + */ + NUMERIC_LESS_THAN = 'NUMERIC_LESS_THAN', + + /** + * Matches a numeric value less than or equal to the target value. + */ + NUMERIC_LESS_EQUAL ='NUMERIC_LESS_EQUAL', + + /** + * Matches a numeric value equal to the target value. + */ + NUMERIC_EQUAL = 'NUMERIC_EQUAL', + + /** + * Matches a numeric value not equal to the target value. + */ + NUMERIC_NOT_EQUAL = 'NUMERIC_NOT_EQUAL', + + /** + * Matches a numeric value greater than the target value. + */ + NUMERIC_GREATER_THAN = 'NUMERIC_GREATER_THAN', + + /** + * Matches a numeric value greater than or equal to the target value. + */ + NUMERIC_GREATER_EQUAL = 'NUMERIC_GREATER_EQUAL', + + /** + * Matches if at least one of the target values is a substring of the actual custom + * signal value (e.g. "abc" contains the string "a", "bc"). + */ + STRING_CONTAINS = 'STRING_CONTAINS', + + /** + * Matches if none of the target values is a substring of the actual custom signal value. + */ + STRING_DOES_NOT_CONTAIN = 'STRING_DOES_NOT_CONTAIN', + + /** + * Matches if the actual value exactly matches at least one of the target values. + */ + STRING_EXACTLY_MATCHES = 'STRING_EXACTLY_MATCHES', + + /** + * The target regular expression matches at least one of the actual values. + * The regex conforms to RE2 format. See https://github.com/google/re2/wiki/Syntax + */ + STRING_CONTAINS_REGEX = 'STRING_CONTAINS_REGEX', + + /** + * Matches if the actual version value is less than the target value. + */ + SEMANTIC_VERSION_LESS_THAN = 'SEMANTIC_VERSION_LESS_THAN', + + /** + * Matches if the actual version value is less than or equal to the target value. + */ + SEMANTIC_VERSION_LESS_EQUAL = 'SEMANTIC_VERSION_LESS_EQUAL', + + /** + * Matches if the actual version value is equal to the target value. + */ + SEMANTIC_VERSION_EQUAL = 'SEMANTIC_VERSION_EQUAL', + + /** + * Matches if the actual version value is not equal to the target value. + */ + SEMANTIC_VERSION_NOT_EQUAL = 'SEMANTIC_VERSION_NOT_EQUAL', + + /** + * Matches if the actual version value is greater than the target value. + */ + SEMANTIC_VERSION_GREATER_THAN = 'SEMANTIC_VERSION_GREATER_THAN', + + /** + * Matches if the actual version value is greater than or equal to the target value. + */ + SEMANTIC_VERSION_GREATER_EQUAL = 'SEMANTIC_VERSION_GREATER_EQUAL', +} + +/** + * Represents a condition that compares provided signals against a target value. + */ +export interface CustomSignalCondition { + + /** + * The choice of custom signal operator to determine how to compare targets + * to value(s). + */ + customSignalOperator?: CustomSignalOperator; + + /** + * The key of the signal set in the EvaluationContext + */ + customSignalKey?: string; + + /** + * A list of at most 100 target custom signal values. For numeric operators, + * this will have exactly ONE target value. + */ + targetCustomSignalValues?: string[]; +} + /** * Interface representing an explicit parameter value. */ @@ -414,9 +535,14 @@ export interface ServerTemplate { } /** - * Represents template evaluation input signals. + * Generic map of developer-defined signals used as evaluation input signals. + */ +export type UserProvidedSignals = {[key: string]: string|number}; + +/** + * Predefined template evaluation input signals. */ -export type EvaluationContext = { +export type PredefinedSignals = { /** * Defines the identifier to use when splitting a group. For example, @@ -425,6 +551,11 @@ export type EvaluationContext = { randomizationId?: string }; +/** + * Represents template evaluation input signals. + */ +export type EvaluationContext = UserProvidedSignals & PredefinedSignals; + /** * Interface representing a Remote Config user. */ diff --git a/test/unit/remote-config/condition-evaluator.spec.ts b/test/unit/remote-config/condition-evaluator.spec.ts index 17e524f6d8..c1159238b4 100644 --- a/test/unit/remote-config/condition-evaluator.spec.ts +++ b/test/unit/remote-config/condition-evaluator.spec.ts @@ -21,7 +21,10 @@ import * as sinon from 'sinon'; import { ConditionEvaluator } from '../../../src/remote-config/condition-evaluator-internal'; import { PercentConditionOperator, - PercentCondition + PercentCondition, + CustomSignalOperator, + NamedCondition, + OneOfCondition, } from '../../../src/remote-config/remote-config-api'; import { v4 as uuidv4 } from 'uuid'; import { clone } from 'lodash'; @@ -41,6 +44,24 @@ describe('ConditionEvaluator', () => { stubs = []; }); + function createNamedCondition( + name: string, + condition: OneOfCondition + ): NamedCondition { + return { + name, + condition: { + orCondition: { + conditions: [{ + andCondition: { + conditions: [condition], + } + }] + } + } + }; + } + describe('evaluateConditions', () => { it('should evaluate empty OR condition to false', () => { const condition = { @@ -857,6 +878,262 @@ describe('ConditionEvaluator', () => { return evalTrueCount; } }); + + describe('customSignalCondition', () => { + it('should evaluate an unknown operator to false', () => { + const condition = createNamedCondition('is_enabled', { + customSignal: { + customSignalOperator: CustomSignalOperator.UNKNOWN + } + }); + const evaluator = new ConditionEvaluator(); + expect(evaluator.evaluateConditions([condition], {})).deep.equals( + new Map([['is_enabled', false]])); + }); + + it('should handle case when EvaluationContext does not have signal', () => { + const condition = createNamedCondition('is_enabled', { + customSignal: { + customSignalOperator: CustomSignalOperator.STRING_CONTAINS, + customSignalKey: 'user_prop', + targetCustomSignalValues: ['def'] // would be contained in 'undefined' + } + }); + const evaluator = new ConditionEvaluator(); + const context = { }; + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([ + ['is_enabled', false] + ])); + }); + + interface CustomSignalTestCase { + targets: string[]; + actual: string|number; + outcome: boolean; + } + + function runCustomSignalTestCase( + operator: CustomSignalOperator + ): (c: CustomSignalTestCase) => void { + return ({ targets, actual, outcome }: CustomSignalTestCase) => { + const targetsStr = JSON.stringify(targets); + it(`Evalutes ${operator} with targets=${targetsStr} and actual="${actual}" to ${outcome}`, () => { + const condition = createNamedCondition('is_enabled', { + customSignal: { + customSignalOperator: operator, + customSignalKey: 'user_prop', + targetCustomSignalValues: targets + } + }); + const evaluator = new ConditionEvaluator(); + const context = { 'user_prop': actual }; + expect(evaluator.evaluateConditions([condition], context)).deep.equals( + new Map([ + ['is_enabled', outcome], + ])); + }); + } + } + + function runCustomSignalTestCaseWithWhitespace( + operator: CustomSignalOperator + ): (c: CustomSignalTestCase) => void { + return (testCase: CustomSignalTestCase) => { + runCustomSignalTestCase(operator)(testCase); + runCustomSignalTestCase(operator)({ + ...testCase, + targets: testCase.targets.map(t => ` ${t} `), + actual: ` ${testCase.actual} ` + }); + } + } + + const invalidNumericSignalTestCase: CustomSignalTestCase = { + targets: ['5'], + actual: 'not a number', + outcome: false + }; + + describe('STRING_CONTAINS', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['foo', 'biz'], actual: 'foobar', outcome: true }, + { targets: ['foo', 'biz'],actual: 'bar',outcome: false }, + ]; + + testCases.forEach(runCustomSignalTestCase(CustomSignalOperator.STRING_CONTAINS)); + }); + + describe('STRING_DOES_NOT_CONTAIN', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['foo', 'biz'],actual: 'bar',outcome: true }, + { targets: ['foo', 'biz'], actual: 'foobar', outcome: false }, + ]; + + testCases.forEach(runCustomSignalTestCase(CustomSignalOperator.STRING_DOES_NOT_CONTAIN)); + }); + + describe('STRING_EXACTLY_MATCHES', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['foo', 'bar'], actual: 'bar', outcome: true }, + { targets: [''], actual: '', outcome: true }, + { targets: ['foo', 'biz'], actual: 'foobar', outcome: false }, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.STRING_EXACTLY_MATCHES)); + }); + + describe('STRING_CONTAINS_REGEX', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['foo', '^ba.*$'], actual: 'bar', outcome: true }, + { targets: [' bar '], actual: 'biz', outcome: false }, + ]; + + testCases.forEach(runCustomSignalTestCase(CustomSignalOperator.STRING_CONTAINS_REGEX)); + }); + + describe('NUMERIC_LESS_THAN', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5'], actual: '4', outcome: true }, + { targets: ['5'], actual: '5', outcome: false }, + { targets: ['5'], actual: '6', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.NUMERIC_LESS_THAN)); + }); + + describe('NUMERIC_LESS_EQUAL', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5'], actual: '4', outcome: true }, + { targets: ['5'], actual: '5', outcome: true }, + { targets: ['5'], actual: '6', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.NUMERIC_LESS_EQUAL)); + }); + + describe('NUMERIC_EQUAL', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5'], actual: '5', outcome: true }, + { targets: ['5'], actual: '6', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.NUMERIC_EQUAL)); + }); + + describe('NUMERIC_NOT_EQUAL', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5'], actual: '6', outcome: true }, + { targets: ['5'], actual: '5', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.NUMERIC_NOT_EQUAL)); + }); + + describe('NUMERIC_GREATER_THAN', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5'], actual: '6', outcome: true }, + { targets: ['5'], actual: '5', outcome: false }, + { targets: ['5'], actual: '4', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.NUMERIC_GREATER_THAN)); + }); + + describe('NUMERIC_GREATER_EQUAL', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5'], actual: '6', outcome: true }, + { targets: ['5'], actual: '5', outcome: true }, + { targets: ['5'], actual: 5.0, outcome: true }, + { targets: ['5.0'], actual: 5.0, outcome: true }, + { targets: ['5'], actual: '4', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.NUMERIC_GREATER_EQUAL)); + }); + + describe('SEMANTIC_VERSION_LESS_THAN', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5.12.3'], actual: '5.11.9', outcome: true }, + { targets: ['5.12.3'], actual: '5.12', outcome: true }, + { targets: ['5.12.3'], actual: '5', outcome: true }, + { targets: ['5.12.3'], actual: '5.12.3', outcome: false }, + { targets: ['5.12.3'], actual: '5.12.9', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.SEMANTIC_VERSION_LESS_THAN)); + }); + + describe('SEMANTIC_VERSION_LESS_EQUAL', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5.12.3'], actual: '5.11.9', outcome: true }, + { targets: ['5.12.3'], actual: '5.12.3', outcome: true }, + { targets: ['5.12.3'], actual: '5.12.9', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.SEMANTIC_VERSION_LESS_EQUAL)); + }); + + describe('SEMANTIC_VERSION_EQUAL', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5.12.3'], actual: '5.12.3', outcome: true }, + { targets: ['5'], actual: 5.0, outcome: true }, + { targets: ['5.0'], actual: 5.0, outcome: true }, + { targets: ['5.12.3'], actual: '5.12.9', outcome: false }, + { targets: ['5.12.3'], actual: '5.12.3.0.0.0.0', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.SEMANTIC_VERSION_EQUAL)); + }); + + describe('SEMANTIC_VERSION_NOT_EQUAL', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5.12.3'], actual: '5.12.9', outcome: true }, + { targets: ['5'], actual: 5.0, outcome: false }, + { targets: ['5.0'], actual: 5.0, outcome: false }, + { targets: ['5.12.3'], actual: '5.12.3', outcome: false }, + { targets: ['5.12.3'], actual: '5.12.3.0.0.0.0', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.SEMANTIC_VERSION_NOT_EQUAL)); + }); + + describe('SEMANTIC_VERSION_GREATER_THAN', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5.12.3'], actual: '5.13.9', outcome: true }, + { targets: ['5.12.3'], actual: '5.13', outcome: true }, + { targets: ['5.12.3'], actual: '6', outcome: true }, + { targets: ['5.12.3'], actual: '5.12.3', outcome: false }, + { targets: ['5.12.3'], actual: '5.11.9', outcome: false }, + invalidNumericSignalTestCase, + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.SEMANTIC_VERSION_GREATER_THAN)); + }); + + describe('SEMANTIC_VERSION_GREATER_EQUAL', () => { + const testCases: CustomSignalTestCase[] = [ + { targets: ['5.12.3'], actual: '5.13.9', outcome: true }, + { targets: ['5.12.3'], actual: '5.12.3', outcome: true }, + { targets: ['5'], actual: 5.0, outcome: true }, + { targets: ['5.0'], actual: 5.0, outcome: true }, + { targets: ['5.12.3'], actual: '5.11.9', outcome: false }, + invalidNumericSignalTestCase + ]; + + testCases.forEach(runCustomSignalTestCaseWithWhitespace(CustomSignalOperator.SEMANTIC_VERSION_GREATER_EQUAL)); + }); + }); }); describe('hashSeededRandomizationId', () => { @@ -868,7 +1145,7 @@ describe('ConditionEvaluator', () => { if (nodeVersion.startsWith('14')) { this.skip(); } - + const stub = sinon .stub(farmhash, 'fingerprint64') // 2^63-1 = 9223372036854775807. @@ -876,7 +1153,7 @@ describe('ConditionEvaluator', () => { stubs.push(stub); const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); - + expect(actual).to.equal(BigInt('9223372036854775807')) }); @@ -884,7 +1161,7 @@ describe('ConditionEvaluator', () => { if (nodeVersion.startsWith('14')) { this.skip(); } - + const stub = sinon .stub(farmhash, 'fingerprint64') // 2^63 = 9223372036854775808. @@ -892,7 +1169,7 @@ describe('ConditionEvaluator', () => { stubs.push(stub); const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); - + // 2^63 is the negation of 2^63-1 expect(actual).to.equal(BigInt('9223372036854775808')) }); @@ -901,7 +1178,7 @@ describe('ConditionEvaluator', () => { if (nodeVersion.startsWith('14')) { this.skip(); } - + const stub = sinon .stub(farmhash, 'fingerprint64') // 2^63+1 9223372036854775809. @@ -909,7 +1186,7 @@ describe('ConditionEvaluator', () => { stubs.push(stub); const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); - + // 2^63+1 is larger than 2^63, so the absolute value is smaller expect(actual).to.equal(BigInt('9223372036854775807')) }); @@ -918,7 +1195,7 @@ describe('ConditionEvaluator', () => { if (nodeVersion.startsWith('14')) { this.skip(); } - + const stub = sinon .stub(farmhash, 'fingerprint64') // We were initially confused about the nature of this value ... @@ -926,7 +1203,7 @@ describe('ConditionEvaluator', () => { stubs.push(stub); const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); - + // ... Now we know it's the unsigned equivalent of this absolute value. expect(actual).to.equal(BigInt('2365658470315593469')) }); From 2bce2cc9da7f9d5d47e306b7670c53a5b009d680 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 10 Sep 2024 17:14:26 -0400 Subject: [PATCH 168/323] chore: Upgrade actions/upload-artifact@v4 (#2700) --- .github/workflows/nightly.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c3edd0b335..379172b7d3 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -72,7 +72,7 @@ jobs: # Attach the packaged artifacts to the workflow output. These can be manually # downloaded for later inspection if necessary. - name: Archive artifacts - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: dist path: dist diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16626cf7f9..2e5c4ac34a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -77,7 +77,7 @@ jobs: # Attach the packaged artifacts to the workflow output. These can be manually # downloaded for later inspection if necessary. - name: Archive artifacts - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: dist path: dist From 84241f8d30bf77ca56f2cf8f6da7e52a90f68695 Mon Sep 17 00:00:00 2001 From: Younes Makhchan <74161217+younes-makhchan@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:17:57 +0100 Subject: [PATCH 169/323] fix: updating comments with VibrateTimingsMillis and defaultVibrateTimings instead of vibrate_timings and default_vibrate_timings (#2598) Co-authored-by: Lahiru Maramba --- src/messaging/messaging-api.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/messaging/messaging-api.ts b/src/messaging/messaging-api.ts index 29f7f1fdc9..c8b5ce1781 100644 --- a/src/messaging/messaging-api.ts +++ b/src/messaging/messaging-api.ts @@ -550,16 +550,16 @@ export interface AndroidNotification { * turn the vibrator on or off. The first value indicates the duration to wait before * turning the vibrator on. The next value indicates the duration to keep the * vibrator on. Subsequent values alternate between duration to turn the vibrator - * off and to turn the vibrator on. If `vibrate_timings` is set and `default_vibrate_timings` - * is set to `true`, the default value is used instead of the user-specified `vibrate_timings`. + * off and to turn the vibrator on. If `vibrateTimingsMillis` is set and `defaultVibrateTimings` + * is set to `true`, the default value is used instead of the user-specified `vibrateTimingsMillis`. */ vibrateTimingsMillis?: number[]; /** * If set to `true`, use the Android framework's default vibrate pattern for the * notification. Default values are specified in {@link https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/values/config.xml | - * config.xml}. If `default_vibrate_timings` is set to `true` and `vibrate_timings` is also set, - * the default value is used instead of the user-specified `vibrate_timings`. + * config.xml}. If `defaultVibrateTimings` is set to `true` and `vibrateTimingsMillis` is also set, + * the default value is used instead of the user-specified `vibrateTimingsMillis`. */ defaultVibrateTimings?: boolean; From 66bea6ee9ce44d577009df0877ce8fb9da6d2cca Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 12 Sep 2024 11:32:28 -0400 Subject: [PATCH 170/323] [chore] Release 12.5.0 (#2702) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 95060f94b2..88550ecca8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.4.0", + "version": "12.5.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From b470ebac26d60da612181c38bfbaa638024c3ae8 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 12 Sep 2024 13:05:44 -0400 Subject: [PATCH 171/323] [chore] Release 12.5.0 Take 2 (#2703) --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2e5c4ac34a..ea333311ef 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -111,6 +111,7 @@ jobs: uses: actions/download-artifact@v4.1.7 with: name: dist + path: dist # Node.js and NPM are needed to complete the publish. - name: Set up Node.js From 25585a318323ee224633f989a6a52e80deb75db7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:27:34 -0400 Subject: [PATCH 172/323] build(deps): bump @google-cloud/firestore from 7.9.0 to 7.10.0 (#2705) Bumps [@google-cloud/firestore](https://github.com/googleapis/nodejs-firestore) from 7.9.0 to 7.10.0. - [Release notes](https://github.com/googleapis/nodejs-firestore/releases) - [Changelog](https://github.com/googleapis/nodejs-firestore/blob/main/CHANGELOG.md) - [Commits](https://github.com/googleapis/nodejs-firestore/compare/v7.9.0...v7.10.0) --- updated-dependencies: - dependency-name: "@google-cloud/firestore" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index a811d0c732..5e1bdd4ba3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.3.1", + "version": "12.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -693,11 +693,12 @@ } }, "@google-cloud/firestore": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.9.0.tgz", - "integrity": "sha512-c4ALHT3G08rV7Zwv8Z2KG63gZh66iKdhCBeDfCpIkLrjX6EAjTD/szMdj14M+FnQuClZLFfW5bAgoOjfNmLtJg==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.10.0.tgz", + "integrity": "sha512-VFNhdHvfnmqcHHs6YhmSNHHxQqaaD64GwiL0c+e1qz85S8SWZPC2XFRf8p9yHRTF40Kow424s1KBU9f0fdQa+Q==", "optional": true, "requires": { + "@opentelemetry/api": "^1.3.0", "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", "google-gax": "^4.3.3", @@ -758,9 +759,9 @@ } }, "@grpc/grpc-js": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.10.11.tgz", - "integrity": "sha512-3RaoxOqkHHN2c05bwtBNVJmOf/UwMam0rZYtdl7dsRpsvDwcNpv6LkGgzltQ7xVf822LzBoKEPRvf4D7+xeIDw==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.11.2.tgz", + "integrity": "sha512-DWp92gDD7/Qkj7r8kus6/HCINeo3yPZWZ3paKgDgsbKbSpoxKg1yvN8xe2Q8uE3zOsPe3bX8FQX2+XValq2yTw==", "optional": true, "requires": { "@grpc/proto-loader": "^0.7.13", @@ -1172,6 +1173,12 @@ "fastq": "^1.6.0" } }, + "@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "optional": true + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -4015,9 +4022,9 @@ } }, "google-gax": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.3.8.tgz", - "integrity": "sha512-SKAQKtvdjtNW3PMOhmKEqpQP+2C5ZqNKfwWxy70efpSwxvRYuAcgMJs6aRHTBPJjz3SO6ZbiXwM6WIuGYFZ7LQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", + "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", "optional": true, "requires": { "@grpc/grpc-js": "^1.10.9", @@ -4026,7 +4033,7 @@ "abort-controller": "^3.0.0", "duplexify": "^4.0.0", "google-auth-library": "^9.3.0", - "node-fetch": "^2.6.1", + "node-fetch": "^2.7.0", "object-hash": "^3.0.0", "proto3-json-serializer": "^2.0.2", "protobufjs": "^7.3.2", @@ -6825,9 +6832,9 @@ } }, "protobufjs": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", - "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", "optional": true, "requires": { "@protobufjs/aspromise": "^1.1.2", From 9abd30e72cb99d4db11a5f16bd6bc6ba4819844d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:32:18 +0000 Subject: [PATCH 173/323] build(deps-dev): bump @microsoft/api-extractor from 7.47.6 to 7.47.9 (#2706) --- package-lock.json | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e1bdd4ba3..e9c73b8747 100644 --- a/package-lock.json +++ b/package-lock.json @@ -982,18 +982,18 @@ } }, "@microsoft/api-extractor": { - "version": "7.47.6", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.6.tgz", - "integrity": "sha512-saI7n319+PdJ8PAePr14LWeIPOW2fHSr3KZfYFqJ2VUpIc1TTSh6ATFZfLPWI1LK7eZHun8+FpNsuxonyvxTgQ==", + "version": "7.47.9", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.9.tgz", + "integrity": "sha512-TTq30M1rikVsO5wZVToQT/dGyJY7UXJmjiRtkHPLb74Prx3Etw8+bX7Bv7iLuby6ysb7fuu1NFWqma+csym8Jw==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.29.5", + "@microsoft/api-extractor-model": "7.29.8", "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.6.0", + "@rushstack/node-core-library": "5.9.0", "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.13.4", - "@rushstack/ts-command-line": "4.22.5", + "@rushstack/terminal": "0.14.2", + "@rushstack/ts-command-line": "4.22.8", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1009,9 +1009,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.6.0.tgz", - "integrity": "sha512-3ixIcEHseqU1sbnvoQkvxvfTYWbi1IIhnq/vexJcex7j6D8lnQCiYnd/E2oXbUH0Zv48CjtfslC/2MVFd71mpg==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", + "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", "dev": true, "requires": { "ajv": "~8.13.0", @@ -1025,12 +1025,12 @@ } }, "@rushstack/ts-command-line": { - "version": "4.22.5", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.5.tgz", - "integrity": "sha512-eFm+5DJboPHAy3epLNQtmG+hDlBzS950g26nZPbciMQeXmZ5shGGNe6ERjV77wnr5IuxfLhYGJ4ZjPy8Z56MBA==", + "version": "4.22.8", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.8.tgz", + "integrity": "sha512-XbFjOoV7qZHJnSuFUHv0pKaFA4ixyCuki+xMjsMfDwfvQjs5MYG0IK5COal3tRnG7KCDe2l/G+9LrzYE/RJhgg==", "dev": true, "requires": { - "@rushstack/terminal": "0.13.4", + "@rushstack/terminal": "0.14.2", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1066,14 +1066,14 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.29.5", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.5.tgz", - "integrity": "sha512-axMwj4pgtYH6/IclP9ly33laSwTym1kBwSUcoHElc2LYAE5NNlhGT78ucEpIZtqEZaGgA8yxGXIyS17XCC2Iuw==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.8.tgz", + "integrity": "sha512-t3Z/xcO6TRbMcnKGVMs4uMzv/gd5j0NhMiJIGjD4cJMeFJ1Hf8wnLSx37vxlRlL0GWlGJhnFgxvnaL6JlS+73g==", "dev": true, "requires": { "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.6.0" + "@rushstack/node-core-library": "5.9.0" }, "dependencies": { "@microsoft/tsdoc": { @@ -1083,9 +1083,9 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.6.0.tgz", - "integrity": "sha512-3ixIcEHseqU1sbnvoQkvxvfTYWbi1IIhnq/vexJcex7j6D8lnQCiYnd/E2oXbUH0Zv48CjtfslC/2MVFd71mpg==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", + "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", "dev": true, "requires": { "ajv": "~8.13.0", @@ -1286,19 +1286,19 @@ } }, "@rushstack/terminal": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.13.4.tgz", - "integrity": "sha512-h7g2RuffpqBCDKOijlUmvQ0b2O9kpIOK9TWCX9IR+2kvudp6MdtCYDu29zeqweWwCSWUnuAaUfB5HT88s0YCiw==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.2.tgz", + "integrity": "sha512-2fC1wqu1VCExKC0/L+0noVcFQEXEnoBOtCIex1TOjBzEDWcw8KzJjjj7aTP6mLxepG0XIyn9OufeFb6SFsa+sg==", "dev": true, "requires": { - "@rushstack/node-core-library": "5.6.0", + "@rushstack/node-core-library": "5.9.0", "supports-color": "~8.1.1" }, "dependencies": { "@rushstack/node-core-library": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.6.0.tgz", - "integrity": "sha512-3ixIcEHseqU1sbnvoQkvxvfTYWbi1IIhnq/vexJcex7j6D8lnQCiYnd/E2oXbUH0Zv48CjtfslC/2MVFd71mpg==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", + "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", "dev": true, "requires": { "ajv": "~8.13.0", From 5c928861fcc42b5f83e59f3b6644bf4323097887 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:37:35 +0000 Subject: [PATCH 174/323] build(deps-dev): bump eslint from 8.57.0 to 8.57.1 (#2707) --- package-lock.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index e9c73b8747..5b57963ece 100644 --- a/package-lock.json +++ b/package-lock.json @@ -414,9 +414,9 @@ } }, "@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true }, "@fastify/busboy": { @@ -796,12 +796,12 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } @@ -3132,16 +3132,16 @@ "dev": true }, "eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", @@ -3285,9 +3285,9 @@ "dev": true }, "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "requires": { "estraverse": "^5.1.0" From 74b54ec2c5637e017cce9b63eb24fec483613653 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 12:53:31 -0400 Subject: [PATCH 175/323] build(deps-dev): bump @firebase/app-compat from 0.2.39 to 0.2.41 (#2711) Bumps [@firebase/app-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/app-compat) from 0.2.39 to 0.2.41. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/main/packages/app-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/app-compat@0.2.41/packages/app-compat) --- updated-dependencies: - dependency-name: "@firebase/app-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 50 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5b57963ece..21381f14bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -441,32 +441,32 @@ } }, "@firebase/app": { - "version": "0.10.9", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.9.tgz", - "integrity": "sha512-AmGlPg/4SoDhwCdvVDeZsN5Yn+czYD/m/NAEOOCOhwn3Cz1xmEFKAKcyZKKahLrh5QPmge5Adyw+sk3cBTubBg==", + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.11.tgz", + "integrity": "sha512-DuI8c+p/ndPmV6V0i+mcSuaU9mK9Pi9h76WOYFkPNsbmkblEy8bpTOazjG7tnfar6Of1Wn5ohvyOHSRqnN6flQ==", "dev": true, "requires": { - "@firebase/component": "0.6.8", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "idb": "7.1.1", "tslib": "^2.1.0" }, "dependencies": { "@firebase/component": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.8.tgz", - "integrity": "sha512-LcNvxGLLGjBwB0dJUsBGCej2fqAepWyBubs4jt1Tiuns7QLbXHuyObZ4aMeBjZjWx4m8g1LoVI9QFpSaq/k4/g==", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", + "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", "dev": true, "requires": { - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" } }, "@firebase/util": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.7.tgz", - "integrity": "sha512-fBVNH/8bRbYjqlbIhZ+lBtdAAS4WqZumx03K06/u7fJSpz1TGjEMm1ImvKD47w+xaFKIP2ori6z8BrbakRfjJA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", + "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -480,32 +480,32 @@ "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "@firebase/app-compat": { - "version": "0.2.39", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.39.tgz", - "integrity": "sha512-NnTFywe+M/jxZn751NIEhidgDePiDvlcfabvGxBy4YbU1E+b0TpEuJUnm3L6YDZtaZLVEz8ieoq9wbJkgGZ2rg==", + "version": "0.2.41", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.41.tgz", + "integrity": "sha512-ktJcObWKjlIWq31kXu6sHoqWlhQD5rx0a2F2ZC2JVuEE5A5f7F43VO1Z6lfeRZXMFZbGG/aqIfXqgsP3zD2JYg==", "dev": true, "requires": { - "@firebase/app": "0.10.9", - "@firebase/component": "0.6.8", + "@firebase/app": "0.10.11", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" }, "dependencies": { "@firebase/component": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.8.tgz", - "integrity": "sha512-LcNvxGLLGjBwB0dJUsBGCej2fqAepWyBubs4jt1Tiuns7QLbXHuyObZ4aMeBjZjWx4m8g1LoVI9QFpSaq/k4/g==", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", + "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", "dev": true, "requires": { - "@firebase/util": "1.9.7", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" } }, "@firebase/util": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.7.tgz", - "integrity": "sha512-fBVNH/8bRbYjqlbIhZ+lBtdAAS4WqZumx03K06/u7fJSpz1TGjEMm1ImvKD47w+xaFKIP2ori6z8BrbakRfjJA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", + "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", "dev": true, "requires": { "tslib": "^2.1.0" From 56d967f62fc8751932969f1de238f6ed1a325300 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:58:23 +0000 Subject: [PATCH 176/323] build(deps-dev): bump @types/lodash from 4.17.7 to 4.17.9 (#2710) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 21381f14bc..21bb143cb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1537,9 +1537,9 @@ } }, "@types/lodash": { - "version": "4.17.7", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.7.tgz", - "integrity": "sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==", + "version": "4.17.9", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz", + "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==", "dev": true }, "@types/long": { From 137a0d9312b0b45b69f6a5111081420729d8eaeb Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:12:13 -0400 Subject: [PATCH 177/323] fix(auth): Add missing `Math.floor()` when setting `validDuration` in `createSessionCookie()` (#2712) * fix(auth): Add missing `Math.floor()` when setting `validDuration` in `createSessionCookie()` * fix unit tests --- src/auth/auth-api-request.ts | 2 +- test/integration/auth.spec.ts | 2 +- test/unit/auth/auth-api-request.spec.ts | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 68975fdae3..65dd04b806 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -1094,7 +1094,7 @@ export abstract class AbstractAuthRequestHandler { const request = { idToken, // Convert to seconds. - validDuration: expiresIn / 1000, + validDuration: Math.floor(expiresIn / 1000), }; return this.invokeRequestHandler(this.getAuthUrlBuilder(), FIREBASE_AUTH_CREATE_SESSION_COOKIE, request) .then((response: any) => response.sessionCookie); diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 7b113b3156..801b51bf80 100644 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -2563,7 +2563,7 @@ describe('admin.auth', () => { describe('createSessionCookie()', () => { let expectedExp: number; let expectedIat: number; - const expiresIn = 24 * 60 * 60 * 1000; + const expiresIn = (24 * 60 * 60 * 1000) + 234; let payloadClaims: any; let currentIdToken: string; const uid = sessionCookieUids[0]; diff --git a/test/unit/auth/auth-api-request.spec.ts b/test/unit/auth/auth-api-request.spec.ts index 574962df53..4a2f4078be 100644 --- a/test/unit/auth/auth-api-request.spec.ts +++ b/test/unit/auth/auth-api-request.spec.ts @@ -1055,7 +1055,8 @@ AUTH_REQUEST_HANDLER_TESTS.forEach((handler) => { const expectedError = new FirebaseAuthError( AuthClientErrorCode.INVALID_SESSION_COOKIE_DURATION, ); - const outOfBoundDuration = 60 * 60 * 1000 * 24 * 14 + 1; + // Add more than a second since this value is Math.floor()'ed + const outOfBoundDuration = 60 * 60 * 1000 * 24 * 14 + 1001; const requestHandler = handler.init(mockApp); return requestHandler.createSessionCookie('ID_TOKEN', outOfBoundDuration) From 1885958e1f0fa08f00c9d0e527214fbd0bbcec8d Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 30 Sep 2024 14:46:02 -0400 Subject: [PATCH 178/323] feat: Add Data Connect API (#2701) * feat(data-connect): Add Data Connect API * Add unit tests * Add DataConnect Service * Add executeGraphqlRead() * Handle query errors * Add docstrings * Increase unit tests coverage * Increase test coverage for executeGraphql * Add emulator unit tests --- entrypoints.json | 4 + etc/firebase-admin.data-connect.api.md | 45 ++++ package.json | 8 + .../data-connect-api-client-internal.ts | 241 ++++++++++++++++++ src/data-connect/data-connect-api.ts | 56 ++++ src/data-connect/data-connect.ts | 106 ++++++++ src/data-connect/index.ts | 79 ++++++ test/integration/data-connect.spec.ts | 141 ++++++++++ .../data-connect-api-client-internal.spec.ts | 227 +++++++++++++++++ test/unit/data-connect/index.spec.ts | 86 +++++++ 10 files changed, 993 insertions(+) create mode 100644 etc/firebase-admin.data-connect.api.md create mode 100644 src/data-connect/data-connect-api-client-internal.ts create mode 100644 src/data-connect/data-connect-api.ts create mode 100644 src/data-connect/data-connect.ts create mode 100644 src/data-connect/index.ts create mode 100644 test/integration/data-connect.spec.ts create mode 100644 test/unit/data-connect/data-connect-api-client-internal.spec.ts create mode 100644 test/unit/data-connect/index.spec.ts diff --git a/entrypoints.json b/entrypoints.json index dd17bd46fb..caa92a7604 100644 --- a/entrypoints.json +++ b/entrypoints.json @@ -20,6 +20,10 @@ "typings": "./lib/database/index.d.ts", "dist": "./lib/database/index.js" }, + "firebase-admin/data-connect": { + "typings": "./lib/data-connect/index.d.ts", + "dist": "./lib/data-connect/index.js" + }, "firebase-admin/extensions": { "typings": "./lib/extensions/index.d.ts", "dist": "./lib/extensions/index.js" diff --git a/etc/firebase-admin.data-connect.api.md b/etc/firebase-admin.data-connect.api.md new file mode 100644 index 0000000000..ab253d17eb --- /dev/null +++ b/etc/firebase-admin.data-connect.api.md @@ -0,0 +1,45 @@ +## API Report File for "firebase-admin.data-connect" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +/// + +import { Agent } from 'http'; + +// @public +export interface ConnectorConfig { + location: string; + serviceId: string; +} + +// @public +export class DataConnect { + // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts + // + // (undocumented) + readonly app: App; + // (undocumented) + readonly connectorConfig: ConnectorConfig; + // @beta + executeGraphql(query: string, options?: GraphqlOptions): Promise>; + // @beta + executeGraphqlRead(query: string, options?: GraphqlOptions): Promise>; +} + +// @public +export interface ExecuteGraphqlResponse { + data: GraphqlResponse; +} + +// @public +export function getDataConnect(connectorConfig: ConnectorConfig, app?: App): DataConnect; + +// @public +export interface GraphqlOptions { + operationName?: string; + variables?: Variables; +} + +``` diff --git a/package.json b/package.json index 88550ecca8..a73dc9694c 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,9 @@ "database": [ "lib/database" ], + "data-connect": [ + "lib/data-connect" + ], "firestore": [ "lib/firestore" ], @@ -134,6 +137,11 @@ "require": "./lib/database/index.js", "import": "./lib/esm/database/index.js" }, + "./data-connect": { + "types": "./lib/data-connect/index.d.ts", + "require": "./lib/data-connect/index.js", + "import": "./lib/esm/data-connect/index.js" + }, "./eventarc": { "types": "./lib/eventarc/index.d.ts", "require": "./lib/eventarc/index.js", diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts new file mode 100644 index 0000000000..969c8492f5 --- /dev/null +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -0,0 +1,241 @@ +/*! + * @license + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { App } from '../app'; +import { FirebaseApp } from '../app/firebase-app'; +import { + HttpRequestConfig, HttpClient, RequestResponseError, AuthorizedHttpClient +} from '../utils/api-request'; +import { PrefixedFirebaseError } from '../utils/error'; +import * as utils from '../utils/index'; +import * as validator from '../utils/validator'; +import { ConnectorConfig, ExecuteGraphqlResponse, GraphqlOptions } from './data-connect-api'; + +// Data Connect backend constants +const DATA_CONNECT_HOST = 'https://firebasedataconnect.googleapis.com'; +const DATA_CONNECT_API_URL_FORMAT = + '{host}/v1alpha/projects/{projectId}/locations/{locationId}/services/{serviceId}:{endpointId}'; + +const EXECUTE_GRAPH_QL_ENDPOINT = 'executeGraphql'; +const EXECUTE_GRAPH_QL_READ_ENDPOINT = 'executeGraphqlRead'; + +const DATA_CONNECT_CONFIG_HEADERS = { + 'X-Firebase-Client': `fire-admin-node/${utils.getSdkVersion()}` +}; + +/** + * Class that facilitates sending requests to the Firebase Data Connect backend API. + * + * @internal + */ +export class DataConnectApiClient { + private readonly httpClient: HttpClient; + private projectId?: string; + + constructor(private readonly connectorConfig: ConnectorConfig, private readonly app: App) { + if (!validator.isNonNullObject(app) || !('options' in app)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'First argument passed to getDataConnect() must be a valid Firebase app instance.'); + } + this.httpClient = new AuthorizedHttpClient(app as FirebaseApp); + } + + /** + * Execute arbitrary GraphQL, including both read and write queries + * + * @param query - The GraphQL string to be executed. + * @param options - GraphQL Options + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + */ + public async executeGraphql( + query: string, + options?: GraphqlOptions, + ): Promise> { + return this.executeGraphqlHelper(query, EXECUTE_GRAPH_QL_ENDPOINT, options); + } + + /** + * Execute arbitrary read-only GraphQL queries + * + * @param query - The GraphQL (read-only) string to be executed. + * @param options - GraphQL Options + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + * @throws FirebaseDataConnectError + */ + public async executeGraphqlRead( + query: string, + options?: GraphqlOptions, + ): Promise> { + return this.executeGraphqlHelper(query, EXECUTE_GRAPH_QL_READ_ENDPOINT, options); + } + + private async executeGraphqlHelper( + query: string, + endpoint: string, + options?: GraphqlOptions, + ): Promise> { + if (!validator.isNonEmptyString(query)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`query` must be a non-empty string.'); + } + if (typeof options !== 'undefined') { + if (!validator.isNonNullObject(options)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'GraphqlOptions must be a non-null object'); + } + } + const host = (process.env.DATA_CONNECT_EMULATOR_HOST || DATA_CONNECT_HOST); + const data = { + query, + ...(options?.variables && { variables: options?.variables }), + ...(options?.operationName && { operationName: options?.operationName }), + }; + return this.getUrl(host, this.connectorConfig.location, this.connectorConfig.serviceId, endpoint) + .then(async (url) => { + const request: HttpRequestConfig = { + method: 'POST', + url, + headers: DATA_CONNECT_CONFIG_HEADERS, + data, + }; + const resp = await this.httpClient.send(request); + if (resp.data.errors && validator.isNonEmptyArray(resp.data.errors)) { + const allMessages = resp.data.errors.map((error: { message: any; }) => error.message).join(' '); + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.QUERY_ERROR, allMessages); + } + return Promise.resolve({ + data: resp.data.data as GraphqlResponse, + }); + }) + .then((resp) => { + return resp; + }) + .catch((err) => { + throw this.toFirebaseError(err); + }); + } + + private async getUrl(host: string, locationId: string, serviceId: string, endpointId: string): Promise { + return this.getProjectId() + .then((projectId) => { + const urlParams = { + host, + projectId, + locationId, + serviceId, + endpointId + }; + const baseUrl = utils.formatString(DATA_CONNECT_API_URL_FORMAT, urlParams); + return utils.formatString(baseUrl); + }); + } + + private getProjectId(): Promise { + if (this.projectId) { + return Promise.resolve(this.projectId); + } + return utils.findProjectId(this.app) + .then((projectId) => { + if (!validator.isNonEmptyString(projectId)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.UNKNOWN, + 'Failed to determine project ID. Initialize the ' + + 'SDK with service account credentials or set project ID as an app option. ' + + 'Alternatively, set the GOOGLE_CLOUD_PROJECT environment variable.'); + } + this.projectId = projectId; + return projectId; + }); + } + + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { + if (err instanceof PrefixedFirebaseError) { + return err; + } + + const response = err.response; + if (!response.isJson()) { + return new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.UNKNOWN, + `Unexpected response with status: ${response.status} and body: ${response.text}`); + } + + const error: ServerError = (response.data as ErrorResponse).error || {}; + let code: DataConnectErrorCode = DATA_CONNECT_ERROR_CODE_MAPPING.UNKNOWN; + if (error.status && error.status in DATA_CONNECT_ERROR_CODE_MAPPING) { + code = DATA_CONNECT_ERROR_CODE_MAPPING[error.status]; + } + const message = error.message || `Unknown server error: ${response.text}`; + return new FirebaseDataConnectError(code, message); + } +} + +interface ErrorResponse { + error?: ServerError; +} + +interface ServerError { + code?: number; + message?: string; + status?: string; +} + +export const DATA_CONNECT_ERROR_CODE_MAPPING: { [key: string]: DataConnectErrorCode } = { + ABORTED: 'aborted', + INVALID_ARGUMENT: 'invalid-argument', + INVALID_CREDENTIAL: 'invalid-credential', + INTERNAL: 'internal-error', + PERMISSION_DENIED: 'permission-denied', + UNAUTHENTICATED: 'unauthenticated', + NOT_FOUND: 'not-found', + UNKNOWN: 'unknown-error', + QUERY_ERROR: 'query-error', +}; + +export type DataConnectErrorCode = + 'aborted' + | 'invalid-argument' + | 'invalid-credential' + | 'internal-error' + | 'permission-denied' + | 'unauthenticated' + | 'not-found' + | 'unknown-error' + | 'query-error'; + +/** + * Firebase Data Connect error code structure. This extends PrefixedFirebaseError. + * + * @param code - The error code. + * @param message - The error message. + * @constructor + */ +export class FirebaseDataConnectError extends PrefixedFirebaseError { + constructor(code: DataConnectErrorCode, message: string) { + super('data-connect', code, message); + + /* tslint:disable:max-line-length */ + // Set the prototype explicitly. See the following link for more details: + // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work + /* tslint:enable:max-line-length */ + (this as any).__proto__ = FirebaseDataConnectError.prototype; + } +} diff --git a/src/data-connect/data-connect-api.ts b/src/data-connect/data-connect-api.ts new file mode 100644 index 0000000000..df997a1dbe --- /dev/null +++ b/src/data-connect/data-connect-api.ts @@ -0,0 +1,56 @@ +/*! + * @license + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Interface representing a Data Connect connector configuration. + */ +export interface ConnectorConfig { + /** + * Location ID of the Data Connect service. + */ + location: string; + + /** + * Service ID of the Data Connect service. + */ + serviceId: string; +} + +/** + * Interface representing GraphQL response. + */ +export interface ExecuteGraphqlResponse { + /** + * Data payload of the GraphQL response. + */ + data: GraphqlResponse; +} + +/** + * Interface representing GraphQL options. + */ +export interface GraphqlOptions { + /** + * Values for GraphQL variables provided in this query or mutation. + */ + variables?: Variables; + + /** + * The name of the GraphQL operation. Required only if `query` contains multiple operations. + */ + operationName?: string; +} diff --git a/src/data-connect/data-connect.ts b/src/data-connect/data-connect.ts new file mode 100644 index 0000000000..dbded00042 --- /dev/null +++ b/src/data-connect/data-connect.ts @@ -0,0 +1,106 @@ +/*! + * @license + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { App } from '../app'; +import { DataConnectApiClient } from './data-connect-api-client-internal'; + +import { + ConnectorConfig, + ExecuteGraphqlResponse, + GraphqlOptions, +} from './data-connect-api'; + +export class DataConnectService { + + private readonly appInternal: App; + private dataConnectInstances: Map = new Map(); + + constructor(app: App) { + this.appInternal = app; + } + + getDataConnect(connectorConfig: ConnectorConfig): DataConnect { + const id = `${connectorConfig.location}-${connectorConfig.serviceId}`; + const dc = this.dataConnectInstances.get(id); + if (typeof dc !== 'undefined') { + return dc; + } + + const newInstance = new DataConnect(connectorConfig, this.appInternal); + this.dataConnectInstances.set(id, newInstance); + return newInstance; + } + + /** + * Returns the app associated with this `DataConnectService` instance. + * + * @returns The app associated with this `DataConnectService` instance. + */ + get app(): App { + return this.appInternal; + } +} + +/** + * The Firebase `DataConnect` service interface. + */ +export class DataConnect { + + private readonly client: DataConnectApiClient; + + /** + * @param connectorConfig - The connector configuration. + * @param app - The app for this `DataConnect` service. + * @constructor + * @internal + */ + constructor(readonly connectorConfig: ConnectorConfig, readonly app: App) { + this.client = new DataConnectApiClient(connectorConfig, app); + } + + /** + * Execute an arbitrary GraphQL query or mutation + * + * @param query - The GraphQL query or mutation. + * @param options - Optional {@link GraphqlOptions} when executing a GraphQL query or mutation. + * + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + * @beta + */ + public executeGraphql( + query: string, + options?: GraphqlOptions, + ): Promise> { + return this.client.executeGraphql(query, options); + } + + /** + * Execute an arbitrary read-only GraphQL query + * + * @param query - The GraphQL read-only query. + * @param options - Optional {@link GraphqlOptions} when executing a read-only GraphQL query. + * + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + * @beta + */ + public executeGraphqlRead( + query: string, + options?: GraphqlOptions, + ): Promise> { + return this.client.executeGraphqlRead(query, options); + } +} diff --git a/src/data-connect/index.ts b/src/data-connect/index.ts new file mode 100644 index 0000000000..77b9ab1e38 --- /dev/null +++ b/src/data-connect/index.ts @@ -0,0 +1,79 @@ +/*! + * @license + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Firebase Data Connect service. + * + * @packageDocumentation + */ + +import { App, getApp } from '../app'; +import { FirebaseApp } from '../app/firebase-app'; +import { DataConnect, DataConnectService } from './data-connect'; +import { ConnectorConfig } from './data-connect-api'; + +export { + GraphqlOptions, + ExecuteGraphqlResponse, + ConnectorConfig, +} from './data-connect-api' +export { + DataConnect, +} from './data-connect' + +/** + * Gets the {@link DataConnect} service with the provided connector configuration + * for the default app or a given app. + * + * `getDataConnect(connectorConfig)` can be called with no app argument to access the default + * app's `DataConnect` service or as `getDataConnect(connectorConfig, app)` to access the + * `DataConnect` service associated with a specific app. + * + * @example + * ```javascript + * const connectorConfig: ConnectorConfig = { + * location: 'us-west2', + * serviceId: 'my-service', + * }; + * + * // Get the `DataConnect` service for the default app + * const defaultDataConnect = getDataConnect(connectorConfig); + * ``` + * + * @example + * ```javascript + * // Get the `DataConnect` service for a given app + * const otherDataConnect = getDataConnect(connectorConfig, otherApp); + * ``` + * + * @param connectorConfig - Connector configuration for the `DataConnect` service. + * + * @param app - Optional app for which to return the `DataConnect` service. + * If not provided, the default `DataConnect` service is returned. + * + * @returns The default `DataConnect` service with the provided connector configuration + * if no app is provided, or the `DataConnect` service associated with the provided app. + */ +export function getDataConnect(connectorConfig: ConnectorConfig, app?: App): DataConnect { + if (typeof app === 'undefined') { + app = getApp(); + } + + const firebaseApp: FirebaseApp = app as FirebaseApp; + const dataConnectService = firebaseApp.getOrInitService('dataConnect', (app) => new DataConnectService(app)); + return dataConnectService.getDataConnect(connectorConfig); +} diff --git a/test/integration/data-connect.spec.ts b/test/integration/data-connect.spec.ts new file mode 100644 index 0000000000..91179c12e3 --- /dev/null +++ b/test/integration/data-connect.spec.ts @@ -0,0 +1,141 @@ +/*! + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as chai from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { getDataConnect, ConnectorConfig } from '../../lib/data-connect/index'; + +chai.should(); +chai.use(chaiAsPromised); + +const expect = chai.expect; + +interface UserResponse { + user: { + name: string; + uid: string; + } +} + +interface UsersResponse { + users: [ + user: { + id: string; + name: string; + address: string; + } + ]; +} + +interface UserUpdateResponse { + user_upsert: { uid: string } +} + +interface EmailsResponse { + emails: [ + email: { + text: string; + subject: string; + id: string; + date: string; + from: { + name: string; + } + } + ]; +} + +interface UserVariables { + id: string; +} + +const connectorConfig: ConnectorConfig = { + location: 'us-west2', + serviceId: 'my-service', +}; + +const userId = 'QVBJcy5ndXJ3'; + +describe('getDataConnect()', () => { + + const queryListUsers = 'query ListUsers @auth(level: PUBLIC) { users { uid, name, address } }'; + const queryListEmails = 'query ListEmails @auth(level: NO_ACCESS) { emails { id subject text date from { name } } }'; + const queryGetUserById = 'query GetUser($id: User_Key!) { user(key: $id) { uid name } }'; + const multipleQueries = ` + ${queryListUsers} + ${queryListEmails} + `; + const mutation = `mutation user { user_insert(data: {uid: "${userId}", address: "32 St", name: "Fred Car"}) }`; + const upsertUser = `mutation UpsertUser($id: String) { + user_upsert(data: { uid: $id, address: "32 St.", name: "Fred" }) }`; + + describe('executeGraphql()', () => { + it('executeGraphql() successfully executes a GraphQL mutation', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + upsertUser, { variables: { id: userId } } + ); + //{ data: { user_insert: { uid: 'QVBJcy5ndXJ3' } } } + expect(resp.data.user_upsert.uid).to.be.not.empty; + expect(resp.data.user_upsert.uid).equals(userId); + }); + + it('executeGraphql() successfully executes a GraphQL', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql(queryListUsers); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + }); + + it('executeGraphql() use the operationName when multiple queries are provided', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + multipleQueries, + { operationName: 'ListEmails' } + ); + expect(resp.data.emails).to.be.not.empty; + expect(resp.data.emails[0].id).to.be.not.undefined; + expect(resp.data.emails[0].from.name).to.be.not.undefined; + }); + + it('executeGraphql() should throw for a query error', async () => { + return getDataConnect(connectorConfig).executeGraphql(mutation) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/query-error'); + }); + + it('executeGraphql() successfully executes a GraphQL query with variables', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryGetUserById, + { variables: { id: userId } } + ); + expect(resp.data.user.name).to.be.not.undefined; + expect(resp.data.user.uid).equals(userId); + }); + }); + + describe('executeGraphqlRead()', () => { + it('executeGraphqlRead() successfully executes a read-only GraphQL', async () => { + const resp = + await getDataConnect(connectorConfig).executeGraphqlRead(queryListUsers); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + }); + + it('executeGraphqlRead() should throw for a GraphQL mutation', async () => { + return getDataConnect(connectorConfig).executeGraphqlRead(mutation) + .should.eventually.be.rejected; + }); + }); +}); diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts new file mode 100644 index 0000000000..aa45f53b9c --- /dev/null +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -0,0 +1,227 @@ +/*! + * @license + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as _ from 'lodash'; +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import { + AuthorizedHttpClient, + HttpClient, +} from '../../../src/utils/api-request'; +import * as utils from '../utils'; +import * as mocks from '../../resources/mocks'; +import { DataConnectApiClient, FirebaseDataConnectError } + from '../../../src/data-connect/data-connect-api-client-internal'; +import { FirebaseApp } from '../../../src/app/firebase-app'; +import { ConnectorConfig } from '../../../src/data-connect'; +import { getSdkVersion } from '../../../src/utils'; + +describe('DataConnectApiClient', () => { + + const ERROR_RESPONSE = { + error: { + code: 404, + message: 'Requested entity not found', + status: 'NOT_FOUND', + }, + }; + + const EXPECTED_HEADERS = { + 'Authorization': 'Bearer mock-token', + 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'x-goog-user-project': 'test-project', + }; + + const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' + + 'account credentials or set project ID as an app option. Alternatively, set the ' + + 'GOOGLE_CLOUD_PROJECT environment variable.'; + + const TEST_RESPONSE = { + data: { + users: [ + { uid: 'QVBJcy5ndXJ1', name: 'Fred', address: '32 Elm St. N' }, + { name: 'Name', address: 'Address', uid: 'QVBJcy5ndXJ2' }, + { name: 'Fred', address: '32 St.', uid: 'QVBJcy5ndXJ3' } + ] + } + }; + + const connectorConfig: ConnectorConfig = { + location: 'us-west2', + serviceId: 'my-service', + }; + + const clientWithoutProjectId = new DataConnectApiClient( + connectorConfig, + mocks.mockCredentialApp()); + + const mockOptions = { + credential: new mocks.MockCredential(), + projectId: 'test-project', + }; + + let app: FirebaseApp; + + let apiClient: DataConnectApiClient; + let sandbox: sinon.SinonSandbox; + + beforeEach(() => { + sandbox = sinon.createSandbox(); + app = mocks.appWithOptions(mockOptions); + apiClient = new DataConnectApiClient(connectorConfig, app); + }); + + afterEach(() => { + sandbox.restore(); + if (process.env.DATA_CONNECT_EMULATOR_HOST) { + delete process.env.DATA_CONNECT_EMULATOR_HOST; + } + return app.delete(); + }); + + describe('constructor', () => { + it('should throw an error if app is not a valid Firebase app instance', () => { + expect(() => new DataConnectApiClient(connectorConfig, null as unknown as FirebaseApp)).to.throw( + FirebaseDataConnectError, + 'First argument passed to getDataConnect() must be a valid Firebase app instance.' + ); + }); + + it('should initialize httpClient with the provided app', () => { + expect((apiClient as any).httpClient).to.be.an.instanceOf(AuthorizedHttpClient); + }); + }); + + describe('executeGraphql', () => { + it('should reject when project id is not available', () => { + return clientWithoutProjectId.executeGraphql('query', {}) + .should.eventually.be.rejectedWith(noProjectId); + }); + + it('should throw an error if query is not a non-empty string', async () => { + await expect(apiClient.executeGraphql('')).to.be.rejectedWith( + FirebaseDataConnectError, + '`query` must be a non-empty string.' + ); + await expect(apiClient.executeGraphql(undefined as any)).to.be.rejectedWith( + FirebaseDataConnectError, + '`query` must be a non-empty string.' + ); + }); + + const invalidQueries = [null, NaN, 0, 1, true, false, [], {}, { a: 1 }, _.noop]; + invalidQueries.forEach((invalidQuery) => { + it('should throw given a non-string query: ' + JSON.stringify(invalidQuery), async () => { + await expect(apiClient.executeGraphql(invalidQuery as any)).to.be.rejectedWith( + FirebaseDataConnectError, + '`query` must be a non-empty string.' + ); + }); + }); + + const invalidOptions = [null, NaN, 0, 1, true, false, [], _.noop]; + invalidOptions.forEach((invalidOption) => { + it('should throw given an invalid options object: ' + JSON.stringify(invalidOption), async () => { + await expect(apiClient.executeGraphql('query', invalidOption as any)).to.be.rejectedWith( + FirebaseDataConnectError, + 'GraphqlOptions must be a non-null object' + ); + }); + }); + + it('should reject when a full platform error response is received', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom(ERROR_RESPONSE, 404)); + const expected = new FirebaseDataConnectError('not-found', 'Requested entity not found'); + return apiClient.executeGraphql('query', {}) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject with unknown-error when error code is not present', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom({}, 404)); + const expected = new FirebaseDataConnectError('unknown-error', 'Unknown server error: {}'); + return apiClient.executeGraphql('query', {}) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject with unknown-error for non-json response', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom('not json', 404)); + const expected = new FirebaseDataConnectError( + 'unknown-error', 'Unexpected response with status: 404 and body: not json'); + return apiClient.executeGraphql('query', {}) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject when rejected with a FirebaseDataConnectError', () => { + const expected = new FirebaseDataConnectError('internal-error', 'socket hang up'); + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(expected); + return apiClient.executeGraphql('query', {}) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should resolve with the GraphQL response on success', () => { + interface UsersResponse { + users: [ + user: { + id: string; + name: string; + address: string; + } + ]; + } + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + return apiClient.executeGraphql('query', {}) + .then((resp) => { + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `https://firebasedataconnect.googleapis.com/v1alpha/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, + headers: EXPECTED_HEADERS, + data: { query: 'query' } + }); + }); + }); + + it('should use DATA_CONNECT_EMULATOR_HOST if set', () => { + process.env.DATA_CONNECT_EMULATOR_HOST = 'http://localhost:9000'; + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + return apiClient.executeGraphql('query', {}) + .then(() => { + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `http://localhost:9000/v1alpha/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, + headers: EXPECTED_HEADERS, + data: { query: 'query' } + }); + }); + }); + }); +}); diff --git a/test/unit/data-connect/index.spec.ts b/test/unit/data-connect/index.spec.ts new file mode 100644 index 0000000000..228cafbf84 --- /dev/null +++ b/test/unit/data-connect/index.spec.ts @@ -0,0 +1,86 @@ +/*! + * @license + * Copyright 2024 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import * as chai from 'chai'; +import * as sinonChai from 'sinon-chai'; +import * as chaiAsPromised from 'chai-as-promised'; + +import * as mocks from '../../resources/mocks'; +import { App } from '../../../src/app/index'; +import { getDataConnect, DataConnect } from '../../../src/data-connect/index'; + +chai.should(); +chai.use(sinonChai); +chai.use(chaiAsPromised); + +const expect = chai.expect; + +describe('DataConnect', () => { + let mockApp: App; + let mockCredentialApp: App; + + const noProjectIdError = 'Failed to determine project ID. Initialize the SDK ' + + 'with service account credentials or set project ID as an app option. Alternatively, set the ' + + 'GOOGLE_CLOUD_PROJECT environment variable.'; + + const connectorConfig = { + location: 'us-west2', + serviceId: 'my-service', + }; + + beforeEach(() => { + mockApp = mocks.app(); + mockCredentialApp = mocks.mockCredentialApp(); + }); + + describe('getDataConnect()', () => { + it('should throw when default app is not available', () => { + expect(() => { + return getDataConnect(connectorConfig); + }).to.throw('The default Firebase app does not exist.'); + }); + + it('should reject given an invalid credential without project ID', () => { + // Project ID not set in the environment. + delete process.env.GOOGLE_CLOUD_PROJECT; + delete process.env.GCLOUD_PROJECT; + const dataConnect = getDataConnect(connectorConfig, mockCredentialApp); + return dataConnect.executeGraphql('query') + .should.eventually.rejectedWith(noProjectIdError); + }); + + it('should not throw given a valid app', () => { + expect(() => { + return getDataConnect(connectorConfig, mockApp); + }).not.to.throw(); + }); + + it('should return the same instance for a given config and app instance', () => { + const dc1: DataConnect = getDataConnect(connectorConfig, mockApp); + const dc2: DataConnect = getDataConnect(connectorConfig, mockApp); + expect(dc1).to.equal(dc2); + }); + + it('should not return the same instance when different configs are provided', () => { + const dc1: DataConnect = getDataConnect(connectorConfig, mockApp); + const dc2: DataConnect = getDataConnect({ location: 'us-east1', serviceId: 'my-db' }, mockApp); + expect(dc1).to.not.equal(dc2); + }); + }); +}); From 0efe26aee4eb199709a648a818ebf1e5b86c3a16 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 30 Sep 2024 15:44:39 -0400 Subject: [PATCH 179/323] [chore] Release 12.6.0 (#2715) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a73dc9694c..a87c2796aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.5.0", + "version": "12.6.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From e64fda356a92390b0ba9d773dac2a1f1d54f12ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:14:06 -0400 Subject: [PATCH 180/323] build(deps-dev): bump @types/mocha from 10.0.7 to 10.0.8 (#2719) Bumps [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) from 10.0.7 to 10.0.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha) --- updated-dependencies: - dependency-name: "@types/mocha" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 21bb143cb9..7ca6dcdd26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.5.0", + "version": "12.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1566,9 +1566,9 @@ "dev": true }, "@types/mocha": { - "version": "10.0.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", - "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "version": "10.0.8", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz", + "integrity": "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw==", "dev": true }, "@types/nock": { From 51bbe76d43f9ec5f66c03e3ba44ed27a523b2b93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:19:27 +0000 Subject: [PATCH 181/323] build(deps): bump @google-cloud/storage from 7.12.1 to 7.13.0 (#2717) --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ca6dcdd26..ed875548d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -728,9 +728,9 @@ "optional": true }, "@google-cloud/storage": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.12.1.tgz", - "integrity": "sha512-Z3ZzOnF3YKLuvpkvF+TjQ6lztxcAyTILp+FjKonmVpEwPa9vFvxpZjubLR4sB6bf19i/8HL2AXRjA0YFgHFRmQ==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.13.0.tgz", + "integrity": "sha512-Y0rYdwM5ZPW3jw/T26sMxxfPrVQTKm9vGrZG8PRyGuUmUJ8a2xNuQ9W/NNA1prxqv2i54DSydV8SJqxF2oCVgA==", "optional": true, "requires": { "@google-cloud/paginator": "^5.0.0", @@ -3420,9 +3420,9 @@ "dev": true }, "fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", "optional": true, "requires": { "strnum": "^1.0.5" From 0bcd7668399bd5fe32d0fd5e4ce2e331411fe90e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:24:32 +0000 Subject: [PATCH 182/323] build(deps-dev): bump nyc from 17.0.0 to 17.1.0 (#2718) --- package-lock.json | 329 +++++++++++++++++++++++----------------------- 1 file changed, 163 insertions(+), 166 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed875548d1..ae08fa2b07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,37 +15,37 @@ } }, "@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", "dev": true, "requires": { - "@babel/highlight": "^7.24.7", + "@babel/highlight": "^7.25.7", "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", + "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", "dev": true }, "@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", + "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -62,26 +62,26 @@ } }, "@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", "dev": true, "requires": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.25.7", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" } }, "@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", "dev": true, "requires": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -109,111 +109,73 @@ } } }, - "@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "requires": { - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "requires": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "requires": { - "@babel/types": "^7.24.7" - } - }, "@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", "dev": true, "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" } }, "@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" } }, "@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", "dev": true, "requires": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "requires": { - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" } }, "@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", "dev": true }, "@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", "dev": true, "requires": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" } }, "@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -278,36 +240,36 @@ } }, "@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", + "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", + "dev": true, + "requires": { + "@babel/types": "^7.25.7" + } }, "@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", "dev": true, "requires": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" } }, "@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -321,13 +283,13 @@ } }, "@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", + "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" } }, @@ -2338,15 +2300,15 @@ "dev": true }, "browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" } }, "buffer": { @@ -2414,9 +2376,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001639", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz", - "integrity": "sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==", + "version": "1.0.30001667", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", + "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", "dev": true }, "caseless": { @@ -2987,9 +2949,9 @@ } }, "electron-to-chromium": { - "version": "1.4.816", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz", - "integrity": "sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==", + "version": "1.5.33", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", + "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", "dev": true }, "emoji-regex": { @@ -3623,13 +3585,13 @@ } }, "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, "requires": { "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" + "signal-exit": "^4.0.1" }, "dependencies": { "cross-spawn": { @@ -3643,6 +3605,12 @@ "which": "^2.0.1" } }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5310,9 +5278,9 @@ "dev": true }, "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true }, "json-bigint": { @@ -6072,9 +6040,9 @@ } }, "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "node-version": { @@ -6255,9 +6223,9 @@ } }, "nyc": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.0.0.tgz", - "integrity": "sha512-ISp44nqNCaPugLLGGfknzQwSwt10SSS5IMoPR7GLoMAyS18Iw5js8U7ga2VF9lYuMZ42gOHr3UddZw4WZltxKg==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", + "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", "dev": true, "requires": { "@istanbuljs/load-nyc-config": "^1.0.0", @@ -6267,7 +6235,7 @@ "decamelize": "^1.2.0", "find-cache-dir": "^3.2.0", "find-up": "^4.1.0", - "foreground-child": "^2.0.0", + "foreground-child": "^3.3.0", "get-package-type": "^0.1.0", "glob": "^7.1.6", "istanbul-lib-coverage": "^3.0.0", @@ -6700,9 +6668,9 @@ "dev": true }, "picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "picomatch": { @@ -7541,6 +7509,27 @@ "which": "^2.0.1" }, "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8253,13 +8242,21 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "requires": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "dependencies": { + "escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true + } } }, "uri-js": { From 83ebae2e5e8970d5b596b615ecaf0bd22b11c92e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 14:26:39 -0400 Subject: [PATCH 183/323] build(deps-dev): bump @firebase/app-compat from 0.2.41 to 0.2.42 (#2722) Bumps [@firebase/app-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/app-compat) from 0.2.41 to 0.2.42. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/main/packages/app-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/app-compat@0.2.42/packages/app-compat) --- updated-dependencies: - dependency-name: "@firebase/app-compat" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index ae08fa2b07..97177df107 100644 --- a/package-lock.json +++ b/package-lock.json @@ -403,9 +403,9 @@ } }, "@firebase/app": { - "version": "0.10.11", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.11.tgz", - "integrity": "sha512-DuI8c+p/ndPmV6V0i+mcSuaU9mK9Pi9h76WOYFkPNsbmkblEy8bpTOazjG7tnfar6Of1Wn5ohvyOHSRqnN6flQ==", + "version": "0.10.12", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.12.tgz", + "integrity": "sha512-fgBqe5j7GKv7/eMfyU4N1FdiW6O1EyrrVbMa8rJOT5MYNpCXqdL/5NNcLDStS1l6CN7h65a7jUNXmMnMSWo0sw==", "dev": true, "requires": { "@firebase/component": "0.6.9", @@ -442,12 +442,12 @@ "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "@firebase/app-compat": { - "version": "0.2.41", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.41.tgz", - "integrity": "sha512-ktJcObWKjlIWq31kXu6sHoqWlhQD5rx0a2F2ZC2JVuEE5A5f7F43VO1Z6lfeRZXMFZbGG/aqIfXqgsP3zD2JYg==", + "version": "0.2.42", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.42.tgz", + "integrity": "sha512-vPI0Aksk8ZuHywigyTxrx/oWbuD41kHxajfxRly7urHOFRiXKxf/q2ftgmcMVPfIeg0K02LzYNBmoh2PWzERpg==", "dev": true, "requires": { - "@firebase/app": "0.10.11", + "@firebase/app": "0.10.12", "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", "@firebase/util": "1.10.0", From 365bdb9cde65f7901553824d4ea149bc6e8897ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 18:31:15 +0000 Subject: [PATCH 184/323] build(deps-dev): bump @types/mocha from 10.0.8 to 10.0.9 (#2721) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 97177df107..66dc4f1ac7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1528,9 +1528,9 @@ "dev": true }, "@types/mocha": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz", - "integrity": "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw==", + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", + "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", "dev": true }, "@types/nock": { From 8367b4212d36e4030e9e4c2d7b3b7d4fa6c1d308 Mon Sep 17 00:00:00 2001 From: blidd-google <112491344+blidd-google@users.noreply.github.com> Date: Fri, 11 Oct 2024 09:09:02 -0400 Subject: [PATCH 185/323] fixes function name resolution to cloud tasks emulator queue (#2726) --- src/functions/functions-api-client-internal.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/functions/functions-api-client-internal.ts b/src/functions/functions-api-client-internal.ts index 6696f18da3..e020a70921 100644 --- a/src/functions/functions-api-client-internal.ts +++ b/src/functions/functions-api-client-internal.ts @@ -92,7 +92,7 @@ export class FunctionsApiClient { } try { - const serviceUrl = tasksEmulatorUrl(resources, functionName)?.concat('/', id) + const serviceUrl = tasksEmulatorUrl(resources)?.concat('/', id) ?? await this.getUrl(resources, CLOUD_TASKS_API_URL_FORMAT.concat('/', id)); const request: HttpRequestConfig = { method: 'DELETE', @@ -147,7 +147,7 @@ export class FunctionsApiClient { const task = this.validateTaskOptions(data, resources, opts); try { const serviceUrl = - tasksEmulatorUrl(resources, functionName) ?? + tasksEmulatorUrl(resources) ?? await this.getUrl(resources, CLOUD_TASKS_API_URL_FORMAT); const taskPayload = await this.updateTaskPayload(task, resources, extensionId); @@ -436,9 +436,9 @@ export class FirebaseFunctionsError extends PrefixedFirebaseError { } } -function tasksEmulatorUrl(resources: utils.ParsedResource, functionName: string): string | undefined { +function tasksEmulatorUrl(resources: utils.ParsedResource): string | undefined { if (process.env.CLOUD_TASKS_EMULATOR_HOST) { - return `http://${process.env.CLOUD_TASKS_EMULATOR_HOST}/projects/${resources.projectId}/locations/${resources.locationId}/queues/${functionName}/tasks`; + return `http://${process.env.CLOUD_TASKS_EMULATOR_HOST}/projects/${resources.projectId}/locations/${resources.locationId}/queues/${resources.resourceId}/tasks`; } return undefined; } From 8a8387247d04058d76a7b43757107086690ac221 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 14:52:21 -0400 Subject: [PATCH 186/323] build(deps-dev): bump @types/lodash from 4.17.9 to 4.17.10 (#2730) Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.9 to 4.17.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 66dc4f1ac7..4997a0b667 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1499,9 +1499,9 @@ } }, "@types/lodash": { - "version": "4.17.9", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz", - "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==", + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", "dev": true }, "@types/long": { From f1c55238a885a76b5225fe5bdaa580c7ae1cc8a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:57:08 +0000 Subject: [PATCH 187/323] build(deps-dev): bump @firebase/app-compat from 0.2.42 to 0.2.43 (#2729) --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4997a0b667..e9f4ce94b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -403,9 +403,9 @@ } }, "@firebase/app": { - "version": "0.10.12", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.12.tgz", - "integrity": "sha512-fgBqe5j7GKv7/eMfyU4N1FdiW6O1EyrrVbMa8rJOT5MYNpCXqdL/5NNcLDStS1l6CN7h65a7jUNXmMnMSWo0sw==", + "version": "0.10.13", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.13.tgz", + "integrity": "sha512-OZiDAEK/lDB6xy/XzYAyJJkaDqmQ+BCtOEPLqFvxWKUz5JbBmej7IiiRHdtiIOD/twW7O5AxVsfaaGA/V1bNsA==", "dev": true, "requires": { "@firebase/component": "0.6.9", @@ -442,12 +442,12 @@ "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "@firebase/app-compat": { - "version": "0.2.42", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.42.tgz", - "integrity": "sha512-vPI0Aksk8ZuHywigyTxrx/oWbuD41kHxajfxRly7urHOFRiXKxf/q2ftgmcMVPfIeg0K02LzYNBmoh2PWzERpg==", + "version": "0.2.43", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.43.tgz", + "integrity": "sha512-HM96ZyIblXjAC7TzE8wIk2QhHlSvksYkQ4Ukh1GmEenzkucSNUmUX4QvoKrqeWsLEQ8hdcojABeCV8ybVyZmeg==", "dev": true, "requires": { - "@firebase/app": "0.10.12", + "@firebase/app": "0.10.13", "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", "@firebase/util": "1.10.0", From 58b1a365a06ff3ee8fd1f746d633438b15640040 Mon Sep 17 00:00:00 2001 From: pragatimodi <110490169+pragatimodi@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:49:26 -0700 Subject: [PATCH 188/323] feat(auth): Add recaptcha and sms toll fraud support for phone auth (#2625) * enable recaptcha enterprise on phone auth * undo autosave editor changes * remove editor whitespace changes * fix unit tests + add sms tf changes * lint fixes and api extractor * restructure with auth/client naming * fixes * address PR feedback * Update src/auth/auth-config.ts Co-authored-by: Kevin Cheung * fixing rCE phone enablement integ tests on project level * fix rCE phone support Integration Tests --------- Co-authored-by: Liubin Jiang <56564857+Xiaoshouzi-gh@users.noreply.github.com> Co-authored-by: Kevin Cheung Co-authored-by: Liubin Jiang --- etc/firebase-admin.auth.api.md | 10 + src/auth/auth-config.ts | 228 +++++++++++++++--- src/auth/index.ts | 1 + src/auth/project-config.ts | 22 +- src/auth/tenant.ts | 14 +- test/integration/auth.spec.ts | 189 +++++++++------ test/unit/auth/project-config.spec.ts | 320 +++++++++++++++++++------- test/unit/auth/tenant.spec.ts | 207 +++++++++++++++-- 8 files changed, 762 insertions(+), 229 deletions(-) diff --git a/etc/firebase-admin.auth.api.md b/etc/firebase-admin.auth.api.md index d921458bec..593b4e674d 100644 --- a/etc/firebase-admin.auth.api.md +++ b/etc/firebase-admin.auth.api.md @@ -877,8 +877,12 @@ export type RecaptchaAction = 'BLOCK'; export interface RecaptchaConfig { emailPasswordEnforcementState?: RecaptchaProviderEnforcementState; managedRules?: RecaptchaManagedRule[]; + phoneEnforcementState?: RecaptchaProviderEnforcementState; recaptchaKeys?: RecaptchaKey[]; + smsTollFraudManagedRules?: RecaptchaTollFraudManagedRule[]; useAccountDefender?: boolean; + useSmsBotScore?: boolean; + useSmsTollFraudProtection?: boolean; } // @public @@ -899,6 +903,12 @@ export interface RecaptchaManagedRule { // @public export type RecaptchaProviderEnforcementState = 'OFF' | 'AUDIT' | 'ENFORCE'; +// @public +export interface RecaptchaTollFraudManagedRule { + action?: RecaptchaAction; + startScore: number; +} + // @public export interface SAMLAuthProviderConfig extends BaseAuthProviderConfig { callbackURL?: string; diff --git a/src/auth/auth-config.ts b/src/auth/auth-config.ts index 28ee595c46..23895d60f3 100644 --- a/src/auth/auth-config.ts +++ b/src/auth/auth-config.ts @@ -1750,6 +1750,21 @@ export interface RecaptchaManagedRule { action?: RecaptchaAction; } +/** + * The managed rules for toll fraud provider, containing the enforcement status. + * The toll fraud provider contains all SMS related user flows. + */ +export interface RecaptchaTollFraudManagedRule { + /** + * The action will be enforced if the reCAPTCHA score of a request is larger than startScore. + */ + startScore: number; + /** + * The action for reCAPTCHA-protected requests. + */ + action?: RecaptchaAction; +} + /** * The key's platform type. */ @@ -1781,34 +1796,131 @@ export interface RecaptchaConfig { * The enforcement state of the email password provider. */ emailPasswordEnforcementState?: RecaptchaProviderEnforcementState; + /** + * The enforcement state of the phone provider. + */ + phoneEnforcementState?: RecaptchaProviderEnforcementState; /** * The reCAPTCHA managed rules. */ managedRules?: RecaptchaManagedRule[]; - /** * The reCAPTCHA keys. */ recaptchaKeys?: RecaptchaKey[]; - /** * Whether to use account defender for reCAPTCHA assessment. * The default value is false. */ useAccountDefender?: boolean; + /** + * Whether to use the rCE bot score for reCAPTCHA phone provider. + * Can only be true when the phone_enforcement_state is AUDIT or ENFORCE. + */ + useSmsBotScore?: boolean; + /** + * Whether to use the rCE SMS toll fraud protection risk score for reCAPTCHA phone provider. + * Can only be true when the phone_enforcement_state is AUDIT or ENFORCE. + */ + useSmsTollFraudProtection?: boolean; + /** + * The managed rules for toll fraud provider, containing the enforcement status. + * The toll fraud provider contains all SMS related user flows. + */ + smsTollFraudManagedRules?: RecaptchaTollFraudManagedRule[]; +} + +/** + * Server side recaptcha configuration. + */ +export interface RecaptchaAuthServerConfig { + emailPasswordEnforcementState?: RecaptchaProviderEnforcementState; + phoneEnforcementState?: RecaptchaProviderEnforcementState; + managedRules?: RecaptchaManagedRule[]; + recaptchaKeys?: RecaptchaKey[]; + useAccountDefender?: boolean; + useSmsBotScore?: boolean; + useSmsTollFraudProtection?: boolean; + tollFraudManagedRules?: RecaptchaTollFraudManagedRule[]; } +/** + * Defines the recaptcha config class used to convert client side RecaptchaConfig + * to a format that is understood by the Auth server. + * + * @internal + */ export class RecaptchaAuthConfig implements RecaptchaConfig { public readonly emailPasswordEnforcementState?: RecaptchaProviderEnforcementState; + public readonly phoneEnforcementState?: RecaptchaProviderEnforcementState; public readonly managedRules?: RecaptchaManagedRule[]; public readonly recaptchaKeys?: RecaptchaKey[]; public readonly useAccountDefender?: boolean; + public readonly useSmsBotScore?: boolean; + public readonly useSmsTollFraudProtection?: boolean; + public readonly smsTollFraudManagedRules?: RecaptchaTollFraudManagedRule[]; + + + /** + * The RecaptchaAuthConfig constructor. + * + * @param response - The server side response used to initialize the + * RecaptchaAuthConfig object. + * @constructor + * @internal + */ + constructor(response: RecaptchaAuthServerConfig) { + const filteredResponse = Object.fromEntries( + Object.entries(response).filter(([, value]) => value !== undefined) + ); + + // Explicitly map the 'tollFraudManagedRules' to 'smsTollFraudManagedRules' + if (filteredResponse.tollFraudManagedRules !== undefined) { + this.smsTollFraudManagedRules = filteredResponse.tollFraudManagedRules; + delete filteredResponse.tollFraudManagedRules; // Remove it if necessary + } + + // Assign the remaining properties directly + Object.assign(this, filteredResponse); + } + + /** + * Builds a server request object from the client-side RecaptchaConfig. + * Converts client-side fields to their server-side equivalents. + * + * @param options - The client-side RecaptchaConfig object. + * @returns The server-side RecaptchaAuthServerConfig object. + */ + public static buildServerRequest(options: RecaptchaConfig): RecaptchaAuthServerConfig { + RecaptchaAuthConfig.validate(options); // Validate options before building request + + const request: RecaptchaAuthServerConfig = {}; - constructor(recaptchaConfig: RecaptchaConfig) { - this.emailPasswordEnforcementState = recaptchaConfig.emailPasswordEnforcementState; - this.managedRules = recaptchaConfig.managedRules; - this.recaptchaKeys = recaptchaConfig.recaptchaKeys; - this.useAccountDefender = recaptchaConfig.useAccountDefender; + if (typeof options.emailPasswordEnforcementState !== 'undefined') { + request.emailPasswordEnforcementState = options.emailPasswordEnforcementState; + } + if (typeof options.phoneEnforcementState !== 'undefined') { + request.phoneEnforcementState = options.phoneEnforcementState; + } + if (typeof options.managedRules !== 'undefined') { + request.managedRules = options.managedRules; + } + if (typeof options.recaptchaKeys !== 'undefined') { + request.recaptchaKeys = options.recaptchaKeys; + } + if (typeof options.useAccountDefender !== 'undefined') { + request.useAccountDefender = options.useAccountDefender; + } + if (typeof options.useSmsBotScore !== 'undefined') { + request.useSmsBotScore = options.useSmsBotScore; + } + if (typeof options.useSmsTollFraudProtection !== 'undefined') { + request.useSmsTollFraudProtection = options.useSmsTollFraudProtection; + } + if (typeof options.smsTollFraudManagedRules !== 'undefined') { + request.tollFraudManagedRules = options.smsTollFraudManagedRules; // Map client-side field to server-side + } + return request; } /** @@ -1818,9 +1930,13 @@ export class RecaptchaAuthConfig implements RecaptchaConfig { public static validate(options: RecaptchaConfig): void { const validKeys = { emailPasswordEnforcementState: true, + phoneEnforcementState: true, managedRules: true, recaptchaKeys: true, useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, + smsTollFraudManagedRules: true, }; if (!validator.isNonNullObject(options)) { @@ -1840,7 +1956,7 @@ export class RecaptchaAuthConfig implements RecaptchaConfig { } // Validation - if (typeof options.emailPasswordEnforcementState !== undefined) { + if (typeof options.emailPasswordEnforcementState !== 'undefined') { if (!validator.isNonEmptyString(options.emailPasswordEnforcementState)) { throw new FirebaseAuthError( AuthClientErrorCode.INVALID_ARGUMENT, @@ -1858,6 +1974,24 @@ export class RecaptchaAuthConfig implements RecaptchaConfig { } } + if (typeof options.phoneEnforcementState !== 'undefined') { + if (!validator.isNonEmptyString(options.phoneEnforcementState)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_ARGUMENT, + '"RecaptchaConfig.phoneEnforcementState" must be a valid non-empty string.', + ); + } + + if (options.phoneEnforcementState !== 'OFF' && + options.phoneEnforcementState !== 'AUDIT' && + options.phoneEnforcementState !== 'ENFORCE') { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"RecaptchaConfig.phoneEnforcementState" must be either "OFF", "AUDIT" or "ENFORCE".', + ); + } + } + if (typeof options.managedRules !== 'undefined') { // Validate array if (!validator.isArray(options.managedRules)) { @@ -1880,6 +2014,38 @@ export class RecaptchaAuthConfig implements RecaptchaConfig { ); } } + + if (typeof options.useSmsBotScore !== 'undefined') { + if (!validator.isBoolean(options.useSmsBotScore)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"RecaptchaConfig.useSmsBotScore" must be a boolean value".', + ); + } + } + + if (typeof options.useSmsTollFraudProtection !== 'undefined') { + if (!validator.isBoolean(options.useSmsTollFraudProtection)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"RecaptchaConfig.useSmsTollFraudProtection" must be a boolean value".', + ); + } + } + + if (typeof options.smsTollFraudManagedRules !== 'undefined') { + // Validate array + if (!validator.isArray(options.smsTollFraudManagedRules)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"RecaptchaConfig.smsTollFraudManagedRules" must be an array of valid "RecaptchaTollFraudManagedRule".', + ); + } + // Validate each rule of the array + options.smsTollFraudManagedRules.forEach((tollFraudManagedRule) => { + RecaptchaAuthConfig.validateTollFraudManagedRule(tollFraudManagedRule); + }); + } } /** @@ -1918,32 +2084,38 @@ export class RecaptchaAuthConfig implements RecaptchaConfig { } /** - * Returns a JSON-serializable representation of this object. - * @returns The JSON-serializable object representation of the ReCaptcha config instance + * Validate each element in TollFraudManagedRule array + * @param options - The options object to validate. */ - public toJSON(): object { - const json: any = { - emailPasswordEnforcementState: this.emailPasswordEnforcementState, - managedRules: deepCopy(this.managedRules), - recaptchaKeys: deepCopy(this.recaptchaKeys), - useAccountDefender: this.useAccountDefender, - } - - if (typeof json.emailPasswordEnforcementState === 'undefined') { - delete json.emailPasswordEnforcementState; + private static validateTollFraudManagedRule(options: RecaptchaTollFraudManagedRule): void { + const validKeys = { + startScore: true, + action: true, } - if (typeof json.managedRules === 'undefined') { - delete json.managedRules; + if (!validator.isNonNullObject(options)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"RecaptchaTollFraudManagedRule" must be a non-null object.', + ); } - if (typeof json.recaptchaKeys === 'undefined') { - delete json.recaptchaKeys; + // Check for unsupported top level attributes. + for (const key in options) { + if (!(key in validKeys)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + `"${key}" is not a valid RecaptchaTollFraudManagedRule parameter.`, + ); + } } - if (typeof json.useAccountDefender === 'undefined') { - delete json.useAccountDefender; + // Validate content. + if (typeof options.action !== 'undefined' && + options.action !== 'BLOCK') { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"RecaptchaTollFraudManagedRule.action" must be "BLOCK".', + ); } - - return json; } } diff --git a/src/auth/index.ts b/src/auth/index.ts index f350b28837..52538eb7d5 100644 --- a/src/auth/index.ts +++ b/src/auth/index.ts @@ -89,6 +89,7 @@ export { RecaptchaKey, RecaptchaKeyClientType, RecaptchaManagedRule, + RecaptchaTollFraudManagedRule, RecaptchaProviderEnforcementState, SAMLAuthProviderConfig, SAMLUpdateAuthProviderRequest, diff --git a/src/auth/project-config.ts b/src/auth/project-config.ts index 250d6549ac..4a40e0c012 100644 --- a/src/auth/project-config.ts +++ b/src/auth/project-config.ts @@ -23,6 +23,7 @@ import { MultiFactorAuthServerConfig, RecaptchaConfig, RecaptchaAuthConfig, + RecaptchaAuthServerConfig, PasswordPolicyAuthConfig, PasswordPolicyAuthServerConfig, PasswordPolicyConfig, @@ -67,7 +68,7 @@ export interface UpdateProjectConfigRequest { export interface ProjectConfigServerResponse { smsRegionConfig?: SmsRegionConfig; mfa?: MultiFactorAuthServerConfig; - recaptchaConfig?: RecaptchaConfig; + recaptchaConfig?: RecaptchaAuthServerConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; emailPrivacyConfig?: EmailPrivacyConfig; } @@ -78,7 +79,7 @@ export interface ProjectConfigServerResponse { export interface ProjectConfigClientRequest { smsRegionConfig?: SmsRegionConfig; mfa?: MultiFactorAuthServerConfig; - recaptchaConfig?: RecaptchaConfig; + recaptchaConfig?: RecaptchaAuthServerConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; emailPrivacyConfig?: EmailPrivacyConfig; } @@ -112,7 +113,12 @@ export class ProjectConfig { * {@link https://cloud.google.com/terms/service-terms | Term of Service}. */ private readonly recaptchaConfig_?: RecaptchaAuthConfig; - + /** + * The reCAPTCHA configuration. + */ + get recaptchaConfig(): RecaptchaConfig | undefined { + return this.recaptchaConfig_; + } /** * The password policy configuration for the project */ @@ -192,7 +198,7 @@ export class ProjectConfig { request.mfa = MultiFactorAuthConfig.buildServerRequest(configOptions.multiFactorConfig); } if (typeof configOptions.recaptchaConfig !== 'undefined') { - request.recaptchaConfig = configOptions.recaptchaConfig; + request.recaptchaConfig = RecaptchaAuthConfig.buildServerRequest(configOptions.recaptchaConfig); } if (typeof configOptions.passwordPolicyConfig !== 'undefined') { request.passwordPolicyConfig = PasswordPolicyAuthConfig.buildServerRequest(configOptions.passwordPolicyConfig); @@ -203,12 +209,6 @@ export class ProjectConfig { return request; } - /** - * The reCAPTCHA configuration. - */ - get recaptchaConfig(): RecaptchaConfig | undefined { - return this.recaptchaConfig_; - } /** * The Project Config object constructor. * @@ -245,7 +245,7 @@ export class ProjectConfig { const json = { smsRegionConfig: deepCopy(this.smsRegionConfig), multiFactorConfig: deepCopy(this.multiFactorConfig), - recaptchaConfig: this.recaptchaConfig_?.toJSON(), + recaptchaConfig: deepCopy(this.recaptchaConfig), passwordPolicyConfig: deepCopy(this.passwordPolicyConfig), emailPrivacyConfig: deepCopy(this.emailPrivacyConfig), }; diff --git a/src/auth/tenant.ts b/src/auth/tenant.ts index 76d97f3259..4b66cace3e 100644 --- a/src/auth/tenant.ts +++ b/src/auth/tenant.ts @@ -21,8 +21,8 @@ import { AuthClientErrorCode, FirebaseAuthError } from '../utils/error'; import { EmailSignInConfig, EmailSignInConfigServerRequest, MultiFactorAuthServerConfig, MultiFactorConfig, validateTestPhoneNumbers, EmailSignInProviderConfig, - MultiFactorAuthConfig, SmsRegionConfig, SmsRegionsAuthConfig, RecaptchaAuthConfig, RecaptchaConfig, - PasswordPolicyConfig, + MultiFactorAuthConfig, SmsRegionConfig, SmsRegionsAuthConfig, RecaptchaAuthConfig, RecaptchaConfig, + RecaptchaAuthServerConfig, PasswordPolicyConfig, PasswordPolicyAuthConfig, PasswordPolicyAuthServerConfig, EmailPrivacyConfig, EmailPrivacyAuthConfig, } from './auth-config'; @@ -92,7 +92,7 @@ export interface TenantOptionsServerRequest extends EmailSignInConfigServerReque mfaConfig?: MultiFactorAuthServerConfig; testPhoneNumbers?: {[key: string]: string}; smsRegionConfig?: SmsRegionConfig; - recaptchaConfig?: RecaptchaConfig; + recaptchaConfig?: RecaptchaAuthServerConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; emailPrivacyConfig?: EmailPrivacyConfig; } @@ -107,7 +107,7 @@ export interface TenantServerResponse { mfaConfig?: MultiFactorAuthServerConfig; testPhoneNumbers?: {[key: string]: string}; smsRegionConfig?: SmsRegionConfig; - recaptchaConfig? : RecaptchaConfig; + recaptchaConfig? : RecaptchaAuthServerConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; emailPrivacyConfig?: EmailPrivacyConfig; } @@ -209,7 +209,7 @@ export class Tenant { request.smsRegionConfig = tenantOptions.smsRegionConfig; } if (typeof tenantOptions.recaptchaConfig !== 'undefined') { - request.recaptchaConfig = tenantOptions.recaptchaConfig; + request.recaptchaConfig = RecaptchaAuthConfig.buildServerRequest(tenantOptions.recaptchaConfig); } if (typeof tenantOptions.passwordPolicyConfig !== 'undefined') { request.passwordPolicyConfig = PasswordPolicyAuthConfig.buildServerRequest(tenantOptions.passwordPolicyConfig); @@ -306,7 +306,7 @@ export class Tenant { } // Validate reCAPTCHAConfig type if provided. if (typeof request.recaptchaConfig !== 'undefined') { - RecaptchaAuthConfig.validate(request.recaptchaConfig); + RecaptchaAuthConfig.buildServerRequest(request.recaptchaConfig); } // Validate passwordPolicyConfig type if provided. if (typeof request.passwordPolicyConfig !== 'undefined') { @@ -400,7 +400,7 @@ export class Tenant { anonymousSignInEnabled: this.anonymousSignInEnabled, testPhoneNumbers: this.testPhoneNumbers, smsRegionConfig: deepCopy(this.smsRegionConfig), - recaptchaConfig: this.recaptchaConfig_?.toJSON(), + recaptchaConfig: deepCopy(this.recaptchaConfig), passwordPolicyConfig: deepCopy(this.passwordPolicyConfig), emailPrivacyConfig: deepCopy(this.emailPrivacyConfig), }; diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 801b51bf80..3ee3468a30 100644 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -32,7 +32,7 @@ import { AuthProviderConfig, CreateTenantRequest, DeleteUsersResult, PhoneMultiFactorInfo, TenantAwareAuth, UpdatePhoneMultiFactorInfoRequest, UpdateTenantRequest, UserImportOptions, UserImportRecord, UserRecord, getAuth, UpdateProjectConfigRequest, UserMetadata, MultiFactorConfig, - PasswordPolicyConfig, SmsRegionConfig, + PasswordPolicyConfig, SmsRegionConfig, RecaptchaConfig, } from '../../lib/auth/index'; import * as sinon from 'sinon'; import * as sinonChai from 'sinon-chai'; @@ -1269,30 +1269,44 @@ describe('admin.auth', () => { allowedRegions: ['AC', 'AD'], } }; + const recaptchaStateAuditConfig: RecaptchaConfig = { + emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', + managedRules: [ + { + endScore: 0.1, + action: 'BLOCK', + }, + ], + useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, + smsTollFraudManagedRules: [ + { + startScore: 0.1, + action: 'BLOCK', + }, + ], + }; + const recaptchaStateOffConfig: RecaptchaConfig = { + emailPasswordEnforcementState: 'OFF', + phoneEnforcementState: 'OFF', + useAccountDefender: false, + useSmsBotScore: false, + useSmsTollFraudProtection: false, + }; const projectConfigOption1: UpdateProjectConfigRequest = { smsRegionConfig: smsRegionAllowByDefaultConfig, multiFactorConfig: mfaSmsEnabledTotpEnabledConfig, passwordPolicyConfig: passwordConfig, - recaptchaConfig: { - emailPasswordEnforcementState: 'AUDIT', - managedRules: [ - { - endScore: 0.1, - action: 'BLOCK', - }, - ], - useAccountDefender: true, - }, + recaptchaConfig: recaptchaStateAuditConfig, emailPrivacyConfig: { enableImprovedEmailPrivacy: true, } }; const projectConfigOption2: UpdateProjectConfigRequest = { smsRegionConfig: smsRegionAllowlistOnlyConfig, - recaptchaConfig: { - emailPasswordEnforcementState: 'OFF', - useAccountDefender: false, - }, + recaptchaConfig: recaptchaStateOffConfig, emailPrivacyConfig: { enableImprovedEmailPrivacy: false, } @@ -1305,48 +1319,44 @@ describe('admin.auth', () => { smsRegionConfig: smsRegionAllowByDefaultConfig, multiFactorConfig: mfaSmsEnabledTotpEnabledConfig, passwordPolicyConfig: passwordConfig, - recaptchaConfig: { - emailPasswordEnforcementState: 'AUDIT', - managedRules: [ - { - endScore: 0.1, - action: 'BLOCK', - }, - ], - useAccountDefender: true, - }, + recaptchaConfig: recaptchaStateAuditConfig, emailPrivacyConfig: { enableImprovedEmailPrivacy: true, }, }; + + const expectedRecaptchaOffConfig: any = { + emailPasswordEnforcementState: 'OFF', + phoneEnforcementState: 'OFF', + managedRules: [ + { + endScore: 0.1, + action: 'BLOCK', + }, + ], + smsTollFraudManagedRules: [ + { + startScore: 0.1, + action: 'BLOCK', + } + ], + useAccountDefender: false, + useSmsBotScore: false, + useSmsTollFraudProtection: false, + }; const expectedProjectConfig2: any = { smsRegionConfig: smsRegionAllowlistOnlyConfig, multiFactorConfig: mfaSmsEnabledTotpEnabledConfig, passwordPolicyConfig: passwordConfig, - recaptchaConfig: { - emailPasswordEnforcementState: 'OFF', - managedRules: [ - { - endScore: 0.1, - action: 'BLOCK', - }, - ], - }, + recaptchaConfig: expectedRecaptchaOffConfig, emailPrivacyConfig: {}, }; + const expectedProjectConfigSmsEnabledTotpDisabled: any = { smsRegionConfig: smsRegionAllowlistOnlyConfig, multiFactorConfig: mfaSmsEnabledTotpDisabledConfig, passwordPolicyConfig: passwordConfig, - recaptchaConfig: { - emailPasswordEnforcementState: 'OFF', - managedRules: [ - { - endScore: 0.1, - action: 'BLOCK', - }, - ], - }, + recaptchaConfig: expectedRecaptchaOffConfig, emailPrivacyConfig: {}, }; @@ -1359,10 +1369,16 @@ describe('admin.auth', () => { return getAuth().projectConfigManager().updateProjectConfig(projectConfigOption2); }) .then((actualProjectConfig) => { + // Existing keys won't be deleted from the response and generated differently each time. + delete actualProjectConfig.recaptchaConfig?.recaptchaKeys; expect(actualProjectConfig.toJSON()).to.deep.equal(expectedProjectConfig2); return getAuth().projectConfigManager().updateProjectConfig(projectConfigOptionSmsEnabledTotpDisabled); }) .then((actualProjectConfig) => { + // Existing keys won't be deleted from the response and generated differently each time. + delete actualProjectConfig.recaptchaConfig?.recaptchaKeys; + // response from backend ignores account defender status when recaptcha status is OFF. + delete expectedProjectConfigSmsEnabledTotpDisabled.recaptchaConfig?.useAccountDefender; expect(actualProjectConfig.toJSON()).to.deep.equal(expectedProjectConfigSmsEnabledTotpDisabled); }); }); @@ -1370,13 +1386,14 @@ describe('admin.auth', () => { it('getProjectConfig() should resolve with expected project config', () => { return getAuth().projectConfigManager().getProjectConfig() .then((actualConfig) => { + delete actualConfig.recaptchaConfig?.recaptchaKeys; const actualConfigObj = actualConfig.toJSON(); expect(actualConfigObj).to.deep.equal(expectedProjectConfigSmsEnabledTotpDisabled); }); }); }); - describe('Tenant management operations', () => { + describe.only('Tenant management operations', () => { let createdTenantId: string; const createdTenants: string[] = []; const mfaSmsEnabledTotpEnabledConfig: MultiFactorConfig = { @@ -1416,6 +1433,32 @@ describe('admin.auth', () => { disallowedRegions: ['AC', 'AD'], } } + const recaptchaStateAuditConfig: RecaptchaConfig = { + emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', + managedRules: [ + { + endScore: 0.1, + action: 'BLOCK', + }, + ], + useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, + smsTollFraudManagedRules: [ + { + startScore: 0.1, + action: 'BLOCK', + }, + ], + } + const recaptchaStateOffConfig: RecaptchaConfig = { + emailPasswordEnforcementState: 'OFF', + phoneEnforcementState: 'OFF', + useAccountDefender: false, + useSmsBotScore: false, + useSmsTollFraudProtection: false, + } const tenantOptions: CreateTenantRequest = { displayName: 'testTenant1', emailSignInConfig: { @@ -1466,18 +1509,28 @@ describe('admin.auth', () => { testPhoneNumbers: { '+16505551234': '123456', }, - recaptchaConfig: { - emailPasswordEnforcementState: 'AUDIT', - managedRules: [ - { - endScore: 0.3, - action: 'BLOCK', - }, - ], - useAccountDefender: true, - }, + recaptchaConfig: recaptchaStateAuditConfig, emailPrivacyConfig: {}, }; + const expectedTenantRecaptchaOffConfig: any = { + emailPasswordEnforcementState: 'OFF', + phoneEnforcementState: 'OFF', + managedRules: [ + { + endScore: 0.1, + action: 'BLOCK', + }, + ], + smsTollFraudManagedRules: [ + { + startScore: 0.1, + action: 'BLOCK', + } + ], + useAccountDefender: false, + useSmsBotScore: false, + useSmsTollFraudProtection: false, + }; const expectedUpdatedTenant2: any = { displayName: 'testTenantUpdated', emailSignInConfig: { @@ -1487,16 +1540,7 @@ describe('admin.auth', () => { anonymousSignInEnabled: false, multiFactorConfig: mfaSmsEnabledTotpEnabledConfig, smsRegionConfig: smsRegionAllowByDefaultConfig, - recaptchaConfig: { - emailPasswordEnforcementState: 'OFF', - managedRules: [ - { - endScore: 0.3, - action: 'BLOCK', - }, - ], - useAccountDefender: false, - }, + recaptchaConfig: recaptchaStateOffConfig, emailPrivacyConfig: {}, }; const expectedUpdatedTenantSmsEnabledTotpDisabled: any = { @@ -1508,16 +1552,7 @@ describe('admin.auth', () => { anonymousSignInEnabled: false, multiFactorConfig: mfaSmsEnabledTotpDisabledConfig, smsRegionConfig: smsRegionAllowByDefaultConfig, - recaptchaConfig: { - emailPasswordEnforcementState: 'OFF', - managedRules: [ - { - endScore: 0.3, - action: 'BLOCK', - }, - ], - useAccountDefender: false, - }, + recaptchaConfig: recaptchaStateOffConfig, emailPrivacyConfig: {}, }; @@ -1972,9 +2007,8 @@ describe('admin.auth', () => { return getAuth().tenantManager().updateTenant(createdTenantId, updatedOptions2); }) .then((actualTenant) => { - // response from backend ignores account defender status is recaptcha status is OFF. const expectedUpdatedTenantCopy = deepCopy(expectedUpdatedTenant2); - delete expectedUpdatedTenantCopy.recaptchaConfig.useAccountDefender; + expectedUpdatedTenantCopy.recaptchaConfig = deepCopy(expectedTenantRecaptchaOffConfig); expect(actualTenant.toJSON()).to.deep.equal(expectedUpdatedTenantCopy); }); }); @@ -1999,6 +2033,7 @@ describe('admin.auth', () => { .then((actualTenant) => { // response from backend ignores account defender status is recaptcha status is OFF. const expectedUpdatedTenantCopy = deepCopy(expectedUpdatedTenant2); + expectedUpdatedTenantCopy.recaptchaConfig = deepCopy(expectedTenantRecaptchaOffConfig); delete expectedUpdatedTenantCopy.recaptchaConfig.useAccountDefender; expect(actualTenant.toJSON()).to.deep.equal(expectedUpdatedTenantCopy); }); @@ -2043,6 +2078,7 @@ describe('admin.auth', () => { .then((actualTenant) => { // response from backend ignores account defender status is recaptcha status is OFF. const expectedUpdatedTenantCopy = deepCopy(expectedUpdatedTenant2); + expectedUpdatedTenantCopy.recaptchaConfig = deepCopy(expectedTenantRecaptchaOffConfig); delete expectedUpdatedTenantCopy.recaptchaConfig.useAccountDefender; expect(actualTenant.toJSON()).to.deep.equal(expectedUpdatedTenantCopy); }); @@ -2076,6 +2112,7 @@ describe('admin.auth', () => { .then((actualTenant) => { // response from backend ignores account defender status is recaptcha status is OFF. const expectedUpdatedTenantCopy = deepCopy(expectedUpdatedTenantSmsEnabledTotpDisabled); + expectedUpdatedTenantCopy.recaptchaConfig = deepCopy(expectedTenantRecaptchaOffConfig); delete expectedUpdatedTenantCopy.recaptchaConfig.useAccountDefender; expect(actualTenant.toJSON()).to.deep.equal(expectedUpdatedTenantCopy); }); diff --git a/test/unit/auth/project-config.spec.ts b/test/unit/auth/project-config.spec.ts index 5934dd15fd..f116647568 100644 --- a/test/unit/auth/project-config.spec.ts +++ b/test/unit/auth/project-config.spec.ts @@ -20,7 +20,6 @@ import * as sinonChai from 'sinon-chai'; import * as chaiAsPromised from 'chai-as-promised'; import { deepCopy } from '../../../src/utils/deep-copy'; -import { RecaptchaAuthConfig } from '../../../src/auth/auth-config'; import { ProjectConfig, ProjectConfigServerResponse, @@ -70,6 +69,25 @@ describe('ProjectConfig', () => { emailPrivacyConfig: { enableImprovedEmailPrivacy: true, }, + recaptchaConfig: { + emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', + managedRules: [ { + endScore: 0.2, + action: 'BLOCK' + } ], + tollFraudManagedRules: [ { + startScore: 0.1, + action: 'BLOCK' + } ], + recaptchaKeys: [ { + type: 'WEB', + key: 'test-key-1' } + ], + useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, + } }; const updateProjectConfigRequest1: UpdateProjectConfigRequest = { @@ -114,26 +132,40 @@ describe('ProjectConfig', () => { }, recaptchaConfig: { emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', managedRules: [ { endScore: 0.2, action: 'BLOCK' } ], + tollFraudManagedRules: [ { + startScore: 0.1, + action: 'BLOCK' + } ], recaptchaKeys: [ { type: 'WEB', key: 'test-key-1' } ], useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, } }; - const updateProjectConfigRequest: UpdateProjectConfigRequest = { + const updateProjectConfigRequest4: UpdateProjectConfigRequest = { recaptchaConfig: { emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', managedRules: [ { endScore: 0.2, action: 'BLOCK' } ], + smsTollFraudManagedRules: [ { + startScore: 0.1, + action: 'BLOCK' + } ], useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, } }; @@ -206,7 +238,7 @@ describe('ProjectConfig', () => { }).not.to.throw; }); it('should throw on null RecaptchaConfig attribute', () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.recaptchaConfig = null; expect(() => { ProjectConfig.buildServerRequest(configOptionsClientRequest); @@ -214,15 +246,32 @@ describe('ProjectConfig', () => { }); it('should throw on invalid RecaptchaConfig attribute', () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.recaptchaConfig.invalidParameter = 'invalid'; expect(() => { ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"invalidParameter" is not a valid RecaptchaConfig parameter.'); }); + it('should throw on null phoneEnforcementState attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; + configOptionsClientRequest.recaptchaConfig.phoneEnforcementState = null; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"RecaptchaConfig.phoneEnforcementState" must be a valid non-empty string.'); + }); + + it('should throw on invalid phoneEnforcementState attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; + configOptionsClientRequest.recaptchaConfig + .phoneEnforcementState = 'INVALID'; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"RecaptchaConfig.phoneEnforcementState" must be either "OFF", "AUDIT" or "ENFORCE".'); + }); + it('should throw on null emailPasswordEnforcementState attribute', () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.recaptchaConfig.emailPasswordEnforcementState = null; expect(() => { ProjectConfig.buildServerRequest(configOptionsClientRequest); @@ -230,7 +279,7 @@ describe('ProjectConfig', () => { }); it('should throw on invalid emailPasswordEnforcementState attribute', () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.recaptchaConfig .emailPasswordEnforcementState = 'INVALID'; expect(() => { @@ -241,16 +290,39 @@ describe('ProjectConfig', () => { const invalidUseAccountDefender = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; invalidUseAccountDefender.forEach((useAccountDefender) => { it(`should throw given invalid useAccountDefender parameter: ${JSON.stringify(useAccountDefender)}`, () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.recaptchaConfig.useAccountDefender = useAccountDefender; expect(() => { ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"RecaptchaConfig.useAccountDefender" must be a boolean value".'); }); }); + + const invalidUseSmsBotScore = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; + invalidUseSmsBotScore.forEach((useSmsBotScore) => { + it(`should throw given invalid useSmsBotScore parameter: ${JSON.stringify(useSmsBotScore)}`, () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; + configOptionsClientRequest.recaptchaConfig.useSmsBotScore = useSmsBotScore; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"RecaptchaConfig.useSmsBotScore" must be a boolean value".'); + }); + }); + + const invalidUseSmsTollFraudProtection = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; + invalidUseSmsTollFraudProtection.forEach((useSmsTollFraudProtection) => { + it(`should throw given invalid useSmsTollFraudProtection parameter: ' + + '${JSON.stringify(useSmsTollFraudProtection)}`, () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; + configOptionsClientRequest.recaptchaConfig.useSmsTollFraudProtection = useSmsTollFraudProtection; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"RecaptchaConfig.useSmsTollFraudProtection" must be a boolean value".'); + }); + }); it('should throw on non-array managedRules attribute', () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.recaptchaConfig.managedRules = 'non-array'; expect(() => { ProjectConfig.buildServerRequest(configOptionsClientRequest); @@ -258,7 +330,7 @@ describe('ProjectConfig', () => { }); it('should throw on invalid managedRules attribute', () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.recaptchaConfig.managedRules = [{ 'score': 0.1, 'action': 'BLOCK' }]; expect(() => { @@ -267,13 +339,40 @@ describe('ProjectConfig', () => { }); it('should throw on invalid RecaptchaManagedRule.action attribute', () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.recaptchaConfig.managedRules = [{ 'endScore': 0.1, 'action': 'ALLOW' }]; expect(() => { ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"RecaptchaManagedRule.action" must be "BLOCK".'); }); + + it('should throw on non-array smsTollFraudManagedRules attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; + configOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = 'non-array'; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"RecaptchaConfig.smsTollFraudManagedRules" must be an array of valid ' + + '"RecaptchaTollFraudManagedRule".'); + }); + + it('should throw on invalid smsTollFraudManagedRules attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; + configOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = + [{ 'score': 0.1, 'action': 'BLOCK' }]; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"score" is not a valid RecaptchaTollFraudManagedRule parameter.'); + }); + + it('should throw on invalid RecaptchaManagedRule.action attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; + configOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = + [{ 'startScore': 0.1, 'action': 'ALLOW' }]; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"RecaptchaTollFraudManagedRule.action" must be "BLOCK".'); + }); it('should throw on null PasswordPolicyConfig attribute', () => { const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; @@ -284,145 +383,145 @@ describe('ProjectConfig', () => { }); it('should throw on invalid PasswordPolicyConfig attribute', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.invalidParameter = 'invalid', + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.invalidParameter = 'invalid', expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"invalidParameter" is not a valid PasswordPolicyConfig parameter.'); }); it('should throw on missing enforcementState', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - delete tenantOptionsClientRequest.passwordPolicyConfig.enforcementState; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + delete configOptionsClientRequest.passwordPolicyConfig.enforcementState; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.enforcementState" must be either "ENFORCE" or "OFF".'); }); it('should throw on invalid enforcementState', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.enforcementState = 'INVALID_STATE'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.enforcementState = 'INVALID_STATE'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.enforcementState" must be either "ENFORCE" or "OFF".'); }); it('should throw on invalid forceUpgradeOnSignin', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.forceUpgradeOnSignin = 'INVALID'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.forceUpgradeOnSignin = 'INVALID'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.forceUpgradeOnSignin" must be a boolean.'); }); it('should throw on undefined constraints when state is enforced', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - delete tenantOptionsClientRequest.passwordPolicyConfig.constraints; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + delete configOptionsClientRequest.passwordPolicyConfig.constraints; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints" must be defined.'); }); it('should throw on invalid constraints attribute', ()=> { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.invalidParameter = 'invalid'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.invalidParameter = 'invalid'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"invalidParameter" is not a valid PasswordPolicyConfig.constraints parameter.'); }); it('should throw on null constraints object', ()=> { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints = null; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints = null; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints" must be a non-empty object.'); }); it('should throw on invalid constraints object', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints = 'invalid'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints = 'invalid'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints" must be a non-empty object.'); }); it('should throw on invalid uppercase type', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.requireUppercase = 'invalid'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.requireUppercase = 'invalid'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.requireUppercase"' + ' must be a boolean.'); }); it('should throw on invalid lowercase type', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.requireLowercase = 'invalid'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.requireLowercase = 'invalid'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.requireLowercase"' + ' must be a boolean.'); }); it('should throw on invalid numeric type', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.requireNumeric = 'invalid'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.requireNumeric = 'invalid'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.requireNumeric"' + ' must be a boolean.'); }); it('should throw on invalid non-alphanumeric type', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.requireNonAlphanumeric = 'invalid'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.requireNonAlphanumeric = 'invalid'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.requireNonAlphanumeric"' + ' must be a boolean.'); }); it('should throw on invalid minLength type', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.minLength = 'invalid'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.minLength = 'invalid'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.minLength" must be a number.'); }); it('should throw on invalid maxLength type', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.maxLength = 'invalid'; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.maxLength = 'invalid'; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.maxLength" must be a number.'); }); it('should throw on invalid minLength range', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.minLength = 45; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.minLength = 45; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.minLength"' + ' must be an integer between 6 and 30, inclusive.'); }); it('should throw on invalid maxLength range', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.maxLength = 5000; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.maxLength = 5000; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.maxLength"' + ' must be greater than or equal to minLength and at max 4096.'); }); it('should throw if minLength is greater than maxLength', () => { - const tenantOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.minLength = 20; - tenantOptionsClientRequest.passwordPolicyConfig.constraints.maxLength = 7; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.passwordPolicyConfig.constraints.minLength = 20; + configOptionsClientRequest.passwordPolicyConfig.constraints.maxLength = 7; expect(() => { - ProjectConfig.buildServerRequest(tenantOptionsClientRequest); + ProjectConfig.buildServerRequest(configOptionsClientRequest); }).to.throw('"PasswordPolicyConfig.constraints.maxLength"' + ' must be greater than or equal to minLength and at max 4096.'); }); @@ -461,7 +560,7 @@ describe('ProjectConfig', () => { }); it('should throw on unsupported attribute for update request', () => { - const configOptionsClientRequest = deepCopy(updateProjectConfigRequest) as any; + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest4) as any; configOptionsClientRequest.unsupported = 'value'; expect(() => { ProjectConfig.buildServerRequest(configOptionsClientRequest); @@ -490,6 +589,7 @@ describe('ProjectConfig', () => { it('should set readonly property multiFactorConfig', () => { const expectedMultiFactorConfig = { state: 'DISABLED', + factorIds: [], providerConfigs: [ { state: 'ENABLED', @@ -503,20 +603,25 @@ describe('ProjectConfig', () => { }); it('should set readonly property recaptchaConfig', () => { - const expectedRecaptchaConfig = new RecaptchaAuthConfig( - { - emailPasswordEnforcementState: 'AUDIT', - managedRules: [ { - endScore: 0.2, - action: 'BLOCK' - } ], - recaptchaKeys: [ { - type: 'WEB', - key: 'test-key-1' } - ], - useAccountDefender: true, - } - ); + const expectedRecaptchaConfig = { + emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', + managedRules: [ { + endScore: 0.2, + action: 'BLOCK' + } ], + smsTollFraudManagedRules: [ { + startScore: 0.1, + action: 'BLOCK' + } ], + recaptchaKeys: [ { + type: 'WEB', + key: 'test-key-1' } + ], + useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, + }; expect(projectConfig.recaptchaConfig).to.deep.equal(expectedRecaptchaConfig); }); @@ -548,11 +653,57 @@ describe('ProjectConfig', () => { const serverResponseCopy: ProjectConfigServerResponse = deepCopy(serverResponse); it('should return the expected object representation of project config', () => { expect(new ProjectConfig(serverResponseCopy).toJSON()).to.deep.equal({ - smsRegionConfig: deepCopy(serverResponse.smsRegionConfig), - multiFactorConfig: deepCopy(serverResponse.mfa), - recaptchaConfig: deepCopy(serverResponse.recaptchaConfig), - passwordPolicyConfig: deepCopy(serverResponse.passwordPolicyConfig), - emailPrivacyConfig: deepCopy(serverResponse.emailPrivacyConfig), + smsRegionConfig: { + allowByDefault: { + disallowedRegions: [ 'AC', 'AD' ], + }, + }, + multiFactorConfig: { + state: 'DISABLED', + factorIds: [], + providerConfigs: [ + { + state: 'ENABLED', + totpProviderConfig: { + adjacentIntervals: 5, + }, + }, + ], + }, + recaptchaConfig: { + emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', + managedRules: [ { + endScore: 0.2, + action: 'BLOCK' + } ], + smsTollFraudManagedRules: [ { + startScore: 0.1, + action: 'BLOCK' + } ], + recaptchaKeys: [ { + type: 'WEB', + key: 'test-key-1' } + ], + useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, + }, + passwordPolicyConfig: { + enforcementState: 'ENFORCE', + forceUpgradeOnSignin: true, + constraints: { + requireLowercase: true, + requireNonAlphanumeric: true, + requireNumeric: true, + requireUppercase: true, + minLength: 8, + maxLength: 30, + }, + }, + emailPrivacyConfig: { + enableImprovedEmailPrivacy: true, + }, }); }); @@ -563,7 +714,10 @@ describe('ProjectConfig', () => { delete serverResponseOptionalCopy.recaptchaConfig?.emailPasswordEnforcementState; delete serverResponseOptionalCopy.recaptchaConfig?.managedRules; delete serverResponseOptionalCopy.recaptchaConfig?.useAccountDefender; - delete serverResponseOptionalCopy.passwordPolicyConfig; + delete serverResponseOptionalCopy.recaptchaConfig?.useSmsBotScore; + delete serverResponseOptionalCopy.recaptchaConfig?.phoneEnforcementState; + delete serverResponseOptionalCopy.recaptchaConfig?.tollFraudManagedRules; + delete serverResponseOptionalCopy.recaptchaConfig?.useSmsTollFraudProtection delete serverResponseOptionalCopy.passwordPolicyConfig; delete serverResponseOptionalCopy.emailPrivacyConfig; expect(new ProjectConfig(serverResponseOptionalCopy).toJSON()).to.deep.equal({ diff --git a/test/unit/auth/tenant.spec.ts b/test/unit/auth/tenant.spec.ts index e1006e47b7..05c8bbf6aa 100644 --- a/test/unit/auth/tenant.spec.ts +++ b/test/unit/auth/tenant.spec.ts @@ -172,12 +172,24 @@ describe('Tenant', () => { '+16505550676': '985235', }, recaptchaConfig: { - managedRules: [{ + emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', + recaptchaKeys: [ { + key: 'test-key-1', + type: 'WEB' + } + ], + managedRules: [ { endScore: 0.2, action: 'BLOCK' - }], - emailPasswordEnforcementState: 'AUDIT', + } ], + smsTollFraudManagedRules: [ { + startScore: 0.1, + action: 'BLOCK' + } ], useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, }, }; @@ -204,15 +216,22 @@ describe('Tenant', () => { }, recaptchaConfig: { emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', managedRules: [ { endScore: 0.2, action: 'BLOCK' } ], + tollFraudManagedRules: [ { + startScore: 0.1, + action: 'BLOCK' + } ], recaptchaKeys: [ { type: 'WEB', key: 'test-key-1' } ], useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, }, smsRegionConfig: smsAllowByDefault, passwordPolicyConfig: passwordPolicyServerConfig, @@ -297,39 +316,107 @@ describe('Tenant', () => { }).to.throw('"RecaptchaConfig.emailPasswordEnforcementState" must be either "OFF", "AUDIT" or "ENFORCE".'); }); - it('should throw on non-array managedRules attribute', () => { + it('should throw on null phoneEnforcementState attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; - tenantOptionsClientRequest.recaptchaConfig.managedRules = 'non-array'; + tenantOptionsClientRequest.recaptchaConfig.phoneEnforcementState = null; expect(() => { Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); - }).to.throw('"RecaptchaConfig.managedRules" must be an array of valid "RecaptchaManagedRule".'); + }).to.throw('"RecaptchaConfig.phoneEnforcementState" must be a valid non-empty string.'); }); - it('should throw on non-boolean useAccountDefender attribute', () => { + it('should throw on invalid phoneEnforcementState attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; - tenantOptionsClientRequest.recaptchaConfig.useAccountDefender = 'yes'; + tenantOptionsClientRequest.recaptchaConfig + .phoneEnforcementState = 'INVALID'; expect(() => { Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); - }).to.throw('"RecaptchaConfig.useAccountDefender" must be a boolean value".'); + }).to.throw('"RecaptchaConfig.phoneEnforcementState" must be either "OFF", "AUDIT" or "ENFORCE".'); }); + + const invalidUseAccountDefender = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; + invalidUseAccountDefender.forEach((useAccountDefender) => { + it(`should throw given invalid useAccountDefender parameter: ${JSON.stringify(useAccountDefender)}`, () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.useAccountDefender = useAccountDefender; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"RecaptchaConfig.useAccountDefender" must be a boolean value".'); + }); + }); + + const invalidUseSmsBotScore = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; + invalidUseSmsBotScore.forEach((useSmsBotScore) => { + it(`should throw given invalid useSmsBotScore parameter: ${JSON.stringify(useSmsBotScore)}`, () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.useSmsBotScore = useSmsBotScore; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"RecaptchaConfig.useSmsBotScore" must be a boolean value".'); + }); + }); + + const invalidUseSmsTollFraudProtection = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; + invalidUseSmsTollFraudProtection.forEach((useSmsTollFraudProtection) => { + it(`should throw given invalid useSmsTollFraudProtection parameter:' + + '${JSON.stringify(useSmsTollFraudProtection)}`, () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.useSmsTollFraudProtection = useSmsTollFraudProtection; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"RecaptchaConfig.useSmsTollFraudProtection" must be a boolean value".'); + }); + }); + + it('should throw on non-array managedRules attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.managedRules = 'non-array'; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"RecaptchaConfig.managedRules" must be an array of valid "RecaptchaManagedRule".'); + }); + it('should throw on invalid managedRules attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; - tenantOptionsClientRequest.recaptchaConfig.managedRules = - [{ 'score': 0.1, 'action': 'BLOCK' }]; + tenantOptionsClientRequest.recaptchaConfig.managedRules = [{ 'score': 0.1, 'action': 'BLOCK' }]; expect(() => { Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); }).to.throw('"score" is not a valid RecaptchaManagedRule parameter.'); }); - + it('should throw on invalid RecaptchaManagedRule.action attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; - tenantOptionsClientRequest.recaptchaConfig.managedRules = - [{ 'endScore': 0.1, 'action': 'ALLOW' }]; + tenantOptionsClientRequest.recaptchaConfig.managedRules = [{ 'endScore': 0.1, 'action': 'ALLOW' }]; expect(() => { Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); }).to.throw('"RecaptchaManagedRule.action" must be "BLOCK".'); }); + + it('should throw on non-array smsTollFraudManagedRules attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = 'non-array'; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"RecaptchaConfig.smsTollFraudManagedRules" must be an array of valid '+ + '"RecaptchaTollFraudManagedRule".'); + }); + + it('should throw on invalid tollFraudManagedRules attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = [{ 'score': 0.1, 'action': 'BLOCK' }]; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"score" is not a valid RecaptchaTollFraudManagedRule parameter.'); + }); + + it('should throw on invalid RecaptchaTollFraudManagedRule.action attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = + [{ 'startScore': 0.1, 'action': 'ALLOW' }]; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, !createRequest); + }).to.throw('"RecaptchaTollFraudManagedRule.action" must be "BLOCK".'); + }); it('should throw on invalid testPhoneNumbers attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequest) as any; @@ -688,17 +775,26 @@ describe('Tenant', () => { }).to.throw('"RecaptchaConfig.emailPasswordEnforcementState" must be either "OFF", "AUDIT" or "ENFORCE".'); }); - it('should throw on non-array managedRules attribute', () => { + it('should throw on null phoneEnforcementState attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; - tenantOptionsClientRequest.recaptchaConfig.managedRules = 'non-array'; + tenantOptionsClientRequest.recaptchaConfig.phoneEnforcementState = null; expect(() => { Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); - }).to.throw('"RecaptchaConfig.managedRules" must be an array of valid "RecaptchaManagedRule".'); + }).to.throw('"RecaptchaConfig.phoneEnforcementState" must be a valid non-empty string.'); }); + it('should throw on invalid phoneEnforcementState attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig + .phoneEnforcementState = 'INVALID'; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"RecaptchaConfig.phoneEnforcementState" must be either "OFF", "AUDIT" or "ENFORCE".'); + }); + const invalidUseAccountDefender = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; invalidUseAccountDefender.forEach((useAccountDefender) => { - it('should throw on non-boolean useAccountDefender attribute', () => { + it(`should throw given invalid useAccountDefender parameter: ${JSON.stringify(useAccountDefender)}`, () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; tenantOptionsClientRequest.recaptchaConfig.useAccountDefender = useAccountDefender; expect(() => { @@ -706,24 +802,80 @@ describe('Tenant', () => { }).to.throw('"RecaptchaConfig.useAccountDefender" must be a boolean value".'); }); }); + + const invalidUseSmsBotScore = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; + invalidUseSmsBotScore.forEach((useSmsBotScore) => { + it(`should throw given invalid useSmsBotScore parameter: ${JSON.stringify(useSmsBotScore)}`, () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.useSmsBotScore = useSmsBotScore; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"RecaptchaConfig.useSmsBotScore" must be a boolean value".'); + }); + }); + + const invalidUseSmsTollFraudProtection = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; + invalidUseSmsTollFraudProtection.forEach((useSmsTollFraudProtection) => { + it(`should throw given invalid useSmsTollFraudProtection parameter:' + + ' ${JSON.stringify(useSmsTollFraudProtection)}`, () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.useSmsTollFraudProtection = useSmsTollFraudProtection; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"RecaptchaConfig.useSmsTollFraudProtection" must be a boolean value".'); + }); + }); + + it('should throw on non-array managedRules attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.managedRules = 'non-array'; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"RecaptchaConfig.managedRules" must be an array of valid "RecaptchaManagedRule".'); + }); + it('should throw on invalid managedRules attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; - tenantOptionsClientRequest.recaptchaConfig.managedRules = - [{ 'score': 0.1, 'action': 'BLOCK' }]; + tenantOptionsClientRequest.recaptchaConfig.managedRules = [{ 'score': 0.1, 'action': 'BLOCK' }]; expect(() => { Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); }).to.throw('"score" is not a valid RecaptchaManagedRule parameter.'); }); - + it('should throw on invalid RecaptchaManagedRule.action attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; - tenantOptionsClientRequest.recaptchaConfig.managedRules = - [{ 'endScore': 0.1, 'action': 'ALLOW' }]; + tenantOptionsClientRequest.recaptchaConfig.managedRules = [{ 'endScore': 0.1, 'action': 'ALLOW' }]; expect(() => { Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); }).to.throw('"RecaptchaManagedRule.action" must be "BLOCK".'); }); + + it('should throw on non-array smsTollFraudManagedRules attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = 'non-array'; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"RecaptchaConfig.smsTollFraudManagedRules" must be an array of valid' + + ' "RecaptchaTollFraudManagedRule".'); + }); + + it('should throw on invalid smsTollFraudManagedRules attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = [{ 'score': 0.1, 'action': 'BLOCK' }]; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"score" is not a valid RecaptchaTollFraudManagedRule parameter.'); + }); + + it('should throw on invalid RecaptchaTollFraudManagedRule.action attribute', () => { + const tenantOptionsClientRequest = deepCopy(clientRequestWithRecaptcha) as any; + tenantOptionsClientRequest.recaptchaConfig.smsTollFraudManagedRules = + [{ 'startScore': 0.1, 'action': 'ALLOW' }]; + expect(() => { + Tenant.buildServerRequest(tenantOptionsClientRequest, createRequest); + }).to.throw('"RecaptchaTollFraudManagedRule.action" must be "BLOCK".'); + }); it('should throw on invalid testPhoneNumbers attribute', () => { const tenantOptionsClientRequest = deepCopy(clientRequest) as any; @@ -1070,15 +1222,22 @@ describe('Tenant', () => { const tenantWithRecaptcha = new Tenant(serverRequestWithRecaptchaCopy); const expectedRecaptchaConfig = new RecaptchaAuthConfig({ emailPasswordEnforcementState: 'AUDIT', + phoneEnforcementState: 'AUDIT', managedRules: [{ endScore: 0.2, action: 'BLOCK' }], + tollFraudManagedRules: [{ + startScore: 0.1, + action: 'BLOCK', + }], recaptchaKeys: [ { type: 'WEB', key: 'test-key-1' } ], useAccountDefender: true, + useSmsBotScore: true, + useSmsTollFraudProtection: true, }); expect(tenantWithRecaptcha.recaptchaConfig).to.deep.equal(expectedRecaptchaConfig); }); @@ -1144,7 +1303,7 @@ describe('Tenant', () => { multiFactorConfig: deepCopy(clientRequest.multiFactorConfig), testPhoneNumbers: deepCopy(clientRequest.testPhoneNumbers), smsRegionConfig: deepCopy(clientRequest.smsRegionConfig), - recaptchaConfig: deepCopy(serverResponseWithRecaptcha.recaptchaConfig), + recaptchaConfig: deepCopy(clientRequestWithRecaptcha.recaptchaConfig), passwordPolicyConfig: deepCopy(clientRequest.passwordPolicyConfig), emailPrivacyConfig: deepCopy(clientRequest.emailPrivacyConfig), }); From 032f2da2ba3c37e7b8f44c05511d6c51e4b9d689 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 23 Oct 2024 13:34:18 -0400 Subject: [PATCH 189/323] chore: fix dataconnect integration tests (#2736) --- test/integration/data-connect.spec.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/test/integration/data-connect.spec.ts b/test/integration/data-connect.spec.ts index 91179c12e3..32ea83cb87 100644 --- a/test/integration/data-connect.spec.ts +++ b/test/integration/data-connect.spec.ts @@ -23,6 +23,22 @@ chai.use(chaiAsPromised); const expect = chai.expect; +/* +// Schema +type User @table(key: "uid") { + uid: String! + name: String! + address: String! +} + +type Email @table { + subject: String! + date: Date! + text: String! + from: User! +} +*/ + interface UserResponse { user: { name: string; @@ -59,7 +75,7 @@ interface EmailsResponse { } interface UserVariables { - id: string; + id: { uid: string }; } const connectorConfig: ConnectorConfig = { @@ -117,7 +133,7 @@ describe('getDataConnect()', () => { it('executeGraphql() successfully executes a GraphQL query with variables', async () => { const resp = await getDataConnect(connectorConfig).executeGraphql( queryGetUserById, - { variables: { id: userId } } + { variables: { id: { uid: userId } } } ); expect(resp.data.user.name).to.be.not.undefined; expect(resp.data.user.uid).equals(userId); From 0d21e944355d88943ccc197227c978c5970e0690 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 23 Oct 2024 13:44:42 -0400 Subject: [PATCH 190/323] chore: Update auth.spec.ts (#2737) - Remove an accidental `describe.only(...` tag that went in #2625 --- test/integration/auth.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 3ee3468a30..8a6374363d 100644 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -1393,7 +1393,7 @@ describe('admin.auth', () => { }); }); - describe.only('Tenant management operations', () => { + describe('Tenant management operations', () => { let createdTenantId: string; const createdTenants: string[] = []; const mfaSmsEnabledTotpEnabledConfig: MultiFactorConfig = { From 4818109126279993b6dd1bdd5fb33994be5e608c Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:37:48 -0400 Subject: [PATCH 191/323] chore: Add `X-Goog-Api-Client` metric header to Auth and FCM requests (#2738) * [chore] Add `X-Goog-Api-Client` metric header to Auth and FCM requests * trigger integration tests --- src/auth/auth-api-request.ts | 5 +++-- src/messaging/messaging-api-request-internal.ts | 2 ++ test/unit/auth/auth-api-request.spec.ts | 2 ++ test/unit/messaging/messaging.spec.ts | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 65dd04b806..3d782fb775 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -45,8 +45,9 @@ import { import { ProjectConfig, ProjectConfigServerResponse, UpdateProjectConfigRequest } from './project-config'; /** Firebase Auth request header. */ -const FIREBASE_AUTH_HEADER = { +const FIREBASE_AUTH_HEADERS = { 'X-Client-Version': `Node/Admin/${utils.getSdkVersion()}`, + 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${utils.getSdkVersion()}` }; /** Firebase Auth request timeout duration in milliseconds. */ const FIREBASE_AUTH_TIMEOUT = 25000; @@ -1919,7 +1920,7 @@ export abstract class AbstractAuthRequestHandler { const req: HttpRequestConfig = { method: apiSettings.getHttpMethod(), url, - headers: FIREBASE_AUTH_HEADER, + headers: FIREBASE_AUTH_HEADERS, data: requestData, timeout: FIREBASE_AUTH_TIMEOUT, }; diff --git a/src/messaging/messaging-api-request-internal.ts b/src/messaging/messaging-api-request-internal.ts index db1aabcc52..4af320f20c 100644 --- a/src/messaging/messaging-api-request-internal.ts +++ b/src/messaging/messaging-api-request-internal.ts @@ -33,9 +33,11 @@ const FIREBASE_MESSAGING_BATCH_URL = 'https://fcm.googleapis.com/batch'; const FIREBASE_MESSAGING_HTTP_METHOD: HttpMethod = 'POST'; const FIREBASE_MESSAGING_HEADERS = { 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}` }; const LEGACY_FIREBASE_MESSAGING_HEADERS = { 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, 'access_token_auth': 'true', }; diff --git a/test/unit/auth/auth-api-request.spec.ts b/test/unit/auth/auth-api-request.spec.ts index 4a2f4078be..8abbc80247 100644 --- a/test/unit/auth/auth-api-request.spec.ts +++ b/test/unit/auth/auth-api-request.spec.ts @@ -863,10 +863,12 @@ AUTH_REQUEST_HANDLER_TESTS.forEach((handler) => { const mockAccessToken: string = utils.generateRandomAccessToken(); const expectedHeaders: {[key: string]: string} = { 'X-Client-Version': `Node/Admin/${getSdkVersion()}`, + 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, 'Authorization': 'Bearer ' + mockAccessToken, }; const expectedHeadersEmulator: {[key: string]: string} = { 'X-Client-Version': `Node/Admin/${getSdkVersion()}`, + 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, 'Authorization': 'Bearer owner', }; const callParams = (path: string, method: any, data: any): HttpRequestConfig => { diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index a56767c123..a391dceb28 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -357,6 +357,7 @@ describe('Messaging', () => { const expectedHeaders = { 'Authorization': 'Bearer ' + mockAccessToken, 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, 'access_token_auth': 'true', }; const emptyResponse = utils.responseFrom({}); From 0455f797445f0c10098fd2f1cf18bd3c1bd6003f Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 23 Oct 2024 16:24:54 -0400 Subject: [PATCH 192/323] fix: Pin `@firebase/database-compat` to `v1.0.8` (#2739) * Update package.json * add package-lock file --- package-lock.json | 11369 +++++++++++++++++++++++++++++++++++++++++++- package.json | 4 +- 2 files changed, 11266 insertions(+), 107 deletions(-) diff --git a/package-lock.json b/package-lock.json index e9f4ce94b4..2b6f973089 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,11160 @@ { "name": "firebase-admin", "version": "12.6.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "firebase-admin", + "version": "12.6.0", + "license": "Apache-2.0", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@firebase/database-compat": "1.0.8", + "@firebase/database-types": "1.0.5", + "@types/node": "^22.0.1", + "farmhash-modern": "^1.1.0", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.1.0", + "node-forge": "^1.3.1", + "uuid": "^10.0.0" + }, + "devDependencies": { + "@firebase/api-documenter": "^0.4.0", + "@firebase/app-compat": "^0.2.1", + "@firebase/auth-compat": "^0.4.1", + "@firebase/auth-types": "^0.12.0", + "@microsoft/api-extractor": "^7.11.2", + "@types/bcrypt": "^5.0.0", + "@types/chai": "^4.0.0", + "@types/chai-as-promised": "^7.1.0", + "@types/firebase-token-generator": "^2.0.28", + "@types/jsonwebtoken": "8.5.1", + "@types/lodash": "^4.14.104", + "@types/minimist": "^1.2.2", + "@types/mocha": "^10.0.0", + "@types/nock": "^11.1.0", + "@types/request": "^2.47.0", + "@types/request-promise": "^4.1.41", + "@types/sinon": "^17.0.2", + "@types/sinon-chai": "^3.0.0", + "@types/uuid": "^10.0.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "bcrypt": "^5.0.0", + "chai": "^4.2.0", + "chai-as-promised": "^7.0.0", + "chai-exclude": "^2.1.0", + "chalk": "^4.1.1", + "child-process-promise": "^2.2.1", + "del": "^6.0.0", + "eslint": "^8.12.0", + "firebase-token-generator": "^2.0.0", + "gulp": "^5.0.0", + "gulp-filter": "^7.0.0", + "gulp-header": "^2.0.9", + "gulp-typescript": "^5.0.1", + "http-message-parser": "^0.0.34", + "lodash": "^4.17.15", + "minimist": "^1.2.6", + "mocha": "^10.0.0", + "mz": "^2.7.0", + "nock": "^13.0.0", + "npm-run-all": "^4.1.5", + "nyc": "^17.0.0", + "request": "^2.75.0", + "request-promise": "^4.1.1", + "run-sequence": "^2.2.1", + "sinon": "^18.0.0", + "sinon-chai": "^3.0.0", + "ts-node": "^10.2.0", + "typescript": "5.1.6", + "yargs": "^17.0.1" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^7.7.0", + "@google-cloud/storage": "^7.7.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.25.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", + "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", + "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", + "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.25.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", + "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.0.0.tgz", + "integrity": "sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==" + }, + "node_modules/@firebase/api-documenter": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/api-documenter/-/api-documenter-0.4.0.tgz", + "integrity": "sha512-UUPxxj1wIAGkXBCF9UL1dhfyzM4Lcd/gMSCoJqy8o75rLqQVGB2GSBaU7I4JmQsQhIIk/nKKLiy4HM/70kEfZA==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.12.24", + "@rushstack/node-core-library": "3.59.7", + "@rushstack/ts-command-line": "4.15.2", + "api-extractor-model-me": "0.1.1", + "colors": "~1.4.0", + "js-yaml": "4.1.0", + "resolve": "~1.22.0", + "tslib": "^2.1.0" + }, + "bin": { + "api-documenter-fire": "dist/start.js" + } + }, + "node_modules/@firebase/app": { + "version": "0.10.13", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.13.tgz", + "integrity": "sha512-OZiDAEK/lDB6xy/XzYAyJJkaDqmQ+BCtOEPLqFvxWKUz5JbBmej7IiiRHdtiIOD/twW7O5AxVsfaaGA/V1bNsA==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.9", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.10.0", + "idb": "7.1.1", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz", + "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" + }, + "node_modules/@firebase/app-compat": { + "version": "0.2.43", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.43.tgz", + "integrity": "sha512-HM96ZyIblXjAC7TzE8wIk2QhHlSvksYkQ4Ukh1GmEenzkucSNUmUX4QvoKrqeWsLEQ8hdcojABeCV8ybVyZmeg==", + "dev": true, + "dependencies": { + "@firebase/app": "0.10.13", + "@firebase/component": "0.6.9", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.10.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/app-types": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", + "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==" + }, + "node_modules/@firebase/auth": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.4.0.tgz", + "integrity": "sha512-SfFXZCHDbY+7oSR52NSwx0U7LjYiA+N8imloxphCf3/F+MFty/+mhdjSXGtrJYd0Gbud/qcyedfn2XnWJeIB/g==", + "dev": true, + "dependencies": { + "@firebase/component": "0.6.4", + "@firebase/logger": "0.4.0", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-compat": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.9.tgz", + "integrity": "sha512-Fw03i7vduIciEBG4imLtA1duJbljgkfbxiBo/EuekcB+BnPxHp+e8OGMUfemPYeO7Munj6kUC9gr5DelsQkiNA==", + "dev": true, + "dependencies": { + "@firebase/auth": "1.4.0", + "@firebase/auth-types": "0.12.0", + "@firebase/component": "0.6.4", + "@firebase/util": "1.9.3", + "node-fetch": "2.6.7", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/auth-types": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", + "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/component": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", + "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", + "dev": true, + "dependencies": { + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/util": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", + "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/auth-compat/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", + "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==" + }, + "node_modules/@firebase/auth-types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", + "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/auth/node_modules/@firebase/component": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", + "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", + "dev": true, + "dependencies": { + "@firebase/util": "1.9.3", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/auth/node_modules/@firebase/logger": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", + "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/auth/node_modules/@firebase/util": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", + "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/auth/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@firebase/component": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", + "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", + "dependencies": { + "@firebase/util": "1.10.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.8.tgz", + "integrity": "sha512-dzXALZeBI1U5TXt6619cv0+tgEhJiwlUtQ55WNZY7vGAjv7Q1QioV969iYwt1AQQ0ovHnEW0YW9TiBfefLvErg==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.2", + "@firebase/auth-interop-types": "0.2.3", + "@firebase/component": "0.6.9", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.10.0", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.8.tgz", + "integrity": "sha512-OpeWZoPE3sGIRPBKYnW9wLad25RaWbGyk7fFQe4xnJQKRzlynWeFBSRRAoLE2Old01WXwskUiucNqUUVlFsceg==", + "dependencies": { + "@firebase/component": "0.6.9", + "@firebase/database": "1.0.8", + "@firebase/database-types": "1.0.5", + "@firebase/logger": "0.4.2", + "@firebase/util": "1.10.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.5.tgz", + "integrity": "sha512-fTlqCNwFYyq/C6W7AJ5OCuq5CeZuBEsEwptnVxlNPkWCo5cTTyukzAHRSO/jaQcItz33FfYrrFk1SJofcu2AaQ==", + "dependencies": { + "@firebase/app-types": "0.9.2", + "@firebase/util": "1.10.0" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", + "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@firebase/util": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", + "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@google-cloud/firestore": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.10.0.tgz", + "integrity": "sha512-VFNhdHvfnmqcHHs6YhmSNHHxQqaaD64GwiL0c+e1qz85S8SWZPC2XFRf8p9yHRTF40Kow424s1KBU9f0fdQa+Q==", + "optional": true, + "dependencies": { + "@opentelemetry/api": "^1.3.0", + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.3.3", + "protobufjs": "^7.2.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.13.0.tgz", + "integrity": "sha512-Y0rYdwM5ZPW3jw/T26sMxxfPrVQTKm9vGrZG8PRyGuUmUJ8a2xNuQ9W/NNA1prxqv2i54DSydV8SJqxF2oCVgA==", + "optional": true, + "dependencies": { + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "duplexify": "^4.1.3", + "fast-xml-parser": "^4.4.1", + "gaxios": "^6.0.2", + "google-auth-library": "^9.6.3", + "html-entities": "^2.5.2", + "mime": "^3.0.0", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.11.2.tgz", + "integrity": "sha512-DWp92gDD7/Qkj7r8kus6/HCINeo3yPZWZ3paKgDgsbKbSpoxKg1yvN8xe2Q8uE3zOsPe3bX8FQX2+XValq2yTw==", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "optional": true, + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@gulpjs/messages": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", + "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@gulpjs/to-absolute-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", + "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", + "dev": true, + "dependencies": { + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/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/@mapbox/node-pre-gyp/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/@microsoft/api-extractor": { + "version": "7.47.9", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.9.tgz", + "integrity": "sha512-TTq30M1rikVsO5wZVToQT/dGyJY7UXJmjiRtkHPLb74Prx3Etw8+bX7Bv7iLuby6ysb7fuu1NFWqma+csym8Jw==", + "dev": true, + "dependencies": { + "@microsoft/api-extractor-model": "7.29.8", + "@microsoft/tsdoc": "~0.15.0", + "@microsoft/tsdoc-config": "~0.17.0", + "@rushstack/node-core-library": "5.9.0", + "@rushstack/rig-package": "0.5.3", + "@rushstack/terminal": "0.14.2", + "@rushstack/ts-command-line": "4.22.8", + "lodash": "~4.17.15", + "minimatch": "~3.0.3", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "source-map": "~0.6.1", + "typescript": "5.4.2" + }, + "bin": { + "api-extractor": "bin/api-extractor" + } + }, + "node_modules/@microsoft/api-extractor-model": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.8.tgz", + "integrity": "sha512-t3Z/xcO6TRbMcnKGVMs4uMzv/gd5j0NhMiJIGjD4cJMeFJ1Hf8wnLSx37vxlRlL0GWlGJhnFgxvnaL6JlS+73g==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "~0.15.0", + "@microsoft/tsdoc-config": "~0.17.0", + "@rushstack/node-core-library": "5.9.0" + } + }, + "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", + "dev": true + }, + "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", + "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", + "dev": true, + "dependencies": { + "ajv": "~8.13.0", + "ajv-draft-04": "~1.0.0", + "ajv-formats": "~3.0.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@microsoft/api-extractor-model/node_modules/ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@microsoft/api-extractor-model/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/@microsoft/tsdoc": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", + "dev": true + }, + "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", + "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", + "dev": true, + "dependencies": { + "ajv": "~8.13.0", + "ajv-draft-04": "~1.0.0", + "ajv-formats": "~3.0.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { + "version": "4.22.8", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.8.tgz", + "integrity": "sha512-XbFjOoV7qZHJnSuFUHv0pKaFA4ixyCuki+xMjsMfDwfvQjs5MYG0IK5COal3tRnG7KCDe2l/G+9LrzYE/RJhgg==", + "dev": true, + "dependencies": { + "@rushstack/terminal": "0.14.2", + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "string-argv": "~0.3.1" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/typescript": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.12.24", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz", + "integrity": "sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg==", + "dev": true + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz", + "integrity": "sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.15.0", + "ajv": "~8.12.0", + "jju": "~1.4.0", + "resolve": "~1.22.2" + } + }, + "node_modules/@microsoft/tsdoc-config/node_modules/@microsoft/tsdoc": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", + "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "optional": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "optional": true + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "optional": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "optional": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "optional": true + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "optional": true + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "optional": true + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "optional": true + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "optional": true + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "optional": true + }, + "node_modules/@rushstack/node-core-library": { + "version": "3.59.7", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.7.tgz", + "integrity": "sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==", + "dev": true, + "dependencies": { + "colors": "~1.2.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4", + "z-schema": "~5.0.2" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/node-core-library/node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rushstack/rig-package": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", + "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", + "dev": true, + "dependencies": { + "resolve": "~1.22.1", + "strip-json-comments": "~3.1.1" + } + }, + "node_modules/@rushstack/terminal": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.2.tgz", + "integrity": "sha512-2fC1wqu1VCExKC0/L+0noVcFQEXEnoBOtCIex1TOjBzEDWcw8KzJjjj7aTP6mLxepG0XIyn9OufeFb6SFsa+sg==", + "dev": true, + "dependencies": { + "@rushstack/node-core-library": "5.9.0", + "supports-color": "~8.1.1" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", + "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", + "dev": true, + "dependencies": { + "ajv": "~8.13.0", + "ajv-draft-04": "~1.0.0", + "ajv-formats": "~3.0.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/terminal/node_modules/ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@rushstack/terminal/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@rushstack/ts-command-line": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz", + "integrity": "sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==", + "dev": true, + "dependencies": { + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "colors": "~1.2.1", + "string-argv": "~0.3.1" + } + }, + "node_modules/@rushstack/ts-command-line/node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "optional": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/argparse": { + "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/bcrypt": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", + "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/bluebird": { + "version": "3.5.42", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.42.tgz", + "integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "devOptional": true + }, + "node_modules/@types/chai": { + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", + "dev": true + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.3", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz", + "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/firebase-token-generator": { + "version": "2.0.33", + "resolved": "https://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.33.tgz", + "integrity": "sha512-FNZyTEHIE5Kq55QpVuyK7ZUJE/yoegRXalGVhbUh8+xC9pa1BUP7zspY+P5ci5SYKgoHjYQruC9gulFCn576Zw==", + "dev": true + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", + "dev": true + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "optional": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", + "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", + "dev": true + }, + "node_modules/@types/nock": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@types/nock/-/nock-11.1.0.tgz", + "integrity": "sha512-jI/ewavBQ7X5178262JQR0ewicPAcJhXS/iFaNJl0VHLfyosZ/kwSrsa6VNQNSO8i9d8SqdRgOtZSOKJ/+iNMw==", + "deprecated": "This is a stub types definition. nock provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "nock": "*" + } + }, + "node_modules/@types/node": { + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "dependencies": { + "undici-types": "~6.18.2" + } + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "devOptional": true, + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/request-promise": { + "version": "4.1.51", + "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.51.tgz", + "integrity": "sha512-qVcP9Fuzh9oaAh8oPxiSoWMFGnWKkJDknnij66vi09Yiy62bsSDqtd+fG5kIM9wLLgZsRP3Y6acqj9O/v2ZtRw==", + "dev": true, + "dependencies": { + "@types/bluebird": "*", + "@types/request": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sinon": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinon-chai": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.12.tgz", + "integrity": "sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "devOptional": true + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "optional": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "optional": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "dependencies": { + "ansi-wrap": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha512-eCjan3AVo/SxZ0/MyIYRtkpxIu/H3xZN7URr1vXVrISxeyz8fUFz0FJziamK4sS8I+t35y4rHg1b2PklyBe/7A==", + "dev": true, + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", + "dev": true, + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow==", + "dev": true, + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/api-extractor-model-me": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/api-extractor-model-me/-/api-extractor-model-me-0.1.1.tgz", + "integrity": "sha512-Ez801ZMADfkseOWNRFquvyQYDm3D9McpxfkKMWL6JFCGcpub0miJ+TFNphIR1nSZbrsxz3kIeOovNMY4VlL6Bw==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.12.24", + "@rushstack/node-core-library": "3.36.0" + } + }, + "node_modules/api-extractor-model-me/node_modules/@rushstack/node-core-library": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.36.0.tgz", + "integrity": "sha512-bID2vzXpg8zweXdXgQkKToEdZwVrVCN9vE9viTRk58gqzYaTlz4fMId6V3ZfpXN6H0d319uGi2KDlm+lUEeqCg==", + "dev": true, + "dependencies": { + "@types/node": "10.17.13", + "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", + "timsort": "~0.3.0", + "z-schema": "~3.18.3" + } + }, + "node_modules/api-extractor-model-me/node_modules/@types/node": { + "version": "10.17.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", + "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", + "dev": true + }, + "node_modules/api-extractor-model-me/node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/api-extractor-model-me/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/api-extractor-model-me/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/api-extractor-model-me/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/api-extractor-model-me/node_modules/validator": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", + "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/api-extractor-model-me/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==", + "dev": true, + "dependencies": { + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^8.0.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "optionalDependencies": { + "commander": "^2.7.1" + } + }, + "node_modules/append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", + "dev": true, + "dependencies": { + "buffer-equal": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async-done": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", + "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.4.4", + "once": "^1.4.0", + "stream-exhaust": "^1.0.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "optional": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/async-settle": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", + "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", + "dev": true, + "dependencies": { + "async-done": "^2.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "devOptional": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", + "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", + "dev": true + }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "dev": true + }, + "node_modules/bach": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", + "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", + "dev": true, + "dependencies": { + "async-done": "^2.0.0", + "async-settle": "^2.0.0", + "now-and-later": "^3.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bare-events": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", + "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", + "dev": true, + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "devOptional": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcrypt": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", + "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", + "dev": true, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001667", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", + "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-as-promised": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", + "dev": true, + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, + "node_modules/chai-exclude": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chai-exclude/-/chai-exclude-2.1.1.tgz", + "integrity": "sha512-IHgNmgAFOkyRPnmOtZio9UsOHQ6RnzVr2LOs+5V9urYYqjhV/ERLQapC0Eq2DmID5eDWyngAcBxNUm0ZK0QbrQ==", + "dev": true, + "dependencies": { + "fclone": "^1.0.11" + }, + "peerDependencies": { + "chai": ">= 4.0.0 < 5" + } + }, + "node_modules/chai/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/child-process-promise": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/child-process-promise/-/child-process-promise-2.2.1.tgz", + "integrity": "sha512-Fi4aNdqBsr0mv+jgWxcZ/7rAIC2mgihrptyVI4foh/rrjY/3BNjfP9+oaiFx/fzim+1ZyCNBae0DlyfQhSugog==", + "dev": true, + "dependencies": { + "cross-spawn": "^4.0.2", + "node-version": "^1.0.0", + "promise-polyfill": "^6.0.1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "devOptional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", + "dev": true + }, + "node_modules/cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "node_modules/cloneable-readable/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/cloneable-readable/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/cloneable-readable/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "devOptional": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/concat-with-sourcemaps": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", + "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", + "dev": true, + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/copy-props": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", + "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", + "dev": true, + "dependencies": { + "each-props": "^3.0.0", + "is-plain-object": "^5.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/cross-spawn/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/cross-spawn/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dev": true, + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "devOptional": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "node_modules/each-props": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", + "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", + "dev": true, + "dependencies": { + "is-plain-object": "^5.0.0", + "object.defaults": "^1.1.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.33", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", + "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "devOptional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/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/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/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/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/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/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "devOptional": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "dependencies": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/farmhash-modern": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", + "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "devOptional": true + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-xml-parser": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "optional": true, + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==", + "dev": true + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/findup-sync": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", + "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.3", + "micromatch": "^4.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/fined": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", + "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^5.0.0", + "object.defaults": "^1.1.0", + "object.pick": "^1.3.0", + "parse-filepath": "^1.0.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/firebase-token-generator": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/firebase-token-generator/-/firebase-token-generator-2.0.0.tgz", + "integrity": "sha512-EX/Rw6C0NLF6StuszW9Pn4zGUU8dw0UdHY6u8zP5t/CsbYRwWVh0CwN6INFE5U4IizZtgqbWQhcAQNkBtNkyfQ==", + "dev": true + }, + "node_modules/flagged-respawn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", + "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/flush-write-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/flush-write-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/flush-write-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "devOptional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "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/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", + "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.8", + "streamx": "^2.12.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "optional": true + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gaxios": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz", + "integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==", + "optional": true, + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "optional": true, + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-prop": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/get-prop/-/get-prop-0.0.10.tgz", + "integrity": "sha512-XRSGBgcIisSMLJ/dwe1y/eMm9yzLicEJKmEXA3ArBkDkCW2nyRroLOoKIz+SdxuG5SI7ym2QHaTU5ifCl7MTDg==", + "dev": true + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-stream": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", + "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", + "dev": true, + "dependencies": { + "@gulpjs/to-absolute-glob": "^4.0.0", + "anymatch": "^3.1.3", + "fastq": "^1.13.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "is-negated-glob": "^1.0.0", + "normalize-path": "^3.0.0", + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-stream/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-watcher": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", + "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", + "dev": true, + "dependencies": { + "async-done": "^2.0.0", + "chokidar": "^3.5.3" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glogg": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", + "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", + "dev": true, + "dependencies": { + "sparkles": "^2.1.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/google-auth-library": { + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.10.0.tgz", + "integrity": "sha512-ol+oSa5NbcGdDqA+gZ3G3mev59OHBZksBTxY/tYwjtcp1H/scAFwJfSQU9/1RALoyZ7FslNbke8j4i3ipwlyuQ==", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", + "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "^1.10.9", + "@grpc/proto-loader": "^0.7.13", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.7.0", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.2", + "protobufjs": "^7.3.2", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "optional": true, + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/gulp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz", + "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==", + "dev": true, + "dependencies": { + "glob-watcher": "^6.0.0", + "gulp-cli": "^3.0.0", + "undertaker": "^2.0.0", + "vinyl-fs": "^4.0.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-filter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-7.0.0.tgz", + "integrity": "sha512-ZGWtJo0j1mHfP77tVuhyqem4MRA5NfNRjoVe6VAkLGeQQ/QGo2VsFwp7zfPTGDsd1rwzBmoDHhxpE6f5B3Zuaw==", + "dev": true, + "dependencies": { + "multimatch": "^5.0.0", + "plugin-error": "^1.0.1", + "streamfilter": "^3.0.0", + "to-absolute-glob": "^2.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + }, + "peerDependencies": { + "gulp": ">=4" + }, + "peerDependenciesMeta": { + "gulp": { + "optional": true + } + } + }, + "node_modules/gulp-header": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-2.0.9.tgz", + "integrity": "sha512-LMGiBx+qH8giwrOuuZXSGvswcIUh0OiioNkUpLhNyvaC6/Ga8X6cfAeme2L5PqsbXMhL8o8b/OmVqIQdxprhcQ==", + "dev": true, + "dependencies": { + "concat-with-sourcemaps": "^1.1.0", + "lodash.template": "^4.5.0", + "map-stream": "0.0.7", + "through2": "^2.0.0" + } + }, + "node_modules/gulp-typescript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-5.0.1.tgz", + "integrity": "sha512-YuMMlylyJtUSHG1/wuSVTrZp60k1dMEFKYOvDf7OvbAJWrDtxxD4oZon4ancdWwzjj30ztiidhe4VXJniF0pIQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^3.0.5", + "plugin-error": "^1.0.1", + "source-map": "^0.7.3", + "through2": "^3.0.0", + "vinyl": "^2.1.0", + "vinyl-fs": "^3.0.3" + }, + "engines": { + "node": ">= 8" + }, + "peerDependencies": { + "typescript": "~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev" + } + }, + "node_modules/gulp-typescript/node_modules/ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/gulp-typescript/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/gulp-typescript/node_modules/glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", + "dev": true, + "dependencies": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/glob-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-typescript/node_modules/lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", + "dev": true, + "dependencies": { + "flush-write-stream": "^1.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-typescript/node_modules/now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "dependencies": { + "once": "^1.3.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", + "dev": true, + "dependencies": { + "value-or-function": "^3.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/gulp-typescript/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/gulp-typescript/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/gulp-typescript/node_modules/through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "node_modules/gulp-typescript/node_modules/to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", + "dev": true, + "dependencies": { + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/to-through/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/to-through/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "dependencies": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/vinyl-fs/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/vinyl-fs/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", + "dev": true, + "dependencies": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/gulp/node_modules/gulp-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", + "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", + "dev": true, + "dependencies": { + "@gulpjs/messages": "^1.1.0", + "chalk": "^4.1.2", + "copy-props": "^4.0.0", + "gulplog": "^2.2.0", + "interpret": "^3.1.1", + "liftoff": "^5.0.0", + "mute-stdout": "^2.0.0", + "replace-homedir": "^2.0.0", + "semver-greatest-satisfied-range": "^2.0.0", + "string-width": "^4.2.3", + "v8flags": "^4.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gulp/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/gulplog": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", + "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", + "dev": true, + "dependencies": { + "glogg": "^2.2.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "optional": true + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-message-parser": { + "version": "0.0.34", + "resolved": "https://registry.npmjs.org/http-message-parser/-/http-message-parser-0.0.34.tgz", + "integrity": "sha512-KABKXT347AYvQoaMZg9/K+/GqW6gfB4pKCiTyMUYnosfkdkaBkrXE/cWGSLk5jvD5tiDeLFlYSHLhhPhQKbRrA==", + "dev": true, + "dependencies": { + "buffer": "^4.9.1", + "concat-stream": "^1.5.1", + "get-prop": "0.0.10", + "minimist": "^1.2.0", + "stream-buffers": "^3.0.0" + }, + "bin": { + "http-message-parser": "bin/http-message-parser.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-message-parser/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "optional": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/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==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "optional": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "dev": true + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "devOptional": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "devOptional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true + }, + "node_modules/jose": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "optional": true, + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "dependencies": { + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", + "debug": "^4.3.4", + "jose": "^4.14.6", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jwks-rsa/node_modules/@types/jsonwebtoken": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", + "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/last-run": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", + "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lead": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", + "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/liftoff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", + "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==", + "dev": true, + "dependencies": { + "extend": "^3.0.2", + "findup-sync": "^5.0.0", + "fined": "^2.0.0", + "flagged-respawn": "^2.0.0", + "is-plain-object": "^5.0.0", + "rechoir": "^0.8.0", + "resolve": "^1.20.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "optional": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "dev": true + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "optional": true + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", + "dev": true + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "devOptional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "devOptional": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mute-stdout": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", + "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/nise": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", + "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + } + }, + "node_modules/nock": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz", + "integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">= 10.13" + } + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "devOptional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, + "node_modules/node-version": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.2.0.tgz", + "integrity": "sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/now-and-later": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", + "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/npm-run-all/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/npm-run-all/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/npm-run-all/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "dev": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/nyc": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", + "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^3.3.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^6.0.2", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", + "dev": true, + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "devOptional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/ordered-read-streams/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/ordered-read-streams/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/ordered-read-streams/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "devOptional": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", + "dev": true, + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, + "dependencies": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/promise-polyfill": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", + "integrity": "sha512-g0LWaH0gFsxovsU7R5LrrhHhWAWiHRnh1GPrhXnPgYsDkIqjRYUYSZEsej/wtleDrz5xVSIDbeKfidztp2XHFQ==", + "dev": true + }, + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/proto3-json-serializer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "optional": true, + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/pumpify/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/pumpify/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/pumpify/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "devOptional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", + "dev": true, + "dependencies": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/replace-homedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", + "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", + "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", + "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "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/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", + "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", + "dev": true, + "dependencies": { + "value-or-function": "^4.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "optional": true, + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/run-sequence": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.1.tgz", + "integrity": "sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "fancy-log": "^1.3.2", + "plugin-error": "^0.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/run-sequence/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha512-OQwDZUqYaQwyyhDJHThmzId8daf4/RFNLaeh3AevmSeZ5Y7ug4Ga/yKc6l6kTZOBW781rCj103ZuTh8GAsB3+Q==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha512-t5db90jq+qdgk8aFnxEkjqta0B/GHrM1pxzuuZz2zWsOXc5nKu3t+76s/PQBA8FTcM/ipspIH9jWG4OxCBc2eA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/run-sequence/node_modules/extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha512-L7AGmkO6jhDkEBBGWlLtftA80Xq8DipnrRPr0pyi7GQLXkaq9JYA4xF4z6qnadIC6euiTDKco0cGSU9muw+WTw==", + "dev": true, + "dependencies": { + "kind-of": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha512-WzZHcm4+GO34sjFMxQMqZbsz3xiNEgonCskQ9v+IroMmYgk/tas8dG+Hr2D6IbRPybZ12oWpzE/w3cGJ6FJzOw==", + "dev": true, + "dependencies": { + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-greatest-satisfied-range": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", + "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", + "dev": true, + "dependencies": { + "sver": "^1.8.3" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sinon": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", + "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon-chai": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", + "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", + "dev": true, + "peerDependencies": { + "chai": "^4.0.0", + "sinon": ">=4.0.0" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sparkles": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", + "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/spawn-wrap/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/spawn-wrap/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "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": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-buffers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", + "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/stream-composer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", + "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", + "dev": true, + "dependencies": { + "streamx": "^2.13.2" + } + }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "devOptional": true + }, + "node_modules/streamfilter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-3.0.0.tgz", + "integrity": "sha512-kvKNfXCmUyC8lAXSSHCIXBUlo/lhsLcCU/OmzACZYpRUdtKIH68xYhm/+HI15jFJYtNJGYtCgn2wmIiExY1VwA==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.6" + }, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "devOptional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "optional": true + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "optional": true + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sver": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", + "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", + "dev": true, + "optionalDependencies": { + "semver": "^6.3.0" + } + }, + "node_modules/sver/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "optional": true, + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/teeny-request/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==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/teeny-request/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==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", + "dev": true + }, + "node_modules/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-through": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", + "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", + "dev": true, + "dependencies": { + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "devOptional": true + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undertaker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", + "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", + "dev": true, + "dependencies": { + "bach": "^2.0.1", + "fast-levenshtein": "^3.0.0", + "last-run": "^2.0.0", + "undertaker-registry": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/undertaker-registry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", + "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/undertaker/node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "dev": true, + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/undici-types": { + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + }, + "node_modules/unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-browserslist-db/node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "devOptional": true + }, + "node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8flags": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", + "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validator": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/value-or-function": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", + "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-contents": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", + "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", + "dev": true, + "dependencies": { + "bl": "^5.0.0", + "vinyl": "^3.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", + "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", + "dev": true, + "dependencies": { + "fs-mkdirp-stream": "^2.0.1", + "glob-stream": "^8.0.0", + "graceful-fs": "^4.2.11", + "iconv-lite": "^0.6.3", + "is-valid-glob": "^1.0.0", + "lead": "^4.0.0", + "normalize-path": "3.0.0", + "resolve-options": "^2.0.0", + "stream-composer": "^1.0.2", + "streamx": "^2.14.0", + "to-through": "^3.0.0", + "value-or-function": "^4.0.0", + "vinyl": "^3.0.0", + "vinyl-sourcemap": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", + "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", + "dev": true, + "dependencies": { + "convert-source-map": "^2.0.0", + "graceful-fs": "^4.2.10", + "now-and-later": "^3.0.0", + "streamx": "^2.12.5", + "vinyl": "^3.0.0", + "vinyl-contents": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "devOptional": true + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "devOptional": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "devOptional": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "devOptional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "devOptional": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "devOptional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "devOptional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dev": true, + "dependencies": { + "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": "^9.4.1" + } + } + }, "dependencies": { "@ampproject/remapping": { "version": "2.3.0", @@ -413,27 +11565,6 @@ "@firebase/util": "1.10.0", "idb": "7.1.1", "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/component": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", - "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", - "dev": true, - "requires": { - "@firebase/util": "1.10.0", - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", - "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - } } }, "@firebase/app-check-interop-types": { @@ -452,27 +11583,6 @@ "@firebase/logger": "0.4.2", "@firebase/util": "1.10.0", "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/component": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", - "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", - "dev": true, - "requires": { - "@firebase/util": "1.10.0", - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", - "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - } } }, "@firebase/app-types": { @@ -550,7 +11660,8 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", - "dev": true + "dev": true, + "requires": {} }, "@firebase/component": { "version": "0.6.4", @@ -591,51 +11702,52 @@ "version": "0.12.2", "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", - "dev": true + "dev": true, + "requires": {} }, "@firebase/component": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.7.tgz", - "integrity": "sha512-baH1AA5zxfaz4O8w0vDwETByrKTQqB5CDjRls79Sa4eAGAoERw4Tnung7XbMl3jbJ4B/dmmtsMrdki0KikwDYA==", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", + "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", "requires": { - "@firebase/util": "1.9.6", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" } }, "@firebase/database": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.5.tgz", - "integrity": "sha512-cAfwBqMQuW6HbhwI3Cb/gDqZg7aR0OmaJ85WUxlnoYW2Tm4eR0hFl5FEijI3/gYPUiUcUPQvTkGV222VkT7KPw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.8.tgz", + "integrity": "sha512-dzXALZeBI1U5TXt6619cv0+tgEhJiwlUtQ55WNZY7vGAjv7Q1QioV969iYwt1AQQ0ovHnEW0YW9TiBfefLvErg==", "requires": { "@firebase/app-check-interop-types": "0.3.2", "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.7", + "@firebase/component": "0.6.9", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.6", + "@firebase/util": "1.10.0", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "@firebase/database-compat": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.5.tgz", - "integrity": "sha512-NDSMaDjQ+TZEMDMmzJwlTL05kh1+0Y84C+kVMaOmNOzRGRM7VHi29I6YUhCetXH+/b1Wh4ZZRyp1CuWkd8s6hg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.8.tgz", + "integrity": "sha512-OpeWZoPE3sGIRPBKYnW9wLad25RaWbGyk7fFQe4xnJQKRzlynWeFBSRRAoLE2Old01WXwskUiucNqUUVlFsceg==", "requires": { - "@firebase/component": "0.6.7", - "@firebase/database": "1.0.5", - "@firebase/database-types": "1.0.3", + "@firebase/component": "0.6.9", + "@firebase/database": "1.0.8", + "@firebase/database-types": "1.0.5", "@firebase/logger": "0.4.2", - "@firebase/util": "1.9.6", + "@firebase/util": "1.10.0", "tslib": "^2.1.0" } }, "@firebase/database-types": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.3.tgz", - "integrity": "sha512-39V/Riv2R3O/aUjYKh0xypj7NTNXNAK1bcgY5Kx+hdQPRS/aPTS8/5c0CGFYKgVuFbYlnlnhrCTYsh2uNhGwzA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.5.tgz", + "integrity": "sha512-fTlqCNwFYyq/C6W7AJ5OCuq5CeZuBEsEwptnVxlNPkWCo5cTTyukzAHRSO/jaQcItz33FfYrrFk1SJofcu2AaQ==", "requires": { "@firebase/app-types": "0.9.2", - "@firebase/util": "1.9.6" + "@firebase/util": "1.10.0" } }, "@firebase/logger": { @@ -647,9 +11759,9 @@ } }, "@firebase/util": { - "version": "1.9.6", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.6.tgz", - "integrity": "sha512-IBr1MZbp4d5MjBCXL3TW1dK/PDXX4yOGbiwRNh1oAbE/+ci5Uuvy9KIrsFYY80as1I0iOaD5oOMA9Q8j4TJWcw==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", + "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", "requires": { "tslib": "^2.1.0" } @@ -1425,7 +12537,8 @@ "@types/caseless": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "devOptional": true }, "@types/chai": { "version": "4.3.16", @@ -1564,6 +12677,7 @@ "version": "2.48.12", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "devOptional": true, "requires": { "@types/caseless": "*", "@types/node": "*", @@ -1634,7 +12748,8 @@ "@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "devOptional": true }, "@types/uuid": { "version": "10.0.0", @@ -1772,7 +12887,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "8.3.2", @@ -1815,7 +12931,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "dev": true + "dev": true, + "requires": {} }, "ajv-formats": { "version": "3.0.1", @@ -1865,12 +12982,14 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, "requires": { "color-convert": "^2.0.1" } @@ -2107,7 +13226,8 @@ "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "devOptional": true }, "asn1": { "version": "0.2.6", @@ -2168,7 +13288,8 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "devOptional": true }, "available-typed-arrays": { "version": "1.0.7", @@ -2224,7 +13345,8 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "devOptional": true }, "bcrypt": { "version": "5.1.1", @@ -2501,6 +13623,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "devOptional": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2572,6 +13695,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, "requires": { "color-name": "~1.1.4" } @@ -2579,7 +13703,8 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true }, "color-support": { "version": "1.1.3", @@ -2597,6 +13722,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "devOptional": true, "requires": { "delayed-stream": "~1.0.0" } @@ -2864,7 +13990,8 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "devOptional": true }, "delegates": { "version": "1.0.0", @@ -2957,12 +14084,14 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "devOptional": true, "requires": { "once": "^1.4.0" } @@ -3085,7 +14214,8 @@ "escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==" + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "devOptional": true }, "escape-string-regexp": { "version": "4.0.0", @@ -3310,7 +14440,8 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "devOptional": true }, "extend-shallow": { "version": "3.0.2", @@ -3348,7 +14479,8 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "devOptional": true }, "fast-fifo": { "version": "1.3.2", @@ -3632,6 +14764,7 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "devOptional": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -3785,7 +14918,8 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "devOptional": true }, "get-func-name": { "version": "2.0.2", @@ -4765,7 +15899,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "devOptional": true }, "ini": { "version": "1.3.8", @@ -4912,7 +16047,8 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true }, "is-glob": { "version": "4.0.3", @@ -5005,7 +16141,8 @@ "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "devOptional": true }, "is-string": { "version": "1.0.7", @@ -5771,12 +16908,14 @@ "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "devOptional": true }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "devOptional": true, "requires": { "mime-db": "1.52.0" } @@ -6021,6 +17160,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "devOptional": true, "requires": { "whatwg-url": "^5.0.0" } @@ -6453,6 +17593,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "devOptional": true, "requires": { "wrappy": "1" } @@ -6516,6 +17657,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "devOptional": true, "requires": { "yocto-queue": "^0.1.0" } @@ -6955,6 +18097,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "devOptional": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -7110,7 +18253,8 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "devOptional": true }, "require-from-string": { "version": "2.0.2", @@ -7475,7 +18619,8 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "dev": true + "dev": true, + "requires": {} }, "slash": { "version": "3.0.0", @@ -7635,7 +18780,8 @@ "stream-shift": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "devOptional": true }, "streamfilter": { "version": "3.0.0", @@ -7658,6 +18804,15 @@ "text-decoder": "^1.1.0" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "devOptional": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -7668,6 +18823,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7720,18 +18876,11 @@ "es-object-atoms": "^1.0.0" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "requires": { "ansi-regex": "^5.0.1" } @@ -8011,7 +19160,8 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "devOptional": true }, "ts-node": { "version": "10.9.2", @@ -8271,7 +19421,8 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "devOptional": true }, "uuid": { "version": "10.0.0", @@ -8393,7 +19544,8 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "devOptional": true }, "websocket-driver": { "version": "0.7.4", @@ -8414,6 +19566,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "devOptional": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -8485,6 +19638,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8494,7 +19648,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "devOptional": true }, "write-file-atomic": { "version": "3.0.3", @@ -8517,7 +19672,8 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "devOptional": true }, "yallist": { "version": "4.0.0", @@ -8528,6 +19684,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "devOptional": true, "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -8541,7 +19698,8 @@ "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "devOptional": true }, "yargs-unparser": { "version": "2.0.0", @@ -8564,7 +19722,8 @@ "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "devOptional": true }, "z-schema": { "version": "5.0.5", diff --git a/package.json b/package.json index a87c2796aa..0465bffc63 100644 --- a/package.json +++ b/package.json @@ -205,8 +205,8 @@ }, "dependencies": { "@fastify/busboy": "^3.0.0", - "@firebase/database-compat": "^1.0.2", - "@firebase/database-types": "^1.0.0", + "@firebase/database-compat": "1.0.8", + "@firebase/database-types": "1.0.5", "@types/node": "^22.0.1", "farmhash-modern": "^1.1.0", "jsonwebtoken": "^9.0.0", From 41e414e753720484365d06d8cbecb520d1e833fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:28:40 -0400 Subject: [PATCH 193/323] build(deps-dev): bump @types/lodash from 4.17.10 to 4.17.12 (#2735) Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.10 to 4.17.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2b6f973089..a82bcfe8ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1862,9 +1862,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.12.tgz", + "integrity": "sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==", "dev": true }, "node_modules/@types/long": { @@ -12612,9 +12612,9 @@ } }, "@types/lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.12.tgz", + "integrity": "sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==", "dev": true }, "@types/long": { From 8fc56a74d6ba8ced611f52956800e91117ad1639 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 20:32:29 +0000 Subject: [PATCH 194/323] build(deps-dev): bump @microsoft/api-extractor from 7.47.9 to 7.47.11 (#2734) --- package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index a82bcfe8ad..132fb9b4a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1213,9 +1213,9 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.47.9", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.9.tgz", - "integrity": "sha512-TTq30M1rikVsO5wZVToQT/dGyJY7UXJmjiRtkHPLb74Prx3Etw8+bX7Bv7iLuby6ysb7fuu1NFWqma+csym8Jw==", + "version": "7.47.11", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.11.tgz", + "integrity": "sha512-lrudfbPub5wzBhymfFtgZKuBvXxoSIAdrvS2UbHjoMT2TjIEddq6Z13pcve7A03BAouw0x8sW8G4txdgfiSwpQ==", "dev": true, "dependencies": { "@microsoft/api-extractor-model": "7.29.8", @@ -1224,7 +1224,7 @@ "@rushstack/node-core-library": "5.9.0", "@rushstack/rig-package": "0.5.3", "@rushstack/terminal": "0.14.2", - "@rushstack/ts-command-line": "4.22.8", + "@rushstack/ts-command-line": "4.23.0", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1339,9 +1339,9 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "4.22.8", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.8.tgz", - "integrity": "sha512-XbFjOoV7qZHJnSuFUHv0pKaFA4ixyCuki+xMjsMfDwfvQjs5MYG0IK5COal3tRnG7KCDe2l/G+9LrzYE/RJhgg==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.0.tgz", + "integrity": "sha512-jYREBtsxduPV6ptNq8jOKp9+yx0ld1Tb/Tkdnlj8gTjazl1sF3DwX2VbluyYrNd0meWIL0bNeer7WDf5tKFjaQ==", "dev": true, "dependencies": { "@rushstack/terminal": "0.14.2", @@ -12056,9 +12056,9 @@ } }, "@microsoft/api-extractor": { - "version": "7.47.9", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.9.tgz", - "integrity": "sha512-TTq30M1rikVsO5wZVToQT/dGyJY7UXJmjiRtkHPLb74Prx3Etw8+bX7Bv7iLuby6ysb7fuu1NFWqma+csym8Jw==", + "version": "7.47.11", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.11.tgz", + "integrity": "sha512-lrudfbPub5wzBhymfFtgZKuBvXxoSIAdrvS2UbHjoMT2TjIEddq6Z13pcve7A03BAouw0x8sW8G4txdgfiSwpQ==", "dev": true, "requires": { "@microsoft/api-extractor-model": "7.29.8", @@ -12067,7 +12067,7 @@ "@rushstack/node-core-library": "5.9.0", "@rushstack/rig-package": "0.5.3", "@rushstack/terminal": "0.14.2", - "@rushstack/ts-command-line": "4.22.8", + "@rushstack/ts-command-line": "4.23.0", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -12099,9 +12099,9 @@ } }, "@rushstack/ts-command-line": { - "version": "4.22.8", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.22.8.tgz", - "integrity": "sha512-XbFjOoV7qZHJnSuFUHv0pKaFA4ixyCuki+xMjsMfDwfvQjs5MYG0IK5COal3tRnG7KCDe2l/G+9LrzYE/RJhgg==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.0.tgz", + "integrity": "sha512-jYREBtsxduPV6ptNq8jOKp9+yx0ld1Tb/Tkdnlj8gTjazl1sF3DwX2VbluyYrNd0meWIL0bNeer7WDf5tKFjaQ==", "dev": true, "requires": { "@rushstack/terminal": "0.14.2", From 8d49b7e67e6867cfe6371d5a76aeadad0743c086 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 24 Oct 2024 11:06:03 -0400 Subject: [PATCH 195/323] [chore] Release 12.7.0 (#2741) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0465bffc63..0b29a03372 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.6.0", + "version": "12.7.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From f33ccd1d5abcb6af46398432cd7a50ae10b0510c Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 30 Oct 2024 13:07:06 -0400 Subject: [PATCH 196/323] feat(fcm): Add directBootOk field to AndroidConfig (#2745) --- etc/firebase-admin.messaging.api.md | 1 + src/messaging/messaging-api.ts | 6 ++++++ src/messaging/messaging-internal.ts | 1 + test/integration/messaging.spec.ts | 1 + test/unit/messaging/messaging.spec.ts | 4 ++++ 5 files changed, 13 insertions(+) diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index 78cb17c5ce..f78156eb5a 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -14,6 +14,7 @@ export interface AndroidConfig { data?: { [key: string]: string; }; + directBootOk?: boolean; fcmOptions?: AndroidFcmOptions; notification?: AndroidNotification; priority?: ('high' | 'normal'); diff --git a/src/messaging/messaging-api.ts b/src/messaging/messaging-api.ts index c8b5ce1781..8d85faa7a7 100644 --- a/src/messaging/messaging-api.ts +++ b/src/messaging/messaging-api.ts @@ -418,6 +418,12 @@ export interface AndroidConfig { * Options for features provided by the FCM SDK for Android. */ fcmOptions?: AndroidFcmOptions; + + /** + * A boolean indicating whether messages will be allowed to be delivered to + * the app while the device is in direct boot mode. + */ + directBootOk?: boolean; } /** diff --git a/src/messaging/messaging-internal.ts b/src/messaging/messaging-internal.ts index c0379fac70..6f1f7a3c74 100644 --- a/src/messaging/messaging-internal.ts +++ b/src/messaging/messaging-internal.ts @@ -398,6 +398,7 @@ function validateAndroidConfig(config: AndroidConfig | undefined): void { const propertyMappings = { collapseKey: 'collapse_key', restrictedPackageName: 'restricted_package_name', + directBootOk: 'direct_boot_ok', }; renameProperties(config, propertyMappings); } diff --git a/test/integration/messaging.spec.ts b/test/integration/messaging.spec.ts index dc6d662f0b..409261f6aa 100644 --- a/test/integration/messaging.spec.ts +++ b/test/integration/messaging.spec.ts @@ -45,6 +45,7 @@ const message: Message = { }, android: { restrictedPackageName: 'com.google.firebase.testing', + directBootOk: true, notification: { title: 'test.title', ticker: 'test.ticker', diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index a391dceb28..4fb5264d5c 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -3961,6 +3961,7 @@ describe('Messaging', () => { android: { collapseKey: 'test.key', restrictedPackageName: 'test.package', + directBootOk: true, notification: { clickAction: 'test.click.action', titleLocKey: 'title.loc.key', @@ -3988,6 +3989,7 @@ describe('Messaging', () => { android: { collapse_key: 'test.key', restricted_package_name: 'test.package', + direct_boot_ok: true, notification: { click_action: 'test.click.action', title_loc_key: 'title.loc.key', @@ -4043,6 +4045,7 @@ describe('Messaging', () => { priority: 'high', collapseKey: 'test.key', restrictedPackageName: 'test.package', + directBootOk: true, ttl: 5, data: { k1: 'v1', @@ -4089,6 +4092,7 @@ describe('Messaging', () => { priority: 'high', collapse_key: 'test.key', restricted_package_name: 'test.package', + direct_boot_ok: true, ttl: '0.005000000s', // 5 ms = 5,000,000 ns data: { k1: 'v1', From 32343093e6534460c153741c2d6e1b0e0a6f321d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:15:06 +0000 Subject: [PATCH 197/323] build(deps-dev): bump @firebase/app-compat from 0.2.43 to 0.2.45 (#2746) --- package-lock.json | 196 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 168 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 132fb9b4a1..1759c62455 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "12.6.0", + "version": "12.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "12.6.0", + "version": "12.7.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -585,16 +585,19 @@ } }, "node_modules/@firebase/app": { - "version": "0.10.13", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.13.tgz", - "integrity": "sha512-OZiDAEK/lDB6xy/XzYAyJJkaDqmQ+BCtOEPLqFvxWKUz5JbBmej7IiiRHdtiIOD/twW7O5AxVsfaaGA/V1bNsA==", + "version": "0.10.15", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.15.tgz", + "integrity": "sha512-he6qlG3pmwL+LHdG/BrSMBQeJzzutciq4fpXN3lGa1uSwYSijJ24VtakS/bP2X9SiDf8jGywJ4u+OgXAenJsNg==", "dev": true, "dependencies": { - "@firebase/component": "0.6.9", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.10.0", + "@firebase/component": "0.6.10", + "@firebase/logger": "0.4.3", + "@firebase/util": "1.10.1", "idb": "7.1.1", "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@firebase/app-check-interop-types": { @@ -603,16 +606,56 @@ "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "node_modules/@firebase/app-compat": { - "version": "0.2.43", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.43.tgz", - "integrity": "sha512-HM96ZyIblXjAC7TzE8wIk2QhHlSvksYkQ4Ukh1GmEenzkucSNUmUX4QvoKrqeWsLEQ8hdcojABeCV8ybVyZmeg==", + "version": "0.2.45", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.45.tgz", + "integrity": "sha512-5rYbXq1ndtMTg+07oH4WrkYuP+NZq61uzVwW1hlmybp/gr4cXq2SfaP9fc6/9IzTKmu3dh3H0fjj++HG7Z7o/w==", "dev": true, "dependencies": { - "@firebase/app": "0.10.13", - "@firebase/component": "0.6.9", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.10.0", + "@firebase/app": "0.10.15", + "@firebase/component": "0.6.10", + "@firebase/logger": "0.4.3", + "@firebase/util": "1.10.1", "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/@firebase/component": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", + "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", + "dev": true, + "dependencies": { + "@firebase/util": "1.10.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/@firebase/logger": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", + "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/@firebase/util": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", + "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@firebase/app-types": { @@ -620,6 +663,43 @@ "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==" }, + "node_modules/@firebase/app/node_modules/@firebase/component": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", + "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", + "dev": true, + "dependencies": { + "@firebase/util": "1.10.1", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app/node_modules/@firebase/logger": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", + "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app/node_modules/@firebase/util": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", + "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@firebase/auth": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.4.0.tgz", @@ -11555,16 +11635,46 @@ } }, "@firebase/app": { - "version": "0.10.13", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.13.tgz", - "integrity": "sha512-OZiDAEK/lDB6xy/XzYAyJJkaDqmQ+BCtOEPLqFvxWKUz5JbBmej7IiiRHdtiIOD/twW7O5AxVsfaaGA/V1bNsA==", + "version": "0.10.15", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.15.tgz", + "integrity": "sha512-he6qlG3pmwL+LHdG/BrSMBQeJzzutciq4fpXN3lGa1uSwYSijJ24VtakS/bP2X9SiDf8jGywJ4u+OgXAenJsNg==", "dev": true, "requires": { - "@firebase/component": "0.6.9", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.10.0", + "@firebase/component": "0.6.10", + "@firebase/logger": "0.4.3", + "@firebase/util": "1.10.1", "idb": "7.1.1", "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/component": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", + "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", + "dev": true, + "requires": { + "@firebase/util": "1.10.1", + "tslib": "^2.1.0" + } + }, + "@firebase/logger": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", + "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", + "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } } }, "@firebase/app-check-interop-types": { @@ -11573,16 +11683,46 @@ "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" }, "@firebase/app-compat": { - "version": "0.2.43", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.43.tgz", - "integrity": "sha512-HM96ZyIblXjAC7TzE8wIk2QhHlSvksYkQ4Ukh1GmEenzkucSNUmUX4QvoKrqeWsLEQ8hdcojABeCV8ybVyZmeg==", + "version": "0.2.45", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.45.tgz", + "integrity": "sha512-5rYbXq1ndtMTg+07oH4WrkYuP+NZq61uzVwW1hlmybp/gr4cXq2SfaP9fc6/9IzTKmu3dh3H0fjj++HG7Z7o/w==", "dev": true, "requires": { - "@firebase/app": "0.10.13", - "@firebase/component": "0.6.9", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.10.0", + "@firebase/app": "0.10.15", + "@firebase/component": "0.6.10", + "@firebase/logger": "0.4.3", + "@firebase/util": "1.10.1", "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/component": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", + "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", + "dev": true, + "requires": { + "@firebase/util": "1.10.1", + "tslib": "^2.1.0" + } + }, + "@firebase/logger": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", + "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@firebase/util": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", + "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } } }, "@firebase/app-types": { From 8bb56916964369dc73b5b759c1913de01cdbe110 Mon Sep 17 00:00:00 2001 From: Harshkant Date: Wed, 30 Oct 2024 22:59:03 +0530 Subject: [PATCH 198/323] Request timeout const name correction (#2743) * request timeout value correction * request timeout constant name change --------- Co-authored-by: Lahiru Maramba --- src/messaging/batch-request-internal.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/messaging/batch-request-internal.ts b/src/messaging/batch-request-internal.ts index 7f87d7bde1..e876fdcbd4 100644 --- a/src/messaging/batch-request-internal.ts +++ b/src/messaging/batch-request-internal.ts @@ -20,7 +20,7 @@ import { import { FirebaseAppError, AppErrorCodes } from '../utils/error'; const PART_BOUNDARY = '__END_OF_PART__'; -const TEN_SECONDS_IN_MILLIS = 15000; +const FIFTEEN_SECONDS_IN_MILLIS = 15000; /** * Represents a request that can be sent as part of an HTTP batch request. @@ -72,7 +72,7 @@ export class BatchRequestClient { url: this.batchUrl, data: this.getMultipartPayload(requests), headers: Object.assign({}, this.commonHeaders, requestHeaders), - timeout: TEN_SECONDS_IN_MILLIS, + timeout: FIFTEEN_SECONDS_IN_MILLIS, }; return this.httpClient.send(request).then((response) => { if (!response.multipart) { From 2144b12d19ca38909617369557d5ed5c897e4ba8 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 4 Nov 2024 15:12:46 -0500 Subject: [PATCH 199/323] change: Migrate credentials to use google-auth-library (#2466) * Convert Service account, refresh token, and compute engine types to use google-auth * Validate credential files * update tests * Update tests * Remove obsolete unit tests * fix package.json * clean up comments * fix integration tests * fix integration tests * fix auth client init process --- package-lock.json | 70 +-- package.json | 1 + src/app/credential-internal.ts | 543 +++++++----------- .../functions-api-client-internal.ts | 5 +- src/utils/index.ts | 6 +- test/resources/mocks.ts | 8 +- test/unit/app/credential-internal.spec.ts | 393 +------------ test/unit/app/firebase-namespace.spec.ts | 13 +- test/unit/app/index.spec.ts | 10 +- test/unit/firebase.spec.ts | 7 +- test/unit/firestore/firestore.spec.ts | 5 +- test/unit/utils/index.spec.ts | 22 - 12 files changed, 262 insertions(+), 821 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1759c62455..c4961706c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@firebase/database-types": "1.0.5", "@types/node": "^22.0.1", "farmhash-modern": "^1.1.0", + "google-auth-library": "^9.14.2", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", "node-forge": "^1.3.1", @@ -2334,7 +2335,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "optional": true, "dependencies": { "debug": "^4.3.4" }, @@ -2923,7 +2923,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "devOptional": true, "funding": [ { "type": "github", @@ -2966,7 +2965,6 @@ "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "optional": true, "engines": { "node": "*" } @@ -4372,8 +4370,7 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "devOptional": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "node_modules/extend-shallow": { "version": "3.0.2", @@ -4957,7 +4954,6 @@ "version": "6.6.0", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz", "integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==", - "optional": true, "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", @@ -4977,7 +4973,6 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "optional": true, "bin": { "uuid": "dist/bin/uuid" } @@ -4986,7 +4981,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", - "optional": true, "dependencies": { "gaxios": "^6.0.0", "json-bigint": "^1.0.0" @@ -5265,10 +5259,10 @@ } }, "node_modules/google-auth-library": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.10.0.tgz", - "integrity": "sha512-ol+oSa5NbcGdDqA+gZ3G3mev59OHBZksBTxY/tYwjtcp1H/scAFwJfSQU9/1RALoyZ7FslNbke8j4i3ipwlyuQ==", - "optional": true, + "version": "9.14.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.2.tgz", + "integrity": "sha512-R+FRIfk1GBo3RdlRYWPdwk8nmtVUOn6+BkDomAC46KoU8kzXzE1HLmOasSCbWUByMMAGkknVF0G5kQ69Vj7dlA==", + "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", @@ -5345,7 +5339,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "optional": true, "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" @@ -6149,7 +6142,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "optional": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -6611,7 +6603,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "devOptional": true, "engines": { "node": ">=8" }, @@ -6989,7 +6980,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "optional": true, "dependencies": { "bignumber.js": "^9.0.0" } @@ -7116,7 +7106,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -7151,7 +7140,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" @@ -7857,7 +7845,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "devOptional": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -10465,8 +10452,7 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "devOptional": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/ts-node": { "version": "10.9.2", @@ -10982,8 +10968,7 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "devOptional": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/websocket-driver": { "version": "0.7.4", @@ -11010,7 +10995,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "devOptional": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -13040,7 +13024,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "optional": true, "requires": { "debug": "^4.3.4" } @@ -13485,8 +13468,7 @@ "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "devOptional": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "bcrypt": { "version": "5.1.1", @@ -13510,8 +13492,7 @@ "bignumber.js": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "optional": true + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" }, "binary-extensions": { "version": "2.3.0", @@ -14580,8 +14561,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "devOptional": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", @@ -15022,7 +15002,6 @@ "version": "6.6.0", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz", "integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==", - "optional": true, "requires": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", @@ -15034,8 +15013,7 @@ "uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "optional": true + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" } } }, @@ -15043,7 +15021,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", - "optional": true, "requires": { "gaxios": "^6.0.0", "json-bigint": "^1.0.0" @@ -15250,10 +15227,9 @@ } }, "google-auth-library": { - "version": "9.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.10.0.tgz", - "integrity": "sha512-ol+oSa5NbcGdDqA+gZ3G3mev59OHBZksBTxY/tYwjtcp1H/scAFwJfSQU9/1RALoyZ7FslNbke8j4i3ipwlyuQ==", - "optional": true, + "version": "9.14.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.2.tgz", + "integrity": "sha512-R+FRIfk1GBo3RdlRYWPdwk8nmtVUOn6+BkDomAC46KoU8kzXzE1HLmOasSCbWUByMMAGkknVF0G5kQ69Vj7dlA==", "requires": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", @@ -15316,7 +15292,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "optional": true, "requires": { "gaxios": "^6.0.0", "jws": "^4.0.0" @@ -15965,7 +15940,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "optional": true, "requires": { "agent-base": "^7.0.2", "debug": "4" @@ -16281,8 +16255,7 @@ "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "devOptional": true + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" }, "is-string": { "version": "1.0.7", @@ -16564,7 +16537,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "optional": true, "requires": { "bignumber.js": "^9.0.0" } @@ -16680,7 +16652,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -16714,7 +16685,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, "requires": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" @@ -17300,7 +17270,6 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "devOptional": true, "requires": { "whatwg-url": "^5.0.0" } @@ -19300,8 +19269,7 @@ "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "devOptional": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "ts-node": { "version": "10.9.2", @@ -19684,8 +19652,7 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "devOptional": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "websocket-driver": { "version": "0.7.4", @@ -19706,7 +19673,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "devOptional": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/package.json b/package.json index 0b29a03372..c61ecd58fa 100644 --- a/package.json +++ b/package.json @@ -209,6 +209,7 @@ "@firebase/database-types": "1.0.5", "@types/node": "^22.0.1", "farmhash-modern": "^1.1.0", + "google-auth-library": "^9.14.2", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", "node-forge": "^1.3.1", diff --git a/src/app/credential-internal.ts b/src/app/credential-internal.ts index 94ac1ea844..2d240cc301 100644 --- a/src/app/credential-internal.ts +++ b/src/app/credential-internal.ts @@ -16,45 +16,92 @@ */ import fs = require('fs'); -import os = require('os'); -import path = require('path'); +import { Credentials as GoogleAuthCredentials, GoogleAuth, Compute, AnyAuthClient } from 'google-auth-library' import { Agent } from 'http'; import { Credential, GoogleOAuthAccessToken } from './credential'; import { AppErrorCodes, FirebaseAppError } from '../utils/error'; -import { HttpClient, HttpRequestConfig, RequestResponseError, RequestResponse } from '../utils/api-request'; import * as util from '../utils/validator'; -const GOOGLE_TOKEN_AUDIENCE = 'https://accounts.google.com/o/oauth2/token'; -const GOOGLE_AUTH_TOKEN_HOST = 'accounts.google.com'; -const GOOGLE_AUTH_TOKEN_PATH = '/o/oauth2/token'; - -// NOTE: the Google Metadata Service uses HTTP over a vlan -const GOOGLE_METADATA_SERVICE_HOST = 'metadata.google.internal'; -const GOOGLE_METADATA_SERVICE_TOKEN_PATH = '/computeMetadata/v1/instance/service-accounts/default/token'; -const GOOGLE_METADATA_SERVICE_IDENTITY_PATH = '/computeMetadata/v1/instance/service-accounts/default/identity'; -const GOOGLE_METADATA_SERVICE_PROJECT_ID_PATH = '/computeMetadata/v1/project/project-id'; -const GOOGLE_METADATA_SERVICE_ACCOUNT_ID_PATH = '/computeMetadata/v1/instance/service-accounts/default/email'; - -const configDir = (() => { - // Windows has a dedicated low-rights location for apps at ~/Application Data - const sys = os.platform(); - if (sys && sys.length >= 3 && sys.substring(0, 3).toLowerCase() === 'win') { - return process.env.APPDATA; +const SCOPES = [ + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/firebase.database', + 'https://www.googleapis.com/auth/firebase.messaging', + 'https://www.googleapis.com/auth/identitytoolkit', + 'https://www.googleapis.com/auth/userinfo.email', +]; + +/** + * Implementation of ADC that uses google-auth-library-nodejs. + */ +export class ApplicationDefaultCredential implements Credential { + + private readonly googleAuth: GoogleAuth; + private authClient: AnyAuthClient; + private projectId?: string; + private accountId?: string; + + constructor(httpAgent?: Agent) { + this.googleAuth = new GoogleAuth({ + scopes: SCOPES, + clientOptions: { + transporterOptions: { + agent: httpAgent, + }, + }, + }); } - // On *nix the gcloud cli creates a . dir. - return process.env.HOME && path.resolve(process.env.HOME, '.config'); -})(); + public async getAccessToken(): Promise { + if (!this.authClient) { + this.authClient = await this.googleAuth.getClient(); + } + await this.authClient.getAccessToken(); + const credentials = this.authClient.credentials; + return populateCredential(credentials); + } -const GCLOUD_CREDENTIAL_SUFFIX = 'gcloud/application_default_credentials.json'; -const GCLOUD_CREDENTIAL_PATH = configDir && path.resolve(configDir, GCLOUD_CREDENTIAL_SUFFIX); + public async getProjectId(): Promise { + if (!this.projectId) { + this.projectId = await this.googleAuth.getProjectId(); + } + return Promise.resolve(this.projectId); + } -const REFRESH_TOKEN_HOST = 'www.googleapis.com'; -const REFRESH_TOKEN_PATH = '/oauth2/v4/token'; + public async isComputeEngineCredential(): Promise { + if (!this.authClient) { + this.authClient = await this.googleAuth.getClient(); + } + return Promise.resolve(this.authClient instanceof Compute); + } -const ONE_HOUR_IN_SECONDS = 60 * 60; -const JWT_ALGORITHM = 'RS256'; + /** + * getIDToken returns a OIDC token from the compute metadata service + * that can be used to make authenticated calls to audience + * @param audience the URL the returned ID token will be used to call. +*/ + public async getIDToken(audience: string): Promise { + if (await this.isComputeEngineCredential()) { + return (this.authClient as Compute).fetchIdToken(audience); + } + else { + throw new FirebaseAppError( + AppErrorCodes.INVALID_CREDENTIAL, + 'Credentials type should be Compute Engine Credentials.', + ); + } + } + + public async getServiceAccountEmail(): Promise { + if (this.accountId) { + return Promise.resolve(this.accountId); + } + + const { client_email: clientEmail } = await this.googleAuth.getCredentials(); + this.accountId = clientEmail ?? ''; + return Promise.resolve(this.accountId); + } +} /** * Implementation of Credential that uses a service account. @@ -65,20 +112,21 @@ export class ServiceAccountCredential implements Credential { public readonly privateKey: string; public readonly clientEmail: string; - private readonly httpClient: HttpClient; + private googleAuth: GoogleAuth; + private authClient: AnyAuthClient | undefined; /** * Creates a new ServiceAccountCredential from the given parameters. * * @param serviceAccountPathOrObject - Service account json object or path to a service account json file. * @param httpAgent - Optional http.Agent to use when calling the remote token server. - * @param implicit - An optinal boolean indicating whether this credential was implicitly discovered from the + * @param implicit - An optional boolean indicating whether this credential was implicitly discovered from the * environment, as opposed to being explicitly specified by the developer. * * @constructor */ constructor( - serviceAccountPathOrObject: string | object, + private readonly serviceAccountPathOrObject: string | object, private readonly httpAgent?: Agent, readonly implicit: boolean = false) { @@ -88,46 +136,26 @@ export class ServiceAccountCredential implements Credential { this.projectId = serviceAccount.projectId; this.privateKey = serviceAccount.privateKey; this.clientEmail = serviceAccount.clientEmail; - this.httpClient = new HttpClient(); } - public getAccessToken(): Promise { - const token = this.createAuthJwt_(); - const postData = 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3A' + - 'grant-type%3Ajwt-bearer&assertion=' + token; - const request: HttpRequestConfig = { - method: 'POST', - url: `https://${GOOGLE_AUTH_TOKEN_HOST}${GOOGLE_AUTH_TOKEN_PATH}`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - data: postData, - httpAgent: this.httpAgent, - }; - return requestAccessToken(this.httpClient, request); + private getGoogleAuth(): GoogleAuth { + if (this.googleAuth) { + return this.googleAuth; + } + const { auth, client } = populateGoogleAuth(this.serviceAccountPathOrObject, this.httpAgent); + this.googleAuth = auth; + this.authClient = client; + return this.googleAuth; } - // eslint-disable-next-line @typescript-eslint/naming-convention - private createAuthJwt_(): string { - const claims = { - scope: [ - 'https://www.googleapis.com/auth/cloud-platform', - 'https://www.googleapis.com/auth/firebase.database', - 'https://www.googleapis.com/auth/firebase.messaging', - 'https://www.googleapis.com/auth/identitytoolkit', - 'https://www.googleapis.com/auth/userinfo.email', - ].join(' '), - }; - - // eslint-disable-next-line @typescript-eslint/no-var-requires - const jwt = require('jsonwebtoken'); - // This method is actually synchronous so we can capture and return the buffer. - return jwt.sign(claims, this.privateKey, { - audience: GOOGLE_TOKEN_AUDIENCE, - expiresIn: ONE_HOUR_IN_SECONDS, - issuer: this.clientEmail, - algorithm: JWT_ALGORITHM, - }); + public async getAccessToken(): Promise { + const googleAuth = this.getGoogleAuth(); + if (this.authClient === undefined) { + this.authClient = await googleAuth.getClient(); + } + await this.authClient.getAccessToken(); + const credentials = this.authClient.credentials; + return populateCredential(credentials); } } @@ -189,96 +217,13 @@ class ServiceAccount { } } -/** - * Implementation of Credential that gets access tokens from the metadata service available - * in the Google Cloud Platform. This authenticates the process as the default service account - * of an App Engine instance or Google Compute Engine machine. - */ -export class ComputeEngineCredential implements Credential { - - private readonly httpClient = new HttpClient(); - private readonly httpAgent?: Agent; - private projectId?: string; - private accountId?: string; - - constructor(httpAgent?: Agent) { - this.httpAgent = httpAgent; - } - - public getAccessToken(): Promise { - const request = this.buildRequest(GOOGLE_METADATA_SERVICE_TOKEN_PATH); - return requestAccessToken(this.httpClient, request); - } - - /** - * getIDToken returns a OIDC token from the compute metadata service - * that can be used to make authenticated calls to audience - * @param audience the URL the returned ID token will be used to call. - */ - public getIDToken(audience: string): Promise { - const request = this.buildRequest(`${GOOGLE_METADATA_SERVICE_IDENTITY_PATH}?audience=${audience}`); - return requestIDToken(this.httpClient, request); - } - - public getProjectId(): Promise { - if (this.projectId) { - return Promise.resolve(this.projectId); - } - - const request = this.buildRequest(GOOGLE_METADATA_SERVICE_PROJECT_ID_PATH); - return this.httpClient.send(request) - .then((resp) => { - this.projectId = resp.text!; - return this.projectId; - }) - .catch((err) => { - const detail: string = - (err instanceof RequestResponseError) ? getDetailFromResponse(err.response) : err.message; - throw new FirebaseAppError( - AppErrorCodes.INVALID_CREDENTIAL, - `Failed to determine project ID: ${detail}`); - }); - } - - public getServiceAccountEmail(): Promise { - if (this.accountId) { - return Promise.resolve(this.accountId); - } - - const request = this.buildRequest(GOOGLE_METADATA_SERVICE_ACCOUNT_ID_PATH); - return this.httpClient.send(request) - .then((resp) => { - this.accountId = resp.text!; - return this.accountId; - }) - .catch((err) => { - const detail: string = - (err instanceof RequestResponseError) ? getDetailFromResponse(err.response) : err.message; - throw new FirebaseAppError( - AppErrorCodes.INVALID_CREDENTIAL, - `Failed to determine service account email: ${detail}`); - }); - } - - private buildRequest(urlPath: string): HttpRequestConfig { - return { - method: 'GET', - url: `http://${GOOGLE_METADATA_SERVICE_HOST}${urlPath}`, - headers: { - 'Metadata-Flavor': 'Google', - }, - httpAgent: this.httpAgent, - }; - } -} - /** * Implementation of Credential that gets access tokens from refresh tokens. */ export class RefreshTokenCredential implements Credential { - private readonly refreshToken: RefreshToken; - private readonly httpClient: HttpClient; + private googleAuth: GoogleAuth; + private authClient: AnyAuthClient | undefined; /** * Creates a new RefreshTokenCredential from the given parameters. @@ -292,32 +237,33 @@ export class RefreshTokenCredential implements Credential { * @constructor */ constructor( - refreshTokenPathOrObject: string | object, + private readonly refreshTokenPathOrObject: string | object, private readonly httpAgent?: Agent, readonly implicit: boolean = false) { - this.refreshToken = (typeof refreshTokenPathOrObject === 'string') ? - RefreshToken.fromPath(refreshTokenPathOrObject) - : new RefreshToken(refreshTokenPathOrObject); - this.httpClient = new HttpClient(); + (typeof refreshTokenPathOrObject === 'string') ? + RefreshToken.validateFromPath(refreshTokenPathOrObject) + : RefreshToken.validateFromJSON(refreshTokenPathOrObject); } - public getAccessToken(): Promise { - const postData = - 'client_id=' + this.refreshToken.clientId + '&' + - 'client_secret=' + this.refreshToken.clientSecret + '&' + - 'refresh_token=' + this.refreshToken.refreshToken + '&' + - 'grant_type=refresh_token'; - const request: HttpRequestConfig = { - method: 'POST', - url: `https://${REFRESH_TOKEN_HOST}${REFRESH_TOKEN_PATH}`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - data: postData, - httpAgent: this.httpAgent, - }; - return requestAccessToken(this.httpClient, request); + private getGoogleAuth(): GoogleAuth { + if (this.googleAuth) { + return this.googleAuth; + } + const { auth, client } = populateGoogleAuth(this.refreshTokenPathOrObject, this.httpAgent); + this.googleAuth = auth; + this.authClient = client; + return this.googleAuth; + } + + public async getAccessToken(): Promise { + const googleAuth = this.getGoogleAuth(); + if (this.authClient === undefined) { + this.authClient = await googleAuth.getClient(); + } + await this.authClient.getAccessToken(); + const credentials = this.authClient.credentials; + return populateCredential(credentials); } } @@ -332,9 +278,9 @@ class RefreshToken { * Tries to load a RefreshToken from a path. Throws if the path doesn't exist or the * data at the path is invalid. */ - public static fromPath(filePath: string): RefreshToken { + public static validateFromPath(filePath: string): void { try { - return new RefreshToken(JSON.parse(fs.readFileSync(filePath, 'utf8'))); + RefreshToken.validateFromJSON(JSON.parse(fs.readFileSync(filePath, 'utf8'))); } catch (error) { // Throw a nicely formed error message if the file contents cannot be parsed throw new FirebaseAppError( @@ -344,20 +290,23 @@ class RefreshToken { } } - constructor(json: object) { - copyAttr(this, json, 'clientId', 'client_id'); - copyAttr(this, json, 'clientSecret', 'client_secret'); - copyAttr(this, json, 'refreshToken', 'refresh_token'); - copyAttr(this, json, 'type', 'type'); + public static validateFromJSON(json: object): void { + + const creds = { clientId: '', clientSecret: '', refreshToken: '', type: '' }; + + copyAttr(creds, json, 'clientId', 'client_id'); + copyAttr(creds, json, 'clientSecret', 'client_secret'); + copyAttr(creds, json, 'refreshToken', 'refresh_token'); + copyAttr(creds, json, 'type', 'type'); let errorMessage; - if (!util.isNonEmptyString(this.clientId)) { + if (!util.isNonEmptyString(creds.clientId)) { errorMessage = 'Refresh token must contain a "client_id" property.'; - } else if (!util.isNonEmptyString(this.clientSecret)) { + } else if (!util.isNonEmptyString(creds.clientSecret)) { errorMessage = 'Refresh token must contain a "client_secret" property.'; - } else if (!util.isNonEmptyString(this.refreshToken)) { + } else if (!util.isNonEmptyString(creds.refreshToken)) { errorMessage = 'Refresh token must contain a "refresh_token" property.'; - } else if (!util.isNonEmptyString(this.type)) { + } else if (!util.isNonEmptyString(creds.type)) { errorMessage = 'Refresh token must contain a "type" property.'; } @@ -367,14 +316,13 @@ class RefreshToken { } } - /** * Implementation of Credential that uses impersonated service account. */ export class ImpersonatedServiceAccountCredential implements Credential { - private readonly impersonatedServiceAccount: ImpersonatedServiceAccount; - private readonly httpClient: HttpClient; + private googleAuth: GoogleAuth; + private authClient: AnyAuthClient | undefined; /** * Creates a new ImpersonatedServiceAccountCredential from the given parameters. @@ -388,52 +336,48 @@ export class ImpersonatedServiceAccountCredential implements Credential { * @constructor */ constructor( - impersonatedServiceAccountPathOrObject: string | object, + private readonly impersonatedServiceAccountPathOrObject: string | object, private readonly httpAgent?: Agent, readonly implicit: boolean = false) { - this.impersonatedServiceAccount = (typeof impersonatedServiceAccountPathOrObject === 'string') ? - ImpersonatedServiceAccount.fromPath(impersonatedServiceAccountPathOrObject) - : new ImpersonatedServiceAccount(impersonatedServiceAccountPathOrObject); - this.httpClient = new HttpClient(); + (typeof impersonatedServiceAccountPathOrObject === 'string') ? + ImpersonatedServiceAccount.validateFromPath(impersonatedServiceAccountPathOrObject) + : ImpersonatedServiceAccount.validateFromJSON(impersonatedServiceAccountPathOrObject); } - public getAccessToken(): Promise { - const postData = - 'client_id=' + this.impersonatedServiceAccount.clientId + '&' + - 'client_secret=' + this.impersonatedServiceAccount.clientSecret + '&' + - 'refresh_token=' + this.impersonatedServiceAccount.refreshToken + '&' + - 'grant_type=refresh_token'; - const request: HttpRequestConfig = { - method: 'POST', - url: `https://${REFRESH_TOKEN_HOST}${REFRESH_TOKEN_PATH}`, - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - data: postData, - httpAgent: this.httpAgent, - }; - return requestAccessToken(this.httpClient, request); + private getGoogleAuth(): GoogleAuth { + if (this.googleAuth) { + return this.googleAuth; + } + const { auth, client } = populateGoogleAuth(this.impersonatedServiceAccountPathOrObject, this.httpAgent); + this.googleAuth = auth; + this.authClient = client; + return this.googleAuth; + } + + public async getAccessToken(): Promise { + const googleAuth = this.getGoogleAuth(); + if (this.authClient === undefined) { + this.authClient = await googleAuth.getClient(); + } + await this.authClient.getAccessToken(); + const credentials = this.authClient.credentials; + return populateCredential(credentials); } } /** - * A struct containing the properties necessary to use impersonated service account JSON credentials. + * A helper class to validate the properties necessary to use impersonated service account credentials. */ class ImpersonatedServiceAccount { - public readonly clientId: string; - public readonly clientSecret: string; - public readonly refreshToken: string; - public readonly type: string; - /* * Tries to load a ImpersonatedServiceAccount from a path. Throws if the path doesn't exist or the * data at the path is invalid. */ - public static fromPath(filePath: string): ImpersonatedServiceAccount { + public static validateFromPath(filePath: string): void { try { - return new ImpersonatedServiceAccount(JSON.parse(fs.readFileSync(filePath, 'utf8'))); + ImpersonatedServiceAccount.validateFromJSON(JSON.parse(fs.readFileSync(filePath, 'utf8'))); } catch (error) { // Throw a nicely formed error message if the file contents cannot be parsed throw new FirebaseAppError( @@ -443,23 +387,19 @@ class ImpersonatedServiceAccount { } } - constructor(json: object) { - const sourceCredentials = (json as {[key: string]: any})['source_credentials'] - if (sourceCredentials) { - copyAttr(this, sourceCredentials, 'clientId', 'client_id'); - copyAttr(this, sourceCredentials, 'clientSecret', 'client_secret'); - copyAttr(this, sourceCredentials, 'refreshToken', 'refresh_token'); - copyAttr(this, sourceCredentials, 'type', 'type'); - } + public static validateFromJSON(json: object): void { + const { + client_id: clientId, client_secret: clientSecret, refresh_token: refreshToken, type + } = (json as { [key: string]: any })['source_credentials']; let errorMessage; - if (!util.isNonEmptyString(this.clientId)) { + if (!util.isNonEmptyString(clientId)) { errorMessage = 'Impersonated Service Account must contain a "source_credentials.client_id" property.'; - } else if (!util.isNonEmptyString(this.clientSecret)) { + } else if (!util.isNonEmptyString(clientSecret)) { errorMessage = 'Impersonated Service Account must contain a "source_credentials.client_secret" property.'; - } else if (!util.isNonEmptyString(this.refreshToken)) { + } else if (!util.isNonEmptyString(refreshToken)) { errorMessage = 'Impersonated Service Account must contain a "source_credentials.refresh_token" property.'; - } else if (!util.isNonEmptyString(this.type)) { + } else if (!util.isNonEmptyString(type)) { errorMessage = 'Impersonated Service Account must contain a "source_credentials.type" property.'; } @@ -470,32 +410,17 @@ class ImpersonatedServiceAccount { } /** - * Checks if the given credential was loaded via the application default credentials mechanism. This - * includes all ComputeEngineCredential instances, and the ServiceAccountCredential and RefreshTokenCredential - * instances that were loaded from well-known files or environment variables, rather than being explicitly - * instantiated. + * Checks if the given credential was loaded via the application default credentials mechanism. * * @param credential - The credential instance to check. */ export function isApplicationDefault(credential?: Credential): boolean { - return credential instanceof ComputeEngineCredential || - (credential instanceof ServiceAccountCredential && credential.implicit) || - (credential instanceof RefreshTokenCredential && credential.implicit) || - (credential instanceof ImpersonatedServiceAccountCredential && credential.implicit); + return credential instanceof ApplicationDefaultCredential || + (credential instanceof RefreshTokenCredential && credential.implicit); } export function getApplicationDefault(httpAgent?: Agent): Credential { - if (process.env.GOOGLE_APPLICATION_CREDENTIALS) { - return credentialFromFile(process.env.GOOGLE_APPLICATION_CREDENTIALS, httpAgent, false)!; - } - - // It is OK to not have this file. If it is present, it must be valid. - if (GCLOUD_CREDENTIAL_PATH) { - const credential = credentialFromFile(GCLOUD_CREDENTIAL_PATH, httpAgent, true); - if (credential) return credential - } - - return new ComputeEngineCredential(httpAgent); + return new ApplicationDefaultCredential(httpAgent); } /** @@ -509,7 +434,7 @@ export function getApplicationDefault(httpAgent?: Agent): Credential { * @param key - Name of the property to copy. * @param alt - Alternative name of the property to copy. */ -function copyAttr(to: {[key: string]: any}, from: {[key: string]: any}, key: string, alt: string): void { +function copyAttr(to: { [key: string]: any }, from: { [key: string]: any }, key: string, alt: string): void { const tmp = from[key] || from[alt]; if (typeof tmp !== 'undefined') { to[key] = tmp; @@ -517,114 +442,56 @@ function copyAttr(to: {[key: string]: any}, from: {[key: string]: any}, key: str } /** - * Obtain a new OAuth2 token by making a remote service call. + * Populate google-auth-library GoogleAuth credentials type. */ -function requestAccessToken(client: HttpClient, request: HttpRequestConfig): Promise { - return client.send(request).then((resp) => { - const json = resp.data; - if (!json.access_token || !json.expires_in) { - throw new FirebaseAppError( - AppErrorCodes.INVALID_CREDENTIAL, - `Unexpected response while fetching access token: ${ JSON.stringify(json) }`, - ); - } - return json; - }).catch((err) => { - throw new FirebaseAppError(AppErrorCodes.INVALID_CREDENTIAL, getErrorMessage(err)); +function populateGoogleAuth(keyFile: string | object, httpAgent?: Agent) + : { auth: GoogleAuth, client: AnyAuthClient | undefined } { + let client: AnyAuthClient | undefined; + const auth = new GoogleAuth({ + scopes: SCOPES, + clientOptions: { + transporterOptions: { + agent: httpAgent, + }, + }, + keyFile: (typeof keyFile === 'string') ? keyFile : undefined, }); -} -/** - * Obtain a new OIDC token by making a remote service call. - */ -function requestIDToken(client: HttpClient, request: HttpRequestConfig): Promise { - return client.send(request).then((resp) => { - if (!resp.text) { + if (typeof keyFile === 'object') { + if (!util.isNonNullObject(keyFile)) { throw new FirebaseAppError( AppErrorCodes.INVALID_CREDENTIAL, - 'Unexpected response while fetching id token: response.text is undefined', + 'Service account must be an object.', ); } - return resp.text; - }).catch((err) => { - throw new FirebaseAppError(AppErrorCodes.INVALID_CREDENTIAL, getErrorMessage(err)); - }); -} - -/** - * Constructs a human-readable error message from the given Error. - */ -function getErrorMessage(err: Error): string { - const detail: string = (err instanceof RequestResponseError) ? getDetailFromResponse(err.response) : err.message; - return `Error fetching access token: ${detail}`; + client = auth.fromJSON(keyFile); + } + return { auth, client }; } /** - * Extracts details from the given HTTP error response, and returns a human-readable description. If - * the response is JSON-formatted, looks up the error and error_description fields sent by the - * Google Auth servers. Otherwise returns the entire response payload as the error detail. + * Populate GoogleOAuthAccessToken credentials from google-auth-library Credentials type. */ -function getDetailFromResponse(response: RequestResponse): string { - if (response.isJson() && response.data.error) { - const json = response.data; - let detail = json.error; - if (json.error_description) { - detail += ' (' + json.error_description + ')'; - } - return detail; - } - return response.text || 'Missing error payload'; -} +function populateCredential(credentials?: GoogleAuthCredentials): GoogleOAuthAccessToken { + const accessToken = credentials?.access_token; + const expiryDate = credentials?.expiry_date; -function credentialFromFile(filePath: string, httpAgent?: Agent, ignoreMissing?: boolean): Credential | null { - const credentialsFile = readCredentialFile(filePath, ignoreMissing); - if (typeof credentialsFile !== 'object' || credentialsFile === null) { - if (ignoreMissing) { return null; } + if (typeof accessToken !== 'string') throw new FirebaseAppError( AppErrorCodes.INVALID_CREDENTIAL, - 'Failed to parse contents of the credentials file as an object', + 'Failed to parse Google auth credential: access_token must be a non empty string.', ); - } - - if (credentialsFile.type === 'service_account') { - return new ServiceAccountCredential(credentialsFile, httpAgent, true); - } - - if (credentialsFile.type === 'authorized_user') { - return new RefreshTokenCredential(credentialsFile, httpAgent, true); - } - - if (credentialsFile.type === 'impersonated_service_account') { - return new ImpersonatedServiceAccountCredential(credentialsFile, httpAgent, true) - } - - throw new FirebaseAppError( - AppErrorCodes.INVALID_CREDENTIAL, - 'Invalid contents in the credentials file', - ); -} - -function readCredentialFile(filePath: string, ignoreMissing?: boolean): {[key: string]: any} | null { - let fileText: string; - try { - fileText = fs.readFileSync(filePath, 'utf8'); - } catch (error) { - if (ignoreMissing) { - return null; - } - + if (typeof expiryDate !== 'number') throw new FirebaseAppError( AppErrorCodes.INVALID_CREDENTIAL, - `Failed to read credentials from file ${filePath}: ` + error, + 'Failed to parse Google auth credential: Invalid expiry_date.', ); - } - try { - return JSON.parse(fileText); - } catch (error) { - throw new FirebaseAppError( - AppErrorCodes.INVALID_CREDENTIAL, - 'Failed to parse contents of the credentials file as an object: ' + error, - ); + return { + ...credentials, + access_token: accessToken, + // inverse operation of following + // https://github.com/googleapis/google-auth-library-nodejs/blob/5ed910513451c82e2551777a3e2212964799ef8e/src/auth/baseexternalclient.ts#L446-L446 + expires_in: Math.floor((expiryDate - new Date().getTime()) / 1000), } } diff --git a/src/functions/functions-api-client-internal.ts b/src/functions/functions-api-client-internal.ts index e020a70921..c3c3859c0d 100644 --- a/src/functions/functions-api-client-internal.ts +++ b/src/functions/functions-api-client-internal.ts @@ -24,7 +24,7 @@ import { PrefixedFirebaseError } from '../utils/error'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; import { TaskOptions } from './functions-api'; -import { ComputeEngineCredential } from '../app/credential-internal'; +import { ApplicationDefaultCredential } from '../app/credential-internal'; const CLOUD_TASKS_API_RESOURCE_PATH = 'projects/{projectId}/locations/{locationId}/queues/{resourceId}/tasks'; const CLOUD_TASKS_API_URL_FORMAT = 'https://cloudtasks.googleapis.com/v2/' + CLOUD_TASKS_API_RESOURCE_PATH; @@ -319,7 +319,8 @@ export class FunctionsApiClient { task.httpRequest.url = functionUrl; // When run from a deployed extension, we should be using ComputeEngineCredentials - if (validator.isNonEmptyString(extensionId) && this.app.options.credential instanceof ComputeEngineCredential) { + if (validator.isNonEmptyString(extensionId) && this.app.options.credential + instanceof ApplicationDefaultCredential && await this.app.options.credential.isComputeEngineCredential()) { const idToken = await this.app.options.credential.getIDToken(functionUrl); task.httpRequest.headers = { ...task.httpRequest.headers, 'Authorization': `Bearer ${idToken}` }; // Don't send httpRequest.oidcToken if we set Authorization header, or Cloud Tasks will overwrite it. diff --git a/src/utils/index.ts b/src/utils/index.ts index 824d41c0f9..ebc405ad8e 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -17,7 +17,7 @@ import { App } from '../app/index'; import { - ServiceAccountCredential, ComputeEngineCredential + ServiceAccountCredential, ApplicationDefaultCredential } from '../app/credential-internal'; import * as validator from './validator'; @@ -113,7 +113,7 @@ export function findProjectId(app: App): Promise { } const credential = app.options.credential; - if (credential instanceof ComputeEngineCredential) { + if (credential instanceof ApplicationDefaultCredential) { return credential.getProjectId(); } @@ -160,7 +160,7 @@ export function findServiceAccountEmail(app: App): Promise { } const credential = app.options.credential; - if (credential instanceof ComputeEngineCredential) { + if (credential instanceof ApplicationDefaultCredential) { return credential.getServiceAccountEmail(); } diff --git a/test/resources/mocks.ts b/test/resources/mocks.ts index 626e9663cb..d4afddd879 100644 --- a/test/resources/mocks.ts +++ b/test/resources/mocks.ts @@ -30,7 +30,7 @@ import * as sinon from 'sinon'; import { AppOptions } from '../../src/firebase-namespace-api'; import { FirebaseApp } from '../../src/app/firebase-app'; import { Credential, GoogleOAuthAccessToken, cert } from '../../src/app/index'; -import { ComputeEngineCredential } from '../../src/app/credential-internal'; +import { ApplicationDefaultCredential } from '../../src/app/credential-internal'; const ALGORITHM = 'RS256' as const; const ONE_HOUR_IN_SECONDS = 60 * 60; @@ -93,7 +93,7 @@ export class MockCredential implements Credential { } } -export class MockComputeEngineCredential extends ComputeEngineCredential { +export class MockComputeEngineCredential extends ApplicationDefaultCredential { public getAccessToken(): Promise { return Promise.resolve({ access_token: 'mock-token', @@ -104,6 +104,10 @@ export class MockComputeEngineCredential extends ComputeEngineCredential { public getIDToken(): Promise { return Promise.resolve('mockIdToken'); } + + public isComputeEngineCredential(): Promise { + return Promise.resolve(true); + } } export function app(altName?: string): FirebaseApp { diff --git a/test/unit/app/credential-internal.spec.ts b/test/unit/app/credential-internal.spec.ts index 93afa1fe9f..f37716e998 100644 --- a/test/unit/app/credential-internal.spec.ts +++ b/test/unit/app/credential-internal.spec.ts @@ -23,24 +23,19 @@ import path = require('path'); import * as _ from 'lodash'; import * as chai from 'chai'; -import * as nock from 'nock'; import * as sinon from 'sinon'; import * as sinonChai from 'sinon-chai'; import * as chaiAsPromised from 'chai-as-promised'; -import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; import { - GoogleOAuthAccessToken, Credential + Credential } from '../../../src/app/index'; import { RefreshTokenCredential, ServiceAccountCredential, - ComputeEngineCredential, getApplicationDefault, isApplicationDefault, ImpersonatedServiceAccountCredential + getApplicationDefault, isApplicationDefault, ImpersonatedServiceAccountCredential, ApplicationDefaultCredential } from '../../../src/app/credential-internal'; -import { HttpClient } from '../../../src/utils/api-request'; -import { Agent } from 'https'; -import { FirebaseAppError } from '../../../src/utils/error'; import { deepCopy } from '../../../src/utils/deep-copy'; chai.should(); @@ -54,12 +49,6 @@ if (!process.env.HOME) { throw new Error('$HOME environment variable must be set to run the tests.'); } const GCLOUD_CREDENTIAL_PATH = path.resolve(process.env.HOME!, '.config', GCLOUD_CREDENTIAL_SUFFIX); -const MOCK_REFRESH_TOKEN_CONFIG = { - client_id: 'test_client_id', - client_secret: 'test_client_secret', - type: 'authorized_user', - refresh_token: 'test_token', -}; const MOCK_IMPERSONATED_TOKEN_CONFIG = { delegates: [], service_account_impersonation_url: '', @@ -72,30 +61,9 @@ const MOCK_IMPERSONATED_TOKEN_CONFIG = { type: 'impersonated_service_account' } -const ONE_HOUR_IN_SECONDS = 60 * 60; -const FIVE_MINUTES_IN_SECONDS = 5 * 60; - - describe('Credential', () => { let mockCertificateObject: any; let oldProcessEnv: NodeJS.ProcessEnv; - let getTokenScope: nock.Scope; - let mockedRequests: nock.Scope[] = []; - - before(() => { - getTokenScope = nock('https://accounts.google.com') - .persist() - .post('/o/oauth2/token') - .reply(200, { - access_token: utils.generateRandomAccessToken(), - token_type: 'Bearer', - expires_in: 3600, - }, { - 'cache-control': 'no-cache, no-store, max-age=0, must-revalidate', - }); - }); - - after(() => getTokenScope.done()); beforeEach(() => { mockCertificateObject = _.clone(mocks.certificateObject); @@ -103,8 +71,6 @@ describe('Credential', () => { }); afterEach(() => { - _.forEach(mockedRequests, (mockedRequest) => mockedRequest.done()); - mockedRequests = []; process.env = oldProcessEnv; }); @@ -212,46 +178,6 @@ describe('Credential', () => { implicit: true, }); }); - - it('should create access tokens', () => { - const c = new ServiceAccountCredential(mockCertificateObject); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.be.a('string').and.to.not.be.empty; - expect(token.expires_in).to.equal(ONE_HOUR_IN_SECONDS); - }); - }); - - describe('Error Handling', () => { - let httpStub: sinon.SinonStub; - before(() => { - httpStub = sinon.stub(HttpClient.prototype, 'send'); - }); - after(() => httpStub.restore()); - - it('should throw an error including error details', () => { - httpStub.rejects(utils.errorFrom({ - error: 'invalid_grant', - error_description: 'reason', - })); - const c = new ServiceAccountCredential(mockCertificateObject); - return expect(c.getAccessToken()).to.be - .rejectedWith('Error fetching access token: invalid_grant (reason)'); - }); - - it('should throw an error including error text payload', () => { - httpStub.rejects(utils.errorFrom('not json')); - const c = new ServiceAccountCredential(mockCertificateObject); - return expect(c.getAccessToken()).to.be - .rejectedWith('Error fetching access token: not json'); - }); - - it('should throw when the success response is malformed', () => { - httpStub.resolves(utils.responseFrom({})); - const c = new ServiceAccountCredential(mockCertificateObject); - return expect(c.getAccessToken()).to.be - .rejectedWith('Unexpected response while fetching access token'); - }); - }); }); describe('RefreshTokenCredential', () => { @@ -298,127 +224,6 @@ describe('Credential', () => { implicit: true, }); }); - - it('should create access tokens', () => { - const scope = nock('https://www.googleapis.com') - .post('/oauth2/v4/token') - .reply(200, { - access_token: 'token', - token_type: 'Bearer', - expires_in: 60 * 60, - }, { - 'cache-control': 'no-cache, no-store, max-age=0, must-revalidate', - }); - mockedRequests.push(scope); - - const c = new RefreshTokenCredential(mocks.refreshToken); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.be.a('string').and.to.not.be.empty; - expect(token.expires_in).to.greaterThan(FIVE_MINUTES_IN_SECONDS); - }); - }); - }); - - describe('ComputeEngineCredential', () => { - let httpStub: sinon.SinonStub; - beforeEach(() => httpStub = sinon.stub(HttpClient.prototype, 'send')); - afterEach(() => httpStub.restore()); - - it('should create access tokens', () => { - const expected: GoogleOAuthAccessToken = { - access_token: 'anAccessToken', - expires_in: 42, - }; - const response = utils.responseFrom(expected); - httpStub.resolves(response); - - const c = new ComputeEngineCredential(); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.equal('anAccessToken'); - expect(token.expires_in).to.equal(42); - expect(httpStub).to.have.been.calledOnce.and.calledWith({ - method: 'GET', - url: 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token', - headers: { 'Metadata-Flavor': 'Google' }, - httpAgent: undefined, - }); - }); - }); - - it('should create id tokens', () => { - const expected = 'an-id-token-encoded'; - const response = utils.responseFrom(expected); - httpStub.resolves(response); - - const c = new ComputeEngineCredential(); - return c.getIDToken('my-audience.cloudfunctions.net').then((token) => { - expect(token).to.equal(expected); - expect(httpStub).to.have.been.calledOnce.and.calledWith({ - method: 'GET', - url: 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=my-audience.cloudfunctions.net', - headers: { 'Metadata-Flavor': 'Google' }, - httpAgent: undefined, - }); - }); - }); - - it('should discover project id', () => { - const expectedProjectId = 'test-project-id'; - const response = utils.responseFrom(expectedProjectId); - httpStub.resolves(response); - - const c = new ComputeEngineCredential(); - return c.getProjectId().then((projectId) => { - expect(projectId).to.equal(expectedProjectId); - expect(httpStub).to.have.been.calledOnce.and.calledWith({ - method: 'GET', - url: 'http://metadata.google.internal/computeMetadata/v1/project/project-id', - headers: { 'Metadata-Flavor': 'Google' }, - httpAgent: undefined, - }); - }); - }); - - it('should cache discovered project id', () => { - const expectedProjectId = 'test-project-id'; - const response = utils.responseFrom(expectedProjectId); - httpStub.resolves(response); - - const c = new ComputeEngineCredential(); - return c.getProjectId() - .then((projectId) => { - expect(projectId).to.equal(expectedProjectId); - return c.getProjectId(); - }) - .then((projectId) => { - expect(projectId).to.equal(expectedProjectId); - expect(httpStub).to.have.been.calledOnce.and.calledWith({ - method: 'GET', - url: 'http://metadata.google.internal/computeMetadata/v1/project/project-id', - headers: { 'Metadata-Flavor': 'Google' }, - httpAgent: undefined, - }); - }); - }); - - it('should reject when the metadata service is not available', () => { - httpStub.rejects(new FirebaseAppError('network-error', 'Failed to connect')); - - const c = new ComputeEngineCredential(); - return c.getProjectId().should.eventually - .rejectedWith('Failed to determine project ID: Failed to connect') - .and.have.property('code', 'app/invalid-credential'); - }); - - it('should reject when the metadata service responds with an error', () => { - const response = utils.errorFrom('Unexpected error'); - httpStub.rejects(response); - - const c = new ComputeEngineCredential(); - return c.getProjectId().should.eventually - .rejectedWith('Failed to determine project ID: Unexpected error') - .and.have.property('code', 'app/invalid-credential'); - }); }); describe('ImpersonatedServiceAccountCredential', () => { @@ -469,25 +274,6 @@ describe('Credential', () => { implicit: true, }); }); - - it('should create access tokens', () => { - const scope = nock('https://www.googleapis.com') - .post('/oauth2/v4/token') - .reply(200, { - access_token: 'token', - token_type: 'Bearer', - expires_in: 60 * 60, - }, { - 'cache-control': 'no-cache, no-store, max-age=0, must-revalidate', - }); - mockedRequests.push(scope); - - const c = new ImpersonatedServiceAccountCredential(MOCK_IMPERSONATED_TOKEN_CONFIG); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.be.a('string').and.to.not.be.empty; - expect(token.expires_in).to.greaterThan(FIVE_MINUTES_IN_SECONDS); - }); - }); }); describe('getApplicationDefault()', () => { @@ -499,40 +285,10 @@ describe('Credential', () => { } }); - it('should return a CertCredential with GOOGLE_APPLICATION_CREDENTIALS set', () => { + it('should return an ApplicationDefaultCredential with GOOGLE_APPLICATION_CREDENTIALS set', () => { process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve(__dirname, '../../resources/mock.key.json'); const c = getApplicationDefault(); - expect(c).to.be.an.instanceof(ServiceAccountCredential); - }); - - it('should return a ImpersonatedCredential with impersonated GOOGLE_APPLICATION_CREDENTIALS set', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS - = path.resolve(__dirname, '../../resources/mock.impersonated_key.json'); - const c = getApplicationDefault(); - expect(c).to.be.an.instanceof(ImpersonatedServiceAccountCredential); - }); - - it('should throw if explicitly pointing to an invalid path', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS = 'invalidpath'; - expect(() => getApplicationDefault()).to.throw(Error); - }); - - it('should throw if explicitly pointing to an invalid cert file', () => { - fsStub = sinon.stub(fs, 'readFileSync').returns('invalidjson'); - expect(() => getApplicationDefault()).to.throw(Error); - }); - - it('should throw error if type not specified on cert file', () => { - fsStub = sinon.stub(fs, 'readFileSync').returns(JSON.stringify({})); - expect(() => getApplicationDefault()) - .to.throw(Error, 'Invalid contents in the credentials file'); - }); - - it('should throw error if type is unknown on cert file', () => { - fsStub = sinon.stub(fs, 'readFileSync').returns(JSON.stringify({ - type: 'foo', - })); - expect(() => getApplicationDefault()).to.throw(Error, 'Invalid contents in the credentials file'); + expect(c).to.be.an.instanceof(ApplicationDefaultCredential); }); it('should return a RefreshTokenCredential with gcloud login', () => { @@ -547,58 +303,10 @@ describe('Credential', () => { expect((getApplicationDefault())).to.be.an.instanceof(RefreshTokenCredential); }); - it('should throw if a the gcloud login cache is invalid', () => { - delete process.env.GOOGLE_APPLICATION_CREDENTIALS; - fsStub = sinon.stub(fs, 'readFileSync').returns('invalidjson'); - expect(() => getApplicationDefault()).to.throw(Error); - }); - - it('should throw if the credentials file content is not an object', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve(__dirname, '../../resources/mock.key.json'); - fsStub = sinon.stub(fs, 'readFileSync').returns('2'); - expect(() => getApplicationDefault()).to.throw(Error); - }); - it('should return a MetadataServiceCredential as a last resort', () => { delete process.env.GOOGLE_APPLICATION_CREDENTIALS; fsStub = sinon.stub(fs, 'readFileSync').throws(new Error('no gcloud credential file')); - expect(getApplicationDefault()).to.be.an.instanceof(ComputeEngineCredential); - }); - - it('should create access tokens', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve(__dirname, '../../resources/mock.key.json'); - const c = getApplicationDefault(); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.be.a('string').and.to.not.be.empty; - expect(token.expires_in).to.equal(ONE_HOUR_IN_SECONDS); - }); - }); - - it('should return a Credential', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve(__dirname, '../../resources/mock.key.json'); - const c = getApplicationDefault(); - expect(c).to.deep.include({ - projectId: mockCertificateObject.project_id, - clientEmail: mockCertificateObject.client_email, - privateKey: mockCertificateObject.private_key, - }); - }); - - it('should parse valid RefreshTokenCredential if GOOGLE_APPLICATION_CREDENTIALS environment variable ' + - 'points to default refresh token location', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS = GCLOUD_CREDENTIAL_PATH; - - fsStub = sinon.stub(fs, 'readFileSync').returns(JSON.stringify(MOCK_REFRESH_TOKEN_CONFIG)); - - const c = getApplicationDefault(); - expect(c).is.instanceOf(RefreshTokenCredential); - expect(c).to.have.property('refreshToken').that.includes({ - clientId: MOCK_REFRESH_TOKEN_CONFIG.client_id, - clientSecret: MOCK_REFRESH_TOKEN_CONFIG.client_secret, - refreshToken: MOCK_REFRESH_TOKEN_CONFIG.refresh_token, - type: MOCK_REFRESH_TOKEN_CONFIG.type, - }); - expect(fsStub.alwaysCalledWith(GCLOUD_CREDENTIAL_PATH, 'utf8')).to.be.true; + expect(getApplicationDefault()).to.be.an.instanceof(ApplicationDefaultCredential); }); }); @@ -611,27 +319,10 @@ describe('Credential', () => { } }); - it('should return true for ServiceAccountCredential loaded from GOOGLE_APPLICATION_CREDENTIALS', () => { + it('should return true for ApplicationDefaultCredential loaded from GOOGLE_APPLICATION_CREDENTIALS', () => { process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve(__dirname, '../../resources/mock.key.json'); const c = getApplicationDefault(); - expect(c).to.be.an.instanceof(ServiceAccountCredential); - expect(isApplicationDefault(c)).to.be.true; - }); - - it('should return true for RefreshTokenCredential loaded from GOOGLE_APPLICATION_CREDENTIALS', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS = GCLOUD_CREDENTIAL_PATH; - fsStub = sinon.stub(fs, 'readFileSync').returns(JSON.stringify(MOCK_REFRESH_TOKEN_CONFIG)); - const c = getApplicationDefault(); - expect(c).is.instanceOf(RefreshTokenCredential); - expect(isApplicationDefault(c)).to.be.true; - }); - - it('should return true for ImpersonatedServiceAccountCredential loaded from GOOGLE_APPLICATION_CREDENTIALS', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve( - __dirname, '../../resources/mock.impersonated_key.json' - ); - const c = getApplicationDefault(); - expect(c).is.instanceOf(ImpersonatedServiceAccountCredential); + expect(c).to.be.an.instanceof(ApplicationDefaultCredential); expect(isApplicationDefault(c)).to.be.true; }); @@ -653,7 +344,7 @@ describe('Credential', () => { delete process.env.GOOGLE_APPLICATION_CREDENTIALS; fsStub = sinon.stub(fs, 'readFileSync').throws(new Error('no gcloud credential file')); const c = getApplicationDefault(); - expect(c).to.be.an.instanceof(ComputeEngineCredential); + expect(c).to.be.an.instanceof(ApplicationDefaultCredential); expect(isApplicationDefault(c)).to.be.true; }); @@ -681,72 +372,4 @@ describe('Credential', () => { expect(isApplicationDefault(c)).to.be.false; }); }); - - describe('HTTP Agent', () => { - const expectedToken = utils.generateRandomAccessToken(); - let stub: sinon.SinonStub; - - beforeEach(() => { - stub = sinon.stub(HttpClient.prototype, 'send').resolves(utils.responseFrom({ - access_token: expectedToken, - token_type: 'Bearer', - expires_in: 60 * 60, - })); - }); - - afterEach(() => { - stub.restore(); - }); - - it('ServiceAccountCredential should use the provided HTTP Agent', () => { - const agent = new Agent(); - const c = new ServiceAccountCredential(mockCertificateObject, agent); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.equal(expectedToken); - expect(stub).to.have.been.calledOnce; - expect(stub.args[0][0].httpAgent).to.equal(agent); - }); - }); - - it('RefreshTokenCredential should use the provided HTTP Agent', () => { - const agent = new Agent(); - const c = new RefreshTokenCredential(MOCK_REFRESH_TOKEN_CONFIG, agent); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.equal(expectedToken); - expect(stub).to.have.been.calledOnce; - expect(stub.args[0][0].httpAgent).to.equal(agent); - }); - }); - - it('ComputeEngineCredential should use the provided HTTP Agent', () => { - const agent = new Agent(); - const c = new ComputeEngineCredential(agent); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.equal(expectedToken); - expect(stub).to.have.been.calledOnce; - expect(stub.args[0][0].httpAgent).to.equal(agent); - }); - }); - - it('ApplicationDefaultCredential should use the provided HTTP Agent', () => { - process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve(__dirname, '../../resources/mock.key.json'); - const agent = new Agent(); - const c = getApplicationDefault(agent); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.equal(expectedToken); - expect(stub).to.have.been.calledOnce; - expect(stub.args[0][0].httpAgent).to.equal(agent); - }); - }); - - it('ImpersonatedServiceAccountCredential should use the provided HTTP Agent', () => { - const agent = new Agent(); - const c = new ImpersonatedServiceAccountCredential(MOCK_IMPERSONATED_TOKEN_CONFIG, agent); - return c.getAccessToken().then((token) => { - expect(token.access_token).to.equal(expectedToken); - expect(stub).to.have.been.calledOnce; - expect(stub.args[0][0].httpAgent).to.equal(agent); - }); - }); - }); }); diff --git a/test/unit/app/firebase-namespace.spec.ts b/test/unit/app/firebase-namespace.spec.ts index 467854d124..ee3cb951fb 100644 --- a/test/unit/app/firebase-namespace.spec.ts +++ b/test/unit/app/firebase-namespace.spec.ts @@ -77,6 +77,7 @@ import ProjectManagement = projectManagement.ProjectManagement; import RemoteConfig = remoteConfig.RemoteConfig; import SecurityRules = securityRules.SecurityRules; import Storage = storage.Storage; +import { ApplicationDefaultCredential } from '../../../src/app/credential-internal'; chai.should(); chai.use(sinonChai); @@ -760,16 +761,14 @@ describe('FirebaseNamespace', () => { }); }); - it('should create application default credentials from environment', () => { + it('should create application default credentials from environment', async () => { process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve(__dirname, '../../resources/mock.key.json'); const mockCertificateObject = mocks.certificateObject; const credential = firebaseNamespace.credential.applicationDefault(); - expect(credential).to.deep.include({ - projectId: mockCertificateObject.project_id, - clientEmail: mockCertificateObject.client_email, - privateKey: mockCertificateObject.private_key, - implicit: true, - }); + const projectId = await (credential as ApplicationDefaultCredential).getProjectId(); + const clientEmail = await (credential as ApplicationDefaultCredential).getServiceAccountEmail(); + expect(projectId).to.eq(mockCertificateObject.project_id); + expect(clientEmail).to.eq(mockCertificateObject.client_email); }); after(clearGlobalAppDefaultCred); diff --git a/test/unit/app/index.spec.ts b/test/unit/app/index.spec.ts index 9de58baf84..896fd2534e 100644 --- a/test/unit/app/index.spec.ts +++ b/test/unit/app/index.spec.ts @@ -31,6 +31,7 @@ import { } from '../../../src/app/index'; import { clearGlobalAppDefaultCred } from '../../../src/app/credential-factory'; import { defaultAppStore } from '../../../src/app/lifecycle'; +import { ApplicationDefaultCredential } from '../../../src/app/credential-internal'; chai.should(); chai.use(chaiAsPromised); @@ -230,14 +231,9 @@ describe('firebase-admin/app', () => { }); it('should create application default credentials from environment', () => { - const mockCertificateObject = mocks.certificateObject; + //const mockCertificateObject = mocks.certificateObject; const credential: Credential = applicationDefault(); - expect(credential).to.deep.include({ - projectId: mockCertificateObject.project_id, - clientEmail: mockCertificateObject.client_email, - privateKey: mockCertificateObject.private_key, - implicit: true, - }); + expect(credential).to.be.instanceOf(ApplicationDefaultCredential); }); it('should cache application default credentials globally', () => { diff --git a/test/unit/firebase.spec.ts b/test/unit/firebase.spec.ts index ca441f852d..3bd63209f8 100644 --- a/test/unit/firebase.spec.ts +++ b/test/unit/firebase.spec.ts @@ -30,6 +30,7 @@ import * as mocks from '../resources/mocks'; import * as firebaseAdmin from '../../src/index'; import { FirebaseApp, FirebaseAppInternals } from '../../src/app/firebase-app'; import { + ApplicationDefaultCredential, RefreshTokenCredential, ServiceAccountCredential, isApplicationDefault } from '../../src/app/credential-internal'; import { defaultAppStore, initializeApp } from '../../src/app/lifecycle'; @@ -129,12 +130,16 @@ describe('Firebase', () => { }); it('should initialize SDK given an application default credential', () => { + getTokenStub.restore(); + getTokenStub = sinon.stub(ApplicationDefaultCredential.prototype, 'getAccessToken').resolves({ + access_token: 'mock-access-token', + expires_in: 3600, + }); const credPath: string | undefined = process.env.GOOGLE_APPLICATION_CREDENTIALS; process.env.GOOGLE_APPLICATION_CREDENTIALS = path.resolve(__dirname, '../resources/mock.key.json'); firebaseAdmin.initializeApp({ credential: firebaseAdmin.credential.applicationDefault(), }); - expect(isApplicationDefault(firebaseAdmin.app().options.credential)).to.be.true; return getAppInternals().getToken().then((token) => { if (typeof credPath === 'undefined') { diff --git a/test/unit/firestore/firestore.spec.ts b/test/unit/firestore/firestore.spec.ts index 19d769c555..146ba2c640 100644 --- a/test/unit/firestore/firestore.spec.ts +++ b/test/unit/firestore/firestore.spec.ts @@ -23,7 +23,8 @@ import { expect } from 'chai'; import * as mocks from '../../resources/mocks'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { - ComputeEngineCredential, RefreshTokenCredential + ApplicationDefaultCredential, + RefreshTokenCredential } from '../../../src/app/credential-internal'; import { FirestoreService, getFirestoreOptions } from '../../../src/firestore/firestore-internal'; import { DEFAULT_DATABASE_ID } from '@google-cloud/firestore/build/src/path'; @@ -48,7 +49,7 @@ describe('Firestore', () => { { name: 'ComputeEngineCredentials', app: mocks.appWithOptions({ - credential: new ComputeEngineCredential(), + credential: new ApplicationDefaultCredential(), }), }, { diff --git a/test/unit/utils/index.spec.ts b/test/unit/utils/index.spec.ts index 7105726e67..5226353107 100644 --- a/test/unit/utils/index.spec.ts +++ b/test/unit/utils/index.spec.ts @@ -26,10 +26,7 @@ import { } from '../../../src/utils/index'; import { isNonEmptyString } from '../../../src/utils/validator'; import { FirebaseApp } from '../../../src/app/firebase-app'; -import { ComputeEngineCredential } from '../../../src/app/credential-internal'; import { HttpClient } from '../../../src/utils/api-request'; -import * as utils from '../utils'; -import { FirebaseAppError } from '../../../src/utils/error'; import { getSdkVersion } from '../../../src/utils/index'; interface Obj { @@ -198,25 +195,6 @@ describe('findProjectId()', () => { return findProjectId(app).should.eventually.equal('env-var-project-id'); }); - it('should return the project ID discovered from the metadata service', () => { - const expectedProjectId = 'test-project-id'; - const response = utils.responseFrom(expectedProjectId); - httpStub.resolves(response); - const app: FirebaseApp = mocks.appWithOptions({ - credential: new ComputeEngineCredential(), - }); - return findProjectId(app).should.eventually.equal(expectedProjectId); - }); - - it('should reject when the metadata service is not available', () => { - httpStub.rejects(new FirebaseAppError('network-error', 'Failed to connect')); - const app: FirebaseApp = mocks.appWithOptions({ - credential: new ComputeEngineCredential(), - }); - return findProjectId(app).should.eventually - .rejectedWith('Failed to determine project ID: Failed to connect'); - }); - it('should return null when project ID is not set and discoverable', () => { const app: FirebaseApp = mocks.mockCredentialApp(); return findProjectId(app).should.eventually.be.null; From 3ae5c6397e7941eeb2740cd886053075ee057e88 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 4 Nov 2024 15:47:24 -0500 Subject: [PATCH 200/323] change: Update Node support to 18 (#2756) --- .github/workflows/ci.yml | 2 +- .github/workflows/nightly.yml | 2 +- .github/workflows/release.yml | 4 ++-- README.md | 3 +-- package-lock.json | 2 +- package.json | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf3a257871..f629d6da10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x, 18.x, 20.x, 22.x] + node-version: [18.x, 20.x, 22.x] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 379172b7d3..17533e318d 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -36,7 +36,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 14.x + node-version: 18.x - name: Install and build run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea333311ef..dab28224c2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -47,7 +47,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 14.x + node-version: 18.x - name: Install and build run: | @@ -117,7 +117,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: 14.x + node-version: 18.x - name: Publish preflight check id: preflight diff --git a/README.md b/README.md index 4eafa48814..8ebe57eab4 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,7 @@ requests, code review feedback, and also pull requests. ## Supported Environments -We support Node.js 14 and higher. However, Node.js 14 and 16 support is deprecated. We strongly encourage -you to use Node.js 18 or higher as we will drop support for Node.js 14 and 16 in the next major version. +We support Node.js 18 and higher. Please also note that the Admin SDK should only be used in server-side/back-end environments controlled by the app developer. diff --git a/package-lock.json b/package-lock.json index c4961706c5..4119954bee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,7 +73,7 @@ "yargs": "^17.0.1" }, "engines": { - "node": ">=14" + "node": ">=18" }, "optionalDependencies": { "@google-cloud/firestore": "^7.7.0", diff --git a/package.json b/package.json index c61ecd58fa..63a4d4cd78 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "homepage": "https://firebase.google.com/", "engines": { - "node": ">=14" + "node": ">=18" }, "scripts": { "build": "gulp build", From ec1dc66b7ff356e06f312fd8b33ef3e20033bfc0 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 5 Nov 2024 12:24:08 -0500 Subject: [PATCH 201/323] chore: Upgrade dependencies (#2757) * chore: Upgrade dependencies * chore: Update Typescript * upgrade typescript * Trigger Build * align typescrip version with the jssdk --- etc/firebase-admin.api.md | 6 +- etc/firebase-admin.app-check.api.md | 2 - etc/firebase-admin.app.api.md | 2 - etc/firebase-admin.auth.api.md | 2 - etc/firebase-admin.data-connect.api.md | 2 - etc/firebase-admin.database.api.md | 2 - etc/firebase-admin.eventarc.api.md | 2 - etc/firebase-admin.extensions.api.md | 2 - etc/firebase-admin.firestore.api.md | 2 - etc/firebase-admin.functions.api.md | 2 - etc/firebase-admin.installations.api.md | 2 - etc/firebase-admin.instance-id.api.md | 2 - etc/firebase-admin.machine-learning.api.md | 2 - etc/firebase-admin.messaging.api.md | 2 - etc/firebase-admin.project-management.api.md | 2 - etc/firebase-admin.remote-config.api.md | 2 - etc/firebase-admin.security-rules.api.md | 2 - etc/firebase-admin.storage.api.md | 7 +- package-lock.json | 12370 +++-------------- package.json | 22 +- 20 files changed, 2233 insertions(+), 10204 deletions(-) diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index ceb4ff1ab4..6d0670cc75 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; import { Bucket } from '@google-cloud/storage'; import { FirebaseDatabase } from '@firebase/database-types'; @@ -511,8 +509,8 @@ export function storage(app?: App): storage.Storage; // @public (undocumented) export namespace storage { - // Warning: (ae-forgotten-export) The symbol "Storage" needs to be exported by the entry point default-namespace.d.ts - export type Storage = Storage; + // Warning: (ae-forgotten-export) The symbol "Storage_2" needs to be exported by the entry point default-namespace.d.ts + export type Storage = Storage_2; } ``` diff --git a/etc/firebase-admin.app-check.api.md b/etc/firebase-admin.app-check.api.md index 7c883d5f38..8486d60ac7 100644 --- a/etc/firebase-admin.app-check.api.md +++ b/etc/firebase-admin.app-check.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.app.api.md b/etc/firebase-admin.app.api.md index 4546fe7824..97ab9667ce 100644 --- a/etc/firebase-admin.app.api.md +++ b/etc/firebase-admin.app.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.auth.api.md b/etc/firebase-admin.auth.api.md index 593b4e674d..7962ca5baa 100644 --- a/etc/firebase-admin.auth.api.md +++ b/etc/firebase-admin.auth.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.data-connect.api.md b/etc/firebase-admin.data-connect.api.md index ab253d17eb..bf3f3b6b19 100644 --- a/etc/firebase-admin.data-connect.api.md +++ b/etc/firebase-admin.data-connect.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.database.api.md b/etc/firebase-admin.database.api.md index 1778f75d51..0cd7d55e9b 100644 --- a/etc/firebase-admin.database.api.md +++ b/etc/firebase-admin.database.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; import { DataSnapshot } from '@firebase/database-types'; import { EventType } from '@firebase/database-types'; diff --git a/etc/firebase-admin.eventarc.api.md b/etc/firebase-admin.eventarc.api.md index a070f8b391..4a6020f33a 100644 --- a/etc/firebase-admin.eventarc.api.md +++ b/etc/firebase-admin.eventarc.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.extensions.api.md b/etc/firebase-admin.extensions.api.md index 127754c9c9..9082d602b9 100644 --- a/etc/firebase-admin.extensions.api.md +++ b/etc/firebase-admin.extensions.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.firestore.api.md b/etc/firebase-admin.firestore.api.md index 8f29baeab3..e8b2932326 100644 --- a/etc/firebase-admin.firestore.api.md +++ b/etc/firebase-admin.firestore.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { AddPrefixToKeys } from '@google-cloud/firestore'; import { Agent } from 'http'; import { AggregateField } from '@google-cloud/firestore'; diff --git a/etc/firebase-admin.functions.api.md b/etc/firebase-admin.functions.api.md index 87f8656b4a..10eee3fef9 100644 --- a/etc/firebase-admin.functions.api.md +++ b/etc/firebase-admin.functions.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.installations.api.md b/etc/firebase-admin.installations.api.md index 56496ef135..2bc45b3e14 100644 --- a/etc/firebase-admin.installations.api.md +++ b/etc/firebase-admin.installations.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts diff --git a/etc/firebase-admin.instance-id.api.md b/etc/firebase-admin.instance-id.api.md index 9c28852a2c..5f7852c15d 100644 --- a/etc/firebase-admin.instance-id.api.md +++ b/etc/firebase-admin.instance-id.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts diff --git a/etc/firebase-admin.machine-learning.api.md b/etc/firebase-admin.machine-learning.api.md index b6c3569de9..d39e2d2a9d 100644 --- a/etc/firebase-admin.machine-learning.api.md +++ b/etc/firebase-admin.machine-learning.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public (undocumented) diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index f78156eb5a..493fd9127a 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.project-management.api.md b/etc/firebase-admin.project-management.api.md index 8f59f54642..4fed0d715a 100644 --- a/etc/firebase-admin.project-management.api.md +++ b/etc/firebase-admin.project-management.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.remote-config.api.md b/etc/firebase-admin.remote-config.api.md index ea0fddd63c..68d760468c 100644 --- a/etc/firebase-admin.remote-config.api.md +++ b/etc/firebase-admin.remote-config.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // @public diff --git a/etc/firebase-admin.security-rules.api.md b/etc/firebase-admin.security-rules.api.md index 890da538d1..13c3be8289 100644 --- a/etc/firebase-admin.security-rules.api.md +++ b/etc/firebase-admin.security-rules.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts diff --git a/etc/firebase-admin.storage.api.md b/etc/firebase-admin.storage.api.md index ab798e8fca..db5e336a07 100644 --- a/etc/firebase-admin.storage.api.md +++ b/etc/firebase-admin.storage.api.md @@ -4,8 +4,6 @@ ```ts -/// - import { Agent } from 'http'; import { Bucket } from '@google-cloud/storage'; import { File as File_2 } from '@google-cloud/storage'; @@ -16,12 +14,13 @@ export function getDownloadURL(file: File_2): Promise; // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts // // @public -export function getStorage(app?: App): Storage; +export function getStorage(app?: App): Storage_2; // @public -export class Storage { +class Storage_2 { get app(): App; bucket(name?: string): Bucket; } +export { Storage_2 as Storage } ``` diff --git a/package-lock.json b/package-lock.json index 4119954bee..617d2f419a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "firebase-admin", "version": "12.7.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -10,20 +10,20 @@ "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", - "@firebase/database-compat": "1.0.8", - "@firebase/database-types": "1.0.5", - "@types/node": "^22.0.1", + "@firebase/database-compat": "^2.0.0", + "@firebase/database-types": "^1.0.6", + "@types/node": "^22.8.7", "farmhash-modern": "^1.1.0", "google-auth-library": "^9.14.2", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", "node-forge": "^1.3.1", - "uuid": "^10.0.0" + "uuid": "^11.0.2" }, "devDependencies": { "@firebase/api-documenter": "^0.4.0", "@firebase/app-compat": "^0.2.1", - "@firebase/auth-compat": "^0.4.1", + "@firebase/auth-compat": "^0.5.13", "@firebase/auth-types": "^0.12.0", "@microsoft/api-extractor": "^7.11.2", "@types/bcrypt": "^5.0.0", @@ -40,8 +40,8 @@ "@types/sinon": "^17.0.2", "@types/sinon-chai": "^3.0.0", "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", "bcrypt": "^5.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.0.0", @@ -49,7 +49,7 @@ "chalk": "^4.1.1", "child-process-promise": "^2.2.1", "del": "^6.0.0", - "eslint": "^8.12.0", + "eslint": "^8.56.0", "firebase-token-generator": "^2.0.0", "gulp": "^5.0.0", "gulp-filter": "^7.0.0", @@ -69,15 +69,15 @@ "sinon": "^18.0.0", "sinon-chai": "^3.0.0", "ts-node": "^10.2.0", - "typescript": "5.1.6", + "typescript": "5.5.4", "yargs": "^17.0.1" }, "engines": { "node": ">=18" }, "optionalDependencies": { - "@google-cloud/firestore": "^7.7.0", - "@google-cloud/storage": "^7.7.0" + "@google-cloud/firestore": "^7.10.0", + "@google-cloud/storage": "^7.14.0" } }, "node_modules/@ampproject/remapping": { @@ -85,6 +85,7 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -94,12 +95,14 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", - "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -107,30 +110,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", - "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", - "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/helper-compilation-targets": "^7.25.7", - "@babel/helper-module-transforms": "^7.25.7", - "@babel/helpers": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/template": "^7.25.7", - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -145,22 +150,32 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", - "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.25.7", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -170,13 +185,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", - "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.7", - "@babel/helper-validator-option": "^7.25.7", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -190,6 +206,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -199,6 +216,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -207,31 +225,33 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", - "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", - "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.7", - "@babel/helper-simple-access": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "@babel/traverse": "^7.25.7" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -240,152 +260,58 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", - "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", - "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", - "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", - "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", - "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", - "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", - "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.25.7" + "@babel/types": "^7.26.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -395,30 +321,32 @@ } }, "node_modules/@babel/template": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", - "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/types": "^7.25.7" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", - "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7", + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -431,19 +359,20 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", - "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -454,6 +383,7 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -466,31 +396,37 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -500,6 +436,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -523,6 +460,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -538,13 +476,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -557,6 +497,7 @@ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -564,13 +505,15 @@ "node_modules/@fastify/busboy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.0.0.tgz", - "integrity": "sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==" + "integrity": "sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==", + "license": "MIT" }, "node_modules/@firebase/api-documenter": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@firebase/api-documenter/-/api-documenter-0.4.0.tgz", "integrity": "sha512-UUPxxj1wIAGkXBCF9UL1dhfyzM4Lcd/gMSCoJqy8o75rLqQVGB2GSBaU7I4JmQsQhIIk/nKKLiy4HM/70kEfZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@microsoft/tsdoc": "0.12.24", "@rushstack/node-core-library": "3.59.7", @@ -590,6 +533,7 @@ "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.15.tgz", "integrity": "sha512-he6qlG3pmwL+LHdG/BrSMBQeJzzutciq4fpXN3lGa1uSwYSijJ24VtakS/bP2X9SiDf8jGywJ4u+OgXAenJsNg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@firebase/component": "0.6.10", "@firebase/logger": "0.4.3", @@ -604,13 +548,15 @@ "node_modules/@firebase/app-check-interop-types": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz", - "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" + "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==", + "license": "Apache-2.0" }, "node_modules/@firebase/app-compat": { "version": "0.2.45", "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.45.tgz", "integrity": "sha512-5rYbXq1ndtMTg+07oH4WrkYuP+NZq61uzVwW1hlmybp/gr4cXq2SfaP9fc6/9IzTKmu3dh3H0fjj++HG7Z7o/w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@firebase/app": "0.10.15", "@firebase/component": "0.6.10", @@ -622,54 +568,115 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/app-compat/node_modules/@firebase/component": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", - "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", + "node_modules/@firebase/app-types": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", + "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.0.tgz", + "integrity": "sha512-/O7UDWE5S5ux456fzNHSLx/0YN/Kykw/WyAzgDQ6wvkddZhSEmPX19EzxgsFldzhuFjsl5uOZTz8kzlosCiJjg==", "dev": true, + "license": "Apache-2.0", "dependencies": { + "@firebase/component": "0.6.10", + "@firebase/logger": "0.4.3", "@firebase/util": "1.10.1", "tslib": "^2.1.0" }, "engines": { "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app": "0.x", + "@react-native-async-storage/async-storage": "^1.18.1" + }, + "peerDependenciesMeta": { + "@react-native-async-storage/async-storage": { + "optional": true + } } }, - "node_modules/@firebase/app-compat/node_modules/@firebase/logger": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", - "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", + "node_modules/@firebase/auth-compat": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.15.tgz", + "integrity": "sha512-jz6k1ridPiecKI8CBRiqCM6IMOhwYp2MD+YvoxnMiK8nQLSTm57GvHETlPNX3WlbyQnCjMCOvrAhe27whyxAEg==", "dev": true, + "license": "Apache-2.0", "dependencies": { + "@firebase/auth": "1.8.0", + "@firebase/auth-types": "0.12.2", + "@firebase/component": "0.6.10", + "@firebase/util": "1.10.1", "tslib": "^2.1.0" }, "engines": { "node": ">=18.0.0" + }, + "peerDependencies": { + "@firebase/app-compat": "0.x" } }, - "node_modules/@firebase/app-compat/node_modules/@firebase/util": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", - "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", + "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", + "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, + "node_modules/@firebase/component": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", + "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", + "license": "Apache-2.0", "dependencies": { + "@firebase/util": "1.10.1", "tslib": "^2.1.0" }, "engines": { "node": ">=18.0.0" } }, - "node_modules/@firebase/app-types": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", - "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==" + "node_modules/@firebase/database": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.9.tgz", + "integrity": "sha512-EkiPSKSu2TJJGtOjyISASf3UFpFJDil1lMbfqnxilfbmIsilvC8DzgjuLoYD+eOitcug4wtU9Fh1tt2vgBhskA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.2", + "@firebase/auth-interop-types": "0.2.3", + "@firebase/component": "0.6.10", + "@firebase/logger": "0.4.3", + "@firebase/util": "1.10.1", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } }, - "node_modules/@firebase/app/node_modules/@firebase/component": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", - "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", - "dev": true, + "node_modules/@firebase/database-compat": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.0.tgz", + "integrity": "sha512-2xlODKWwf/vNAxCmou0GFhymx2pqZKkhXMN9B5aiTjZ6+81sOxGim53ELY2lj+qKG2IvgiCYFc4X+ZJA2Ad5vg==", + "license": "Apache-2.0", "dependencies": { + "@firebase/component": "0.6.10", + "@firebase/database": "1.0.9", + "@firebase/database-types": "1.0.6", + "@firebase/logger": "0.4.3", "@firebase/util": "1.10.1", "tslib": "^2.1.0" }, @@ -677,11 +684,21 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/app/node_modules/@firebase/logger": { + "node_modules/@firebase/database-types": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.6.tgz", + "integrity": "sha512-sMI7IynSZBsyGbUugc8PKE1jwKbnvaieAz/RxuM57PZQNCi6Rteiviwcw/jqZOX6igqYJwXWZ3UzKOZo2nUDRA==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.2", + "@firebase/util": "1.10.1" + } + }, + "node_modules/@firebase/logger": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", - "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" }, @@ -689,11 +706,11 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/app/node_modules/@firebase/util": { + "node_modules/@firebase/util": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", - "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" }, @@ -701,269 +718,62 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/auth": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.4.0.tgz", - "integrity": "sha512-SfFXZCHDbY+7oSR52NSwx0U7LjYiA+N8imloxphCf3/F+MFty/+mhdjSXGtrJYd0Gbud/qcyedfn2XnWJeIB/g==", - "dev": true, + "node_modules/@google-cloud/firestore": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.10.0.tgz", + "integrity": "sha512-VFNhdHvfnmqcHHs6YhmSNHHxQqaaD64GwiL0c+e1qz85S8SWZPC2XFRf8p9yHRTF40Kow424s1KBU9f0fdQa+Q==", + "license": "Apache-2.0", + "optional": true, "dependencies": { - "@firebase/component": "0.6.4", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.3", - "node-fetch": "2.6.7", - "tslib": "^2.1.0" - }, - "peerDependencies": { - "@firebase/app": "0.x", - "@react-native-async-storage/async-storage": "^1.18.1" + "@opentelemetry/api": "^1.3.0", + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.3.3", + "protobufjs": "^7.2.6" }, - "peerDependenciesMeta": { - "@react-native-async-storage/async-storage": { - "optional": true - } + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@firebase/auth-compat": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.9.tgz", - "integrity": "sha512-Fw03i7vduIciEBG4imLtA1duJbljgkfbxiBo/EuekcB+BnPxHp+e8OGMUfemPYeO7Munj6kUC9gr5DelsQkiNA==", - "dev": true, + "node_modules/@google-cloud/paginator": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", + "license": "Apache-2.0", + "optional": true, "dependencies": { - "@firebase/auth": "1.4.0", - "@firebase/auth-types": "0.12.0", - "@firebase/component": "0.6.4", - "@firebase/util": "1.9.3", - "node-fetch": "2.6.7", - "tslib": "^2.1.0" + "arrify": "^2.0.0", + "extend": "^3.0.2" }, - "peerDependencies": { - "@firebase/app-compat": "0.x" + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@firebase/auth-compat/node_modules/@firebase/auth-types": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", - "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", - "dev": true, - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@firebase/auth-compat/node_modules/@firebase/component": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", - "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", - "dev": true, - "dependencies": { - "@firebase/util": "1.9.3", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/auth-compat/node_modules/@firebase/util": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", - "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/auth-compat/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/@firebase/auth-interop-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", - "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==" - }, - "node_modules/@firebase/auth-types": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", - "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", - "dev": true, - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" - } - }, - "node_modules/@firebase/auth/node_modules/@firebase/component": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", - "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", - "dev": true, - "dependencies": { - "@firebase/util": "1.9.3", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/auth/node_modules/@firebase/logger": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", - "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/auth/node_modules/@firebase/util": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", - "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/auth/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/@firebase/component": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", - "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", - "dependencies": { - "@firebase/util": "1.10.0", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.8.tgz", - "integrity": "sha512-dzXALZeBI1U5TXt6619cv0+tgEhJiwlUtQ55WNZY7vGAjv7Q1QioV969iYwt1AQQ0ovHnEW0YW9TiBfefLvErg==", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.9", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.10.0", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database-compat": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.8.tgz", - "integrity": "sha512-OpeWZoPE3sGIRPBKYnW9wLad25RaWbGyk7fFQe4xnJQKRzlynWeFBSRRAoLE2Old01WXwskUiucNqUUVlFsceg==", - "dependencies": { - "@firebase/component": "0.6.9", - "@firebase/database": "1.0.8", - "@firebase/database-types": "1.0.5", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.10.0", - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/database-types": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.5.tgz", - "integrity": "sha512-fTlqCNwFYyq/C6W7AJ5OCuq5CeZuBEsEwptnVxlNPkWCo5cTTyukzAHRSO/jaQcItz33FfYrrFk1SJofcu2AaQ==", - "dependencies": { - "@firebase/app-types": "0.9.2", - "@firebase/util": "1.10.0" - } - }, - "node_modules/@firebase/logger": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", - "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@firebase/util": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", - "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@google-cloud/firestore": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.10.0.tgz", - "integrity": "sha512-VFNhdHvfnmqcHHs6YhmSNHHxQqaaD64GwiL0c+e1qz85S8SWZPC2XFRf8p9yHRTF40Kow424s1KBU9f0fdQa+Q==", - "optional": true, - "dependencies": { - "@opentelemetry/api": "^1.3.0", - "fast-deep-equal": "^3.1.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^4.3.3", - "protobufjs": "^7.2.6" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/paginator": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", - "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", - "optional": true, - "dependencies": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/projectify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", - "optional": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@google-cloud/promisify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", - "optional": true, - "engines": { - "node": ">=14" + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14" } }, "node_modules/@google-cloud/storage": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.13.0.tgz", - "integrity": "sha512-Y0rYdwM5ZPW3jw/T26sMxxfPrVQTKm9vGrZG8PRyGuUmUJ8a2xNuQ9W/NNA1prxqv2i54DSydV8SJqxF2oCVgA==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.14.0.tgz", + "integrity": "sha512-H41bPL2cMfSi4EEnFzKvg7XSb7T67ocSXrmF7MPjfgFB0L6CKGzfIYJheAZi1iqXjz6XaCT1OBf6HCG5vDBTOQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@google-cloud/paginator": "^5.0.0", @@ -990,15 +800,17 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "optional": true, "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/@grpc/grpc-js": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.11.2.tgz", - "integrity": "sha512-DWp92gDD7/Qkj7r8kus6/HCINeo3yPZWZ3paKgDgsbKbSpoxKg1yvN8xe2Q8uE3zOsPe3bX8FQX2+XValq2yTw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.2.tgz", + "integrity": "sha512-bgxdZmgTrJZX50OjyVwz3+mNEnCTNkh3cIqGPWVNeW9jX6bn1ZkU80uPd+67/ZpIJIjRQ9qaHCjhavyoWYxumg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@grpc/proto-loader": "^0.7.13", @@ -1012,6 +824,7 @@ "version": "0.7.13", "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "license": "Apache-2.0", "optional": true, "dependencies": { "lodash.camelcase": "^4.3.0", @@ -1031,6 +844,7 @@ "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -1040,6 +854,7 @@ "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", "dev": true, + "license": "MIT", "dependencies": { "is-negated-glob": "^1.0.0" }, @@ -1053,6 +868,7 @@ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -1067,6 +883,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -1080,13 +897,15 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "deprecated": "Use @eslint/object-schema instead", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -1098,20 +917,12 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -1125,6 +936,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -1138,6 +950,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -1150,6 +963,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -1165,6 +979,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -1177,6 +992,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1186,6 +1002,7 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1195,6 +1012,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -1209,6 +1027,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -1218,21 +1037,24 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1242,6 +1064,7 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", "optional": true, "funding": { "type": "opencollective", @@ -1253,6 +1076,7 @@ "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "detect-libc": "^2.0.0", "https-proxy-agent": "^5.0.0", @@ -1268,36 +1092,12 @@ "node-pre-gyp": "bin/node-pre-gyp" } }, - "node_modules/@mapbox/node-pre-gyp/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/@mapbox/node-pre-gyp/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/@microsoft/api-extractor": { "version": "7.47.11", "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.11.tgz", "integrity": "sha512-lrudfbPub5wzBhymfFtgZKuBvXxoSIAdrvS2UbHjoMT2TjIEddq6Z13pcve7A03BAouw0x8sW8G4txdgfiSwpQ==", "dev": true, + "license": "MIT", "dependencies": { "@microsoft/api-extractor-model": "7.29.8", "@microsoft/tsdoc": "~0.15.0", @@ -1322,6 +1122,7 @@ "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.8.tgz", "integrity": "sha512-t3Z/xcO6TRbMcnKGVMs4uMzv/gd5j0NhMiJIGjD4cJMeFJ1Hf8wnLSx37vxlRlL0GWlGJhnFgxvnaL6JlS+73g==", "dev": true, + "license": "MIT", "dependencies": { "@microsoft/tsdoc": "~0.15.0", "@microsoft/tsdoc-config": "~0.17.0", @@ -1332,13 +1133,15 @@ "version": "0.15.0", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { "version": "5.9.0", "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", @@ -1363,6 +1166,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -1374,32 +1178,19 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@microsoft/api-extractor-model/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@microsoft/api-extractor/node_modules/@microsoft/tsdoc": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { "version": "5.9.0", "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", @@ -1424,6 +1215,7 @@ "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.0.tgz", "integrity": "sha512-jYREBtsxduPV6ptNq8jOKp9+yx0ld1Tb/Tkdnlj8gTjazl1sF3DwX2VbluyYrNd0meWIL0bNeer7WDf5tKFjaQ==", "dev": true, + "license": "MIT", "dependencies": { "@rushstack/terminal": "0.14.2", "@types/argparse": "1.0.38", @@ -1436,6 +1228,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -1447,26 +1240,12 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@microsoft/api-extractor/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1479,13 +1258,15 @@ "version": "0.12.24", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz", "integrity": "sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@microsoft/tsdoc-config": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz", "integrity": "sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==", "dev": true, + "license": "MIT", "dependencies": { "@microsoft/tsdoc": "0.15.0", "ajv": "~8.12.0", @@ -1497,13 +1278,15 @@ "version": "0.15.0", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1517,6 +1300,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -1526,6 +1310,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1538,6 +1323,7 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8.0.0" @@ -1547,30 +1333,35 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", "optional": true, "dependencies": { "@protobufjs/aspromise": "^1.1.1", @@ -1581,30 +1372,35 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause", "optional": true }, "node_modules/@rushstack/node-core-library": { @@ -1612,6 +1408,7 @@ "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.7.tgz", "integrity": "sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==", "dev": true, + "license": "MIT", "dependencies": { "colors": "~1.2.1", "fs-extra": "~7.0.1", @@ -1635,30 +1432,17 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.1.90" } }, - "node_modules/@rushstack/node-core-library/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@rushstack/rig-package": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", "dev": true, + "license": "MIT", "dependencies": { "resolve": "~1.22.1", "strip-json-comments": "~3.1.1" @@ -1669,6 +1453,7 @@ "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.2.tgz", "integrity": "sha512-2fC1wqu1VCExKC0/L+0noVcFQEXEnoBOtCIex1TOjBzEDWcw8KzJjjj7aTP6mLxepG0XIyn9OufeFb6SFsa+sg==", "dev": true, + "license": "MIT", "dependencies": { "@rushstack/node-core-library": "5.9.0", "supports-color": "~8.1.1" @@ -1687,6 +1472,7 @@ "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", @@ -1711,6 +1497,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -1722,26 +1509,12 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@rushstack/terminal/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@rushstack/ts-command-line": { "version": "4.15.2", "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz", "integrity": "sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/argparse": "1.0.38", "argparse": "~1.0.9", @@ -1754,6 +1527,7 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.1.90" } @@ -1763,49 +1537,55 @@ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, + "node_modules/@sinonjs/commons/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@sinonjs/fake-timers": { "version": "11.2.2", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^2.0.0", + "@sinonjs/commons": "^3.0.1", "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" + "type-detect": "^4.1.0" } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "dev": true, + "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "license": "MIT", "optional": true, "engines": { "node": ">= 10" @@ -1815,37 +1595,43 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/argparse": { "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 + "dev": true, + "license": "MIT" }, "node_modules/@types/bcrypt": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1854,12 +1640,14 @@ "version": "3.5.42", "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.42.tgz", "integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -1869,19 +1657,22 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", - "dev": true + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", + "dev": true, + "license": "MIT" }, "node_modules/@types/chai-as-promised": { "version": "7.1.8", "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", "dev": true, + "license": "MIT", "dependencies": { "@types/chai": "*" } @@ -1890,6 +1681,7 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1898,6 +1690,7 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -1906,9 +1699,10 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz", - "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==", + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -1920,62 +1714,65 @@ "version": "2.0.33", "resolved": "https://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.33.tgz", "integrity": "sha512-FNZyTEHIE5Kq55QpVuyK7ZUJE/yoegRXalGVhbUh8+xC9pa1BUP7zspY+P5ci5SYKgoHjYQruC9gulFCn576Zw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "license": "MIT" }, "node_modules/@types/jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", "integrity": "sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/lodash": { - "version": "4.17.12", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.12.tgz", - "integrity": "sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==", - "dev": true + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", + "dev": true, + "license": "MIT" }, "node_modules/@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT", "optional": true }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/mocha": { "version": "10.0.9", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/nock": { "version": "11.1.0", @@ -1983,33 +1780,38 @@ "integrity": "sha512-jI/ewavBQ7X5178262JQR0ewicPAcJhXS/iFaNJl0VHLfyosZ/kwSrsa6VNQNSO8i9d8SqdRgOtZSOKJ/+iNMw==", "deprecated": "This is a stub types definition. nock provides its own type definitions, so you do not need this installed.", "dev": true, + "license": "MIT", "dependencies": { "nock": "*" } }, "node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": "~6.19.8" } }, "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", + "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" }, "node_modules/@types/request": { "version": "2.48.12", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", "devOptional": true, + "license": "MIT", "dependencies": { "@types/caseless": "*", "@types/node": "*", @@ -2022,21 +1824,17 @@ "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.51.tgz", "integrity": "sha512-qVcP9Fuzh9oaAh8oPxiSoWMFGnWKkJDknnij66vi09Yiy62bsSDqtd+fG5kIM9wLLgZsRP3Y6acqj9O/v2ZtRw==", "dev": true, + "license": "MIT", "dependencies": { "@types/bluebird": "*", "@types/request": "*" } }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -2046,6 +1844,7 @@ "version": "1.15.7", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -2057,6 +1856,7 @@ "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, + "license": "MIT", "dependencies": { "@types/sinonjs__fake-timers": "*" } @@ -2066,6 +1866,7 @@ "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.12.tgz", "integrity": "sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/chai": "*", "@types/sinon": "*" @@ -2075,47 +1876,50 @@ "version": "8.1.5", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/@types/uuid": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2124,25 +1928,27 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2151,16 +1957,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2168,25 +1975,26 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2195,12 +2003,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2208,21 +2017,23 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2234,43 +2045,80 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2281,18 +2129,21 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", "optional": true, "dependencies": { "event-target-shim": "^5.0.0" @@ -2302,10 +2153,11 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -2318,28 +2170,35 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "devOptional": true, + "license": "MIT", "dependencies": { - "debug": "^4.3.4" + "debug": "4" }, "engines": { - "node": ">= 14" + "node": ">= 6.0.0" } }, "node_modules/aggregate-error": { @@ -2347,6 +2206,7 @@ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, + "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -2360,6 +2220,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -2376,6 +2237,7 @@ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^8.5.0" }, @@ -2390,6 +2252,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -2403,15 +2266,13 @@ } }, "node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", "dev": true, - "dependencies": { - "ansi-wrap": "^0.1.0" - }, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/ansi-cyan": { @@ -2419,6 +2280,7 @@ "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", "integrity": "sha512-eCjan3AVo/SxZ0/MyIYRtkpxIu/H3xZN7URr1vXVrISxeyz8fUFz0FJziamK4sS8I+t35y4rHg1b2PklyBe/7A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-wrap": "0.1.0" }, @@ -2431,6 +2293,7 @@ "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", "dev": true, + "license": "MIT", "dependencies": { "ansi-wrap": "0.1.0" }, @@ -2443,6 +2306,7 @@ "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", "integrity": "sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow==", "dev": true, + "license": "MIT", "dependencies": { "ansi-wrap": "0.1.0" }, @@ -2455,6 +2319,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2464,6 +2329,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "devOptional": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -2479,6 +2345,7 @@ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2487,13 +2354,15 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -2507,6 +2376,7 @@ "resolved": "https://registry.npmjs.org/api-extractor-model-me/-/api-extractor-model-me-0.1.1.tgz", "integrity": "sha512-Ez801ZMADfkseOWNRFquvyQYDm3D9McpxfkKMWL6JFCGcpub0miJ+TFNphIR1nSZbrsxz3kIeOovNMY4VlL6Bw==", "dev": true, + "license": "MIT", "dependencies": { "@microsoft/tsdoc": "0.12.24", "@rushstack/node-core-library": "3.36.0" @@ -2517,6 +2387,7 @@ "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.36.0.tgz", "integrity": "sha512-bID2vzXpg8zweXdXgQkKToEdZwVrVCN9vE9viTRk58gqzYaTlz4fMId6V3ZfpXN6H0d319uGi2KDlm+lUEeqCg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "10.17.13", "colors": "~1.2.1", @@ -2533,13 +2404,15 @@ "version": "10.17.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/api-extractor-model-me/node_modules/colors": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.1.90" } @@ -2549,13 +2422,28 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, + "license": "MIT", "optional": true }, + "node_modules/api-extractor-model-me/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/api-extractor-model-me/node_modules/resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, + "license": "MIT", "dependencies": { "path-parse": "^1.0.6" }, @@ -2568,6 +2456,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2583,15 +2472,24 @@ "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } }, + "node_modules/api-extractor-model-me/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/api-extractor-model-me/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==", "dev": true, + "license": "MIT", "dependencies": { "lodash.get": "^4.0.0", "lodash.isequal": "^4.0.0", @@ -2609,6 +2507,7 @@ "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", "dev": true, + "license": "MIT", "dependencies": { "buffer-equal": "^1.0.0" }, @@ -2621,6 +2520,7 @@ "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", "dev": true, + "license": "MIT", "dependencies": { "default-require-extensions": "^3.0.0" }, @@ -2632,13 +2532,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/are-we-there-yet": { "version": "2.0.0", @@ -2646,6 +2548,7 @@ "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", "deprecated": "This package is no longer supported.", "dev": true, + "license": "ISC", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -2658,13 +2561,15 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -2674,6 +2579,7 @@ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2683,6 +2589,7 @@ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2692,6 +2599,7 @@ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2701,6 +2609,7 @@ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -2717,6 +2626,7 @@ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2726,6 +2636,7 @@ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2735,6 +2646,7 @@ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2744,6 +2656,7 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2753,6 +2666,7 @@ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -2775,6 +2689,7 @@ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2784,6 +2699,7 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" } @@ -2793,6 +2709,7 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -2802,6 +2719,7 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -2811,6 +2729,7 @@ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2820,6 +2739,7 @@ "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.4.4", "once": "^1.4.0", @@ -2833,6 +2753,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", "optional": true, "dependencies": { "retry": "0.13.1" @@ -2843,6 +2764,7 @@ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", "dev": true, + "license": "MIT", "dependencies": { "async-done": "^2.0.0" }, @@ -2854,13 +2776,15 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -2876,27 +2800,24 @@ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "*" } }, "node_modules/aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", - "dev": true - }, - "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true, + "license": "MIT" }, "node_modules/bach": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", "dev": true, + "license": "MIT", "dependencies": { "async-done": "^2.0.0", "async-settle": "^2.0.0", @@ -2910,13 +2831,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/bare-events": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", - "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", + "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", "dev": true, + "license": "Apache-2.0", "optional": true }, "node_modules/base64-js": { @@ -2936,7 +2859,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/bcrypt": { "version": "5.1.1", @@ -2944,6 +2868,7 @@ "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@mapbox/node-pre-gyp": "^1.0.11", "node-addon-api": "^5.0.0" @@ -2957,6 +2882,7 @@ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tweetnacl": "^0.14.3" } @@ -2965,6 +2891,7 @@ "version": "9.1.2", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "license": "MIT", "engines": { "node": "*" } @@ -2974,6 +2901,7 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -2986,23 +2914,51 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, + "node_modules/bl/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3013,6 +2969,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -3024,12 +2981,13 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -3045,11 +3003,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -3059,27 +3018,15 @@ } }, "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "license": "MIT", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "node_modules/buffer-equal": { @@ -3087,6 +3034,7 @@ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4" }, @@ -3097,19 +3045,22 @@ "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/caching-transform": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", "dev": true, + "license": "MIT", "dependencies": { "hasha": "^5.0.0", "make-dir": "^3.0.0", @@ -3125,6 +3076,7 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -3144,26 +3096,25 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", + "version": "1.0.30001677", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", + "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", "dev": true, "funding": [ { @@ -3178,19 +3129,22 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/chai": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, + "license": "MIT", "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -3209,6 +3163,7 @@ "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", "dev": true, + "license": "WTFPL", "dependencies": { "check-error": "^1.0.2" }, @@ -3221,6 +3176,7 @@ "resolved": "https://registry.npmjs.org/chai-exclude/-/chai-exclude-2.1.1.tgz", "integrity": "sha512-IHgNmgAFOkyRPnmOtZio9UsOHQ6RnzVr2LOs+5V9urYYqjhV/ERLQapC0Eq2DmID5eDWyngAcBxNUm0ZK0QbrQ==", "dev": true, + "license": "MIT", "dependencies": { "fclone": "^1.0.11" }, @@ -3228,20 +3184,12 @@ "chai": ">= 4.0.0 < 5" } }, - "node_modules/chai/node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3258,6 +3206,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3270,6 +3219,7 @@ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.2" }, @@ -3282,6 +3232,7 @@ "resolved": "https://registry.npmjs.org/child-process-promise/-/child-process-promise-2.2.1.tgz", "integrity": "sha512-Fi4aNdqBsr0mv+jgWxcZ/7rAIC2mgihrptyVI4foh/rrjY/3BNjfP9+oaiFx/fzim+1ZyCNBae0DlyfQhSugog==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^4.0.2", "node-version": "^1.0.0", @@ -3293,6 +3244,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -3312,11 +3264,25 @@ "fsevents": "~2.3.2" } }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -3326,6 +3292,7 @@ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3335,6 +3302,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "devOptional": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -3349,6 +3317,7 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -3358,6 +3327,7 @@ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -3366,13 +3336,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cloneable-readable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "process-nextick-args": "^2.0.0", @@ -3384,6 +3356,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3398,13 +3371,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cloneable-readable/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -3414,6 +3389,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "devOptional": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -3425,13 +3401,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, + "license": "ISC", "bin": { "color-support": "bin.js" } @@ -3441,6 +3419,7 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.1.90" } @@ -3450,6 +3429,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "devOptional": true, + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -3462,6 +3442,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": "^12.20.0 || >=14" @@ -3471,13 +3452,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-stream": { "version": "1.6.2", @@ -3487,6 +3470,7 @@ "engines": [ "node >= 0.8" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -3499,6 +3483,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3513,13 +3498,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -3529,6 +3516,7 @@ "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", "dev": true, + "license": "ISC", "dependencies": { "source-map": "^0.6.1" } @@ -3537,19 +3525,22 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" }, "node_modules/copy-props": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", "dev": true, + "license": "MIT", "dependencies": { "each-props": "^3.0.0", "is-plain-object": "^5.0.0" @@ -3559,48 +3550,36 @@ } }, "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT" }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", "dev": true, + "license": "MIT", "dependencies": { "lru-cache": "^4.0.1", "which": "^1.2.9" } }, - "node_modules/cross-spawn/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/cross-spawn/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" }, @@ -3613,6 +3592,7 @@ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -3630,6 +3610,7 @@ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -3647,6 +3628,7 @@ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -3660,11 +3642,12 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3676,15 +3659,13 @@ } }, "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, "node_modules/deep-eql": { @@ -3692,6 +3673,7 @@ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", "dev": true, + "license": "MIT", "dependencies": { "type-detect": "^4.0.0" }, @@ -3703,13 +3685,15 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/default-require-extensions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", "dev": true, + "license": "MIT", "dependencies": { "strip-bom": "^4.0.0" }, @@ -3720,20 +3704,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/default-require-extensions/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -3751,6 +3727,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -3768,6 +3745,7 @@ "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", "dev": true, + "license": "MIT", "dependencies": { "globby": "^11.0.1", "graceful-fs": "^4.2.4", @@ -3790,6 +3768,7 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -3798,13 +3777,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3814,6 +3795,7 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -3823,6 +3805,7 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -3832,6 +3815,7 @@ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -3844,6 +3828,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -3855,6 +3840,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", "optional": true, "dependencies": { "end-of-stream": "^1.4.1", @@ -3868,6 +3854,7 @@ "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0" @@ -3881,6 +3868,7 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": true, + "license": "MIT", "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -3890,27 +3878,31 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" } }, "node_modules/electron-to-chromium": { - "version": "1.5.33", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", - "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", - "dev": true + "version": "1.5.51", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.51.tgz", + "integrity": "sha512-kKeWV57KSS8jH4alKt/jKnvHPmJgBxXzGUSbMd4eQF+iOsVPl7bz2KUmu6eo80eMP8wVioTfTyTzdMgM15WXNg==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "devOptional": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -3920,6 +3912,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } @@ -3929,6 +3922,7 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -3989,6 +3983,7 @@ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -4001,6 +3996,7 @@ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -4010,6 +4006,7 @@ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0" }, @@ -4022,6 +4019,7 @@ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -4036,6 +4034,7 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -4052,13 +4051,15 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4068,6 +4069,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4081,6 +4083,7 @@ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4132,16 +4135,20 @@ } }, "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { @@ -4149,6 +4156,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4161,6 +4169,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4177,6 +4186,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4186,54 +4196,19 @@ "node": ">= 8" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4246,6 +4221,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4261,6 +4237,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -4278,6 +4255,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -4291,6 +4269,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -4298,20 +4277,12 @@ "node": ">=0.10" } }, - "node_modules/esquery/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/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -4319,20 +4290,12 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "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/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -4342,6 +4305,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -4350,6 +4314,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=6" @@ -4360,6 +4325,7 @@ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", "dev": true, + "license": "MIT", "dependencies": { "homedir-polyfill": "^1.0.1" }, @@ -4370,13 +4336,15 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" }, "node_modules/extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -4392,13 +4360,15 @@ "dev": true, "engines": [ "node >=0.6.0" - ] + ], + "license": "MIT" }, "node_modules/fancy-log": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", "dev": true, + "license": "MIT", "dependencies": { "ansi-gray": "^0.1.1", "color-support": "^1.1.3", @@ -4413,6 +4383,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", + "license": "MIT", "engines": { "node": ">=18.0.0" } @@ -4421,19 +4392,22 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -4445,17 +4419,32 @@ "node": ">=8.6.0" } }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-xml-parser": { "version": "4.5.0", @@ -4471,6 +4460,7 @@ "url": "https://paypal.me/naturalintelligence" } ], + "license": "MIT", "optional": true, "dependencies": { "strnum": "^1.0.5" @@ -4484,6 +4474,7 @@ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.9.1" } @@ -4493,6 +4484,7 @@ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -4501,6 +4493,7 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -4512,13 +4505,15 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -4531,6 +4526,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4543,6 +4539,7 @@ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, + "license": "MIT", "dependencies": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -4560,6 +4557,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -4576,6 +4574,7 @@ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", "dev": true, + "license": "MIT", "dependencies": { "detect-file": "^1.0.0", "is-glob": "^4.0.3", @@ -4591,6 +4590,7 @@ "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", "dev": true, + "license": "MIT", "dependencies": { "expand-tilde": "^2.0.2", "is-plain-object": "^5.0.0", @@ -4606,13 +4606,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/firebase-token-generator/-/firebase-token-generator-2.0.0.tgz", "integrity": "sha512-EX/Rw6C0NLF6StuszW9Pn4zGUU8dw0UdHY6u8zP5t/CsbYRwWVh0CwN6INFE5U4IizZtgqbWQhcAQNkBtNkyfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/flagged-respawn": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -4622,6 +4624,7 @@ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, + "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } @@ -4631,6 +4634,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -4644,13 +4648,15 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "readable-stream": "^2.3.6" @@ -4661,6 +4667,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4675,13 +4682,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/flush-write-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -4691,6 +4700,7 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } @@ -4700,6 +4710,7 @@ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4709,6 +4720,7 @@ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", "dev": true, + "license": "MIT", "dependencies": { "for-in": "^1.0.1" }, @@ -4721,6 +4733,7 @@ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -4737,6 +4750,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4751,6 +4765,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -4763,6 +4778,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4778,19 +4794,22 @@ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "*" } }, "node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", + "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", "devOptional": true, + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "mime-types": "^2.1.12", + "safe-buffer": "^5.2.1" }, "engines": { "node": ">= 0.12" @@ -4814,13 +4833,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -4835,6 +4856,7 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -4847,6 +4869,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -4854,11 +4877,19 @@ "node": ">=8" } }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/fs-mkdirp-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.8", "streamx": "^2.12.0" @@ -4871,7 +4902,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -4879,6 +4911,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -4892,6 +4925,7 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4901,6 +4935,7 @@ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -4918,6 +4953,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "license": "MIT", "optional": true }, "node_modules/functions-have-names": { @@ -4925,6 +4961,7 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4935,6 +4972,7 @@ "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", "deprecated": "This package is no longer supported.", "dev": true, + "license": "ISC", "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.2", @@ -4951,9 +4989,10 @@ } }, "node_modules/gaxios": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz", - "integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", @@ -4965,6 +5004,31 @@ "node": ">=14" } }, + "node_modules/gaxios/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/gaxios/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/gaxios/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -4973,6 +5037,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -4981,6 +5046,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "license": "Apache-2.0", "dependencies": { "gaxios": "^6.0.0", "json-bigint": "^1.0.0" @@ -4994,6 +5060,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -5003,6 +5070,7 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "devOptional": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -5012,6 +5080,7 @@ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -5021,6 +5090,7 @@ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -5040,6 +5110,7 @@ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -5048,13 +5119,15 @@ "version": "0.0.10", "resolved": "https://registry.npmjs.org/get-prop/-/get-prop-0.0.10.tgz", "integrity": "sha512-XRSGBgcIisSMLJ/dwe1y/eMm9yzLicEJKmEXA3ArBkDkCW2nyRroLOoKIz+SdxuG5SI7ym2QHaTU5ifCl7MTDg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -5072,41 +5145,43 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, "node_modules/glob-stream": { @@ -5114,6 +5189,7 @@ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", "dev": true, + "license": "MIT", "dependencies": { "@gulpjs/to-absolute-glob": "^4.0.0", "anymatch": "^3.1.3", @@ -5128,23 +5204,12 @@ "node": ">=10.13.0" } }, - "node_modules/glob-stream/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/glob-watcher": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", "dev": true, + "license": "MIT", "dependencies": { "async-done": "^2.0.0", "chokidar": "^3.5.3" @@ -5153,16 +5218,27 @@ "node": ">= 10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=10" } }, "node_modules/global-modules": { @@ -5170,6 +5246,7 @@ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, + "license": "MIT", "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", @@ -5184,6 +5261,7 @@ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", "dev": true, + "license": "MIT", "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", @@ -5200,6 +5278,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -5215,6 +5294,7 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -5231,6 +5311,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -5251,6 +5332,7 @@ "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", "dev": true, + "license": "MIT", "dependencies": { "sparkles": "^2.1.0" }, @@ -5279,6 +5361,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@grpc/grpc-js": "^1.10.9", @@ -5306,6 +5389,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "optional": true, "bin": { "uuid": "dist/bin/uuid" @@ -5316,6 +5400,7 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -5327,18 +5412,21 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/gtoken": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" @@ -5352,6 +5440,7 @@ "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz", "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==", "dev": true, + "license": "MIT", "dependencies": { "glob-watcher": "^6.0.0", "gulp-cli": "^3.0.0", @@ -5365,11 +5454,70 @@ "node": ">=10.13.0" } }, + "node_modules/gulp-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", + "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@gulpjs/messages": "^1.1.0", + "chalk": "^4.1.2", + "copy-props": "^4.0.0", + "gulplog": "^2.2.0", + "interpret": "^3.1.1", + "liftoff": "^5.0.0", + "mute-stdout": "^2.0.0", + "replace-homedir": "^2.0.0", + "semver-greatest-satisfied-range": "^2.0.0", + "string-width": "^4.2.3", + "v8flags": "^4.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-cli/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/gulp-cli/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/gulp-filter": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-7.0.0.tgz", "integrity": "sha512-ZGWtJo0j1mHfP77tVuhyqem4MRA5NfNRjoVe6VAkLGeQQ/QGo2VsFwp7zfPTGDsd1rwzBmoDHhxpE6f5B3Zuaw==", "dev": true, + "license": "MIT", "dependencies": { "multimatch": "^5.0.0", "plugin-error": "^1.0.1", @@ -5396,6 +5544,7 @@ "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-2.0.9.tgz", "integrity": "sha512-LMGiBx+qH8giwrOuuZXSGvswcIUh0OiioNkUpLhNyvaC6/Ga8X6cfAeme2L5PqsbXMhL8o8b/OmVqIQdxprhcQ==", "dev": true, + "license": "MIT", "dependencies": { "concat-with-sourcemaps": "^1.1.0", "lodash.template": "^4.5.0", @@ -5408,6 +5557,7 @@ "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-5.0.1.tgz", "integrity": "sha512-YuMMlylyJtUSHG1/wuSVTrZp60k1dMEFKYOvDf7OvbAJWrDtxxD4oZon4ancdWwzjj30ztiidhe4VXJniF0pIQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-colors": "^3.0.5", "plugin-error": "^1.0.1", @@ -5423,26 +5573,12 @@ "typescript": "~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev" } }, - "node_modules/gulp-typescript/node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/gulp-typescript/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.11", "through2": "^2.0.3" @@ -5451,29 +5587,37 @@ "node": ">= 0.10" } }, - "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, + "license": "MIT", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, - "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "node_modules/gulp-typescript/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/gulp-typescript/node_modules/glob-parent": { @@ -5481,6 +5625,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" @@ -5491,6 +5636,7 @@ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", "dev": true, + "license": "MIT", "dependencies": { "extend": "^3.0.0", "glob": "^7.1.1", @@ -5507,26 +5653,12 @@ "node": ">= 0.10" } }, - "node_modules/gulp-typescript/node_modules/glob-stream/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "node_modules/gulp-typescript/node_modules/is-glob": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.0" }, @@ -5539,6 +5671,7 @@ "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", "dev": true, + "license": "MIT", "dependencies": { "flush-write-stream": "^1.0.2" }, @@ -5546,11 +5679,25 @@ "node": ">= 0.10" } }, + "node_modules/gulp-typescript/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/gulp-typescript/node_modules/normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dev": true, + "license": "MIT", "dependencies": { "remove-trailing-separator": "^1.0.1" }, @@ -5563,6 +5710,7 @@ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.3.2" }, @@ -5570,13 +5718,20 @@ "node": ">= 0.10" } }, - "node_modules/gulp-typescript/node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "node_modules/gulp-typescript/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "engines": { - "node": ">= 0.10" + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "node_modules/gulp-typescript/node_modules/resolve-options": { @@ -5584,6 +5739,7 @@ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", "dev": true, + "license": "MIT", "dependencies": { "value-or-function": "^3.0.0" }, @@ -5595,13 +5751,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/gulp-typescript/node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } @@ -5611,6 +5769,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -5620,6 +5779,7 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.4", "readable-stream": "2 || 3" @@ -5630,6 +5790,7 @@ "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", "dev": true, + "license": "MIT", "dependencies": { "through2": "^2.0.3" }, @@ -5637,26 +5798,12 @@ "node": ">= 0.10" } }, - "node_modules/gulp-typescript/node_modules/to-through/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "node_modules/gulp-typescript/node_modules/to-through/node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -5667,23 +5814,7 @@ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/gulp-typescript/node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -5693,6 +5824,7 @@ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", "dev": true, + "license": "MIT", "dependencies": { "fs-mkdirp-stream": "^1.0.0", "glob-stream": "^6.1.0", @@ -5716,26 +5848,12 @@ "node": ">= 0.10" } }, - "node_modules/gulp-typescript/node_modules/vinyl-fs/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "node_modules/gulp-typescript/node_modules/vinyl-fs/node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -5746,6 +5864,7 @@ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", "dev": true, + "license": "MIT", "dependencies": { "append-buffer": "^1.0.2", "convert-source-map": "^1.5.0", @@ -5759,75 +5878,12 @@ "node": ">= 0.10" } }, - "node_modules/gulp/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/gulp/node_modules/gulp-cli": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", - "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", - "dev": true, - "dependencies": { - "@gulpjs/messages": "^1.1.0", - "chalk": "^4.1.2", - "copy-props": "^4.0.0", - "gulplog": "^2.2.0", - "interpret": "^3.1.1", - "liftoff": "^5.0.0", - "mute-stdout": "^2.0.0", - "replace-homedir": "^2.0.0", - "semver-greatest-satisfied-range": "^2.0.0", - "string-width": "^4.2.3", - "v8flags": "^4.0.0", - "yargs": "^16.2.0" - }, - "bin": { - "gulp": "bin/gulp.js" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/gulp/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gulp/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/gulplog": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", "dev": true, + "license": "MIT", "dependencies": { "glogg": "^2.2.0" }, @@ -5840,6 +5896,7 @@ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "dev": true, + "license": "ISC", "engines": { "node": ">=4" } @@ -5850,6 +5907,7 @@ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -5863,6 +5921,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5878,13 +5937,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -5897,6 +5958,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5906,6 +5968,7 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5915,6 +5978,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5924,6 +5988,7 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -5936,6 +6001,7 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5948,6 +6014,7 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5960,6 +6027,7 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -5974,13 +6042,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", "dev": true, + "license": "MIT", "dependencies": { "is-stream": "^2.0.0", "type-fest": "^0.8.0" @@ -5997,6 +6067,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } @@ -6006,6 +6077,7 @@ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -6018,6 +6090,7 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, + "license": "MIT", "bin": { "he": "bin/he" } @@ -6027,6 +6100,7 @@ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, + "license": "MIT", "dependencies": { "parse-passwd": "^1.0.0" }, @@ -6038,7 +6112,8 @@ "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/html-entities": { "version": "2.5.2", @@ -6054,19 +6129,22 @@ "url": "https://patreon.com/mdevils" } ], + "license": "MIT", "optional": true }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/http-message-parser": { "version": "0.0.34", "resolved": "https://registry.npmjs.org/http-message-parser/-/http-message-parser-0.0.34.tgz", "integrity": "sha512-KABKXT347AYvQoaMZg9/K+/GqW6gfB4pKCiTyMUYnosfkdkaBkrXE/cWGSLk5jvD5tiDeLFlYSHLhhPhQKbRrA==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^4.9.1", "concat-stream": "^1.5.1", @@ -6081,26 +6159,17 @@ "node": ">=0.10.0" } }, - "node_modules/http-message-parser/node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "license": "MIT" }, "node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "license": "MIT", "optional": true, "dependencies": { "@tootallnate/once": "2", @@ -6111,23 +6180,12 @@ "node": ">= 6" } }, - "node_modules/http-proxy-agent/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==", - "optional": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -6139,15 +6197,17 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "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==", + "devOptional": true, + "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 14" + "node": ">= 6" } }, "node_modules/iconv-lite": { @@ -6155,6 +6215,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -6166,7 +6227,8 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ieee754": { "version": "1.2.1", @@ -6186,13 +6248,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -6202,6 +6266,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6218,6 +6283,7 @@ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6227,6 +6293,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -6236,6 +6303,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6246,6 +6314,7 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -6255,19 +6324,22 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -6282,6 +6354,7 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -6291,6 +6364,7 @@ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, + "license": "MIT", "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" @@ -6304,6 +6378,7 @@ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -6319,13 +6394,15 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -6338,6 +6415,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -6350,6 +6428,7 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6365,13 +6444,15 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6380,12 +6461,16 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6396,6 +6481,7 @@ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", "dev": true, + "license": "MIT", "dependencies": { "is-typed-array": "^1.1.13" }, @@ -6411,6 +6497,7 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6426,6 +6513,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -6438,6 +6526,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -6450,6 +6539,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6459,6 +6549,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6468,6 +6559,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -6480,6 +6572,7 @@ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6489,6 +6582,7 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6501,6 +6595,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -6510,6 +6605,7 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6525,6 +6621,7 @@ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -6534,6 +6631,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6543,6 +6641,7 @@ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6552,6 +6651,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6561,6 +6661,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -6577,6 +6678,7 @@ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, + "license": "MIT", "dependencies": { "is-unc-path": "^1.0.0" }, @@ -6589,6 +6691,7 @@ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7" }, @@ -6603,6 +6706,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -6615,6 +6719,7 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -6630,6 +6735,7 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -6645,6 +6751,7 @@ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, + "license": "MIT", "dependencies": { "which-typed-array": "^1.1.14" }, @@ -6659,13 +6766,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, + "license": "MIT", "dependencies": { "unc-path-regex": "^0.1.2" }, @@ -6678,6 +6787,7 @@ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6689,13 +6799,15 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-valid-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6705,6 +6817,7 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -6717,6 +6830,7 @@ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6725,19 +6839,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6746,13 +6863,15 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } @@ -6762,6 +6881,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "append-transform": "^2.0.0" }, @@ -6774,6 +6894,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", @@ -6790,6 +6911,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, + "license": "ISC", "dependencies": { "archy": "^1.0.0", "cross-spawn": "^7.0.3", @@ -6807,6 +6929,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6821,6 +6944,7 @@ "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, + "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -6833,6 +6957,7 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -6842,6 +6967,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -6857,6 +6983,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -6871,6 +6998,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.3" }, @@ -6886,6 +7014,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -6898,6 +7027,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -6912,6 +7042,7 @@ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -6924,12 +7055,14 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" } @@ -6938,13 +7071,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -6956,19 +7091,22 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -6980,6 +7118,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" } @@ -6988,43 +7127,50 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -7037,6 +7183,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -7045,6 +7192,7 @@ "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -7066,6 +7214,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -7076,6 +7225,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" @@ -7086,6 +7236,7 @@ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, + "license": "MIT", "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -7100,12 +7251,14 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jwa": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "license": "MIT", "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -7116,6 +7269,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "license": "MIT", "dependencies": { "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.2", @@ -7129,9 +7283,10 @@ } }, "node_modules/jwks-rsa/node_modules/@types/jsonwebtoken": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", - "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", + "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -7140,6 +7295,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" @@ -7150,6 +7306,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -7159,6 +7316,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", "integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7168,6 +7326,7 @@ "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -7177,6 +7336,7 @@ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" }, @@ -7189,6 +7349,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7203,13 +7364,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -7219,6 +7382,7 @@ "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -7228,6 +7392,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -7241,6 +7406,7 @@ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==", "dev": true, + "license": "MIT", "dependencies": { "extend": "^3.0.2", "findup-sync": "^5.0.0", @@ -7264,6 +7430,7 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -7274,11 +7441,22 @@ "node": ">=4" } }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -7293,89 +7471,105 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT", "optional": true }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" }, "node_modules/lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" }, "node_modules/lodash.isboolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" }, "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" }, "node_modules/lodash.template": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dev": true, + "license": "MIT", "dependencies": { "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" @@ -7386,6 +7580,7 @@ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "dev": true, + "license": "MIT", "dependencies": { "lodash._reinterpolate": "^3.0.0" } @@ -7395,6 +7590,7 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -7410,6 +7606,7 @@ "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "license": "Apache-2.0", "optional": true }, "node_modules/loupe": { @@ -7417,35 +7614,56 @@ "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, + "license": "MIT", "dependencies": { "get-func-name": "^2.0.1" } }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "node_modules/lru-memoizer": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "license": "MIT", "dependencies": { "lodash.clonedeep": "^4.5.0", "lru-cache": "6.0.0" } }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -7461,6 +7679,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -7469,13 +7688,15 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7484,7 +7705,8 @@ "version": "0.0.7", "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/memorystream": { "version": "0.3.1", @@ -7500,15 +7722,17 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -7521,6 +7745,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", "optional": true, "bin": { "mime": "cli.js" @@ -7534,6 +7759,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7543,6 +7769,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "devOptional": true, + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -7555,6 +7782,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7567,6 +7795,7 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7576,6 +7805,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=8" } @@ -7585,6 +7815,7 @@ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, + "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -7598,6 +7829,7 @@ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -7605,11 +7837,19 @@ "node": ">=8" } }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, + "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -7618,10 +7858,11 @@ } }, "node_modules/mocha": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", - "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", @@ -7657,6 +7898,7 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -7666,6 +7908,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -7675,37 +7918,19 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, - "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/mocha/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7713,17 +7938,12 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/mocha/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -7737,25 +7957,18 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/multimatch": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", "dev": true, + "license": "MIT", "dependencies": { "@types/minimatch": "^3.0.3", "array-differ": "^3.0.0", @@ -7775,6 +7988,7 @@ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -7784,6 +7998,7 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -7794,38 +8009,46 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" + "path-to-regexp": "^8.1.0" + } + }, + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" } }, "node_modules/nock": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz", - "integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==", + "version": "13.5.5", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.5.tgz", + "integrity": "sha512-XKYnqUrCwXC8DGG1xX4YH5yNIrlh9c065uaMZZHUoeUUINTOyt+x/G+ezYk0Ft6ExSREVIs+qBJDK503viTfFA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", @@ -7839,12 +8062,14 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -7864,6 +8089,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } @@ -7873,6 +8099,7 @@ "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", "dev": true, + "license": "MIT", "dependencies": { "process-on-spawn": "^1.0.0" }, @@ -7884,13 +8111,15 @@ "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-version": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.2.0.tgz", "integrity": "sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -7900,6 +8129,7 @@ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "dev": true, + "license": "ISC", "dependencies": { "abbrev": "1" }, @@ -7915,6 +8145,7 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -7927,6 +8158,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } @@ -7936,6 +8168,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7945,6 +8178,7 @@ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" }, @@ -7957,6 +8191,7 @@ "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "chalk": "^2.4.1", @@ -7982,6 +8217,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -7994,6 +8230,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -8008,6 +8245,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -8016,13 +8254,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/npm-run-all/node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, + "license": "MIT", "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -8039,6 +8279,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -8048,6 +8289,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -8057,6 +8299,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -8066,6 +8309,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } @@ -8075,6 +8319,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^1.0.0" }, @@ -8087,6 +8332,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8096,6 +8342,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -8109,6 +8356,7 @@ "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", "deprecated": "This package is no longer supported.", "dev": true, + "license": "ISC", "dependencies": { "are-we-there-yet": "^2.0.0", "console-control-strings": "^1.1.0", @@ -8121,6 +8369,7 @@ "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", @@ -8157,46 +8406,24 @@ "node": ">=18" } }, - "node_modules/nyc/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/nyc/node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, - "node_modules/nyc/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/nyc/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nyc/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -8205,11 +8432,34 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/nyc/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -8217,11 +8467,25 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/nyc/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -8237,6 +8501,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -8249,6 +8514,7 @@ "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", "dev": true, + "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -8261,6 +8527,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8270,6 +8537,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8283,13 +8551,15 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/nyc/node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -8312,6 +8582,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -8325,6 +8596,7 @@ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "*" } @@ -8334,6 +8606,7 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8342,16 +8615,21 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", "optional": true, "engines": { "node": ">= 6" } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8361,6 +8639,7 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8370,6 +8649,7 @@ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -8388,6 +8668,7 @@ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", "dev": true, + "license": "MIT", "dependencies": { "array-each": "^1.0.1", "array-slice": "^1.0.0", @@ -8403,6 +8684,7 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -8415,6 +8697,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "devOptional": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -8424,6 +8707,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -8441,6 +8725,7 @@ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "^2.0.1" } @@ -8450,6 +8735,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8464,13 +8750,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ordered-read-streams/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -8480,6 +8768,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "devOptional": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -8495,6 +8784,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -8510,6 +8800,7 @@ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, + "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -8525,6 +8816,7 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -8534,6 +8826,7 @@ "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", "dev": true, + "license": "ISC", "dependencies": { "graceful-fs": "^4.1.15", "hasha": "^5.0.0", @@ -8549,6 +8842,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -8561,6 +8855,7 @@ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", "dev": true, + "license": "MIT", "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", @@ -8575,6 +8870,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, + "license": "MIT", "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -8588,6 +8884,7 @@ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -8597,6 +8894,7 @@ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8605,13 +8903,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8621,6 +8921,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8630,6 +8931,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8638,13 +8940,15 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", "dev": true, + "license": "MIT", "dependencies": { "path-root-regex": "^0.1.0" }, @@ -8657,21 +8961,27 @@ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8681,6 +8991,7 @@ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -8689,19 +9000,22 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -8714,6 +9028,7 @@ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", "dev": true, + "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -8726,6 +9041,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -8735,6 +9051,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -8747,6 +9064,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -8760,6 +9078,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -8772,6 +9091,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -8787,6 +9107,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -8799,6 +9120,7 @@ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-colors": "^1.0.1", "arr-diff": "^4.0.0", @@ -8809,11 +9131,25 @@ "node": ">= 0.10" } }, + "node_modules/plugin-error/node_modules/ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-wrap": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8823,6 +9159,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -8831,13 +9168,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", "dev": true, + "license": "MIT", "dependencies": { "fromentries": "^1.2.0" }, @@ -8849,13 +9188,15 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", "integrity": "sha512-g0LWaH0gFsxovsU7R5LrrhHhWAWiHRnh1GPrhXnPgYsDkIqjRYUYSZEsej/wtleDrz5xVSIDbeKfidztp2XHFQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/propagate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -8864,6 +9205,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "protobufjs": "^7.2.5" @@ -8877,6 +9219,7 @@ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", "hasInstallScript": true, + "license": "BSD-3-Clause", "optional": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -8900,19 +9243,22 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -8923,6 +9269,7 @@ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, + "license": "MIT", "dependencies": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -8934,6 +9281,7 @@ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -8946,6 +9294,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8960,13 +9309,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pumpify/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -8976,6 +9327,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -8985,6 +9337,7 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.6" } @@ -9007,19 +9360,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/queue-tick": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } @@ -9029,6 +9385,7 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, + "license": "MIT", "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -9043,6 +9400,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^3.0.0" }, @@ -9055,6 +9413,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "devOptional": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -9069,6 +9428,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -9081,6 +9441,7 @@ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, + "license": "MIT", "dependencies": { "resolve": "^1.20.0" }, @@ -9089,15 +9450,16 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -9111,6 +9473,7 @@ "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "dev": true, + "license": "ISC", "dependencies": { "es6-error": "^4.0.1" }, @@ -9123,6 +9486,7 @@ "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5", "is-utf8": "^0.2.1" @@ -9136,6 +9500,7 @@ "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", "dev": true, + "license": "MIT", "dependencies": { "remove-bom-buffer": "^3.0.0", "safe-buffer": "^5.1.0", @@ -9149,15 +9514,17 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/replace-ext": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", - "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 10" + "node": ">= 0.10" } }, "node_modules/replace-homedir": { @@ -9165,6 +9532,7 @@ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -9175,6 +9543,7 @@ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, + "license": "Apache-2.0", "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -9207,6 +9576,7 @@ "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", "dev": true, + "license": "ISC", "dependencies": { "bluebird": "^3.5.0", "request-promise-core": "1.1.4", @@ -9225,6 +9595,7 @@ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, + "license": "ISC", "dependencies": { "lodash": "^4.17.19" }, @@ -9240,6 +9611,7 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -9255,6 +9627,7 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, + "license": "MIT", "bin": { "uuid": "bin/uuid" } @@ -9264,6 +9637,7 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9273,6 +9647,7 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9281,13 +9656,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -9305,6 +9682,7 @@ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", "dev": true, + "license": "MIT", "dependencies": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" @@ -9318,6 +9696,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -9327,6 +9706,7 @@ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", "dev": true, + "license": "MIT", "dependencies": { "value-or-function": "^4.0.0" }, @@ -9338,6 +9718,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "optional": true, "engines": { "node": ">= 4" @@ -9347,6 +9728,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", "optional": true, "dependencies": { "@types/request": "^2.48.8", @@ -9362,6 +9744,7 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -9373,6 +9756,7 @@ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -9383,6 +9767,41 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9402,6 +9821,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -9411,6 +9831,7 @@ "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.1.tgz", "integrity": "sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^1.1.3", "fancy-log": "^1.3.2", @@ -9425,6 +9846,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9434,6 +9856,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9443,6 +9866,7 @@ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", "integrity": "sha512-OQwDZUqYaQwyyhDJHThmzId8daf4/RFNLaeh3AevmSeZ5Y7ug4Ga/yKc6l6kTZOBW781rCj103ZuTh8GAsB3+Q==", "dev": true, + "license": "MIT", "dependencies": { "arr-flatten": "^1.0.1", "array-slice": "^0.2.3" @@ -9456,6 +9880,7 @@ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", "integrity": "sha512-t5db90jq+qdgk8aFnxEkjqta0B/GHrM1pxzuuZz2zWsOXc5nKu3t+76s/PQBA8FTcM/ipspIH9jWG4OxCBc2eA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9465,6 +9890,7 @@ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", "integrity": "sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9474,6 +9900,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -9490,6 +9917,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -9499,6 +9927,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", "integrity": "sha512-L7AGmkO6jhDkEBBGWlLtftA80Xq8DipnrRPr0pyi7GQLXkaq9JYA4xF4z6qnadIC6euiTDKco0cGSU9muw+WTw==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^1.1.0" }, @@ -9511,6 +9940,7 @@ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", "integrity": "sha512-WzZHcm4+GO34sjFMxQMqZbsz3xiNEgonCskQ9v+IroMmYgk/tas8dG+Hr2D6IbRPybZ12oWpzE/w3cGJ6FJzOw==", "dev": true, + "license": "MIT", "dependencies": { "ansi-cyan": "^0.1.1", "ansi-red": "^0.1.1", @@ -9527,6 +9957,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -9539,6 +9970,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -9548,6 +9980,7 @@ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -9565,7 +9998,8 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/safe-buffer": { "version": "5.2.1", @@ -9584,13 +10018,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-regex-test": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -9607,12 +10043,17 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -9625,6 +10066,7 @@ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", "dev": true, + "license": "MIT", "dependencies": { "sver": "^1.8.3" }, @@ -9632,11 +10074,30 @@ "node": ">= 10.13.0" } }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -9645,13 +10106,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9669,6 +10132,7 @@ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9684,6 +10148,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -9696,6 +10161,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9705,6 +10171,7 @@ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9714,6 +10181,7 @@ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -9731,16 +10199,18 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.1.tgz", + "integrity": "sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/fake-timers": "11.2.2", "@sinonjs/samsam": "^8.0.0", "diff": "^5.2.0", "nise": "^6.0.0", @@ -9756,25 +10226,18 @@ "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", "dev": true, + "license": "(BSD-2-Clause OR WTFPL)", "peerDependencies": { "chai": "^4.0.0", "sinon": ">=4.0.0" } }, - "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/sinon/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -9787,6 +10250,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -9796,6 +10260,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -9805,6 +10270,7 @@ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -9814,6 +10280,7 @@ "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^2.0.0", "is-windows": "^1.0.2", @@ -9831,6 +10298,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -9845,6 +10313,7 @@ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" @@ -9858,6 +10327,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -9873,6 +10343,7 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -9882,35 +10353,40 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true + "dev": true, + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, + "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "dev": true + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true, + "license": "CC0-1.0" }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", "dev": true, + "license": "MIT", "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -9936,15 +10412,17 @@ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", "dev": true, + "license": "ISC", "engines": { "node": ">=0.10.0" } }, "node_modules/stream-buffers": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", - "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.3.tgz", + "integrity": "sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==", "dev": true, + "license": "Unlicense", "engines": { "node": ">= 0.10.0" } @@ -9954,6 +10432,7 @@ "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", "dev": true, + "license": "MIT", "dependencies": { "streamx": "^2.13.2" } @@ -9962,6 +10441,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "license": "MIT", "optional": true, "dependencies": { "stubs": "^3.0.0" @@ -9971,19 +10451,22 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/stream-shift": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/streamfilter": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-3.0.0.tgz", "integrity": "sha512-kvKNfXCmUyC8lAXSSHCIXBUlo/lhsLcCU/OmzACZYpRUdtKIH68xYhm/+HI15jFJYtNJGYtCgn2wmIiExY1VwA==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "^3.0.6" }, @@ -9992,10 +10475,11 @@ } }, "node_modules/streamx": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", - "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", "dev": true, + "license": "MIT", "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", @@ -10010,6 +10494,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "devOptional": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -10019,6 +10504,7 @@ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6.19" } @@ -10028,6 +10514,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "devOptional": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10042,6 +10529,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10060,6 +10548,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10078,6 +10567,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10092,6 +10582,7 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -10109,6 +10600,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -10117,12 +10609,13 @@ } }, "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-json-comments": { @@ -10130,6 +10623,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -10141,12 +10635,14 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "license": "MIT", "optional": true }, "node_modules/stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "license": "MIT", "optional": true }, "node_modules/supports-color": { @@ -10154,6 +10650,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -10169,6 +10666,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -10181,6 +10679,7 @@ "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", "dev": true, + "license": "MIT", "optionalDependencies": { "semver": "^6.3.0" } @@ -10190,6 +10689,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "optional": true, "bin": { "semver": "bin/semver.js" @@ -10200,6 +10700,7 @@ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, + "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -10212,10 +10713,18 @@ "node": ">=10" } }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/teeny-request": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "license": "Apache-2.0", "optional": true, "dependencies": { "http-proxy-agent": "^5.0.0", @@ -10228,31 +10737,6 @@ "node": ">=14" } }, - "node_modules/teeny-request/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==", - "optional": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/teeny-request/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==", - "optional": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/teeny-request/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -10261,6 +10745,7 @@ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "optional": true, "bin": { "uuid": "dist/bin/uuid" @@ -10271,6 +10756,7 @@ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "dev": true, + "license": "MIT", "dependencies": { "streamx": "^2.12.5" } @@ -10280,6 +10766,7 @@ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -10289,26 +10776,61 @@ "node": ">=8" } }, - "node_modules/text-decoder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", - "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { - "b4a": "^1.6.4" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, + "node_modules/text-decoder": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", + "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -10318,6 +10840,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, + "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -10330,6 +10853,7 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -10340,6 +10864,7 @@ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "dev": true, + "license": "MIT", "dependencies": { "through2": "~2.0.0", "xtend": "~4.0.0" @@ -10350,6 +10875,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -10364,13 +10890,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/through2/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -10380,6 +10908,7 @@ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10388,13 +10917,15 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", "dev": true, + "license": "MIT", "dependencies": { "is-absolute": "^1.0.0", "is-negated-glob": "^1.0.0" @@ -10403,20 +10934,12 @@ "node": ">=0.10.0" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -10429,6 +10952,7 @@ "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", "dev": true, + "license": "MIT", "dependencies": { "streamx": "^2.12.5" }, @@ -10441,6 +10965,7 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -10452,13 +10977,28 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/ts-api-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", + "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -10502,41 +11042,23 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" }, @@ -10548,13 +11070,15 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "dev": true, + "license": "Unlicense" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -10563,10 +11087,11 @@ } }, "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -10576,6 +11101,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -10588,6 +11114,7 @@ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -10602,6 +11129,7 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -10621,6 +11149,7 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -10641,6 +11170,7 @@ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -10660,22 +11190,25 @@ "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, + "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10689,6 +11222,7 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -10704,6 +11238,7 @@ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10713,6 +11248,7 @@ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", "dev": true, + "license": "MIT", "dependencies": { "bach": "^2.0.1", "fast-levenshtein": "^3.0.0", @@ -10728,6 +11264,7 @@ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -10737,20 +11274,23 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", "dev": true, + "license": "MIT", "dependencies": { "fastest-levenshtein": "^1.0.7" } }, "node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/unique-stream": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", "dev": true, + "license": "MIT", "dependencies": { "json-stable-stringify-without-jsonify": "^1.0.1", "through2-filter": "^3.0.0" @@ -10761,6 +11301,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } @@ -10784,6 +11325,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.0" @@ -10795,20 +11337,12 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/update-browserslist-db/node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -10817,31 +11351,35 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.2.tgz", + "integrity": "sha512-14FfcOJmqdjbBPdDjFQyk/SdT4NySW4eM0zcG+HqbHP5jzuH56xO3J1DGhgs/cEMCfwYi3HQI1gnTO62iaG+tQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/v8flags": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -10851,6 +11389,7 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -10861,6 +11400,7 @@ "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -10870,6 +11410,7 @@ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -10882,32 +11423,29 @@ "engines": [ "node >=0.6.0" ], + "license": "MIT", "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, "node_modules/vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", "dev": true, + "license": "MIT", "dependencies": { - "clone": "^2.1.2", + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", "clone-stats": "^1.0.0", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" }, "engines": { - "node": ">=10.13.0" + "node": ">= 0.10" } }, "node_modules/vinyl-contents": { @@ -10915,6 +11453,7 @@ "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^5.0.0", "vinyl": "^3.0.0" @@ -10923,11 +11462,39 @@ "node": ">=10.13.0" } }, + "node_modules/vinyl-contents/node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/vinyl-contents/node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/vinyl-fs": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", "dev": true, + "license": "MIT", "dependencies": { "fs-mkdirp-stream": "^2.0.1", "glob-stream": "^8.0.0", @@ -10948,11 +11515,39 @@ "node": ">=10.13.0" } }, + "node_modules/vinyl-fs/node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/vinyl-fs/node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/vinyl-sourcemap": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", "dev": true, + "license": "MIT", "dependencies": { "convert-source-map": "^2.0.0", "graceful-fs": "^4.2.10", @@ -10965,15 +11560,51 @@ "node": ">=10.13.0" } }, + "node_modules/vinyl-sourcemap/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/vinyl-sourcemap/node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -10987,6 +11618,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } @@ -10995,6 +11627,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -11005,6 +11638,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -11017,6 +11651,7 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -11032,13 +11667,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/which-typed-array": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -11058,6 +11695,7 @@ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -11067,6 +11705,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11075,13 +11714,15 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "devOptional": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -11098,13 +11739,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -11117,6 +11760,7 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4" } @@ -11126,20 +11770,24 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "devOptional": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true, + "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "devOptional": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -11154,12 +11802,13 @@ } }, "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "devOptional": true, + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", "engines": { - "node": ">=12" + "node": ">=10" } }, "node_modules/yargs-unparser": { @@ -11167,6 +11816,7 @@ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -11177,20 +11827,25 @@ "node": ">=10" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "devOptional": true, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -11198,8649 +11853,58 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/z-schema": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", - "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", - "dev": true, - "dependencies": { - "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": "^9.4.1" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@babel/code-frame": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", - "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.25.7", - "picocolors": "^1.0.0" - } - }, - "@babel/compat-data": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", - "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", - "dev": true - }, - "@babel/core": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", - "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/helper-compilation-targets": "^7.25.7", - "@babel/helper-module-transforms": "^7.25.7", - "@babel/helpers": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/template": "^7.25.7", - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", - "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", - "dev": true, - "requires": { - "@babel/types": "^7.25.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", - "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.25.7", - "@babel/helper-validator-option": "^7.25.7", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } - } - }, - "@babel/helper-module-imports": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", - "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", - "dev": true, - "requires": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/helper-module-transforms": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", - "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.25.7", - "@babel/helper-simple-access": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "@babel/traverse": "^7.25.7" - } - }, - "@babel/helper-simple-access": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", - "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", - "dev": true, - "requires": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/helper-string-parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", - "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", - "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", - "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", - "dev": true - }, - "@babel/helpers": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", - "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", - "dev": true, - "requires": { - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/highlight": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", - "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.25.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", - "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", - "dev": true, - "requires": { - "@babel/types": "^7.25.7" - } - }, - "@babel/template": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", - "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/types": "^7.25.7" - } - }, - "@babel/traverse": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", - "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", - "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "to-fast-properties": "^2.0.0" - } - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "dev": true - }, - "@fastify/busboy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.0.0.tgz", - "integrity": "sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==" - }, - "@firebase/api-documenter": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/api-documenter/-/api-documenter-0.4.0.tgz", - "integrity": "sha512-UUPxxj1wIAGkXBCF9UL1dhfyzM4Lcd/gMSCoJqy8o75rLqQVGB2GSBaU7I4JmQsQhIIk/nKKLiy4HM/70kEfZA==", - "dev": true, - "requires": { - "@microsoft/tsdoc": "0.12.24", - "@rushstack/node-core-library": "3.59.7", - "@rushstack/ts-command-line": "4.15.2", - "api-extractor-model-me": "0.1.1", - "colors": "~1.4.0", - "js-yaml": "4.1.0", - "resolve": "~1.22.0", - "tslib": "^2.1.0" - } - }, - "@firebase/app": { - "version": "0.10.15", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.15.tgz", - "integrity": "sha512-he6qlG3pmwL+LHdG/BrSMBQeJzzutciq4fpXN3lGa1uSwYSijJ24VtakS/bP2X9SiDf8jGywJ4u+OgXAenJsNg==", - "dev": true, - "requires": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", - "idb": "7.1.1", - "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/component": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", - "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", - "dev": true, - "requires": { - "@firebase/util": "1.10.1", - "tslib": "^2.1.0" - } - }, - "@firebase/logger": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", - "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", - "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - } - } - }, - "@firebase/app-check-interop-types": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz", - "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==" - }, - "@firebase/app-compat": { - "version": "0.2.45", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.45.tgz", - "integrity": "sha512-5rYbXq1ndtMTg+07oH4WrkYuP+NZq61uzVwW1hlmybp/gr4cXq2SfaP9fc6/9IzTKmu3dh3H0fjj++HG7Z7o/w==", - "dev": true, - "requires": { - "@firebase/app": "0.10.15", - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", - "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/component": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", - "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", - "dev": true, - "requires": { - "@firebase/util": "1.10.1", - "tslib": "^2.1.0" - } - }, - "@firebase/logger": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", - "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", - "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - } - } - }, - "@firebase/app-types": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", - "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==" - }, - "@firebase/auth": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.4.0.tgz", - "integrity": "sha512-SfFXZCHDbY+7oSR52NSwx0U7LjYiA+N8imloxphCf3/F+MFty/+mhdjSXGtrJYd0Gbud/qcyedfn2XnWJeIB/g==", - "dev": true, - "requires": { - "@firebase/component": "0.6.4", - "@firebase/logger": "0.4.0", - "@firebase/util": "1.9.3", - "node-fetch": "2.6.7", - "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/component": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", - "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", - "dev": true, - "requires": { - "@firebase/util": "1.9.3", - "tslib": "^2.1.0" - } - }, - "@firebase/logger": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", - "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", - "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, - "@firebase/auth-compat": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.9.tgz", - "integrity": "sha512-Fw03i7vduIciEBG4imLtA1duJbljgkfbxiBo/EuekcB+BnPxHp+e8OGMUfemPYeO7Munj6kUC9gr5DelsQkiNA==", - "dev": true, - "requires": { - "@firebase/auth": "1.4.0", - "@firebase/auth-types": "0.12.0", - "@firebase/component": "0.6.4", - "@firebase/util": "1.9.3", - "node-fetch": "2.6.7", - "tslib": "^2.1.0" - }, - "dependencies": { - "@firebase/auth-types": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.0.tgz", - "integrity": "sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==", - "dev": true, - "requires": {} - }, - "@firebase/component": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz", - "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==", - "dev": true, - "requires": { - "@firebase/util": "1.9.3", - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", - "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - } - } - }, - "@firebase/auth-interop-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", - "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==" - }, - "@firebase/auth-types": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", - "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", - "dev": true, - "requires": {} - }, - "@firebase/component": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.9.tgz", - "integrity": "sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==", - "requires": { - "@firebase/util": "1.10.0", - "tslib": "^2.1.0" - } - }, - "@firebase/database": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.8.tgz", - "integrity": "sha512-dzXALZeBI1U5TXt6619cv0+tgEhJiwlUtQ55WNZY7vGAjv7Q1QioV969iYwt1AQQ0ovHnEW0YW9TiBfefLvErg==", - "requires": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.9", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.10.0", - "faye-websocket": "0.11.4", - "tslib": "^2.1.0" - } - }, - "@firebase/database-compat": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.8.tgz", - "integrity": "sha512-OpeWZoPE3sGIRPBKYnW9wLad25RaWbGyk7fFQe4xnJQKRzlynWeFBSRRAoLE2Old01WXwskUiucNqUUVlFsceg==", - "requires": { - "@firebase/component": "0.6.9", - "@firebase/database": "1.0.8", - "@firebase/database-types": "1.0.5", - "@firebase/logger": "0.4.2", - "@firebase/util": "1.10.0", - "tslib": "^2.1.0" - } - }, - "@firebase/database-types": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.5.tgz", - "integrity": "sha512-fTlqCNwFYyq/C6W7AJ5OCuq5CeZuBEsEwptnVxlNPkWCo5cTTyukzAHRSO/jaQcItz33FfYrrFk1SJofcu2AaQ==", - "requires": { - "@firebase/app-types": "0.9.2", - "@firebase/util": "1.10.0" - } - }, - "@firebase/logger": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.2.tgz", - "integrity": "sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==", - "requires": { - "tslib": "^2.1.0" - } - }, - "@firebase/util": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.0.tgz", - "integrity": "sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==", - "requires": { - "tslib": "^2.1.0" - } - }, - "@google-cloud/firestore": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.10.0.tgz", - "integrity": "sha512-VFNhdHvfnmqcHHs6YhmSNHHxQqaaD64GwiL0c+e1qz85S8SWZPC2XFRf8p9yHRTF40Kow424s1KBU9f0fdQa+Q==", - "optional": true, - "requires": { - "@opentelemetry/api": "^1.3.0", - "fast-deep-equal": "^3.1.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^4.3.3", - "protobufjs": "^7.2.6" - } - }, - "@google-cloud/paginator": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", - "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - } - }, - "@google-cloud/projectify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", - "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", - "optional": true - }, - "@google-cloud/promisify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", - "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", - "optional": true - }, - "@google-cloud/storage": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.13.0.tgz", - "integrity": "sha512-Y0rYdwM5ZPW3jw/T26sMxxfPrVQTKm9vGrZG8PRyGuUmUJ8a2xNuQ9W/NNA1prxqv2i54DSydV8SJqxF2oCVgA==", - "optional": true, - "requires": { - "@google-cloud/paginator": "^5.0.0", - "@google-cloud/projectify": "^4.0.0", - "@google-cloud/promisify": "^4.0.0", - "abort-controller": "^3.0.0", - "async-retry": "^1.3.3", - "duplexify": "^4.1.3", - "fast-xml-parser": "^4.4.1", - "gaxios": "^6.0.2", - "google-auth-library": "^9.6.3", - "html-entities": "^2.5.2", - "mime": "^3.0.0", - "p-limit": "^3.0.1", - "retry-request": "^7.0.0", - "teeny-request": "^9.0.0", - "uuid": "^8.0.0" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true - } - } - }, - "@grpc/grpc-js": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.11.2.tgz", - "integrity": "sha512-DWp92gDD7/Qkj7r8kus6/HCINeo3yPZWZ3paKgDgsbKbSpoxKg1yvN8xe2Q8uE3zOsPe3bX8FQX2+XValq2yTw==", - "optional": true, - "requires": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" - } - }, - "@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", - "optional": true, - "requires": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - } - }, - "@gulpjs/messages": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", - "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", - "dev": true - }, - "@gulpjs/to-absolute-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", - "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", - "dev": true, - "requires": { - "is-negated-glob": "^1.0.0" - } - }, - "@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@js-sdsl/ordered-map": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", - "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", - "optional": true - }, - "@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dev": true, - "requires": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "dependencies": { - "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" - } - }, - "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" - } - } - } - }, - "@microsoft/api-extractor": { - "version": "7.47.11", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.11.tgz", - "integrity": "sha512-lrudfbPub5wzBhymfFtgZKuBvXxoSIAdrvS2UbHjoMT2TjIEddq6Z13pcve7A03BAouw0x8sW8G4txdgfiSwpQ==", - "dev": true, - "requires": { - "@microsoft/api-extractor-model": "7.29.8", - "@microsoft/tsdoc": "~0.15.0", - "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.9.0", - "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.14.2", - "@rushstack/ts-command-line": "4.23.0", - "lodash": "~4.17.15", - "minimatch": "~3.0.3", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "source-map": "~0.6.1", - "typescript": "5.4.2" - }, - "dependencies": { - "@microsoft/tsdoc": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", - "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true - }, - "@rushstack/node-core-library": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", - "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", - "dev": true, - "requires": { - "ajv": "~8.13.0", - "ajv-draft-04": "~1.0.0", - "ajv-formats": "~3.0.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4" - } - }, - "@rushstack/ts-command-line": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.0.tgz", - "integrity": "sha512-jYREBtsxduPV6ptNq8jOKp9+yx0ld1Tb/Tkdnlj8gTjazl1sF3DwX2VbluyYrNd0meWIL0bNeer7WDf5tKFjaQ==", - "dev": true, - "requires": { - "@rushstack/terminal": "0.14.2", - "@types/argparse": "1.0.38", - "argparse": "~1.0.9", - "string-argv": "~0.3.1" - } - }, - "ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", - "dev": true - } - } - }, - "@microsoft/api-extractor-model": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.8.tgz", - "integrity": "sha512-t3Z/xcO6TRbMcnKGVMs4uMzv/gd5j0NhMiJIGjD4cJMeFJ1Hf8wnLSx37vxlRlL0GWlGJhnFgxvnaL6JlS+73g==", - "dev": true, - "requires": { - "@microsoft/tsdoc": "~0.15.0", - "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.9.0" - }, - "dependencies": { - "@microsoft/tsdoc": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", - "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true - }, - "@rushstack/node-core-library": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", - "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", - "dev": true, - "requires": { - "ajv": "~8.13.0", - "ajv-draft-04": "~1.0.0", - "ajv-formats": "~3.0.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4" - } - }, - "ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@microsoft/tsdoc": { - "version": "0.12.24", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz", - "integrity": "sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg==", - "dev": true - }, - "@microsoft/tsdoc-config": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz", - "integrity": "sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==", - "dev": true, - "requires": { - "@microsoft/tsdoc": "0.15.0", - "ajv": "~8.12.0", - "jju": "~1.4.0", - "resolve": "~1.22.2" - }, - "dependencies": { - "@microsoft/tsdoc": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", - "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", - "optional": true - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "optional": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "optional": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "optional": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "optional": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "optional": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "optional": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "optional": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "optional": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "optional": true - }, - "@rushstack/node-core-library": { - "version": "3.59.7", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.7.tgz", - "integrity": "sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==", - "dev": true, - "requires": { - "colors": "~1.2.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" - }, - "dependencies": { - "colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@rushstack/rig-package": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", - "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", - "dev": true, - "requires": { - "resolve": "~1.22.1", - "strip-json-comments": "~3.1.1" - } - }, - "@rushstack/terminal": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.2.tgz", - "integrity": "sha512-2fC1wqu1VCExKC0/L+0noVcFQEXEnoBOtCIex1TOjBzEDWcw8KzJjjj7aTP6mLxepG0XIyn9OufeFb6SFsa+sg==", - "dev": true, - "requires": { - "@rushstack/node-core-library": "5.9.0", - "supports-color": "~8.1.1" - }, - "dependencies": { - "@rushstack/node-core-library": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", - "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", - "dev": true, - "requires": { - "ajv": "~8.13.0", - "ajv-draft-04": "~1.0.0", - "ajv-formats": "~3.0.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4" - } - }, - "ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@rushstack/ts-command-line": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz", - "integrity": "sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==", - "dev": true, - "requires": { - "@types/argparse": "1.0.38", - "argparse": "~1.0.9", - "colors": "~1.2.1", - "string-argv": "~0.3.1" - }, - "dependencies": { - "colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true - } - } - }, - "@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - } - }, - "@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - } - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true - }, - "@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "@types/argparse": { - "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/bcrypt": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", - "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/bluebird": { - "version": "3.5.42", - "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.42.tgz", - "integrity": "sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==", - "dev": true - }, - "@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/caseless": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", - "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", - "devOptional": true - }, - "@types/chai": { - "version": "4.3.16", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", - "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", - "dev": true - }, - "@types/chai-as-promised": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", - "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", - "dev": true, - "requires": { - "@types/chai": "*" - } - }, - "@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "requires": { - "@types/node": "*" - } - }, - "@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.19.3", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz", - "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "@types/firebase-token-generator": { - "version": "2.0.33", - "resolved": "https://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.33.tgz", - "integrity": "sha512-FNZyTEHIE5Kq55QpVuyK7ZUJE/yoegRXalGVhbUh8+xC9pa1BUP7zspY+P5ci5SYKgoHjYQruC9gulFCn576Zw==", - "dev": true - }, - "@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "@types/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/lodash": { - "version": "4.17.12", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.12.tgz", - "integrity": "sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==", - "dev": true - }, - "@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "optional": true - }, - "@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true - }, - "@types/mocha": { - "version": "10.0.9", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", - "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", - "dev": true - }, - "@types/nock": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@types/nock/-/nock-11.1.0.tgz", - "integrity": "sha512-jI/ewavBQ7X5178262JQR0ewicPAcJhXS/iFaNJl0VHLfyosZ/kwSrsa6VNQNSO8i9d8SqdRgOtZSOKJ/+iNMw==", - "dev": true, - "requires": { - "nock": "*" - } - }, - "@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", - "requires": { - "undici-types": "~6.18.2" - } - }, - "@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" - }, - "@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "@types/request": { - "version": "2.48.12", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", - "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", - "devOptional": true, - "requires": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "@types/request-promise": { - "version": "4.1.51", - "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.51.tgz", - "integrity": "sha512-qVcP9Fuzh9oaAh8oPxiSoWMFGnWKkJDknnij66vi09Yiy62bsSDqtd+fG5kIM9wLLgZsRP3Y6acqj9O/v2ZtRw==", - "dev": true, - "requires": { - "@types/bluebird": "*", - "@types/request": "*" - } - }, - "@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, - "@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "requires": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "@types/sinon": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", - "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", - "dev": true, - "requires": { - "@types/sinonjs__fake-timers": "*" - } - }, - "@types/sinon-chai": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.12.tgz", - "integrity": "sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==", - "dev": true, - "requires": { - "@types/chai": "*", - "@types/sinon": "*" - } - }, - "@types/sinonjs__fake-timers": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", - "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", - "dev": true - }, - "@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "devOptional": true - }, - "@types/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "optional": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true - }, - "agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "requires": { - "debug": "^4.3.4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "dev": true, - "requires": {} - }, - "ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha512-eCjan3AVo/SxZ0/MyIYRtkpxIu/H3xZN7URr1vXVrISxeyz8fUFz0FJziamK4sS8I+t35y4rHg1b2PklyBe/7A==", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow==", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "devOptional": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", - "dev": true - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "api-extractor-model-me": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/api-extractor-model-me/-/api-extractor-model-me-0.1.1.tgz", - "integrity": "sha512-Ez801ZMADfkseOWNRFquvyQYDm3D9McpxfkKMWL6JFCGcpub0miJ+TFNphIR1nSZbrsxz3kIeOovNMY4VlL6Bw==", - "dev": true, - "requires": { - "@microsoft/tsdoc": "0.12.24", - "@rushstack/node-core-library": "3.36.0" - }, - "dependencies": { - "@rushstack/node-core-library": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.36.0.tgz", - "integrity": "sha512-bID2vzXpg8zweXdXgQkKToEdZwVrVCN9vE9viTRk58gqzYaTlz4fMId6V3ZfpXN6H0d319uGi2KDlm+lUEeqCg==", - "dev": true, - "requires": { - "@types/node": "10.17.13", - "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", - "timsort": "~0.3.0", - "z-schema": "~3.18.3" - } - }, - "@types/node": { - "version": "10.17.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", - "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", - "dev": true - }, - "colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true - }, - "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 - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "validator": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", - "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", - "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==", - "dev": true, - "requires": { - "commander": "^2.7.1", - "lodash.get": "^4.0.0", - "lodash.isequal": "^4.0.0", - "validator": "^8.0.0" - } - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true - }, - "array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - } - }, - "array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - } - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "devOptional": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true - }, - "async-done": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", - "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.4", - "once": "^1.4.0", - "stream-exhaust": "^1.0.2" - } - }, - "async-retry": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", - "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", - "optional": true, - "requires": { - "retry": "0.13.1" - } - }, - "async-settle": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", - "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", - "dev": true, - "requires": { - "async-done": "^2.0.0" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "devOptional": true - }, - "available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "requires": { - "possible-typed-array-names": "^1.0.0" - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true - }, - "aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", - "dev": true - }, - "b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "dev": true - }, - "bach": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", - "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", - "dev": true, - "requires": { - "async-done": "^2.0.0", - "async-settle": "^2.0.0", - "now-and-later": "^3.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "bare-events": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", - "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", - "dev": true, - "optional": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", - "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", - "dev": true, - "requires": { - "@mapbox/node-pre-gyp": "^1.0.11", - "node-addon-api": "^5.0.0" - } - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" - }, - "binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true - }, - "bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dev": true, - "requires": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "requires": { - "fill-range": "^7.1.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", - "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", - "dev": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - } - }, - "call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "chai": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.1.0" - }, - "dependencies": { - "type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true - } - } - }, - "chai-as-promised": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", - "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", - "dev": true, - "requires": { - "check-error": "^1.0.2" - } - }, - "chai-exclude": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chai-exclude/-/chai-exclude-2.1.1.tgz", - "integrity": "sha512-IHgNmgAFOkyRPnmOtZio9UsOHQ6RnzVr2LOs+5V9urYYqjhV/ERLQapC0Eq2DmID5eDWyngAcBxNUm0ZK0QbrQ==", - "dev": true, - "requires": { - "fclone": "^1.0.11" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "requires": { - "get-func-name": "^2.0.2" - } - }, - "child-process-promise": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/child-process-promise/-/child-process-promise-2.2.1.tgz", - "integrity": "sha512-Fi4aNdqBsr0mv+jgWxcZ/7rAIC2mgihrptyVI4foh/rrjY/3BNjfP9+oaiFx/fzim+1ZyCNBae0DlyfQhSugog==", - "dev": true, - "requires": { - "cross-spawn": "^4.0.2", - "node-version": "^1.0.0", - "promise-polyfill": "^6.0.1" - } - }, - "chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "devOptional": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "devOptional": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "optional": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - } - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true - }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "copy-props": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", - "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", - "dev": true, - "requires": { - "each-props": "^3.0.0", - "is-plain-object": "^5.0.0" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - } - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "requires": { - "strip-bom": "^4.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - } - } - }, - "define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - } - }, - "define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "requires": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "devOptional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", - "dev": true - }, - "detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true - }, - "diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "duplexify": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", - "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", - "optional": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.2" - } - }, - "each-props": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", - "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", - "dev": true, - "requires": { - "is-plain-object": "^5.0.0", - "object.defaults": "^1.1.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "electron-to-chromium": { - "version": "1.5.33", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.33.tgz", - "integrity": "sha512-+cYTcFB1QqD4j4LegwLfpCNxifb6dDFUAwk6RsLusCwIaZI6or2f+q8rs5tTB2YC53HhOlIbEaqHMAAC8IOIwA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "devOptional": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - } - }, - "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4" - } - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true - }, - "es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "requires": { - "es-errors": "^1.3.0" - } - }, - "es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "devOptional": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "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 - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "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 - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "optional": true - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "farmhash-modern": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", - "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "devOptional": true - }, - "fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fast-xml-parser": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", - "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", - "optional": true, - "requires": { - "strnum": "^1.0.5" - } - }, - "fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true - }, - "fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fclone": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", - "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==", - "dev": true - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "findup-sync": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", - "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.3", - "micromatch": "^4.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", - "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^5.0.0", - "object.defaults": "^1.1.0", - "object.pick": "^1.3.0", - "parse-filepath": "^1.0.2" - } - }, - "firebase-token-generator": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/firebase-token-generator/-/firebase-token-generator-2.0.0.tgz", - "integrity": "sha512-EX/Rw6C0NLF6StuszW9Pn4zGUU8dw0UdHY6u8zP5t/CsbYRwWVh0CwN6INFE5U4IizZtgqbWQhcAQNkBtNkyfQ==", - "dev": true - }, - "flagged-respawn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", - "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", - "dev": true - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "devOptional": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true - }, - "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" - } - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "fs-mkdirp-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", - "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.8", - "streamx": "^2.12.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "optional": true - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - } - }, - "gaxios": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.6.0.tgz", - "integrity": "sha512-bpOZVQV5gthH/jVCSuYuokRo2bTKOcuBiVWpjmTn6C5Agl5zclGfTljuGsQZxwwDBkli+YhZhP4TdlqTnhOezQ==", - "requires": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9", - "uuid": "^9.0.1" - }, - "dependencies": { - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" - } - } - }, - "gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", - "requires": { - "gaxios": "^6.0.0", - "json-bigint": "^1.0.0" - } - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "devOptional": true - }, - "get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-prop": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/get-prop/-/get-prop-0.0.10.tgz", - "integrity": "sha512-XRSGBgcIisSMLJ/dwe1y/eMm9yzLicEJKmEXA3ArBkDkCW2nyRroLOoKIz+SdxuG5SI7ym2QHaTU5ifCl7MTDg==", - "dev": true - }, - "get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-stream": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", - "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", - "dev": true, - "requires": { - "@gulpjs/to-absolute-glob": "^4.0.0", - "anymatch": "^3.1.3", - "fastq": "^1.13.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "is-negated-glob": "^1.0.0", - "normalize-path": "^3.0.0", - "streamx": "^2.12.5" - }, - "dependencies": { - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - } - } - }, - "glob-watcher": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", - "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", - "dev": true, - "requires": { - "async-done": "^2.0.0", - "chokidar": "^3.5.3" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "requires": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "glogg": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", - "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", - "dev": true, - "requires": { - "sparkles": "^2.1.0" - } - }, - "google-auth-library": { - "version": "9.14.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.2.tgz", - "integrity": "sha512-R+FRIfk1GBo3RdlRYWPdwk8nmtVUOn6+BkDomAC46KoU8kzXzE1HLmOasSCbWUByMMAGkknVF0G5kQ69Vj7dlA==", - "requires": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", - "jws": "^4.0.0" - } - }, - "google-gax": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", - "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", - "optional": true, - "requires": { - "@grpc/grpc-js": "^1.10.9", - "@grpc/proto-loader": "^0.7.13", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^4.0.0", - "google-auth-library": "^9.3.0", - "node-fetch": "^2.7.0", - "object-hash": "^3.0.0", - "proto3-json-serializer": "^2.0.2", - "protobufjs": "^7.3.2", - "retry-request": "^7.0.0", - "uuid": "^9.0.1" - }, - "dependencies": { - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "optional": true - } - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "gtoken": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", - "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", - "requires": { - "gaxios": "^6.0.0", - "jws": "^4.0.0" - } - }, - "gulp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz", - "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==", - "dev": true, - "requires": { - "glob-watcher": "^6.0.0", - "gulp-cli": "^3.0.0", - "undertaker": "^2.0.0", - "vinyl-fs": "^4.0.0" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "gulp-cli": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", - "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", - "dev": true, - "requires": { - "@gulpjs/messages": "^1.1.0", - "chalk": "^4.1.2", - "copy-props": "^4.0.0", - "gulplog": "^2.2.0", - "interpret": "^3.1.1", - "liftoff": "^5.0.0", - "mute-stdout": "^2.0.0", - "replace-homedir": "^2.0.0", - "semver-greatest-satisfied-range": "^2.0.0", - "string-width": "^4.2.3", - "v8flags": "^4.0.0", - "yargs": "^16.2.0" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } - }, - "gulp-filter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-7.0.0.tgz", - "integrity": "sha512-ZGWtJo0j1mHfP77tVuhyqem4MRA5NfNRjoVe6VAkLGeQQ/QGo2VsFwp7zfPTGDsd1rwzBmoDHhxpE6f5B3Zuaw==", - "dev": true, - "requires": { - "multimatch": "^5.0.0", - "plugin-error": "^1.0.1", - "streamfilter": "^3.0.0", - "to-absolute-glob": "^2.0.2" - } - }, - "gulp-header": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-2.0.9.tgz", - "integrity": "sha512-LMGiBx+qH8giwrOuuZXSGvswcIUh0OiioNkUpLhNyvaC6/Ga8X6cfAeme2L5PqsbXMhL8o8b/OmVqIQdxprhcQ==", - "dev": true, - "requires": { - "concat-with-sourcemaps": "^1.1.0", - "lodash.template": "^4.5.0", - "map-stream": "0.0.7", - "through2": "^2.0.0" - } - }, - "gulp-typescript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-5.0.1.tgz", - "integrity": "sha512-YuMMlylyJtUSHG1/wuSVTrZp60k1dMEFKYOvDf7OvbAJWrDtxxD4oZon4ancdWwzjj30ztiidhe4VXJniF0pIQ==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.5", - "plugin-error": "^1.0.1", - "source-map": "^0.7.3", - "through2": "^3.0.0", - "vinyl": "^2.1.0", - "vinyl-fs": "^3.0.3" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", - "dev": true, - "requires": { - "through2": "^2.0.3" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", - "dev": true - }, - "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - } - } - } - }, - "gulplog": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", - "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", - "dev": true, - "requires": { - "glogg": "^2.2.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - } - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0" - } - }, - "has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.3" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", - "optional": true - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-message-parser": { - "version": "0.0.34", - "resolved": "https://registry.npmjs.org/http-message-parser/-/http-message-parser-0.0.34.tgz", - "integrity": "sha512-KABKXT347AYvQoaMZg9/K+/GqW6gfB4pKCiTyMUYnosfkdkaBkrXE/cWGSLk5jvD5tiDeLFlYSHLhhPhQKbRrA==", - "dev": true, - "requires": { - "buffer": "^4.9.1", - "concat-stream": "^1.5.1", - "get-prop": "0.0.10", - "minimist": "^1.2.0", - "stream-buffers": "^3.0.0" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - } - } - }, - "http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "dependencies": { - "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==", - "optional": true, - "requires": { - "debug": "4" - } - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", - "dev": true - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.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 - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "devOptional": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "requires": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "requires": { - "is-typed-array": "^1.1.13" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - }, - "dependencies": { - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - } - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.14" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "requires": { - "append-transform": "^2.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "dev": true, - "requires": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - } - }, - "istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", - "dev": true - }, - "jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - } - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "dependencies": { - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "just-extend": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", - "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", - "dev": true - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jwks-rsa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", - "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", - "requires": { - "@types/express": "^4.17.17", - "@types/jsonwebtoken": "^9.0.2", - "debug": "^4.3.4", - "jose": "^4.14.6", - "limiter": "^1.1.5", - "lru-memoizer": "^2.2.0" - }, - "dependencies": { - "@types/jsonwebtoken": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", - "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", - "requires": { - "@types/node": "*" - } - } - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==", - "dev": true - }, - "last-run": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", - "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", - "dev": true - }, - "lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "lead": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", - "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "liftoff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", - "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==", - "dev": true, - "requires": { - "extend": "^3.0.2", - "findup-sync": "^5.0.0", - "fined": "^2.0.0", - "flagged-respawn": "^2.0.0", - "is-plain-object": "^5.0.0", - "rechoir": "^0.8.0", - "resolve": "^1.20.0" - } - }, - "limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "optional": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "dev": true - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "optional": true - }, - "loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "requires": { - "get-func-name": "^2.0.1" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "lru-memoizer": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", - "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", - "requires": { - "lodash.clonedeep": "^4.5.0", - "lru-cache": "6.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true - }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", - "dev": true - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "requires": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "optional": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "devOptional": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "devOptional": true, - "requires": { - "mime-db": "1.52.0" - } - }, - "minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mocha": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", - "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.3", - "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", - "debug": "^4.3.5", - "diff": "^5.2.0", - "escape-string-regexp": "^4.0.0", - "find-up": "^5.0.0", - "glob": "^8.1.0", - "he": "^1.2.0", - "js-yaml": "^4.1.0", - "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", - "ms": "^2.1.3", - "serialize-javascript": "^6.0.2", - "strip-json-comments": "^3.1.1", - "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", - "yargs-unparser": "^2.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multimatch": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", - "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", - "dev": true, - "requires": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - } - }, - "mute-stdout": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", - "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", - "dev": true - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", - "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" - } - }, - "nock": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz", - "integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "propagate": "^2.0.0" - } - }, - "node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "dev": true - }, - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" - }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "requires": { - "process-on-spawn": "^1.0.0" - } - }, - "node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true - }, - "node-version": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.2.0.tgz", - "integrity": "sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==", - "dev": true - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "now-and-later": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", - "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "dev": true, - "requires": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "nyc": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", - "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", - "dev": true, - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^3.3.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^6.0.2", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "optional": true - }, - "object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "devOptional": true, - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "devOptional": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", - "dev": true - }, - "path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - } - }, - "possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "requires": { - "fromentries": "^1.2.0" - } - }, - "promise-polyfill": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", - "integrity": "sha512-g0LWaH0gFsxovsU7R5LrrhHhWAWiHRnh1GPrhXnPgYsDkIqjRYUYSZEsej/wtleDrz5xVSIDbeKfidztp2XHFQ==", - "dev": true - }, - "propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true - }, - "proto3-json-serializer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", - "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", - "optional": true, - "requires": { - "protobufjs": "^7.2.5" - } - }, - "protobufjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/node": ">=13.7.0", - "long": "^5.0.0" - } - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "dependencies": { - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - } - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "devOptional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "requires": { - "resolve": "^1.20.0" - } - }, - "regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "replace-ext": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", - "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", - "dev": true - }, - "replace-homedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", - "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", - "dev": true - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "request-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", - "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "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" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "devOptional": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-options": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", - "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", - "dev": true, - "requires": { - "value-or-function": "^4.0.0" - } - }, - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "optional": true - }, - "retry-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", - "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", - "optional": true, - "requires": { - "@types/request": "^2.48.8", - "extend": "^3.0.2", - "teeny-request": "^9.0.0" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "run-sequence": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.1.tgz", - "integrity": "sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "fancy-log": "^1.3.2", - "plugin-error": "^0.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha512-OQwDZUqYaQwyyhDJHThmzId8daf4/RFNLaeh3AevmSeZ5Y7ug4Ga/yKc6l6kTZOBW781rCj103ZuTh8GAsB3+Q==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha512-t5db90jq+qdgk8aFnxEkjqta0B/GHrM1pxzuuZz2zWsOXc5nKu3t+76s/PQBA8FTcM/ipspIH9jWG4OxCBc2eA==", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q==", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha512-L7AGmkO6jhDkEBBGWlLtftA80Xq8DipnrRPr0pyi7GQLXkaq9JYA4xF4z6qnadIC6euiTDKco0cGSU9muw+WTw==", - "dev": true, - "requires": { - "kind-of": "^1.1.0" - } - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha512-WzZHcm4+GO34sjFMxQMqZbsz3xiNEgonCskQ9v+IroMmYgk/tas8dG+Hr2D6IbRPybZ12oWpzE/w3cGJ6FJzOw==", - "dev": true, - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - } - } - }, - "safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==" - }, - "semver-greatest-satisfied-range": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", - "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", - "dev": true, - "requires": { - "sver": "^1.8.3" - } - }, - "serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - } - }, - "set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true - }, - "side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.2.0", - "nise": "^6.0.0", - "supports-color": "^7" - }, - "dependencies": { - "diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "sinon-chai": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", - "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "dev": true, - "requires": {} - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "sparkles": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", - "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", - "dev": true - }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "dev": true - }, - "stream-buffers": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", - "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", - "dev": true - }, - "stream-composer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", - "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", - "dev": true, - "requires": { - "streamx": "^2.13.2" - } - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "optional": true, - "requires": { - "stubs": "^3.0.0" - } - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "stream-shift": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", - "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "devOptional": true - }, - "streamfilter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-3.0.0.tgz", - "integrity": "sha512-kvKNfXCmUyC8lAXSSHCIXBUlo/lhsLcCU/OmzACZYpRUdtKIH68xYhm/+HI15jFJYtNJGYtCgn2wmIiExY1VwA==", - "dev": true, - "requires": { - "readable-stream": "^3.0.6" - } - }, - "streamx": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", - "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", - "dev": true, - "requires": { - "bare-events": "^2.2.0", - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "devOptional": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "devOptional": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.padend": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", - "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "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 - }, - "strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", - "optional": true - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", - "optional": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "sver": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", - "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "optional": true - } - } - }, - "tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "teeny-request": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", - "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", - "optional": true, - "requires": { - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.9", - "stream-events": "^1.0.5", - "uuid": "^9.0.0" - }, - "dependencies": { - "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==", - "optional": true, - "requires": { - "debug": "4" - } - }, - "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==", - "optional": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "optional": true - } - } - }, - "teex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", - "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", - "dev": true, - "requires": { - "streamx": "^2.12.5" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-decoder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", - "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", - "dev": true, - "requires": { - "b4a": "^1.6.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", - "dev": true - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "dev": true - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "to-through": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", - "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", - "dev": true, - "requires": { - "streamx": "^2.12.5" - } - }, - "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" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } - } - }, - "tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true - }, - "undertaker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", - "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", - "dev": true, - "requires": { - "bach": "^2.0.1", - "fast-levenshtein": "^3.0.0", - "last-run": "^2.0.0", - "undertaker-registry": "^2.0.0" - }, - "dependencies": { - "fast-levenshtein": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", - "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", - "dev": true, - "requires": { - "fastest-levenshtein": "^1.0.7" - } - } - } - }, - "undertaker-registry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", - "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", - "dev": true - }, - "undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==" - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "dev": true, - "requires": { - "escalade": "^3.2.0", - "picocolors": "^1.1.0" - }, - "dependencies": { - "escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "devOptional": true - }, - "uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==" - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "v8flags": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", - "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validator": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", - "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", - "dev": true - }, - "value-or-function": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", - "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - } - } - }, - "vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", - "dev": true, - "requires": { - "clone": "^2.1.2", - "clone-stats": "^1.0.0", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" - } - }, - "vinyl-contents": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", - "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", - "dev": true, - "requires": { - "bl": "^5.0.0", - "vinyl": "^3.0.0" - } - }, - "vinyl-fs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", - "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^2.0.1", - "glob-stream": "^8.0.0", - "graceful-fs": "^4.2.11", - "iconv-lite": "^0.6.3", - "is-valid-glob": "^1.0.0", - "lead": "^4.0.0", - "normalize-path": "3.0.0", - "resolve-options": "^2.0.0", - "stream-composer": "^1.0.2", - "streamx": "^2.14.0", - "to-through": "^3.0.0", - "value-or-function": "^4.0.0", - "vinyl": "^3.0.0", - "vinyl-sourcemap": "^2.0.0" - } - }, - "vinyl-sourcemap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", - "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", - "dev": true, - "requires": { - "convert-source-map": "^2.0.0", - "graceful-fs": "^4.2.10", - "now-and-later": "^3.0.0", - "streamx": "^2.12.5", - "vinyl": "^3.0.0", - "vinyl-contents": "^2.0.0" - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true - }, - "workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "devOptional": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "devOptional": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "devOptional": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "devOptional": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { + "node_modules/yargs/node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "devOptional": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" + "devOptional": true, + "license": "ISC", + "engines": { + "node": ">=12" } }, - "yn": { + "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "devOptional": true + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "z-schema": { + "node_modules/z-schema": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", "dev": true, - "requires": { - "commander": "^9.4.1", + "license": "MIT", + "dependencies": { "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": "^9.4.1" } } } diff --git a/package.json b/package.json index 63a4d4cd78..a56570a152 100644 --- a/package.json +++ b/package.json @@ -205,24 +205,24 @@ }, "dependencies": { "@fastify/busboy": "^3.0.0", - "@firebase/database-compat": "1.0.8", - "@firebase/database-types": "1.0.5", - "@types/node": "^22.0.1", + "@firebase/database-compat": "^2.0.0", + "@firebase/database-types": "^1.0.6", + "@types/node": "^22.8.7", "farmhash-modern": "^1.1.0", "google-auth-library": "^9.14.2", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", "node-forge": "^1.3.1", - "uuid": "^10.0.0" + "uuid": "^11.0.2" }, "optionalDependencies": { - "@google-cloud/firestore": "^7.7.0", - "@google-cloud/storage": "^7.7.0" + "@google-cloud/firestore": "^7.10.0", + "@google-cloud/storage": "^7.14.0" }, "devDependencies": { "@firebase/api-documenter": "^0.4.0", "@firebase/app-compat": "^0.2.1", - "@firebase/auth-compat": "^0.4.1", + "@firebase/auth-compat": "^0.5.13", "@firebase/auth-types": "^0.12.0", "@microsoft/api-extractor": "^7.11.2", "@types/bcrypt": "^5.0.0", @@ -239,8 +239,8 @@ "@types/sinon": "^17.0.2", "@types/sinon-chai": "^3.0.0", "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", "bcrypt": "^5.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.0.0", @@ -248,7 +248,7 @@ "chalk": "^4.1.1", "child-process-promise": "^2.2.1", "del": "^6.0.0", - "eslint": "^8.12.0", + "eslint": "^8.56.0", "firebase-token-generator": "^2.0.0", "gulp": "^5.0.0", "gulp-filter": "^7.0.0", @@ -268,7 +268,7 @@ "sinon": "^18.0.0", "sinon-chai": "^3.0.0", "ts-node": "^10.2.0", - "typescript": "5.1.6", + "typescript": "5.5.4", "yargs": "^17.0.1" } } From 5affb73bc38ffcb0c9c4e26571b6f84672629177 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 5 Nov 2024 12:37:45 -0500 Subject: [PATCH 202/323] change(fcm): Remove deprecated FCM APIs (#2759) --- etc/firebase-admin.api.md | 10 - etc/firebase-admin.messaging.api.md | 52 +- src/messaging/batch-request-internal.ts | 141 - src/messaging/index.ts | 5 - .../messaging-api-request-internal.ts | 46 +- src/messaging/messaging-api.ts | 105 +- src/messaging/messaging-namespace.ts | 30 - src/messaging/messaging.ts | 691 +---- test/unit/index.spec.ts | 1 - test/unit/messaging/batch-requests.spec.ts | 270 -- test/unit/messaging/messaging.spec.ts | 2361 +---------------- 11 files changed, 103 insertions(+), 3609 deletions(-) delete mode 100644 src/messaging/batch-request-internal.ts delete mode 100644 test/unit/messaging/batch-requests.spec.ts diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index 6d0670cc75..e9d4bb0e49 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -380,22 +380,12 @@ export namespace messaging { export type Message = Message; // Warning: (ae-forgotten-export) The symbol "Messaging" needs to be exported by the entry point default-namespace.d.ts export type Messaging = Messaging; - // Warning: (ae-forgotten-export) The symbol "MessagingConditionResponse" needs to be exported by the entry point default-namespace.d.ts - export type MessagingConditionResponse = MessagingConditionResponse; - // Warning: (ae-forgotten-export) The symbol "MessagingDeviceGroupResponse" needs to be exported by the entry point default-namespace.d.ts - export type MessagingDeviceGroupResponse = MessagingDeviceGroupResponse; - // Warning: (ae-forgotten-export) The symbol "MessagingDeviceResult" needs to be exported by the entry point default-namespace.d.ts - export type MessagingDeviceResult = MessagingDeviceResult; - // Warning: (ae-forgotten-export) The symbol "MessagingDevicesResponse" needs to be exported by the entry point default-namespace.d.ts - export type MessagingDevicesResponse = MessagingDevicesResponse; // Warning: (ae-forgotten-export) The symbol "MessagingOptions" needs to be exported by the entry point default-namespace.d.ts export type MessagingOptions = MessagingOptions; // Warning: (ae-forgotten-export) The symbol "MessagingPayload" needs to be exported by the entry point default-namespace.d.ts export type MessagingPayload = MessagingPayload; // Warning: (ae-forgotten-export) The symbol "MessagingTopicManagementResponse" needs to be exported by the entry point default-namespace.d.ts export type MessagingTopicManagementResponse = MessagingTopicManagementResponse; - // Warning: (ae-forgotten-export) The symbol "MessagingTopicResponse" needs to be exported by the entry point default-namespace.d.ts - export type MessagingTopicResponse = MessagingTopicResponse; // Warning: (ae-forgotten-export) The symbol "MulticastMessage" needs to be exported by the entry point default-namespace.d.ts export type MulticastMessage = MulticastMessage; // Warning: (ae-forgotten-export) The symbol "Notification" needs to be exported by the entry point default-namespace.d.ts diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index 493fd9127a..b4ee30a9f0 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -191,20 +191,8 @@ export class Messaging { // @deprecated enableLegacyHttpTransport(): void; send(message: Message, dryRun?: boolean): Promise; - // @deprecated - sendAll(messages: Message[], dryRun?: boolean): Promise; sendEach(messages: Message[], dryRun?: boolean): Promise; sendEachForMulticast(message: MulticastMessage, dryRun?: boolean): Promise; - // @deprecated - sendMulticast(message: MulticastMessage, dryRun?: boolean): Promise; - // @deprecated - sendToCondition(condition: string, payload: MessagingPayload, options?: MessagingOptions): Promise; - // @deprecated - sendToDevice(registrationTokenOrTokens: string | string[], payload: MessagingPayload, options?: MessagingOptions): Promise; - // @deprecated - sendToDeviceGroup(notificationKey: string, payload: MessagingPayload, options?: MessagingOptions): Promise; - // @deprecated - sendToTopic(topic: string, payload: MessagingPayload, options?: MessagingOptions): Promise; subscribeToTopic(registrationTokenOrTokens: string | string[], topic: string): Promise; unsubscribeFromTopic(registrationTokenOrTokens: string | string[], topic: string): Promise; } @@ -308,40 +296,6 @@ export class MessagingClientErrorCode { }; } -// @public -export interface MessagingConditionResponse { - messageId: number; -} - -// @public @deprecated -export interface MessagingDeviceGroupResponse { - failedRegistrationTokens: string[]; - failureCount: number; - successCount: number; -} - -// @public @deprecated -export interface MessagingDeviceResult { - canonicalRegistrationToken?: string; - // Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts - error?: FirebaseError; - messageId?: string; -} - -// @public @deprecated -export interface MessagingDevicesResponse { - // (undocumented) - canonicalRegistrationTokenCount: number; - // (undocumented) - failureCount: number; - // (undocumented) - multicastId: number; - // (undocumented) - results: MessagingDeviceResult[]; - // (undocumented) - successCount: number; -} - // @public export interface MessagingOptions { // (undocumented) @@ -369,11 +323,6 @@ export interface MessagingTopicManagementResponse { successCount: number; } -// @public -export interface MessagingTopicResponse { - messageId: number; -} - // @public export interface MulticastMessage extends BaseMessage { // (undocumented) @@ -407,6 +356,7 @@ export interface NotificationMessagePayload { // @public export interface SendResponse { + // Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts error?: FirebaseError; messageId?: string; success: boolean; diff --git a/src/messaging/batch-request-internal.ts b/src/messaging/batch-request-internal.ts deleted file mode 100644 index e876fdcbd4..0000000000 --- a/src/messaging/batch-request-internal.ts +++ /dev/null @@ -1,141 +0,0 @@ -/*! - * Copyright 2019 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - HttpClient, HttpRequestConfig, RequestResponse, parseHttpResponse, -} from '../utils/api-request'; -import { FirebaseAppError, AppErrorCodes } from '../utils/error'; - -const PART_BOUNDARY = '__END_OF_PART__'; -const FIFTEEN_SECONDS_IN_MILLIS = 15000; - -/** - * Represents a request that can be sent as part of an HTTP batch request. - */ -export interface SubRequest { - url: string; - body: object; - headers?: {[key: string]: any}; -} - -/** - * An HTTP client that can be used to make batch requests. This client is not tied to any service - * (FCM or otherwise). Therefore it can be used to make batch requests to any service that allows - * it. If this requirement ever arises we can move this implementation to the utils module - * where it can be easily shared among other modules. - */ -export class BatchRequestClient { - - /** - * @param {HttpClient} httpClient The client that will be used to make HTTP calls. - * @param {string} batchUrl The URL that accepts batch requests. - * @param {object=} commonHeaders Optional headers that will be included in all requests. - * - * @constructor - */ - constructor( - private readonly httpClient: HttpClient, - private readonly batchUrl: string, - private readonly commonHeaders?: object) { - } - - /** - * Sends the given array of sub requests as a single batch, and parses the results into an array - * of `RequestResponse` objects. - * - * @param requests - An array of sub requests to send. - * @returns A promise that resolves when the send operation is complete. - */ - public send(requests: SubRequest[]): Promise { - requests = requests.map((req) => { - req.headers = Object.assign({}, this.commonHeaders, req.headers); - return req; - }); - const requestHeaders = { - 'Content-Type': `multipart/mixed; boundary=${PART_BOUNDARY}`, - }; - const request: HttpRequestConfig = { - method: 'POST', - url: this.batchUrl, - data: this.getMultipartPayload(requests), - headers: Object.assign({}, this.commonHeaders, requestHeaders), - timeout: FIFTEEN_SECONDS_IN_MILLIS, - }; - return this.httpClient.send(request).then((response) => { - if (!response.multipart) { - throw new FirebaseAppError(AppErrorCodes.INTERNAL_ERROR, 'Expected a multipart response.'); - } - return response.multipart.map((buff) => { - return parseHttpResponse(buff, request); - }); - }); - } - - private getMultipartPayload(requests: SubRequest[]): Buffer { - let buffer = ''; - requests.forEach((request: SubRequest, idx: number) => { - buffer += createPart(request, PART_BOUNDARY, idx); - }); - buffer += `--${PART_BOUNDARY}--\r\n`; - return Buffer.from(buffer, 'utf-8'); - } -} - -/** - * Creates a single part in a multipart HTTP request body. The part consists of several headers - * followed by the serialized sub request as the body. As per the requirements of the FCM batch - * API, sets the content-type header to application/http, and the content-transfer-encoding to - * binary. - * - * @param request - A sub request that will be used to populate the part. - * @param boundary - Multipart boundary string. - * @param idx - An index number that is used to set the content-id header. - * @returns The part as a string that can be included in the HTTP body. - */ -function createPart(request: SubRequest, boundary: string, idx: number): string { - const serializedRequest: string = serializeSubRequest(request); - let part = `--${boundary}\r\n`; - part += `Content-Length: ${serializedRequest.length}\r\n`; - part += 'Content-Type: application/http\r\n'; - part += `content-id: ${idx + 1}\r\n`; - part += 'content-transfer-encoding: binary\r\n'; - part += '\r\n'; - part += `${serializedRequest}\r\n`; - return part; -} - -/** - * Serializes a sub request into a string that can be embedded in a multipart HTTP request. The - * format of the string is the wire format of a typical HTTP request, consisting of a header and a - * body. - * - * @param request - The sub request to be serialized. - * @returns String representation of the SubRequest. - */ -function serializeSubRequest(request: SubRequest): string { - const requestBody: string = JSON.stringify(request.body); - let messagePayload = `POST ${request.url} HTTP/1.1\r\n`; - messagePayload += `Content-Length: ${requestBody.length}\r\n`; - messagePayload += 'Content-Type: application/json; charset=UTF-8\r\n'; - if (request.headers) { - Object.keys(request.headers).forEach((key) => { - messagePayload += `${key}: ${request.headers![key]}\r\n`; - }); - } - messagePayload += '\r\n'; - messagePayload += requestBody; - return messagePayload; -} diff --git a/src/messaging/index.ts b/src/messaging/index.ts index 298a2d5f10..d0a39df2fb 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -56,13 +56,8 @@ export { // Legacy APIs DataMessagePayload, - MessagingConditionResponse, - MessagingDeviceGroupResponse, - MessagingDeviceResult, - MessagingDevicesResponse, MessagingOptions, MessagingPayload, - MessagingTopicResponse, NotificationMessagePayload, } from './messaging-api'; diff --git a/src/messaging/messaging-api-request-internal.ts b/src/messaging/messaging-api-request-internal.ts index 4af320f20c..07621978f3 100644 --- a/src/messaging/messaging-api-request-internal.ts +++ b/src/messaging/messaging-api-request-internal.ts @@ -22,20 +22,14 @@ import { AuthorizedHttp2Client, Http2SessionHandler, Http2RequestConfig, } from '../utils/api-request'; import { createFirebaseError, getErrorCode } from './messaging-errors-internal'; -import { SubRequest, BatchRequestClient } from './batch-request-internal'; import { getSdkVersion } from '../utils/index'; -import { SendResponse, BatchResponse } from './messaging-api'; +import { SendResponse } from './messaging-api'; // FCM backend constants const FIREBASE_MESSAGING_TIMEOUT = 15000; -const FIREBASE_MESSAGING_BATCH_URL = 'https://fcm.googleapis.com/batch'; const FIREBASE_MESSAGING_HTTP_METHOD: HttpMethod = 'POST'; const FIREBASE_MESSAGING_HEADERS = { - 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}` -}; -const LEGACY_FIREBASE_MESSAGING_HEADERS = { 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, 'access_token_auth': 'true', @@ -48,7 +42,6 @@ const LEGACY_FIREBASE_MESSAGING_HEADERS = { export class FirebaseMessagingRequestHandler { private readonly httpClient: AuthorizedHttpClient; private readonly http2Client: AuthorizedHttp2Client; - private readonly batchClient: BatchRequestClient; /** * @param app - The app used to fetch access tokens to sign API requests. @@ -57,8 +50,6 @@ export class FirebaseMessagingRequestHandler { constructor(app: App) { this.httpClient = new AuthorizedHttpClient(app as FirebaseApp); this.http2Client = new AuthorizedHttp2Client(app as FirebaseApp); - this.batchClient = new BatchRequestClient( - this.httpClient, FIREBASE_MESSAGING_BATCH_URL, FIREBASE_MESSAGING_HEADERS); } /** @@ -74,7 +65,7 @@ export class FirebaseMessagingRequestHandler { method: FIREBASE_MESSAGING_HTTP_METHOD, url: `https://${host}${path}`, data: requestData, - headers: LEGACY_FIREBASE_MESSAGING_HEADERS, + headers: FIREBASE_MESSAGING_HEADERS, timeout: FIREBASE_MESSAGING_TIMEOUT, }; return this.httpClient.send(request).then((response) => { @@ -116,7 +107,7 @@ export class FirebaseMessagingRequestHandler { method: FIREBASE_MESSAGING_HTTP_METHOD, url: `https://${host}${path}`, data: requestData, - headers: LEGACY_FIREBASE_MESSAGING_HEADERS, + headers: FIREBASE_MESSAGING_HEADERS, timeout: FIREBASE_MESSAGING_TIMEOUT, }; return this.httpClient.send(request).then((response) => { @@ -146,7 +137,7 @@ export class FirebaseMessagingRequestHandler { method: FIREBASE_MESSAGING_HTTP_METHOD, url: `https://${host}${path}`, data: requestData, - headers: LEGACY_FIREBASE_MESSAGING_HEADERS, + headers: FIREBASE_MESSAGING_HEADERS, timeout: FIREBASE_MESSAGING_TIMEOUT, http2SessionHandler: http2SessionHandler }; @@ -162,35 +153,6 @@ export class FirebaseMessagingRequestHandler { }); } - /** - * Sends the given array of sub requests as a single batch to FCM, and parses the result into - * a `BatchResponse` object. - * - * @param requests - An array of sub requests to send. - * @returns A promise that resolves when the send operation is complete. - */ - public sendBatchRequest(requests: SubRequest[]): Promise { - return this.batchClient.send(requests) - .then((responses: RequestResponse[]) => { - return responses.map((part: RequestResponse) => { - return this.buildSendResponse(part); - }); - }).then((responses: SendResponse[]) => { - const successCount: number = responses.filter((resp) => resp.success).length; - return { - responses, - successCount, - failureCount: responses.length - successCount, - }; - }).catch((err) => { - if (err instanceof RequestResponseError) { - throw createFirebaseError(err); - } - // Re-throw the error if it already has the proper format. - throw err; - }); - } - private buildSendResponse(response: RequestResponse): SendResponse { const result: SendResponse = { success: response.status === 200, diff --git a/src/messaging/messaging-api.ts b/src/messaging/messaging-api.ts index 8d85faa7a7..01c20c7291 100644 --- a/src/messaging/messaging-api.ts +++ b/src/messaging/messaging-api.ts @@ -45,7 +45,7 @@ export interface ConditionMessage extends BaseMessage { export type Message = TokenMessage | TopicMessage | ConditionMessage; /** - * Payload for the {@link Messaging.sendMulticast} method. The payload contains all the fields + * Payload for the {@link Messaging.sendEachForMulticast} method. The payload contains all the fields * in the BaseMessage type, and a list of tokens. */ export interface MulticastMessage extends BaseMessage { @@ -946,107 +946,6 @@ export interface MessagingOptions { [key: string]: any | undefined; } -/** - * Individual status response payload from single devices - * - * @deprecated Returned by {@link Messaging#sendToDevice}, which is also deprecated. - */ -export interface MessagingDeviceResult { - /** - * The error that occurred when processing the message for the recipient. - */ - error?: FirebaseError; - - /** - * A unique ID for the successfully processed message. - */ - messageId?: string; - - /** - * The canonical registration token for the client app that the message was - * processed and sent to. You should use this value as the registration token - * for future requests. Otherwise, future messages might be rejected. - */ - canonicalRegistrationToken?: string; -} - -/** - * Interface representing the status of a message sent to an individual device - * via the FCM legacy APIs. - * - * See - * {@link https://firebase.google.com/docs/cloud-messaging/admin/send-messages#send_to_individual_devices | - * Send to individual devices} for code samples and detailed documentation. - * - * @deprecated Returned by {@link Messaging.sendToDevice}, which is also deprecated. - */ -export interface MessagingDevicesResponse { - canonicalRegistrationTokenCount: number; - failureCount: number; - multicastId: number; - results: MessagingDeviceResult[]; - successCount: number; -} - -/** - * Interface representing the server response from the {@link Messaging.sendToDeviceGroup} - * method. - * - * See - * {@link https://firebase.google.com/docs/cloud-messaging/send-message?authuser=0#send_messages_to_device_groups | - * Send messages to device groups} for code samples and detailed documentation. - * - * @deprecated Returned by {@link Messaging.sendToDeviceGroup}, which is also deprecated. - */ -export interface MessagingDeviceGroupResponse { - - /** - * The number of messages that could not be processed and resulted in an error. - */ - successCount: number; - - /** - * The number of messages that could not be processed and resulted in an error. - */ - failureCount: number; - - /** - * An array of registration tokens that failed to receive the message. - */ - failedRegistrationTokens: string[]; -} - -/** - * Interface representing the server response from the legacy {@link Messaging.sendToTopic} method. - * - * See - * {@link https://firebase.google.com/docs/cloud-messaging/admin/send-messages#send_to_a_topic | - * Send to a topic} for code samples and detailed documentation. - */ -export interface MessagingTopicResponse { - /** - * The message ID for a successfully received request which FCM will attempt to - * deliver to all subscribed devices. - */ - messageId: number; -} - -/** - * Interface representing the server response from the legacy - * {@link Messaging.sendToCondition} method. - * - * See - * {@link https://firebase.google.com/docs/cloud-messaging/admin/send-messages#send_to_a_condition | - * Send to a condition} for code samples and detailed documentation. - */ -export interface MessagingConditionResponse { - /** - * The message ID for a successfully received request which FCM will attempt to - * deliver to all subscribed devices. - */ - messageId: number; -} - /** * Interface representing the server response from the * {@link Messaging.subscribeToTopic} and {@link Messaging.unsubscribeFromTopic} @@ -1078,7 +977,7 @@ export interface MessagingTopicManagementResponse { /** * Interface representing the server response from the - * {@link Messaging.sendAll} and {@link Messaging.sendMulticast} methods. + * {@link Messaging.sendEach} and {@link Messaging.sendEachForMulticast} methods. */ export interface BatchResponse { diff --git a/src/messaging/messaging-namespace.ts b/src/messaging/messaging-namespace.ts index 8171e9c212..40ca3a3ed2 100644 --- a/src/messaging/messaging-namespace.ts +++ b/src/messaging/messaging-namespace.ts @@ -43,13 +43,8 @@ import { // Legacy APIs DataMessagePayload as TDataMessagePayload, - MessagingConditionResponse as TMessagingConditionResponse, - MessagingDeviceGroupResponse as TMessagingDeviceGroupResponse, - MessagingDeviceResult as TMessagingDeviceResult, - MessagingDevicesResponse as TMessagingDevicesResponse, MessagingOptions as TMessagingOptions, MessagingPayload as TMessagingPayload, - MessagingTopicResponse as TMessagingTopicResponse, NotificationMessagePayload as TNotificationMessagePayload, } from './messaging-api'; @@ -211,26 +206,6 @@ export namespace messaging { */ export type DataMessagePayload = TDataMessagePayload; - /** - * Type alias to {@link firebase-admin.messaging#MessagingConditionResponse}. - */ - export type MessagingConditionResponse = TMessagingConditionResponse; - - /** - * Type alias to {@link firebase-admin.messaging#MessagingDeviceGroupResponse}. - */ - export type MessagingDeviceGroupResponse = TMessagingDeviceGroupResponse; - - /** - * Type alias to {@link firebase-admin.messaging#MessagingDeviceResult}. - */ - export type MessagingDeviceResult = TMessagingDeviceResult; - - /** - * Type alias to {@link firebase-admin.messaging#MessagingDevicesResponse}. - */ - export type MessagingDevicesResponse = TMessagingDevicesResponse; - /** * Type alias to {@link firebase-admin.messaging#MessagingOptions}. */ @@ -241,11 +216,6 @@ export namespace messaging { */ export type MessagingPayload = TMessagingPayload; - /** - * Type alias to {@link firebase-admin.messaging#MessagingTopicResponse}. - */ - export type MessagingTopicResponse = TMessagingTopicResponse; - /** * Type alias to {@link firebase-admin.messaging#NotificationMessagePayload}. */ diff --git a/src/messaging/messaging.ts b/src/messaging/messaging.ts index 38c6edcc42..1c1e2a5887 100644 --- a/src/messaging/messaging.ts +++ b/src/messaging/messaging.ts @@ -16,12 +16,11 @@ */ import { App } from '../app'; -import { deepCopy, deepExtend } from '../utils/deep-copy'; -import { SubRequest } from './batch-request-internal'; +import { deepCopy } from '../utils/deep-copy'; import { ErrorInfo, MessagingClientErrorCode, FirebaseMessagingError } from '../utils/error'; import * as utils from '../utils'; import * as validator from '../utils/validator'; -import { validateMessage, BLACKLISTED_DATA_PAYLOAD_KEYS, BLACKLISTED_OPTIONS_KEYS } from './messaging-internal'; +import { validateMessage } from './messaging-internal'; import { FirebaseMessagingRequestHandler } from './messaging-api-request-internal'; import { @@ -31,21 +30,12 @@ import { MulticastMessage, // Legacy API types - MessagingDevicesResponse, - MessagingDeviceGroupResponse, - MessagingPayload, - MessagingOptions, - MessagingTopicResponse, - MessagingConditionResponse, - DataMessagePayload, - NotificationMessagePayload, SendResponse, } from './messaging-api'; import { Http2SessionHandler } from '../utils/api-request'; // FCM endpoints const FCM_SEND_HOST = 'fcm.googleapis.com'; -const FCM_SEND_PATH = '/fcm/send'; const FCM_TOPIC_MANAGEMENT_HOST = 'iid.googleapis.com'; const FCM_TOPIC_MANAGEMENT_ADD_PATH = '/iid/v1:batchAdd'; const FCM_TOPIC_MANAGEMENT_REMOVE_PATH = '/iid/v1:batchRemove'; @@ -53,101 +43,6 @@ const FCM_TOPIC_MANAGEMENT_REMOVE_PATH = '/iid/v1:batchRemove'; // Maximum messages that can be included in a batch request. const FCM_MAX_BATCH_SIZE = 500; -// Key renames for the messaging notification payload object. -const CAMELCASED_NOTIFICATION_PAYLOAD_KEYS_MAP = { - bodyLocArgs: 'body_loc_args', - bodyLocKey: 'body_loc_key', - clickAction: 'click_action', - titleLocArgs: 'title_loc_args', - titleLocKey: 'title_loc_key', -}; - -// Key renames for the messaging options object. -const CAMELCASE_OPTIONS_KEYS_MAP = { - dryRun: 'dry_run', - timeToLive: 'time_to_live', - collapseKey: 'collapse_key', - mutableContent: 'mutable_content', - contentAvailable: 'content_available', - restrictedPackageName: 'restricted_package_name', -}; - -// Key renames for the MessagingDeviceResult object. -const MESSAGING_DEVICE_RESULT_KEYS_MAP = { - message_id: 'messageId', - registration_id: 'canonicalRegistrationToken', -}; - -// Key renames for the MessagingDevicesResponse object. -const MESSAGING_DEVICES_RESPONSE_KEYS_MAP = { - canonical_ids: 'canonicalRegistrationTokenCount', - failure: 'failureCount', - success: 'successCount', - multicast_id: 'multicastId', -}; - -// Key renames for the MessagingDeviceGroupResponse object. -const MESSAGING_DEVICE_GROUP_RESPONSE_KEYS_MAP = { - success: 'successCount', - failure: 'failureCount', - failed_registration_ids: 'failedRegistrationTokens', -}; - -// Key renames for the MessagingTopicResponse object. -const MESSAGING_TOPIC_RESPONSE_KEYS_MAP = { - message_id: 'messageId', -}; - -// Key renames for the MessagingConditionResponse object. -const MESSAGING_CONDITION_RESPONSE_KEYS_MAP = { - message_id: 'messageId', -}; - -/** - * Maps a raw FCM server response to a `MessagingDevicesResponse` object. - * - * @param response - The raw FCM server response to map. - * - * @returns The mapped `MessagingDevicesResponse` object. - */ -function mapRawResponseToDevicesResponse(response: object): MessagingDevicesResponse { - // Rename properties on the server response - utils.renameProperties(response, MESSAGING_DEVICES_RESPONSE_KEYS_MAP); - if ('results' in response) { - (response as any).results.forEach((messagingDeviceResult: any) => { - utils.renameProperties(messagingDeviceResult, MESSAGING_DEVICE_RESULT_KEYS_MAP); - - // Map the FCM server's error strings to actual error objects. - if ('error' in messagingDeviceResult) { - const newError = FirebaseMessagingError.fromServerError( - messagingDeviceResult.error, /* message */ undefined, messagingDeviceResult.error, - ); - messagingDeviceResult.error = newError; - } - }); - } - - return response as MessagingDevicesResponse; -} - -/** - * Maps a raw FCM server response to a `MessagingDeviceGroupResponse` object. - * - * @param response - The raw FCM server response to map. - * - * @returns The mapped `MessagingDeviceGroupResponse` object. - */ -function mapRawResponseToDeviceGroupResponse(response: object): MessagingDeviceGroupResponse { - // Rename properties on the server response - utils.renameProperties(response, MESSAGING_DEVICE_GROUP_RESPONSE_KEYS_MAP); - - // Add the 'failedRegistrationTokens' property if it does not exist on the response, which - // it won't when the 'failureCount' property has a value of 0) - (response as any).failedRegistrationTokens = (response as any).failedRegistrationTokens || []; - - return response as MessagingDeviceGroupResponse; -} - /** * Maps a raw FCM server response to a `MessagingTopicManagementResponse` object. * @@ -273,7 +168,7 @@ export class Messaging { /** * Sends each message in the given array via Firebase Cloud Messaging. * - * Unlike {@link Messaging.sendAll}, this method makes a single RPC call for each message + * This method makes a single RPC call for each message * in the given array. * * The responses list obtained from the return value corresponds to the order of `messages`. @@ -401,389 +296,6 @@ export class Messaging { return this.sendEach(messages, dryRun); } - /** - * Sends all the messages in the given array via Firebase Cloud Messaging. - * Employs batching to send the entire list as a single RPC call. Compared - * to the `send()` method, this method is a significantly more efficient way - * to send multiple messages. - * - * The responses list obtained from the return value - * corresponds to the order of tokens in the `MulticastMessage`. An error - * from this method indicates a total failure, meaning that none of the messages - * in the list could be sent. Partial failures are indicated by a `BatchResponse` - * return value. - * - * @param messages - A non-empty array - * containing up to 500 messages. - * @param dryRun - Whether to send the messages in the dry-run - * (validation only) mode. - * @returns A Promise fulfilled with an object representing the result of the - * send operation. - * - * @deprecated Use {@link Messaging.sendEach} instead. - */ - public sendAll(messages: Message[], dryRun?: boolean): Promise { - if (validator.isArray(messages) && messages.constructor !== Array) { - // In more recent JS specs, an array-like object might have a constructor that is not of - // Array type. Our deepCopy() method doesn't handle them properly. Convert such objects to - // a regular array here before calling deepCopy(). See issue #566 for details. - messages = Array.from(messages); - } - - const copy: Message[] = deepCopy(messages); - if (!validator.isNonEmptyArray(copy)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_ARGUMENT, 'messages must be a non-empty array'); - } - if (copy.length > FCM_MAX_BATCH_SIZE) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_ARGUMENT, - `messages list must not contain more than ${FCM_MAX_BATCH_SIZE} items`); - } - if (typeof dryRun !== 'undefined' && !validator.isBoolean(dryRun)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_ARGUMENT, 'dryRun must be a boolean'); - } - - return this.getUrlPath() - .then((urlPath) => { - const requests: SubRequest[] = copy.map((message) => { - validateMessage(message); - const request: { message: Message; validate_only?: boolean } = { message }; - if (dryRun) { - request.validate_only = true; - } - return { - url: `https://${FCM_SEND_HOST}${urlPath}`, - body: request, - }; - }); - return this.messagingRequestHandler.sendBatchRequest(requests); - }); - } - - /** - * Sends the given multicast message to all the FCM registration tokens - * specified in it. - * - * This method uses the `sendAll()` API under the hood to send the given - * message to all the target recipients. The responses list obtained from the - * return value corresponds to the order of tokens in the `MulticastMessage`. - * An error from this method indicates a total failure, meaning that the message - * was not sent to any of the tokens in the list. Partial failures are indicated - * by a `BatchResponse` return value. - * - * @param message - A multicast message - * containing up to 500 tokens. - * @param dryRun - Whether to send the message in the dry-run - * (validation only) mode. - * @returns A Promise fulfilled with an object representing the result of the - * send operation. - * - * @deprecated Use {@link Messaging.sendEachForMulticast} instead. - */ - public sendMulticast(message: MulticastMessage, dryRun?: boolean): Promise { - const copy: MulticastMessage = deepCopy(message); - if (!validator.isNonNullObject(copy)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_ARGUMENT, 'MulticastMessage must be a non-null object'); - } - if (!validator.isNonEmptyArray(copy.tokens)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_ARGUMENT, 'tokens must be a non-empty array'); - } - if (copy.tokens.length > FCM_MAX_BATCH_SIZE) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_ARGUMENT, - `tokens list must not contain more than ${FCM_MAX_BATCH_SIZE} items`); - } - - const messages: Message[] = copy.tokens.map((token) => { - return { - token, - android: copy.android, - apns: copy.apns, - data: copy.data, - notification: copy.notification, - webpush: copy.webpush, - fcmOptions: copy.fcmOptions, - }; - }); - return this.sendAll(messages, dryRun); - } - - /** - * Sends an FCM message to a single device corresponding to the provided - * registration token. - * - * See {@link https://firebase.google.com/docs/cloud-messaging/admin/legacy-fcm#send_to_individual_devices | - * Send to individual devices} - * for code samples and detailed documentation. Takes either a - * `registrationToken` to send to a single device or a - * `registrationTokens` parameter containing an array of tokens to send - * to multiple devices. - * - * @param registrationToken - A device registration token or an array of - * device registration tokens to which the message should be sent. - * @param payload - The message payload. - * @param options - Optional options to - * alter the message. - * - * @returns A promise fulfilled with the server's response after the message - * has been sent. - * - * @deprecated Use {@link Messaging.send} instead. - */ - public sendToDevice( - registrationTokenOrTokens: string | string[], - payload: MessagingPayload, - options: MessagingOptions = {}, - ): Promise { - // Validate the input argument types. Since these are common developer errors when getting - // started, throw an error instead of returning a rejected promise. - this.validateRegistrationTokensType( - registrationTokenOrTokens, 'sendToDevice', MessagingClientErrorCode.INVALID_RECIPIENT, - ); - this.validateMessagingPayloadAndOptionsTypes(payload, options); - - return Promise.resolve() - .then(() => { - // Validate the contents of the input arguments. Because we are now in a promise, any thrown - // error will cause this method to return a rejected promise. - this.validateRegistrationTokens( - registrationTokenOrTokens, 'sendToDevice', MessagingClientErrorCode.INVALID_RECIPIENT, - ); - const payloadCopy = this.validateMessagingPayload(payload); - const optionsCopy = this.validateMessagingOptions(options); - - const request: any = deepCopy(payloadCopy); - deepExtend(request, optionsCopy); - - if (validator.isString(registrationTokenOrTokens)) { - request.to = registrationTokenOrTokens; - } else { - request.registration_ids = registrationTokenOrTokens; - } - - return this.messagingRequestHandler.invokeRequestHandler(FCM_SEND_HOST, FCM_SEND_PATH, request); - }) - .then((response) => { - // The sendToDevice() and sendToDeviceGroup() methods both set the `to` query parameter in - // the underlying FCM request. If the provided registration token argument is actually a - // valid notification key, the response from the FCM server will be a device group response. - // If that is the case, we map the response to a MessagingDeviceGroupResponse. - // See b/35394951 for more context. - if ('multicast_id' in response) { - return mapRawResponseToDevicesResponse(response); - } else { - const groupResponse = mapRawResponseToDeviceGroupResponse(response); - return { - ...groupResponse, - canonicalRegistrationTokenCount: -1, - multicastId: -1, - results: [], - } - } - }); - } - - /** - * Sends an FCM message to a device group corresponding to the provided - * notification key. - * - * See {@link https://firebase.google.com/docs/cloud-messaging/admin/legacy-fcm#send_to_a_device_group | - * Send to a device group} for code samples and detailed documentation. - * - * @param notificationKey - The notification key for the device group to - * which to send the message. - * @param payload - The message payload. - * @param options - Optional options to - * alter the message. - * - * @returns A promise fulfilled with the server's response after the message - * has been sent. - * - * @deprecated Use {@link Messaging.send} instead. - */ - public sendToDeviceGroup( - notificationKey: string, - payload: MessagingPayload, - options: MessagingOptions = {}, - ): Promise { - if (!validator.isNonEmptyString(notificationKey)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_RECIPIENT, - 'Notification key provided to sendToDeviceGroup() must be a non-empty string.', - ); - } else if (notificationKey.indexOf(':') !== -1) { - // It is possible the developer provides a registration token instead of a notification key - // to this method. We can detect some of those cases by checking to see if the string contains - // a colon. Not all registration tokens will contain a colon (only newer ones will), but no - // notification keys will contain a colon, so we can use it as a rough heuristic. - // See b/35394951 for more context. - return Promise.reject(new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_RECIPIENT, - 'Notification key provided to sendToDeviceGroup() has the format of a registration token. ' + - 'You should use sendToDevice() instead.', - )); - } - - // Validate the types of the payload and options arguments. Since these are common developer - // errors, throw an error instead of returning a rejected promise. - this.validateMessagingPayloadAndOptionsTypes(payload, options); - - return Promise.resolve() - .then(() => { - // Validate the contents of the payload and options objects. Because we are now in a - // promise, any thrown error will cause this method to return a rejected promise. - const payloadCopy = this.validateMessagingPayload(payload); - const optionsCopy = this.validateMessagingOptions(options); - - const request: any = deepCopy(payloadCopy); - deepExtend(request, optionsCopy); - request.to = notificationKey; - - return this.messagingRequestHandler.invokeRequestHandler(FCM_SEND_HOST, FCM_SEND_PATH, request); - }) - .then((response) => { - // The sendToDevice() and sendToDeviceGroup() methods both set the `to` query parameter in - // the underlying FCM request. If the provided notification key argument has an invalid - // format (that is, it is either a registration token or some random string), the response - // from the FCM server will default to a devices response (which we detect by looking for - // the `multicast_id` property). If that is the case, we either throw an error saying the - // provided notification key is invalid (if the message failed to send) or map the response - // to a MessagingDevicesResponse (if the message succeeded). - // See b/35394951 for more context. - if ('multicast_id' in response) { - if ((response as any).success === 0) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_RECIPIENT, - 'Notification key provided to sendToDeviceGroup() is invalid.', - ); - } else { - const devicesResponse = mapRawResponseToDevicesResponse(response); - return { - ...devicesResponse, - failedRegistrationTokens: [], - } - } - } - - return mapRawResponseToDeviceGroupResponse(response); - }); - } - - /** - * Sends an FCM message to a topic. - * - * See {@link https://firebase.google.com/docs/cloud-messaging/admin/legacy-fcm#send_to_a_topic | - * Send to a topic} for code samples and detailed documentation. - * - * @param topic - The topic to which to send the message. - * @param payload - The message payload. - * @param options - Optional options to - * alter the message. - * - * @returns A promise fulfilled with the server's response after the message - * has been sent. - * - * @deprecated Use {@link Messaging.send} instead. - */ - public sendToTopic( - topic: string, - payload: MessagingPayload, - options: MessagingOptions = {}, - ): Promise { - // Validate the input argument types. Since these are common developer errors when getting - // started, throw an error instead of returning a rejected promise. - this.validateTopicType(topic, 'sendToTopic', MessagingClientErrorCode.INVALID_RECIPIENT); - this.validateMessagingPayloadAndOptionsTypes(payload, options); - - // Prepend the topic with /topics/ if necessary. - topic = this.normalizeTopic(topic); - - return Promise.resolve() - .then(() => { - // Validate the contents of the payload and options objects. Because we are now in a - // promise, any thrown error will cause this method to return a rejected promise. - const payloadCopy = this.validateMessagingPayload(payload); - const optionsCopy = this.validateMessagingOptions(options); - this.validateTopic(topic, 'sendToTopic', MessagingClientErrorCode.INVALID_RECIPIENT); - - const request: any = deepCopy(payloadCopy); - deepExtend(request, optionsCopy); - request.to = topic; - - return this.messagingRequestHandler.invokeRequestHandler(FCM_SEND_HOST, FCM_SEND_PATH, request); - }) - .then((response) => { - // Rename properties on the server response - utils.renameProperties(response, MESSAGING_TOPIC_RESPONSE_KEYS_MAP); - - return response as MessagingTopicResponse; - }); - } - - /** - * Sends an FCM message to a condition. - * - * See {@link https://firebase.google.com/docs/cloud-messaging/admin/legacy-fcm#send_to_a_condition | - * Send to a condition} - * for code samples and detailed documentation. - * - * @param condition - The condition determining to which topics to send - * the message. - * @param payload - The message payload. - * @param options - Optional options to - * alter the message. - * - * @returns A promise fulfilled with the server's response after the message - * has been sent. - * - * @deprecated Use {@link Messaging.send} instead. - */ - public sendToCondition( - condition: string, - payload: MessagingPayload, - options: MessagingOptions = {}, - ): Promise { - if (!validator.isNonEmptyString(condition)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_RECIPIENT, - 'Condition provided to sendToCondition() must be a non-empty string.', - ); - } - // Validate the types of the payload and options arguments. Since these are common developer - // errors, throw an error instead of returning a rejected promise. - this.validateMessagingPayloadAndOptionsTypes(payload, options); - - // The FCM server rejects conditions which are surrounded in single quotes. When the condition - // is stringified over the wire, double quotes in it get converted to \" which the FCM server - // does not properly handle. We can get around this by replacing internal double quotes with - // single quotes. - condition = condition.replace(/"/g, '\''); - - return Promise.resolve() - .then(() => { - // Validate the contents of the payload and options objects. Because we are now in a - // promise, any thrown error will cause this method to return a rejected promise. - const payloadCopy = this.validateMessagingPayload(payload); - const optionsCopy = this.validateMessagingOptions(options); - - const request: any = deepCopy(payloadCopy); - deepExtend(request, optionsCopy); - request.condition = condition; - - return this.messagingRequestHandler.invokeRequestHandler(FCM_SEND_HOST, FCM_SEND_PATH, request); - }) - .then((response) => { - // Rename properties on the server response - utils.renameProperties(response, MESSAGING_CONDITION_RESPONSE_KEYS_MAP); - - return response as MessagingConditionResponse; - }); - } - /** * Subscribes a device to an FCM topic. * @@ -911,203 +423,6 @@ export class Messaging { }); } - /** - * Validates the types of the messaging payload and options. If invalid, an error will be thrown. - * - * @param payload - The messaging payload to validate. - * @param options - The messaging options to validate. - */ - private validateMessagingPayloadAndOptionsTypes( - payload: MessagingPayload, - options: MessagingOptions, - ): void { - // Validate the payload is an object - if (!validator.isNonNullObject(payload)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_PAYLOAD, - 'Messaging payload must be an object with at least one of the "data" or "notification" properties.', - ); - } - - // Validate the options argument is an object - if (!validator.isNonNullObject(options)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - 'Messaging options must be an object.', - ); - } - } - - /** - * Validates the messaging payload. If invalid, an error will be thrown. - * - * @param payload - The messaging payload to validate. - * - * @returns A copy of the provided payload with whitelisted properties switched - * from camelCase to underscore_case. - */ - private validateMessagingPayload(payload: MessagingPayload): MessagingPayload { - const payloadCopy: MessagingPayload = deepCopy(payload); - - const payloadKeys = Object.keys(payloadCopy); - const validPayloadKeys = ['data', 'notification']; - - let containsDataOrNotificationKey = false; - payloadKeys.forEach((payloadKey) => { - // Validate the payload does not contain any invalid keys - if (validPayloadKeys.indexOf(payloadKey) === -1) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_PAYLOAD, - `Messaging payload contains an invalid "${payloadKey}" property. Valid properties are ` + - '"data" and "notification".', - ); - } else { - containsDataOrNotificationKey = true; - } - }); - - // Validate the payload contains at least one of the "data" and "notification" keys - if (!containsDataOrNotificationKey) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_PAYLOAD, - 'Messaging payload must contain at least one of the "data" or "notification" properties.', - ); - } - - const validatePayload = (payloadKey: string, value: DataMessagePayload | NotificationMessagePayload): void => { - // Validate each top-level key in the payload is an object - if (!validator.isNonNullObject(value)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_PAYLOAD, - `Messaging payload contains an invalid value for the "${payloadKey}" property. ` + - 'Value must be an object.', - ); - } - - Object.keys(value).forEach((subKey) => { - if (!validator.isString(value[subKey])) { - // Validate all sub-keys have a string value - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_PAYLOAD, - `Messaging payload contains an invalid value for the "${payloadKey}.${subKey}" ` + - 'property. Values must be strings.', - ); - } else if (payloadKey === 'data' && /^google\./.test(subKey)) { - // Validate the data payload does not contain keys which start with 'google.'. - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_PAYLOAD, - `Messaging payload contains the blacklisted "data.${subKey}" property.`, - ); - } - }); - }; - - if (payloadCopy.data !== undefined) { - validatePayload('data', payloadCopy.data); - } - if (payloadCopy.notification !== undefined) { - validatePayload('notification', payloadCopy.notification); - } - - // Validate the data payload object does not contain blacklisted properties - if ('data' in payloadCopy) { - BLACKLISTED_DATA_PAYLOAD_KEYS.forEach((blacklistedKey) => { - if (blacklistedKey in payloadCopy.data!) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_PAYLOAD, - `Messaging payload contains the blacklisted "data.${blacklistedKey}" property.`, - ); - } - }); - } - - // Convert whitelisted camelCase keys to underscore_case - if (payloadCopy.notification) { - utils.renameProperties(payloadCopy.notification, CAMELCASED_NOTIFICATION_PAYLOAD_KEYS_MAP); - } - - return payloadCopy; - } - - /** - * Validates the messaging options. If invalid, an error will be thrown. - * - * @param options - The messaging options to validate. - * - * @returns A copy of the provided options with whitelisted properties switched - * from camelCase to underscore_case. - */ - private validateMessagingOptions(options: MessagingOptions): MessagingOptions { - const optionsCopy: MessagingOptions = deepCopy(options); - - // Validate the options object does not contain blacklisted properties - BLACKLISTED_OPTIONS_KEYS.forEach((blacklistedKey) => { - if (blacklistedKey in optionsCopy) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - `Messaging options contains the blacklisted "${blacklistedKey}" property.`, - ); - } - }); - - // Convert whitelisted camelCase keys to underscore_case - utils.renameProperties(optionsCopy, CAMELCASE_OPTIONS_KEYS_MAP); - - // Validate the options object contains valid values for whitelisted properties - if ('collapse_key' in optionsCopy && !validator.isNonEmptyString((optionsCopy as any).collapse_key)) { - const keyName = ('collapseKey' in options) ? 'collapseKey' : 'collapse_key'; - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - `Messaging options contains an invalid value for the "${keyName}" property. Value must ` + - 'be a non-empty string.', - ); - } else if ('dry_run' in optionsCopy && !validator.isBoolean((optionsCopy as any).dry_run)) { - const keyName = ('dryRun' in options) ? 'dryRun' : 'dry_run'; - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - `Messaging options contains an invalid value for the "${keyName}" property. Value must ` + - 'be a boolean.', - ); - } else if ('priority' in optionsCopy && !validator.isNonEmptyString(optionsCopy.priority)) { - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - 'Messaging options contains an invalid value for the "priority" property. Value must ' + - 'be a non-empty string.', - ); - } else if ('restricted_package_name' in optionsCopy && - !validator.isNonEmptyString((optionsCopy as any).restricted_package_name)) { - const keyName = ('restrictedPackageName' in options) ? 'restrictedPackageName' : 'restricted_package_name'; - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - `Messaging options contains an invalid value for the "${keyName}" property. Value must ` + - 'be a non-empty string.', - ); - } else if ('time_to_live' in optionsCopy && !validator.isNumber((optionsCopy as any).time_to_live)) { - const keyName = ('timeToLive' in options) ? 'timeToLive' : 'time_to_live'; - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - `Messaging options contains an invalid value for the "${keyName}" property. Value must ` + - 'be a number.', - ); - } else if ('content_available' in optionsCopy && !validator.isBoolean((optionsCopy as any).content_available)) { - const keyName = ('contentAvailable' in options) ? 'contentAvailable' : 'content_available'; - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - `Messaging options contains an invalid value for the "${keyName}" property. Value must ` + - 'be a boolean.', - ); - } else if ('mutable_content' in optionsCopy && !validator.isBoolean((optionsCopy as any).mutable_content)) { - const keyName = ('mutableContent' in options) ? 'mutableContent' : 'mutable_content'; - throw new FirebaseMessagingError( - MessagingClientErrorCode.INVALID_OPTIONS, - `Messaging options contains an invalid value for the "${keyName}" property. Value must ` + - 'be a boolean.', - ); - } - - return optionsCopy; - } - /** * Validates the type of the provided registration token(s). If invalid, an error will be thrown. * diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index 31efeaf979..53847f6d62 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -50,7 +50,6 @@ import './database/index.spec'; // Messaging import './messaging/index.spec'; import './messaging/messaging.spec'; -import './messaging/batch-requests.spec'; // Machine Learning import './machine-learning/index.spec'; diff --git a/test/unit/messaging/batch-requests.spec.ts b/test/unit/messaging/batch-requests.spec.ts deleted file mode 100644 index 4f3b09957d..0000000000 --- a/test/unit/messaging/batch-requests.spec.ts +++ /dev/null @@ -1,270 +0,0 @@ -/*! - * Copyright 2019 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -import * as chai from 'chai'; -import * as sinon from 'sinon'; -import * as sinonChai from 'sinon-chai'; -import * as chaiAsPromised from 'chai-as-promised'; - -import * as utils from '../utils'; - -import { HttpClient, RequestResponse, HttpRequestConfig, RequestResponseError } from '../../../src/utils/api-request'; -import { SubRequest, BatchRequestClient } from '../../../src/messaging/batch-request-internal'; - -chai.should(); -chai.use(sinonChai); -chai.use(chaiAsPromised); - -const expect = chai.expect; - -function parseHttpRequest(text: string | Buffer): any { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const httpMessageParser = require('http-message-parser'); - return httpMessageParser(text); -} - -function getParsedPartData(obj: object): string { - const json = JSON.stringify(obj); - return 'POST https://example.com HTTP/1.1\r\n' - + `Content-Length: ${json.length}\r\n` - + 'Content-Type: application/json; charset=UTF-8\r\n' - + '\r\n' - + `${json}`; -} - -function createMultipartResponse(success: object[], failures: object[] = []): RequestResponse { - const multipart: Buffer[] = []; - success.forEach((part) => { - let payload = ''; - payload += 'HTTP/1.1 200 OK\r\n'; - payload += 'Content-type: application/json\r\n\r\n'; - payload += `${JSON.stringify(part)}\r\n`; - multipart.push(Buffer.from(payload, 'utf-8')); - }); - failures.forEach((part) => { - let payload = ''; - payload += 'HTTP/1.1 500 Internal Server Error\r\n'; - payload += 'Content-type: application/json\r\n\r\n'; - payload += `${JSON.stringify(part)}\r\n`; - multipart.push(Buffer.from(payload, 'utf-8')); - }); - return { - status: 200, - headers: { 'Content-Type': 'multipart/mixed; boundary=boundary' }, - multipart, - text: '', - data: null, - isJson: () => false, - }; -} - -describe('BatchRequestClient', () => { - - const batchUrl = 'https://batch.url'; - const responseObject = { success: true }; - const httpClient = new HttpClient(); - - let stubs: sinon.SinonStub[] = []; - - afterEach(() => { - stubs.forEach((mock) => { - mock.restore(); - }); - stubs = []; - }); - - it('should serialize a batch with a single request', async () => { - const stub = sinon.stub(httpClient, 'send').resolves( - createMultipartResponse([responseObject])); - stubs.push(stub); - const requests: SubRequest[] = [ - { url: 'https://example.com', body: { foo: 1 } }, - ]; - const batch = new BatchRequestClient(httpClient, batchUrl); - - const responses: RequestResponse[] = await batch.send(requests); - - expect(responses.length).to.equal(1); - expect(responses[0].status).to.equal(200); - expect(responses[0].data).to.deep.equal(responseObject); - checkOutgoingRequest(stub, requests); - }); - - it('should serialize a batch with multiple requests', async () => { - const stub = sinon.stub(httpClient, 'send').resolves( - createMultipartResponse([responseObject, responseObject, responseObject])); - stubs.push(stub); - const requests: SubRequest[] = [ - { url: 'https://example.com', body: { foo: 1 } }, - { url: 'https://example.com', body: { foo: 2 } }, - { url: 'https://example.com', body: { foo: 3 } }, - ]; - const batch = new BatchRequestClient(httpClient, batchUrl); - - const responses: RequestResponse[] = await batch.send(requests); - - expect(responses.length).to.equal(3); - responses.forEach((response) => { - expect(response.status).to.equal(200); - expect(response.data).to.deep.equal(responseObject); - }); - checkOutgoingRequest(stub, requests); - }); - - it('should handle both success and failure HTTP responses in a batch', async () => { - const stub = sinon.stub(httpClient, 'send').resolves( - createMultipartResponse([responseObject, responseObject], [responseObject])); - stubs.push(stub); - const requests: SubRequest[] = [ - { url: 'https://example.com', body: { foo: 1 } }, - { url: 'https://example.com', body: { foo: 2 } }, - { url: 'https://example.com', body: { foo: 3 } }, - ]; - const batch = new BatchRequestClient(httpClient, batchUrl); - - const responses: RequestResponse[] = await batch.send(requests); - - expect(responses.length).to.equal(3); - responses.forEach((response, idx) => { - const expectedStatus = idx < 2 ? 200 : 500; - expect(response.status).to.equal(expectedStatus); - expect(response.data).to.deep.equal(responseObject); - }); - checkOutgoingRequest(stub, requests); - }); - - it('should reject on top-level HTTP error responses', async () => { - const stub = sinon.stub(httpClient, 'send').rejects( - utils.errorFrom({ error: 'test' })); - stubs.push(stub); - const requests: SubRequest[] = [ - { url: 'https://example.com', body: { foo: 1 } }, - { url: 'https://example.com', body: { foo: 2 } }, - { url: 'https://example.com', body: { foo: 3 } }, - ]; - const batch = new BatchRequestClient(httpClient, batchUrl); - - try { - await batch.send(requests); - sinon.assert.fail('No error thrown for HTTP error'); - } catch (err) { - expect(err).to.be.instanceOf(RequestResponseError); - expect((err as RequestResponseError).response.status).to.equal(500); - checkOutgoingRequest(stub, requests); - } - }); - - it('should add common headers to the parent and sub requests in a batch', async () => { - const stub = sinon.stub(httpClient, 'send').resolves( - createMultipartResponse([responseObject])); - stubs.push(stub); - const requests: SubRequest[] = [ - { url: 'https://example.com', body: { foo: 1 } }, - { url: 'https://example.com', body: { foo: 2 } }, - ]; - const commonHeaders = { 'X-Custom-Header': 'value' }; - const batch = new BatchRequestClient(httpClient, batchUrl, commonHeaders); - - const responses: RequestResponse[] = await batch.send(requests); - - expect(responses.length).to.equal(1); - expect(stub).to.have.been.calledOnce; - const args: HttpRequestConfig = stub.getCall(0).args[0]; - expect(args.headers).to.have.property('X-Custom-Header', 'value'); - - const parsedRequest = parseHttpRequest(args.data as Buffer); - expect(parsedRequest.multipart.length).to.equal(requests.length); - parsedRequest.multipart.forEach((sub: {body: Buffer}) => { - const parsedSubRequest: {headers: object} = parseHttpRequest(sub.body.toString().trim()); - expect(parsedSubRequest.headers).to.have.property('X-Custom-Header', 'value'); - }); - }); - - it('should add sub request headers to the payload', async () => { - const stub = sinon.stub(httpClient, 'send').resolves( - createMultipartResponse([responseObject])); - stubs.push(stub); - const requests: SubRequest[] = [ - { url: 'https://example.com', body: { foo: 1 }, headers: { 'X-Custom-Header': 'value' } }, - { url: 'https://example.com', body: { foo: 1 }, headers: { 'X-Custom-Header': 'value' } }, - ]; - const batch = new BatchRequestClient(httpClient, batchUrl); - - const responses: RequestResponse[] = await batch.send(requests); - - expect(responses.length).to.equal(1); - expect(stub).to.have.been.calledOnce; - const args: HttpRequestConfig = stub.getCall(0).args[0]; - const parsedRequest = parseHttpRequest(args.data as Buffer); - expect(parsedRequest.multipart.length).to.equal(requests.length); - parsedRequest.multipart.forEach((sub: {body: Buffer}) => { - const parsedSubRequest: {headers: object} = parseHttpRequest(sub.body.toString().trim()); - expect(parsedSubRequest.headers).to.have.property('X-Custom-Header', 'value'); - }); - }); - - it('sub request headers should get precedence', async () => { - const stub = sinon.stub(httpClient, 'send').resolves( - createMultipartResponse([responseObject])); - stubs.push(stub); - const requests: SubRequest[] = [ - { url: 'https://example.com', body: { foo: 1 }, headers: { 'X-Custom-Header': 'overwrite' } }, - { url: 'https://example.com', body: { foo: 1 }, headers: { 'X-Custom-Header': 'overwrite' } }, - ]; - const commonHeaders = { 'X-Custom-Header': 'value' }; - const batch = new BatchRequestClient(httpClient, batchUrl, commonHeaders); - - const responses: RequestResponse[] = await batch.send(requests); - - expect(responses.length).to.equal(1); - expect(stub).to.have.been.calledOnce; - const args: HttpRequestConfig = stub.getCall(0).args[0]; - const parsedRequest = parseHttpRequest(args.data as Buffer); - expect(parsedRequest.multipart.length).to.equal(requests.length); - parsedRequest.multipart.forEach((part: {body: Buffer}) => { - const parsedPart: {headers: object} = parseHttpRequest(part.body.toString().trim()); - expect(parsedPart.headers).to.have.property('X-Custom-Header', 'overwrite'); - }); - }); - - function checkOutgoingRequest(stub: sinon.SinonStub, requests: SubRequest[]): void { - expect(stub).to.have.been.calledOnce; - const args: HttpRequestConfig = stub.getCall(0).args[0]; - expect(args.method).to.equal('POST'); - expect(args.url).to.equal(batchUrl); - expect(args.headers).to.have.property( - 'Content-Type', 'multipart/mixed; boundary=__END_OF_PART__'); - expect(args.timeout).to.equal(15000); - const parsedRequest = parseHttpRequest(args.data as Buffer); - expect(parsedRequest.multipart.length).to.equal(requests.length); - - if (requests.length === 1) { - // http-message-parser handles single-element batches slightly differently. Specifically, the - // payload contents are exposed through body instead of multipart, and the body string uses - // \n instead of \r\n for line breaks. - let expectedPartData = getParsedPartData(requests[0].body); - expectedPartData = expectedPartData.replace(/\r\n/g, '\n'); - expect(parsedRequest.body.trim()).to.equal(expectedPartData); - } else { - requests.forEach((req, idx) => { - const part = parsedRequest.multipart[idx].body.toString().trim(); - expect(part).to.equal(getParsedPartData(req.body)); - }); - } - } -}); diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index 4fb5264d5c..6a14f17171 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -27,11 +27,10 @@ import * as chaiAsPromised from 'chai-as-promised'; import * as mocks from '../../resources/mocks'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { - Message, MessagingOptions, MessagingPayload, MessagingDevicesResponse, - MessagingDeviceGroupResponse, MessagingTopicManagementResponse, BatchResponse, + Message, + MessagingTopicManagementResponse, BatchResponse, SendResponse, MulticastMessage, Messaging, TokenMessage, TopicMessage, ConditionMessage, } from '../../../src/messaging/index'; -import { BLACKLISTED_OPTIONS_KEYS, BLACKLISTED_DATA_PAYLOAD_KEYS } from '../../../src/messaging/messaging-internal'; import { HttpClient } from '../../../src/utils/api-request'; import { getSdkVersion } from '../../../src/utils/index'; import * as utils from '../utils'; @@ -44,7 +43,6 @@ const expect = chai.expect; // FCM endpoints const FCM_SEND_HOST = 'fcm.googleapis.com'; -const FCM_SEND_PATH = '/fcm/send'; const FCM_TOPIC_MANAGEMENT_HOST = 'iid.googleapis.com'; const FCM_TOPIC_MANAGEMENT_ADD_PATH = '/iid/v1:batchAdd'; const FCM_TOPIC_MANAGEMENT_REMOVE_PATH = '/iid/v1:batchRemove'; @@ -89,44 +87,6 @@ function mockHttp2SendRequestResponse(messageId = 'projects/projec_id/messages/m } as mocks.MockHttp2Response } -function mockBatchRequest(ids: string[]): nock.Scope { - return mockBatchRequestWithErrors(ids); -} - -function mockBatchRequestWithErrors(ids: string[], errors: object[] = []): nock.Scope { - const mockPayload = createMultipartPayloadWithErrors(ids.map((id) => { - return { name: id }; - }), errors); - return nock(`https://${FCM_SEND_HOST}:443`) - .post('/batch') - .reply(200, mockPayload, { - 'Content-type': 'multipart/mixed; boundary=boundary', - }); -} - -function createMultipartPayloadWithErrors( - success: object[], failures: object[] = []): string { - - const boundary = 'boundary'; - let payload = ''; - success.forEach((part) => { - payload += `--${boundary}\r\n`; - payload += 'Content-type: application/http\r\n\r\n'; - payload += 'HTTP/1.1 200 OK\r\n'; - payload += 'Content-type: application/json\r\n\r\n'; - payload += `${JSON.stringify(part)}\r\n`; - }); - failures.forEach((part) => { - payload += `--${boundary}\r\n`; - payload += 'Content-type: application/http\r\n\r\n'; - payload += 'HTTP/1.1 500 Internal Server Error\r\n'; - payload += 'Content-type: application/json\r\n\r\n'; - payload += `${JSON.stringify(part)}\r\n`; - }); - payload += `--${boundary}--\r\n`; - return payload; -} - function mockSendError( statusCode: number, errorFormat: 'json' | 'text', @@ -161,13 +121,6 @@ function mockHttp2SendRequestError( } as mocks.MockHttp2Response } -function mockBatchError( - statusCode: number, - errorFormat: 'json' | 'text', - responseOverride?: any, -): nock.Scope { - return mockErrorResponse('/batch', statusCode, errorFormat, responseOverride); -} function mockErrorResponse( path: string, @@ -192,76 +145,6 @@ function mockErrorResponse( }); } -function mockSendToDeviceStringRequest(mockFailure = false): nock.Scope { - let deviceResult: object = { message_id: `0:${mocks.messaging.messageId}` }; - if (mockFailure) { - deviceResult = { error: 'InvalidRegistration' }; - } - - return nock(`https://${FCM_SEND_HOST}:443`) - .post(FCM_SEND_PATH) - .reply(200, { - multicast_id: mocks.messaging.multicastId, - success: mockFailure ? 0 : 1, - failure: mockFailure ? 1 : 0, - canonical_ids: 0, - results: [deviceResult], - }); -} - -function mockSendToDeviceArrayRequest(): nock.Scope { - return nock(`https://${FCM_SEND_HOST}:443`) - .post(FCM_SEND_PATH) - .reply(200, { - multicast_id: mocks.messaging.multicastId, - success: 1, - failure: 2, - canonical_ids: 1, - results: [ - { - message_id: `0:${mocks.messaging.messageId}`, - registration_id: mocks.messaging.registrationToken + '3', - }, - { error: 'some-error' }, - { error: mockServerErrorResponse.json.error }, - ], - }); -} - -function mockSendToDeviceGroupRequest(numFailedRegistrationTokens = 0): nock.Scope { - const response: any = { - success: 5 - numFailedRegistrationTokens, - failure: numFailedRegistrationTokens, - }; - - if (numFailedRegistrationTokens > 0) { - response.failed_registration_ids = []; - for (let i = 0; i < numFailedRegistrationTokens; i++) { - response.failed_registration_ids.push(mocks.messaging.registrationToken + i); - } - } - - return nock(`https://${FCM_SEND_HOST}:443`) - .post(FCM_SEND_PATH) - .reply(200, response); -} - -function mockSendToTopicRequest(): nock.Scope { - return nock(`https://${FCM_SEND_HOST}:443`) - .post(FCM_SEND_PATH) - .reply(200, { - message_id: mocks.messaging.messageId, - }); -} - -function mockSendToConditionRequest(): nock.Scope { - return nock(`https://${FCM_SEND_HOST}:443`) - .post(FCM_SEND_PATH) - .reply(200, { - message_id: mocks.messaging.messageId, - }); -} - function mockTopicSubscriptionRequest( methodName: string, successCount = 1, @@ -286,28 +169,6 @@ function mockTopicSubscriptionRequest( }); } -function mockSendRequestWithError( - statusCode: number, - errorFormat: 'json' | 'text', - responseOverride?: any, -): nock.Scope { - let response; - let contentType; - if (errorFormat === 'json') { - response = mockServerErrorResponse.json; - contentType = 'application/json; charset=UTF-8'; - } else { - response = mockServerErrorResponse.text; - contentType = 'text/html; charset=UTF-8'; - } - - return nock(`https://${FCM_SEND_HOST}:443`) - .post(FCM_SEND_PATH) - .reply(statusCode, responseOverride || response, { - 'Content-Type': contentType, - }); -} - function mockTopicSubscriptionRequestWithError( methodName: string, statusCode: number, @@ -1499,1912 +1360,114 @@ describe('Messaging', () => { }); }); - describe('sendAll()', () => { - const validMessage: Message = { token: 'a' }; - - function checkSendResponseSuccess(response: SendResponse, messageId: string): void { - expect(response.success).to.be.true; - expect(response.messageId).to.equal(messageId); - expect(response.error).to.be.undefined; - } - - function checkSendResponseFailure(response: SendResponse, code: string, msg?: string): void { - expect(response.success).to.be.false; - expect(response.messageId).to.be.undefined; - expect(response.error).to.have.property('code', code); - if (msg) { - expect(response.error!.toString()).to.contain(msg); - } - } - - it('should throw given no messages', () => { - expect(() => { - messaging.sendAll(undefined as any); - }).to.throw('messages must be a non-empty array'); - expect(() => { - messaging.sendAll(null as any); - }).to.throw('messages must be a non-empty array'); - expect(() => { - messaging.sendAll([]); - }).to.throw('messages must be a non-empty array'); + describe('Payload validation', () => { + const invalidImages = ['', 'a', 'foo', 'image.jpg']; + invalidImages.forEach((imageUrl) => { + it(`should throw given an invalid imageUrl: ${imageUrl}`, () => { + const message: Message = { + condition: 'topic-name', + notification: { + imageUrl, + }, + }; + expect(() => { + messaging.send(message); + }).to.throw('notification.imageUrl must be a valid URL string'); + }); }); - it('should throw when called with more than 500 messages', () => { - const messages: Message[] = []; - for (let i = 0; i < 501; i++) { - messages.push(validMessage); - } - expect(() => { - messaging.sendAll(messages); - }).to.throw('messages list must not contain more than 500 items'); + const invalidTtls = ['', 'abc', '123', '-123s', '1.2.3s', 'As', 's', '1s', -1]; + invalidTtls.forEach((ttl) => { + it(`should throw given an invalid ttl: ${ ttl }`, () => { + const message: Message = { + condition: 'topic-name', + android: { + ttl: (ttl as any), + }, + }; + expect(() => { + messaging.send(message); + }).to.throw('TTL must be a non-negative duration in milliseconds'); + }); }); - it('should reject when a message is invalid', () => { - const invalidMessage: Message = {} as any; - messaging.sendAll([validMessage, invalidMessage]) - .should.eventually.be.rejectedWith('Exactly one of topic, token or condition is required'); + const invalidColors = ['', 'foo', '123', '#AABBCX', '112233', '#11223']; + invalidColors.forEach((color) => { + it(`should throw given an invalid color: ${ color }`, () => { + const message: Message = { + condition: 'topic-name', + android: { + notification: { + color, + }, + }, + }; + expect(() => { + messaging.send(message); + }).to.throw('android.notification.color must be in the form #RRGGBB'); + }); }); - const invalidDryRun = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; - invalidDryRun.forEach((dryRun) => { - it(`should throw given invalid dryRun parameter: ${JSON.stringify(dryRun)}`, () => { + invalidImages.forEach((imageUrl) => { + it(`should throw given an invalid imageUrl: ${ imageUrl }`, () => { + const message: Message = { + condition: 'topic-name', + android: { + notification: { + imageUrl, + }, + }, + }; expect(() => { - messaging.sendAll([{ token: 'a' }], dryRun as any); - }).to.throw('dryRun must be a boolean'); + messaging.send(message); + }).to.throw('android.notification.imageUrl must be a valid URL string'); }); }); - it('should be fulfilled with a BatchResponse given valid messages', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - 'projects/projec_id/messages/2', - 'projects/projec_id/messages/3', - ]; - mockedRequests.push(mockBatchRequest(messageIds)); - return messaging.sendAll([validMessage, validMessage, validMessage]) - .then((response: BatchResponse) => { - expect(response.successCount).to.equal(3); - expect(response.failureCount).to.equal(0); - response.responses.forEach((resp, idx) => { - expect(resp.success).to.be.true; - expect(resp.messageId).to.equal(messageIds[idx]); - expect(resp.error).to.be.undefined; - }); - }); + it('should throw given android titleLocArgs without titleLocKey', () => { + const message: Message = { + condition: 'topic-name', + android: { + notification: { + titleLocArgs: ['foo'], + }, + }, + }; + expect(() => { + messaging.send(message); + }).to.throw('titleLocKey is required when specifying titleLocArgs'); }); - it('should be fulfilled with a BatchResponse given array-like (issue #566)', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - 'projects/projec_id/messages/2', - 'projects/projec_id/messages/3', - ]; - mockedRequests.push(mockBatchRequest(messageIds)); - const message = { - token: 'a', + it('should throw given android bodyLocArgs without bodyLocKey', () => { + const message: Message = { + condition: 'topic-name', android: { - ttl: 3600, + notification: { + bodyLocArgs: ['foo'], + }, }, }; - const arrayLike = new CustomArray(); - arrayLike.push(message); - arrayLike.push(message); - arrayLike.push(message); - // Explicitly patch the constructor so that down compiling to ES5 doesn't affect the test. - // See https://github.com/firebase/firebase-admin-node/issues/566#issuecomment-501974238 - // for more context. - arrayLike.constructor = CustomArray; - - return messaging.sendAll(arrayLike) - .then((response: BatchResponse) => { - expect(response.successCount).to.equal(3); - expect(response.failureCount).to.equal(0); - response.responses.forEach((resp, idx) => { - expect(resp.success).to.be.true; - expect(resp.messageId).to.equal(messageIds[idx]); - expect(resp.error).to.be.undefined; - }); - }); + expect(() => { + messaging.send(message); + }).to.throw('bodyLocKey is required when specifying bodyLocArgs'); }); - it('should be fulfilled with a BatchResponse given valid messages in dryRun mode', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - 'projects/projec_id/messages/2', - 'projects/projec_id/messages/3', - ]; - mockedRequests.push(mockBatchRequest(messageIds)); - return messaging.sendAll([validMessage, validMessage, validMessage], true) - .then((response: BatchResponse) => { - expect(response.successCount).to.equal(3); - expect(response.failureCount).to.equal(0); - expect(response.responses.length).to.equal(3); - response.responses.forEach((resp, idx) => { - checkSendResponseSuccess(resp, messageIds[idx]); - }); - }); - }); - - it('should be fulfilled with a BatchResponse when the response contains some errors', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - 'projects/projec_id/messages/2', - ]; - const errors = [ - { - error: { - status: 'INVALID_ARGUMENT', - message: 'test error message', - }, - }, - ]; - mockedRequests.push(mockBatchRequestWithErrors(messageIds, errors)); - return messaging.sendAll([validMessage, validMessage, validMessage], true) - .then((response: BatchResponse) => { - expect(response.successCount).to.equal(2); - expect(response.failureCount).to.equal(1); - expect(response.responses.length).to.equal(3); - - const responses = response.responses; - checkSendResponseSuccess(responses[0], messageIds[0]); - checkSendResponseSuccess(responses[1], messageIds[1]); - checkSendResponseFailure( - responses[2], 'messaging/invalid-argument', 'test error message'); - }); - }); - - it('should expose the FCM error code via BatchResponse', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - ]; - const errors = [ - { - error: { - status: 'INVALID_ARGUMENT', - message: 'test error message', - details: [ - { - '@type': 'type.googleapis.com/google.firebase.fcm.v1.FcmError', - 'errorCode': 'UNREGISTERED', - }, - ], - }, - }, - ]; - mockedRequests.push(mockBatchRequestWithErrors(messageIds, errors)); - return messaging.sendAll([validMessage, validMessage], true) - .then((response: BatchResponse) => { - expect(response.successCount).to.equal(1); - expect(response.failureCount).to.equal(1); - expect(response.responses.length).to.equal(2); - - const responses = response.responses; - checkSendResponseSuccess(responses[0], messageIds[0]); - checkSendResponseFailure( - responses[1], 'messaging/registration-token-not-registered'); - }); - }); - - it('should fail when the backend server returns a detailed error', () => { - const resp = { - error: { - status: 'INVALID_ARGUMENT', - message: 'test error message', - }, - }; - mockedRequests.push(mockBatchError(400, 'json', resp)); - return messaging.sendAll( - [validMessage], - ).should.eventually.be.rejectedWith('test error message') - .and.have.property('code', 'messaging/invalid-argument'); - }); - - it('should fail when the backend server returns a detailed error with FCM error code', () => { - const resp = { - error: { - status: 'INVALID_ARGUMENT', - message: 'test error message', - details: [ - { - '@type': 'type.googleapis.com/google.firebase.fcm.v1.FcmError', - 'errorCode': 'UNREGISTERED', - }, - ], - }, - }; - mockedRequests.push(mockBatchError(404, 'json', resp)); - return messaging.sendAll( - [validMessage], - ).should.eventually.be.rejectedWith('test error message') - .and.have.property('code', 'messaging/registration-token-not-registered'); - }); - - it('should map server error code to client-side error', () => { - const resp = { - error: { - status: 'NOT_FOUND', - message: 'test error message', - }, - }; - mockedRequests.push(mockBatchError(404, 'json', resp)); - return messaging.sendAll( - [validMessage], - ).should.eventually.be.rejectedWith('test error message') - .and.have.property('code', 'messaging/registration-token-not-registered'); - }); - - it('should fail when the backend server returns an unknown error', () => { - const resp = { error: 'test error message' }; - mockedRequests.push(mockBatchError(400, 'json', resp)); - return messaging.sendAll( - [validMessage], - ).should.eventually.be.rejected.and.have.property('code', 'messaging/unknown-error'); - }); - - it('should fail when the backend server returns a non-json error', () => { - // Error code will be determined based on the status code. - mockedRequests.push(mockBatchError(400, 'text', 'foo bar')); - return messaging.sendAll( - [validMessage], - ).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-argument'); - }); - - it('should be rejected given an app which returns null access tokens', () => { - return nullAccessTokenMessaging.sendAll( - [validMessage], - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - // This test was added to also verify https://github.com/firebase/firebase-admin-node/issues/1146 - it('should be fulfilled when called with different message types', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - 'projects/projec_id/messages/2', - 'projects/projec_id/messages/3', - ]; - const tokenMessage: TokenMessage = { token: 'test' }; - const topicMessage: TopicMessage = { topic: 'test' }; - const conditionMessage: ConditionMessage = { condition: 'test' }; - const messages: Message[] = [tokenMessage, topicMessage, conditionMessage]; - - mockedRequests.push(mockBatchRequest(messageIds)); - - return messaging.sendAll(messages) - .then((response: BatchResponse) => { - expect(response.successCount).to.equal(3); - expect(response.failureCount).to.equal(0); - response.responses.forEach((resp, idx) => { - expect(resp.success).to.be.true; - expect(resp.messageId).to.equal(messageIds[idx]); - expect(resp.error).to.be.undefined; - }); - }); - }); - }); - - describe('sendMulticast()', () => { - const mockResponse: BatchResponse = { - successCount: 3, - failureCount: 0, - responses: [ - { success: true, messageId: 'projects/projec_id/messages/1' }, - { success: true, messageId: 'projects/projec_id/messages/2' }, - { success: true, messageId: 'projects/projec_id/messages/3' }, - ], - }; - - let stub: sinon.SinonStub | null; - - afterEach(() => { - if (stub) { - stub.restore(); - } - stub = null; - }); - - it('should throw given no messages', () => { - expect(() => { - messaging.sendMulticast(undefined as any); - }).to.throw('MulticastMessage must be a non-null object'); - expect(() => { - messaging.sendMulticast({} as any); - }).to.throw('tokens must be a non-empty array'); - expect(() => { - messaging.sendMulticast({ tokens: [] }); - }).to.throw('tokens must be a non-empty array'); - }); - - it('should throw when called with more than 500 messages', () => { - const tokens: string[] = []; - for (let i = 0; i < 501; i++) { - tokens.push(`token${i}`); - } - expect(() => { - messaging.sendMulticast({ tokens }); - }).to.throw('tokens list must not contain more than 500 items'); - }); - - const invalidDryRun = [null, NaN, 0, 1, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; - invalidDryRun.forEach((dryRun) => { - it(`should throw given invalid dryRun parameter: ${JSON.stringify(dryRun)}`, () => { - expect(() => { - messaging.sendMulticast({ tokens: ['a'] }, dryRun as any); - }).to.throw('dryRun must be a boolean'); - }); - }); - - it('should create multiple messages using the empty multicast payload', () => { - stub = sinon.stub(messaging, 'sendAll').resolves(mockResponse); - const tokens = ['a', 'b', 'c']; - return messaging.sendMulticast({ tokens }) - .then((response: BatchResponse) => { - expect(response).to.deep.equal(mockResponse); - expect(stub).to.have.been.calledOnce; - const messages: Message[] = stub!.args[0][0]; - expect(messages.length).to.equal(3); - expect(stub!.args[0][1]).to.be.undefined; - messages.forEach((message, idx) => { - expect((message as TokenMessage).token).to.equal(tokens[idx]); - expect(message.android).to.be.undefined; - expect(message.apns).to.be.undefined; - expect(message.data).to.be.undefined; - expect(message.notification).to.be.undefined; - expect(message.webpush).to.be.undefined; - }); - }); - }); - - it('should create multiple messages using the multicast payload', () => { - stub = sinon.stub(messaging, 'sendAll').resolves(mockResponse); - const tokens = ['a', 'b', 'c']; - const multicast: MulticastMessage = { - tokens, - android: { ttl: 100 }, - apns: { payload: { aps: { badge: 42 } } }, - data: { key: 'value' }, - notification: { title: 'test title' }, - webpush: { data: { webKey: 'webValue' } }, - fcmOptions: { analyticsLabel: 'label' }, - }; - return messaging.sendMulticast(multicast) - .then((response: BatchResponse) => { - expect(response).to.deep.equal(mockResponse); - expect(stub).to.have.been.calledOnce; - const messages: Message[] = stub!.args[0][0]; - expect(messages.length).to.equal(3); - expect(stub!.args[0][1]).to.be.undefined; - messages.forEach((message, idx) => { - expect((message as TokenMessage).token).to.equal(tokens[idx]); - expect(message.android).to.deep.equal(multicast.android); - expect(message.apns).to.be.deep.equal(multicast.apns); - expect(message.data).to.be.deep.equal(multicast.data); - expect(message.notification).to.deep.equal(multicast.notification); - expect(message.webpush).to.deep.equal(multicast.webpush); - expect(message.fcmOptions).to.deep.equal(multicast.fcmOptions); - }); - }); - }); - - it('should pass dryRun argument through', () => { - stub = sinon.stub(messaging, 'sendAll').resolves(mockResponse); - const tokens = ['a', 'b', 'c']; - return messaging.sendMulticast({ tokens }, true) - .then((response: BatchResponse) => { - expect(response).to.deep.equal(mockResponse); - expect(stub).to.have.been.calledOnce; - expect(stub!.args[0][1]).to.be.true; - }); - }); - - it('should be fulfilled with a BatchResponse given valid message', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - 'projects/projec_id/messages/2', - 'projects/projec_id/messages/3', - ]; - mockedRequests.push(mockBatchRequest(messageIds)); - return messaging.sendMulticast({ - tokens: ['a', 'b', 'c'], - android: { ttl: 100 }, - apns: { payload: { aps: { badge: 42 } } }, - data: { key: 'value' }, - notification: { title: 'test title' }, - webpush: { data: { webKey: 'webValue' } }, - }).then((response: BatchResponse) => { - expect(response.successCount).to.equal(3); - expect(response.failureCount).to.equal(0); - response.responses.forEach((resp, idx) => { - expect(resp.success).to.be.true; - expect(resp.messageId).to.equal(messageIds[idx]); - expect(resp.error).to.be.undefined; - }); - }); - }); - - it('should be fulfilled with a BatchResponse given valid message in dryRun mode', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - 'projects/projec_id/messages/2', - 'projects/projec_id/messages/3', - ]; - mockedRequests.push(mockBatchRequest(messageIds)); - return messaging.sendMulticast({ - tokens: ['a', 'b', 'c'], - android: { ttl: 100 }, - apns: { payload: { aps: { badge: 42 } } }, - data: { key: 'value' }, - notification: { title: 'test title' }, - webpush: { data: { webKey: 'webValue' } }, - }, true).then((response: BatchResponse) => { - expect(response.successCount).to.equal(3); - expect(response.failureCount).to.equal(0); - expect(response.responses.length).to.equal(3); - response.responses.forEach((resp, idx) => { - checkSendResponseSuccess(resp, messageIds[idx]); - }); - }); - }); - - it('should be fulfilled with a BatchResponse when the response contains some errors', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - 'projects/projec_id/messages/2', - ]; - const errors = [ - { - error: { - status: 'INVALID_ARGUMENT', - message: 'test error message', - }, - }, - ]; - mockedRequests.push(mockBatchRequestWithErrors(messageIds, errors)); - return messaging.sendMulticast({ tokens: ['a', 'b'] }) - .then((response: BatchResponse) => { - expect(response.successCount).to.equal(2); - expect(response.failureCount).to.equal(1); - expect(response.responses.length).to.equal(3); - - const responses = response.responses; - checkSendResponseSuccess(responses[0], messageIds[0]); - checkSendResponseSuccess(responses[1], messageIds[1]); - checkSendResponseFailure( - responses[2], 'messaging/invalid-argument', 'test error message'); - }); - }); - - it('should expose the FCM error code via BatchResponse', () => { - const messageIds = [ - 'projects/projec_id/messages/1', - ]; - const errors = [ - { - error: { - status: 'INVALID_ARGUMENT', - message: 'test error message', - details: [ - { - '@type': 'type.googleapis.com/google.firebase.fcm.v1.FcmError', - 'errorCode': 'UNREGISTERED', - }, - ], - }, - }, - ]; - mockedRequests.push(mockBatchRequestWithErrors(messageIds, errors)); - return messaging.sendMulticast({ tokens: ['a', 'b'] }) - .then((response: BatchResponse) => { - expect(response.successCount).to.equal(1); - expect(response.failureCount).to.equal(1); - expect(response.responses.length).to.equal(2); - - const responses = response.responses; - checkSendResponseSuccess(responses[0], messageIds[0]); - checkSendResponseFailure( - responses[1], 'messaging/registration-token-not-registered'); - }); - }); - - it('should fail when the backend server returns a detailed error', () => { - const resp = { - error: { - status: 'INVALID_ARGUMENT', - message: 'test error message', - }, - }; - mockedRequests.push(mockBatchError(400, 'json', resp)); - return messaging.sendMulticast( - { tokens: ['a'] }, - ).should.eventually.be.rejectedWith('test error message') - .and.have.property('code', 'messaging/invalid-argument'); - }); - - it('should fail when the backend server returns a detailed error with FCM error code', () => { - const resp = { - error: { - status: 'INVALID_ARGUMENT', - message: 'test error message', - details: [ - { - '@type': 'type.googleapis.com/google.firebase.fcm.v1.FcmError', - 'errorCode': 'UNREGISTERED', - }, - ], - }, - }; - mockedRequests.push(mockBatchError(404, 'json', resp)); - return messaging.sendMulticast( - { tokens: ['a'] }, - ).should.eventually.be.rejectedWith('test error message') - .and.have.property('code', 'messaging/registration-token-not-registered'); - }); - - it('should map server error code to client-side error', () => { - const resp = { - error: { - status: 'NOT_FOUND', - message: 'test error message', - }, - }; - mockedRequests.push(mockBatchError(404, 'json', resp)); - return messaging.sendMulticast( - { tokens: ['a'] }, - ).should.eventually.be.rejectedWith('test error message') - .and.have.property('code', 'messaging/registration-token-not-registered'); - }); - - it('should fail when the backend server returns an unknown error', () => { - const resp = { error: 'test error message' }; - mockedRequests.push(mockBatchError(400, 'json', resp)); - return messaging.sendMulticast( - { tokens: ['a'] }, - ).should.eventually.be.rejected.and.have.property('code', 'messaging/unknown-error'); - }); - - it('should fail when the backend server returns a non-json error', () => { - // Error code will be determined based on the status code. - mockedRequests.push(mockBatchError(400, 'text', 'foo bar')); - return messaging.sendMulticast( - { tokens: ['a'] }, - ).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-argument'); - }); - - it('should be rejected given an app which returns null access tokens', () => { - return nullAccessTokenMessaging.sendMulticast( - { tokens: ['a'] }, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - function checkSendResponseSuccess(response: SendResponse, messageId: string): void { - expect(response.success).to.be.true; - expect(response.messageId).to.equal(messageId); - expect(response.error).to.be.undefined; - } - - function checkSendResponseFailure(response: SendResponse, code: string, msg?: string): void { - expect(response.success).to.be.false; - expect(response.messageId).to.be.undefined; - expect(response.error).to.have.property('code', code); - if (msg) { - expect(response.error!.toString()).to.contain(msg); - } - } - }); - - describe('sendToDevice()', () => { - const invalidArgumentError = 'Registration token(s) provided to sendToDevice() must be a ' + - 'non-empty string or a non-empty array'; - - const invalidRegistrationTokens = [null, NaN, 0, 1, true, false, {}, { a: 1 }, _.noop]; - invalidRegistrationTokens.forEach((invalidRegistrationToken) => { - it('should throw given invalid type for registration token(s) argument: ' + - JSON.stringify(invalidRegistrationToken), () => { - expect(() => { - messaging.sendToDevice(invalidRegistrationToken as string, mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - }); - - it('should throw given no registration token(s) argument', () => { - expect(() => { - messaging.sendToDevice(undefined as any, mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - - it('should throw given empty string for registration token(s) argument', () => { - expect(() => { - messaging.sendToDevice('', mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - - it('should throw given empty array for registration token(s) argument', () => { - expect(() => { - messaging.sendToDevice([], mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - - it('should be rejected given empty string within array for registration token(s) argument', () => { - return messaging.sendToDevice(['foo', 'bar', ''], mocks.messaging.payloadDataOnly) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-recipient'); - }); - - it('should be rejected given non-string value within array for registration token(s) argument', () => { - return messaging.sendToDevice(['foo', true as any, 'bar'], mocks.messaging.payloadDataOnly) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-recipient'); - }); - - it('should be rejected given an array containing more than 1,000 registration tokens', () => { - mockedRequests.push(mockSendToDeviceArrayRequest()); - - // Create an array of exactly 1,000 registration tokens - const registrationTokens = (Array(1000) as any).fill(mocks.messaging.registrationToken); - - return messaging.sendToDevice(registrationTokens, mocks.messaging.payload) - .then(() => { - // Push the array of registration tokens over 1,000 items - registrationTokens.push(mocks.messaging.registrationToken); - - return messaging.sendToDevice(registrationTokens, mocks.messaging.payload) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-recipient'); - }); - }); - - it('should be rejected given a 200 JSON server response with a known error', () => { - mockedRequests.push(mockSendRequestWithError(200, 'json')); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.json); - }); - - it('should be rejected given a 200 JSON server response with an unknown error', () => { - mockedRequests.push(mockSendRequestWithError(200, 'json', { error: 'Unknown' })); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - it('should be rejected given a non-2xx JSON server response', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json')); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.json); - }); - - it('should be rejected given a non-2xx JSON server response with an unknown error', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json', { error: 'Unknown' })); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - it('should be rejected given a non-2xx JSON server response without an error', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json', { foo: 'bar' })); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - _.forEach(STATUS_CODE_TO_ERROR_MAP, (expectedError, statusCode) => { - it(`should be rejected given a ${ statusCode } text server response`, () => { - mockedRequests.push(mockSendRequestWithError(parseInt(statusCode, 10), 'text')); - disableRetries(messaging); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedError); - }); - }); - - it('should be rejected given an app which returns null access tokens', () => { - return nullAccessTokenMessaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which returns invalid access tokens', () => { - return nullAccessTokenMessaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which fails to generate access tokens', () => { - return nullAccessTokenMessaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be fulfilled given a valid registration token and payload', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ); - }); - - it('should be fulfilled given a valid registration token, payload, and options', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - mocks.messaging.options, - ); - }); - - it('should be fulfilled given a valid array of registration tokens and payload', () => { - mockedRequests.push(mockSendToDeviceArrayRequest()); - - return messaging.sendToDevice( - [ - mocks.messaging.registrationToken + '0', - mocks.messaging.registrationToken + '1', - mocks.messaging.registrationToken + '2', - ], - mocks.messaging.payload, - ); - }); - - it('should be fulfilled given a valid array of registration tokens, payload, and options', () => { - mockedRequests.push(mockSendToDeviceArrayRequest()); - - return messaging.sendToDevice( - [ - mocks.messaging.registrationToken + '0', - mocks.messaging.registrationToken + '1', - mocks.messaging.registrationToken + '2', - ], - mocks.messaging.payload, - mocks.messaging.options, - ); - }); - - it('should be fulfilled with the server response given a single registration token', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.deep.equal({ - failureCount: 0, - successCount: 1, - canonicalRegistrationTokenCount: 0, - multicastId: mocks.messaging.multicastId, - results: [ - { messageId: `0:${ mocks.messaging.messageId }` }, - ], - }); - }); - - it('should be fulfilled with the server response given an array of registration tokens', () => { - mockedRequests.push(mockSendToDeviceArrayRequest()); - - return messaging.sendToDevice( - [ - mocks.messaging.registrationToken + '0', - mocks.messaging.registrationToken + '1', - mocks.messaging.registrationToken + '2', - ], - mocks.messaging.payload, - ).then((response: MessagingDevicesResponse | MessagingDeviceGroupResponse) => { - expect(response).to.have.keys([ - 'failureCount', 'successCount', 'canonicalRegistrationTokenCount', 'multicastId', 'results', - ]); - response = response as MessagingDevicesResponse; - expect(response.failureCount).to.equal(2); - expect(response.successCount).to.equal(1); - expect(response.canonicalRegistrationTokenCount).to.equal(1); - expect(response.multicastId).to.equal(mocks.messaging.multicastId); - expect(response.results).to.have.length(3); - expect(response.results[0]).to.deep.equal({ - messageId: `0:${ mocks.messaging.messageId }`, - canonicalRegistrationToken: mocks.messaging.registrationToken + '3', - }); - expect(response.results[1]).to.have.keys(['error']); - expect(response.results[1].error).to.have.property('code', expectedErrorCodes.unknownError); - expect(response.results[2]).to.have.keys(['error']); - expect(response.results[2].error).to.have.property('code', expectedErrorCodes.json); - }); - }); - - it('should set the appropriate request data given a single registration token', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.deep.equal({ - to: mocks.messaging.registrationToken, - data: mocks.messaging.payload.data, - notification: mocks.messaging.payload.notification, - }); - }); - }); - - it('should set the appropriate request data given an array of registration tokens', () => { - const registrationTokens = [ - mocks.messaging.registrationToken + '0', - mocks.messaging.registrationToken + '1', - mocks.messaging.registrationToken + '2', - ]; - - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDevice( - registrationTokens, - mocks.messaging.payload, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.deep.equal({ - registration_ids: registrationTokens, - data: mocks.messaging.payload.data, - notification: mocks.messaging.payload.notification, - }); - }); - }); - - it('should be fulfilled given a notification key which actually causes a device group response', () => { - mockedRequests.push(mockSendToDeviceGroupRequest(/* numFailedRegistrationTokens */ 2)); - - return messaging.sendToDevice( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.deep.equal({ - failureCount: 2, - successCount: 3, - failedRegistrationTokens: [ - mocks.messaging.registrationToken + '0', - mocks.messaging.registrationToken + '1', - ], - canonicalRegistrationTokenCount: -1, - multicastId: -1, - results: [], - }); - }); - - it('should not mutate the payload argument', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - const mockPayloadClone: MessagingPayload = _.clone(mocks.messaging.payload); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mockPayloadClone, - ).then(() => { - expect(mockPayloadClone).to.deep.equal(mocks.messaging.payload); - }); - }); - - it('should not mutate the options argument', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - const mockOptionsClone: MessagingOptions = _.clone(mocks.messaging.options); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - mockOptionsClone, - ).then(() => { - expect(mockOptionsClone).to.deep.equal(mocks.messaging.options); - }); - }); - }); - - describe('sendToDeviceGroup()', () => { - const invalidArgumentError = 'Notification key provided to sendToDeviceGroup() must be a ' + - 'non-empty string.'; - - const invalidNotificationKeys = [null, NaN, 0, 1, true, false, [], ['a', 1], {}, { a: 1 }, _.noop]; - invalidNotificationKeys.forEach((invalidNotificationKey) => { - it('should throw given invalid type for notification key argument: ' + - JSON.stringify(invalidNotificationKey), () => { - expect(() => { - messaging.sendToDeviceGroup(invalidNotificationKey as string, mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - }); - - it('should throw given no notification key argument', () => { - expect(() => { - messaging.sendToDeviceGroup(undefined as any, mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - - it('should throw given empty string for notification key argument', () => { - expect(() => { - messaging.sendToDeviceGroup('', mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - - it('should throw given a registration token which has a colon', () => { - return messaging.sendToDeviceGroup('tok:en', mocks.messaging.payloadDataOnly) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-recipient'); - }); - - it('should be rejected given a 200 JSON server response with a known error', () => { - mockedRequests.push(mockSendRequestWithError(200, 'json')); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.json); - }); - - it('should be rejected given a 200 JSON server response with an unknown error', () => { - mockedRequests.push(mockSendRequestWithError(200, 'json', { error: 'Unknown' })); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - it('should be rejected given a non-2xx JSON server response', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json')); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.json); - }); - - it('should be rejected given a non-2xx JSON server response with an unknown error', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json', { error: 'Unknown' })); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - it('should be rejected given a non-2xx JSON server response without an error', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json', { foo: 'bar' })); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - _.forEach(STATUS_CODE_TO_ERROR_MAP, (expectedError, statusCode) => { - it(`should be rejected given a ${ statusCode } text server response`, () => { - mockedRequests.push(mockSendRequestWithError(parseInt(statusCode, 10), 'text')); - disableRetries(messaging); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedError); - }); - }); - - it('should be rejected given a devices response which has a success count of 0', () => { - mockedRequests.push(mockSendToDeviceStringRequest(/* mockFailure */ true)); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-recipient'); - }); - - it('should be rejected given an app which returns null access tokens', () => { - return nullAccessTokenMessaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which returns invalid access tokens', () => { - return nullAccessTokenMessaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which fails to generate access tokens', () => { - return nullAccessTokenMessaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be fulfilled given a valid notification key and payload', () => { - mockedRequests.push(mockSendToDeviceGroupRequest()); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payloadDataOnly, - ); - }); - - it('should be fulfilled given a valid notification key, payload, and options', () => { - mockedRequests.push(mockSendToDeviceGroupRequest()); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payloadDataOnly, - mocks.messaging.options, - ); - }); - - it('should be fulfilled with the server response (no failed registration tokens)', () => { - mockedRequests.push(mockSendToDeviceGroupRequest()); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payloadDataOnly, - ).should.eventually.deep.equal({ - failureCount: 0, - successCount: 5, - failedRegistrationTokens: [], - }); - }); - - it('should be fulfilled with the server response (some failed registration token)', () => { - mockedRequests.push(mockSendToDeviceGroupRequest(/* numFailedRegistrationTokens */ 2)); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payloadDataOnly, - ).should.eventually.deep.equal({ - failureCount: 2, - successCount: 3, - failedRegistrationTokens: [ - mocks.messaging.registrationToken + '0', - mocks.messaging.registrationToken + '1', - ], - }); - }); - - it('should be fulfilled with the server response (all failed registration token)', () => { - mockedRequests.push(mockSendToDeviceGroupRequest(/* numFailedRegistrationTokens */ 5)); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payloadDataOnly, - ).should.eventually.deep.equal({ - failureCount: 5, - successCount: 0, - failedRegistrationTokens: [ - mocks.messaging.registrationToken + '0', - mocks.messaging.registrationToken + '1', - mocks.messaging.registrationToken + '2', - mocks.messaging.registrationToken + '3', - mocks.messaging.registrationToken + '4', - ], - }); - }); - - it('should set the appropriate request data', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - ); - }).then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.deep.equal({ - to: mocks.messaging.notificationKey, - data: mocks.messaging.payload.data, - notification: mocks.messaging.payload.notification, - }); - }); - }); - - it('should be fulfilled given a registration token which actually causes a devices response', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDeviceGroup( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ).should.eventually.deep.equal({ - failureCount: 0, - successCount: 1, - canonicalRegistrationTokenCount: 0, - multicastId: mocks.messaging.multicastId, - results: [ - { messageId: `0:${ mocks.messaging.messageId }` }, - ], - failedRegistrationTokens: [], - }); - }); - - it('should not mutate the payload argument', () => { - mockedRequests.push(mockSendToDeviceGroupRequest()); - - const mockPayloadClone: MessagingPayload = _.clone(mocks.messaging.payload); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mockPayloadClone, - ).then(() => { - expect(mockPayloadClone).to.deep.equal(mocks.messaging.payload); - }); - }); - - it('should not mutate the options argument', () => { - mockedRequests.push(mockSendToDeviceGroupRequest()); - - const mockOptionsClone: MessagingOptions = _.clone(mocks.messaging.options); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - mockOptionsClone, - ).then(() => { - expect(mockOptionsClone).to.deep.equal(mocks.messaging.options); - }); - }); - }); - - describe('sendToTopic()', () => { - const invalidArgumentError = 'Topic provided to sendToTopic() must be a string which matches'; - - const invalidTopics = [null, NaN, 0, 1, true, false, [], ['a', 1], {}, { a: 1 }, _.noop]; - invalidTopics.forEach((invalidTopic) => { - it(`should throw given invalid type for topic argument: ${ JSON.stringify(invalidTopic) }`, () => { - expect(() => { - messaging.sendToTopic(invalidTopic as string, mocks.messaging.payload); - }).to.throw(invalidArgumentError); - }); - }); - - it('should throw given no topic argument', () => { - expect(() => { - messaging.sendToTopic(undefined as any, mocks.messaging.payload); - }).to.throw(invalidArgumentError); - }); - - it('should throw given empty string for topic argument', () => { - expect(() => { - messaging.sendToTopic('', mocks.messaging.payload); - }).to.throw(invalidArgumentError); - }); - - const topicsWithInvalidCharacters = ['f*o*o', '/topics/f+o+o', 'foo/topics/foo', '$foo', '/topics/foo&']; - topicsWithInvalidCharacters.forEach((invalidTopic) => { - it(`should be rejected given topic argument which has invalid characters: ${ invalidTopic }`, () => { - return messaging.sendToTopic(invalidTopic, mocks.messaging.payload) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-recipient'); - }); - }); - - it('should be rejected given a 200 JSON server response with a known error', () => { - mockedRequests.push(mockSendRequestWithError(200, 'json')); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.json); - }); - - it('should be rejected given a 200 JSON server response with an unknown error', () => { - mockedRequests.push(mockSendRequestWithError(200, 'json', { error: 'Unknown' })); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - it('should be rejected given a non-2xx JSON server response', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json')); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.json); - }); - - it('should be rejected given a non-2xx JSON server response with an unknown error', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json', { error: 'Unknown' })); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - it('should be rejected given a non-2xx JSON server response without an error', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json', { foo: 'bar' })); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - _.forEach(STATUS_CODE_TO_ERROR_MAP, (expectedError, statusCode) => { - it(`should be rejected given a ${ statusCode } text server response`, () => { - mockedRequests.push(mockSendRequestWithError(parseInt(statusCode, 10), 'text')); - disableRetries(messaging); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedError); - }); - }); - - it('should be rejected given an app which returns null access tokens', () => { - return nullAccessTokenMessaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which returns invalid access tokens', () => { - return nullAccessTokenMessaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which fails to generate access tokens', () => { - return nullAccessTokenMessaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be fulfilled given a valid topic and payload (topic name not prefixed with "/topics/")', () => { - mockedRequests.push(mockSendToTopicRequest()); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ); - }); - - it('should be fulfilled given a valid topic and payload (topic name prefixed with "/topics/")', () => { - mockedRequests.push(mockSendToTopicRequest()); - - return messaging.sendToTopic( - mocks.messaging.topicWithPrefix, - mocks.messaging.payload, - ); - }); - - it('should be fulfilled given a valid topic and payload (topic name prefixed with "/topics/private/")', () => { - mockedRequests.push(mockSendToTopicRequest()); - - return messaging.sendToTopic( - mocks.messaging.topicWithPrivatePrefix, - mocks.messaging.payload, - ); - }); - - it('should be fulfilled given a valid topic, payload, and options', () => { - mockedRequests.push(mockSendToTopicRequest()); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - mocks.messaging.options, - ); - }); - - it('should be fulfilled with the server response', () => { - mockedRequests.push(mockSendToTopicRequest()); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.deep.equal({ - messageId: mocks.messaging.messageId, - }); - }); - - it('should set the appropriate request data (topic name not prefixed with "/topics/")', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - ); - }).then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.deep.equal({ - to: mocks.messaging.topicWithPrefix, - data: mocks.messaging.payload.data, - notification: mocks.messaging.payload.notification, - }); - }); - }); - - it('should set the appropriate request data (topic name prefixed with "/topics/")', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToTopic( - mocks.messaging.topicWithPrefix, - mocks.messaging.payload, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.deep.equal({ - to: mocks.messaging.topicWithPrefix, - data: mocks.messaging.payload.data, - notification: mocks.messaging.payload.notification, - }); - }); - }); - - it('should not mutate the payload argument', () => { - mockedRequests.push(mockSendToTopicRequest()); - - const mockPayloadClone: MessagingPayload = _.clone(mocks.messaging.payload); - - return messaging.sendToTopic( - mocks.messaging.topic, - mockPayloadClone, - ).then(() => { - expect(mockPayloadClone).to.deep.equal(mocks.messaging.payload); - }); - }); - - it('should not mutate the options argument', () => { - mockedRequests.push(mockSendToTopicRequest()); - - const mockOptionsClone: MessagingOptions = _.clone(mocks.messaging.options); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - mockOptionsClone, - ).then(() => { - expect(mockOptionsClone).to.deep.equal(mocks.messaging.options); - }); - }); - }); - - describe('sendToCondition()', () => { - const invalidArgumentError = 'Condition provided to sendToCondition() must be a non-empty string.'; - - const invalidConditions = [null, NaN, 0, 1, true, false, [], ['a', 1], {}, { a: 1 }, _.noop]; - invalidConditions.forEach((invalidCondition) => { - it(`should throw given invalid type for condition argument: ${ JSON.stringify(invalidCondition) }`, () => { - expect(() => { - messaging.sendToCondition(invalidCondition as string, mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - }); - - it('should throw given no condition argument', () => { - expect(() => { - messaging.sendToCondition(undefined as any, mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - - it('should throw given empty string for condition argument', () => { - expect(() => { - messaging.sendToCondition('', mocks.messaging.payloadDataOnly); - }).to.throw(invalidArgumentError); - }); - - it('should be rejected given a 200 JSON server response with a known error', () => { - mockedRequests.push(mockSendRequestWithError(200, 'json')); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.json); - }); - - it('should be rejected given a 200 JSON server response with an unknown error', () => { - mockedRequests.push(mockSendRequestWithError(200, 'json', { error: 'Unknown' })); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - it('should be rejected given a non-2xx JSON server response', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json')); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.json); - }); - - it('should be rejected given a non-2xx JSON server response with an unknown error', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json', { error: 'Unknown' })); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - it('should be rejected given a non-2xx JSON server response without an error', () => { - mockedRequests.push(mockSendRequestWithError(400, 'json', { foo: 'bar' })); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedErrorCodes.unknownError); - }); - - _.forEach(STATUS_CODE_TO_ERROR_MAP, (expectedError, statusCode) => { - it(`should be rejected given a ${ statusCode } text server response`, () => { - mockedRequests.push(mockSendRequestWithError(parseInt(statusCode, 10), 'text')); - disableRetries(messaging); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', expectedError); - }); - }); - - it('should be rejected given an app which returns null access tokens', () => { - return nullAccessTokenMessaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which returns invalid access tokens', () => { - return nullAccessTokenMessaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which fails to generate access tokens', () => { - return nullAccessTokenMessaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be fulfilled given a valid condition and payload', () => { - mockedRequests.push(mockSendToConditionRequest()); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payloadDataOnly, - ); - }); - - it('should be fulfilled given a valid condition, payload, and options', () => { - mockedRequests.push(mockSendToConditionRequest()); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payloadDataOnly, - mocks.messaging.options, - ); - }); - - it('should be fulfilled with the server response', () => { - mockedRequests.push(mockSendToConditionRequest()); - - return messaging.sendToCondition( - mocks.messaging.topic, - mocks.messaging.payload, - ).should.eventually.deep.equal({ - messageId: mocks.messaging.messageId, - }); - }); - - it('should set the appropriate request data', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.deep.equal({ - condition: mocks.messaging.condition, - data: mocks.messaging.payload.data, - notification: mocks.messaging.payload.notification, - }); - }); - }); - - it('should not mutate the payload argument', () => { - mockedRequests.push(mockSendToConditionRequest()); - - const mockPayloadClone: MessagingPayload = _.clone(mocks.messaging.payload); - - return messaging.sendToCondition( - mocks.messaging.condition, - mockPayloadClone, - ).then(() => { - expect(mockPayloadClone).to.deep.equal(mocks.messaging.payload); - }); - }); - - it('should not mutate the options argument', () => { - mockedRequests.push(mockSendToConditionRequest()); - - const mockOptionsClone: MessagingOptions = _.clone(mocks.messaging.options); - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - mockOptionsClone, - ).then(() => { - expect(mockOptionsClone).to.deep.equal(mocks.messaging.options); - }); - }); - }); - - describe('Payload validation', () => { - const invalidPayloads = [null, NaN, 0, 1, true, false, '', 'a', [], ['a', 1], _.noop]; - invalidPayloads.forEach((invalidPayload) => { - it(`should throw given invalid type for payload argument: ${ JSON.stringify(invalidPayload) }`, () => { - expect(() => { - messaging.sendToDevice(mocks.messaging.registrationToken, invalidPayload as any); - }).to.throw('Messaging payload must be an object'); - - expect(() => { - messaging.sendToDeviceGroup(mocks.messaging.notificationKey, invalidPayload as any); - }).to.throw('Messaging payload must be an object'); - - expect(() => { - messaging.sendToTopic(mocks.messaging.topic, invalidPayload as any); - }).to.throw('Messaging payload must be an object'); - - expect(() => { - messaging.sendToCondition(mocks.messaging.condition, invalidPayload as any); - }).to.throw('Messaging payload must be an object'); - }); - }); - - it('should be rejected given an empty payload', () => { - const msg: any = {}; - return messaging.sendToDeviceGroup(mocks.messaging.notificationKey, msg) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('should be rejected given a non-empty payload with neither the "data" nor the "notification" property', () => { - const msg: any = { - foo: 'one', - bar: 'two', - }; - return messaging.sendToTopic(mocks.messaging.topic, msg) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('should be rejected given an otherwise valid payload with an additional invalid property', () => { - const mockPayloadClone: MessagingPayload = _.clone(mocks.messaging.payload); - (mockPayloadClone as any).foo = 'one'; - - return messaging.sendToCondition(mocks.messaging.condition, mockPayloadClone) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('should be rejected given a non-object value for the "data" property', () => { - return messaging.sendToDevice(mocks.messaging.registrationToken, { - data: 'foo' as any, - }).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('should be rejected given a non-object value for the "notification" property', () => { - return messaging.sendToDevice(mocks.messaging.registrationToken, { - notification: true as any, - }).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('should be rejected given a non-string value for a property within the "data" property', () => { - return messaging.sendToDevice(mocks.messaging.registrationToken, { - data: { - foo: 1 as any, - }, - }).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('should be rejected given a non-string value for a property within the "notification" property', () => { - return messaging.sendToDevice(mocks.messaging.registrationToken, { - notification: { - foo: true as any, - }, - }).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('should be rejected given a valid "data" property but invalid "notification" property', () => { - const mockPayloadClone: MessagingPayload = _.clone(mocks.messaging.payloadDataOnly); - (mockPayloadClone as any).notification = 'foo'; - - return messaging.sendToDevice(mocks.messaging.registrationToken, mockPayloadClone) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - it('should be rejected given a valid "notification" property but invalid "data" property', () => { - const mockPayloadClone: MessagingPayload = _.clone(mocks.messaging.payloadNotificationOnly); - (mockPayloadClone as any).data = 'foo'; - - return messaging.sendToDevice(mocks.messaging.registrationToken, mockPayloadClone) - .should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - - const blacklistedDataPayloadKeys = BLACKLISTED_DATA_PAYLOAD_KEYS.concat(['google.', 'google.foo']); - blacklistedDataPayloadKeys.forEach((blacklistedProperty) => { - it(`should be rejected given blacklisted "data.${blacklistedProperty}" property`, () => { - return messaging.sendToDevice( - mocks.messaging.registrationToken, - { - data: { - [blacklistedProperty]: 'foo', - }, - }, - ).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-payload'); - }); - }); - - const nonBlacklistedDataPayloadKeys = ['google', '.google', 'goo.gle', 'googlefoo', 'googlef.oo']; - nonBlacklistedDataPayloadKeys.forEach((nonBlacklistedProperty) => { - it(`should be fulfilled given non-blacklisted "data.${nonBlacklistedProperty}" property`, () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - { - data: { - [nonBlacklistedProperty]: 'foo', - }, - }, - ); - }); - }); - - it('should be fulfilled given a valid payload containing only the "data" property', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDevice(mocks.messaging.registrationToken, mocks.messaging.payloadDataOnly); - }); - - it('should be fulfillled given a valid payload containing only the "notification" property', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDevice(mocks.messaging.registrationToken, mocks.messaging.payloadNotificationOnly); - }); - - it('should be fulfillled given a valid payload containing both "data" and "notification" properties', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDevice(mocks.messaging.registrationToken, mocks.messaging.payload); - }); - - it('should add "data" and "notification" as top-level properties of the request data', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.have.keys(['to', 'data', 'notification']); - expect(requestData.data).to.deep.equal(mocks.messaging.payload.data); - expect(requestData.notification).to.deep.equal(mocks.messaging.payload.notification); - }); - }); - - it('should convert whitelisted camelCased properties to underscore_cased properties', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDevice( - mocks.messaging.registrationToken, - { - notification: { - bodyLocArgs: 'one', - bodyLocKey: 'two', - clickAction: 'three', - titleLocArgs: 'four', - titleLocKey: 'five', - otherKey: 'six', - }, - }, - ); - }).then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData.notification).to.deep.equal({ - body_loc_args: 'one', - body_loc_key: 'two', - click_action: 'three', - title_loc_args: 'four', - title_loc_key: 'five', - otherKey: 'six', - }); - }); - }); - - it('should give whitelisted camelCased properties higher precedence than underscore_cased properties', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDevice( - mocks.messaging.registrationToken, - { - notification: { - bodyLocArgs: 'foo', - body_loc_args: 'bar', - }, - }, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData.notification.body_loc_args).to.equal('foo'); - }); - }); - - it('should not mutate the provided payload object', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - const mockPayloadClone: MessagingPayload = _.clone(mocks.messaging.payload); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mockPayloadClone, - ).then(() => { - expect(mockPayloadClone).to.deep.equal(mocks.messaging.payload); - }); - }); - - const invalidImages = ['', 'a', 'foo', 'image.jpg']; - invalidImages.forEach((imageUrl) => { - it(`should throw given an invalid imageUrl: ${imageUrl}`, () => { - const message: Message = { - condition: 'topic-name', - notification: { - imageUrl, - }, - }; - expect(() => { - messaging.send(message); - }).to.throw('notification.imageUrl must be a valid URL string'); - }); - }); - - const invalidTtls = ['', 'abc', '123', '-123s', '1.2.3s', 'As', 's', '1s', -1]; - invalidTtls.forEach((ttl) => { - it(`should throw given an invalid ttl: ${ ttl }`, () => { - const message: Message = { - condition: 'topic-name', - android: { - ttl: (ttl as any), - }, - }; - expect(() => { - messaging.send(message); - }).to.throw('TTL must be a non-negative duration in milliseconds'); - }); - }); - - const invalidColors = ['', 'foo', '123', '#AABBCX', '112233', '#11223']; - invalidColors.forEach((color) => { - it(`should throw given an invalid color: ${ color }`, () => { - const message: Message = { - condition: 'topic-name', - android: { - notification: { - color, - }, - }, - }; - expect(() => { - messaging.send(message); - }).to.throw('android.notification.color must be in the form #RRGGBB'); - }); - }); - - invalidImages.forEach((imageUrl) => { - it(`should throw given an invalid imageUrl: ${ imageUrl }`, () => { - const message: Message = { - condition: 'topic-name', - android: { - notification: { - imageUrl, - }, - }, - }; - expect(() => { - messaging.send(message); - }).to.throw('android.notification.imageUrl must be a valid URL string'); - }); - }); - - it('should throw given android titleLocArgs without titleLocKey', () => { - const message: Message = { - condition: 'topic-name', - android: { - notification: { - titleLocArgs: ['foo'], - }, - }, - }; - expect(() => { - messaging.send(message); - }).to.throw('titleLocKey is required when specifying titleLocArgs'); - }); - - it('should throw given android bodyLocArgs without bodyLocKey', () => { - const message: Message = { - condition: 'topic-name', - android: { - notification: { - bodyLocArgs: ['foo'], - }, - }, - }; - expect(() => { - messaging.send(message); - }).to.throw('bodyLocKey is required when specifying bodyLocArgs'); - }); - - const invalidVibrateTimings = [[null, 500], [-100]]; - invalidVibrateTimings.forEach((vibrateTimingsMillisMaybeNull) => { - const vibrateTimingsMillis = vibrateTimingsMillisMaybeNull as number[]; - it(`should throw given an null or negative vibrateTimingsMillis: ${ vibrateTimingsMillis }`, () => { - const message: Message = { - condition: 'topic-name', - android: { - notification: { - vibrateTimingsMillis, - }, - }, - }; - expect(() => { - messaging.send(message); - }).to.throw('android.notification.vibrateTimingsMillis must be non-negative durations in milliseconds'); - }); + const invalidVibrateTimings = [[null, 500], [-100]]; + invalidVibrateTimings.forEach((vibrateTimingsMillisMaybeNull) => { + const vibrateTimingsMillis = vibrateTimingsMillisMaybeNull as number[]; + it(`should throw given an null or negative vibrateTimingsMillis: ${ vibrateTimingsMillis }`, () => { + const message: Message = { + condition: 'topic-name', + android: { + notification: { + vibrateTimingsMillis, + }, + }, + }; + expect(() => { + messaging.send(message); + }).to.throw('android.notification.vibrateTimingsMillis must be non-negative durations in milliseconds'); + }); }); it('should throw given an empty vibrateTimingsMillis array', () => { @@ -3696,180 +1759,6 @@ describe('Messaging', () => { }); describe('Options validation', () => { - const invalidOptions = [null, NaN, 0, 1, true, false, '', 'a', [], ['a', 1], _.noop]; - invalidOptions.forEach((invalidOption) => { - it(`should throw given invalid type for options argument: ${ JSON.stringify(invalidOption) }`, () => { - expect(() => { - messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - invalidOption as MessagingOptions, - ); - }).to.throw('Messaging options must be an object'); - - expect(() => { - messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - invalidOption as MessagingOptions, - ); - }).to.throw('Messaging options must be an object'); - - expect(() => { - messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - invalidOption as MessagingOptions, - ); - }).to.throw('Messaging options must be an object'); - - expect(() => { - messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - invalidOption as MessagingOptions, - ); - }).to.throw('Messaging options must be an object'); - }); - }); - - BLACKLISTED_OPTIONS_KEYS.forEach((blacklistedProperty) => { - it(`should be rejected given blacklisted "${blacklistedProperty}" property`, () => { - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - { - [blacklistedProperty]: 'foo', - }, - ).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-options'); - }); - }); - - const whitelistedOptionsKeys: { - [name: string]: { - type: string; - underscoreCasedKey?: string; - }; - } = { - dryRun: { type: 'boolean', underscoreCasedKey: 'dry_run' }, - priority: { type: 'string' }, - timeToLive: { type: 'number', underscoreCasedKey: 'time_to_live' }, - collapseKey: { type: 'string', underscoreCasedKey: 'collapse_key' }, - mutableContent: { type: 'boolean', underscoreCasedKey: 'mutable_content' }, - contentAvailable: { type: 'boolean', underscoreCasedKey: 'content_available' }, - restrictedPackageName: { type: 'string', underscoreCasedKey: 'restricted_package_name' }, - }; - - _.forEach(whitelistedOptionsKeys, ({ type, underscoreCasedKey }, camelCasedKey) => { - let validValue: any; - let invalidValues: Array<{value: any; text: string}>; - if (type === 'string') { - invalidValues = [ - { value: true, text: 'non-string' }, - { value: '', text: 'empty string' }, - ]; - validValue = 'foo'; - } else if (type === 'number') { - invalidValues = [ - { value: true, text: 'non-number' }, - { value: NaN, text: 'NaN' }, - ]; - validValue = 1; - } else if (type === 'boolean') { - invalidValues = [ - { value: '', text: 'non-boolean' }, - ]; - validValue = false; - } - - // Only test the alternate underscoreCasedKey if it is defined - const keysToTest = [camelCasedKey]; - if (typeof underscoreCasedKey !== 'undefined') { - keysToTest.push(underscoreCasedKey); - } - - keysToTest.forEach((key) => { - invalidValues.forEach(({ value, text }) => { - it(`should be rejected given ${ text } value for the "${ key }" property`, () => { - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - { - [key]: value as any, - }, - ).should.eventually.be.rejected.and.have.property('code', 'messaging/invalid-options'); - }); - }); - - it(`should be fulfilled given ${ type } value for the "${ key }" property`, () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - { - [key]: validValue, - }, - ); - }); - }); - }); - - it('should be fulfilled given an empty options object', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToDeviceGroup( - mocks.messaging.notificationKey, - mocks.messaging.payload, - {}, - ); - }); - - it('should be fulfilled given an options object containing only whitelisted properties', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - return messaging.sendToTopic( - mocks.messaging.topic, - mocks.messaging.payload, - mocks.messaging.options, - ); - }); - - it('should be fulfilled given an options object containing non-whitelisted properties', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - const mockOptionsClone: MessagingOptions = _.clone(mocks.messaging.options); - (mockOptionsClone as any).foo = 'bar'; - - return messaging.sendToCondition( - mocks.messaging.condition, - mocks.messaging.payload, - mockOptionsClone, - ); - }); - - it('should add provided options as top-level properties of the request data', () => { - const mockOptionsClone: MessagingOptions = _.clone(mocks.messaging.options); - - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payloadDataOnly, - mockOptionsClone, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.have.keys(['to', 'data', 'dry_run', 'collapse_key']); - expect(requestData.dry_run).to.equal(mockOptionsClone.dryRun); - expect(requestData.collapse_key).to.equal(mockOptionsClone.collapseKey); - }); - }); - const validMessages: Array<{ label: string; req: any; @@ -4505,70 +2394,6 @@ describe('Messaging', () => { expect(requestData.message).to.deep.equal(expectedReq); }); }); - - it('should convert whitelisted camelCased properties to underscore_cased properties', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payloadDataOnly, - { - dryRun: true, - timeToLive: 1, - collapseKey: 'foo', - mutableContent: true, - contentAvailable: false, - restrictedPackageName: 'bar', - otherKey: true, - }, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData).to.have.keys([ - 'to', 'data', 'dry_run', 'time_to_live', 'collapse_key', 'mutable_content', - 'content_available', 'restricted_package_name', 'otherKey', - ]); - }); - }); - - it('should give whitelisted camelCased properties higher precedence than underscore_cased properties', () => { - // Wait for the initial getToken() call to complete before stubbing https.request. - return mockApp.INTERNAL.getToken() - .then(() => { - httpsRequestStub = sinon.stub(HttpClient.prototype, 'send').resolves(emptyResponse); - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payloadDataOnly, - { - dryRun: true, - dry_run: false, - }, - ); - }) - .then(() => { - expect(httpsRequestStub).to.have.been.calledOnce; - const requestData = httpsRequestStub.args[0][0].data; - expect(requestData.dry_run).to.be.true; - }); - }); - - it('should not mutate the provided options object', () => { - mockedRequests.push(mockSendToDeviceStringRequest()); - - const mockOptionsClone: MessagingOptions = _.clone(mocks.messaging.options); - - return messaging.sendToDevice( - mocks.messaging.registrationToken, - mocks.messaging.payload, - mockOptionsClone, - ).then(() => { - expect(mockOptionsClone).to.deep.equal(mocks.messaging.options); - }); - }); }); function tokenSubscriptionTests(methodName: string): void { From dcef2aebda043564167d32ef8d6ea86516048976 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 7 Nov 2024 16:04:42 -0500 Subject: [PATCH 203/323] chore: Add `X-Goog-Api-Client` metric header to outgoing authorized http requests (#2763) * chore: Add `X-Goog-Api-Client` metric header to outgoing requests * fix lint * remove quota project id headers from HTTP/2 --- src/auth/auth-api-request.ts | 1 - .../messaging-api-request-internal.ts | 1 - src/utils/api-request.ts | 6 ++ src/utils/index.ts | 4 ++ .../app-check-api-client-internal.spec.ts | 3 +- test/unit/auth/auth-api-request.spec.ts | 6 +- .../data-connect-api-client-internal.spec.ts | 3 +- test/unit/database/database.spec.ts | 3 + test/unit/eventarc/eventarc.spec.ts | 70 ++++++------------- .../extensions-api-client-internal.spec.ts | 31 +++++--- .../functions-api-client-internal.spec.ts | 3 +- .../installations-request-handler.spec.ts | 2 + .../machine-learning-api-client.spec.ts | 3 +- test/unit/messaging/messaging.spec.ts | 4 +- .../project-management-api-request.spec.ts | 3 +- .../remote-config-api-client.spec.ts | 3 +- .../security-rules-api-client.spec.ts | 3 +- test/unit/utils/crypto-signer.spec.ts | 11 ++- 18 files changed, 86 insertions(+), 74 deletions(-) diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 3d782fb775..cd9c145b1e 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -47,7 +47,6 @@ import { ProjectConfig, ProjectConfigServerResponse, UpdateProjectConfigRequest /** Firebase Auth request header. */ const FIREBASE_AUTH_HEADERS = { 'X-Client-Version': `Node/Admin/${utils.getSdkVersion()}`, - 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${utils.getSdkVersion()}` }; /** Firebase Auth request timeout duration in milliseconds. */ const FIREBASE_AUTH_TIMEOUT = 25000; diff --git a/src/messaging/messaging-api-request-internal.ts b/src/messaging/messaging-api-request-internal.ts index 07621978f3..830fbed568 100644 --- a/src/messaging/messaging-api-request-internal.ts +++ b/src/messaging/messaging-api-request-internal.ts @@ -31,7 +31,6 @@ const FIREBASE_MESSAGING_TIMEOUT = 15000; const FIREBASE_MESSAGING_HTTP_METHOD: HttpMethod = 'POST'; const FIREBASE_MESSAGING_HEADERS = { 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, 'access_token_auth': 'true', }; diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index 69406c27ea..d64e0a2762 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -26,6 +26,7 @@ import url = require('url'); import { EventEmitter } from 'events'; import { Readable } from 'stream'; import * as zlibmod from 'zlib'; +import { getMetricsHeader } from '../utils/index'; /** Http method type definition. */ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD'; @@ -1085,6 +1086,9 @@ export class AuthorizedHttpClient extends HttpClient { if (!requestCopy.httpAgent && this.app.options.httpAgent) { requestCopy.httpAgent = this.app.options.httpAgent; } + + requestCopy.headers['X-Goog-Api-Client'] = getMetricsHeader() + return super.send(requestCopy); }); } @@ -1108,6 +1112,8 @@ export class AuthorizedHttp2Client extends Http2Client { const authHeader = 'Authorization'; requestCopy.headers[authHeader] = `Bearer ${token}`; + requestCopy.headers['X-Goog-Api-Client'] = getMetricsHeader() + return super.send(requestCopy); }); } diff --git a/src/utils/index.ts b/src/utils/index.ts index ebc405ad8e..c7c331206d 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -32,6 +32,10 @@ export function getSdkVersion(): string { return sdkVersion; } +export function getMetricsHeader(): string { + return `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}` +} + /** * Renames properties on an object given a mapping from old to new property names. * diff --git a/test/unit/app-check/app-check-api-client-internal.spec.ts b/test/unit/app-check/app-check-api-client-internal.spec.ts index e5a483d91c..3f2746cf59 100644 --- a/test/unit/app-check/app-check-api-client-internal.spec.ts +++ b/test/unit/app-check/app-check-api-client-internal.spec.ts @@ -23,7 +23,7 @@ import * as sinon from 'sinon'; import { HttpClient } from '../../../src/utils/api-request'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; -import { getSdkVersion } from '../../../src/utils'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { AppCheckApiClient, FirebaseAppCheckError } from '../../../src/app-check/app-check-api-client-internal'; @@ -46,6 +46,7 @@ describe('AppCheckApiClient', () => { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'x-goog-user-project': 'test-project', + 'X-Goog-Api-Client': getMetricsHeader(), }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' diff --git a/test/unit/auth/auth-api-request.spec.ts b/test/unit/auth/auth-api-request.spec.ts index 8abbc80247..bd789421b8 100644 --- a/test/unit/auth/auth-api-request.spec.ts +++ b/test/unit/auth/auth-api-request.spec.ts @@ -42,7 +42,7 @@ import { AuthClientErrorCode, FirebaseAuthError } from '../../../src/utils/error import { ActionCodeSettingsBuilder } from '../../../src/auth/action-code-settings-builder'; import { SAMLConfigServerResponse } from '../../../src/auth/auth-config'; import { expectUserImportResult } from './user-import-builder.spec'; -import { getSdkVersion } from '../../../src/utils/index'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils/index'; import { UserImportRecord, OIDCAuthProviderConfig, SAMLAuthProviderConfig, OIDCUpdateAuthProviderRequest, SAMLUpdateAuthProviderRequest, UserIdentifier, UpdateRequest, UpdateMultiFactorInfoRequest, @@ -863,12 +863,12 @@ AUTH_REQUEST_HANDLER_TESTS.forEach((handler) => { const mockAccessToken: string = utils.generateRandomAccessToken(); const expectedHeaders: {[key: string]: string} = { 'X-Client-Version': `Node/Admin/${getSdkVersion()}`, - 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, + 'X-Goog-Api-Client': getMetricsHeader(), 'Authorization': 'Bearer ' + mockAccessToken, }; const expectedHeadersEmulator: {[key: string]: string} = { 'X-Client-Version': `Node/Admin/${getSdkVersion()}`, - 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, + 'X-Goog-Api-Client': getMetricsHeader(), 'Authorization': 'Bearer owner', }; const callParams = (path: string, method: any, data: any): HttpRequestConfig => { diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index aa45f53b9c..0815515204 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -28,7 +28,7 @@ import { DataConnectApiClient, FirebaseDataConnectError } from '../../../src/data-connect/data-connect-api-client-internal'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { ConnectorConfig } from '../../../src/data-connect'; -import { getSdkVersion } from '../../../src/utils'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils'; describe('DataConnectApiClient', () => { @@ -44,6 +44,7 @@ describe('DataConnectApiClient', () => { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'x-goog-user-project': 'test-project', + 'X-Goog-Api-Client': getMetricsHeader(), }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' diff --git a/test/unit/database/database.spec.ts b/test/unit/database/database.spec.ts index ce86082842..5032deb3c3 100644 --- a/test/unit/database/database.spec.ts +++ b/test/unit/database/database.spec.ts @@ -27,6 +27,7 @@ import { Database, DatabaseService } from '../../../src/database/database'; import { ServiceAccountCredential } from '../../../src/app/credential-internal'; import * as utils from '../utils'; import { HttpClient, HttpRequestConfig } from '../../../src/utils/api-request'; +import { getMetricsHeader } from '../../../src/utils'; describe('Database', () => { let mockApp: FirebaseApp; @@ -332,6 +333,7 @@ describe('Database', () => { url, headers: { Authorization: 'Bearer ' + mockAccessToken, + 'X-Goog-Api-Client': getMetricsHeader(), }, }; @@ -485,6 +487,7 @@ describe('Database', () => { headers: { 'Authorization': 'Bearer ' + mockAccessToken, 'content-type': 'application/json; charset=utf-8', + 'X-Goog-Api-Client': getMetricsHeader(), }, data, }; diff --git a/test/unit/eventarc/eventarc.spec.ts b/test/unit/eventarc/eventarc.spec.ts index 1bbddd5a4d..94587cde16 100644 --- a/test/unit/eventarc/eventarc.spec.ts +++ b/test/unit/eventarc/eventarc.spec.ts @@ -27,7 +27,7 @@ import * as mocks from '../../resources/mocks'; import * as utils from '../utils'; import * as chai from 'chai'; import chaiExclude from 'chai-exclude'; -import { getSdkVersion } from '../../../src/utils/index'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils/index'; const expect = chai.expect; chai.use(chaiExclude); @@ -56,6 +56,14 @@ describe('eventarc', () => { let mockApp: FirebaseApp; let eventarc: Eventarc; + const getExpectedHeaders = (mockAccessToken: string): object => { + return { + 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), + Authorization: 'Bearer ' + mockAccessToken, + 'X-Goog-Api-Client': getMetricsHeader(), + } + } + before(() => { mockApp = mocks.app(); eventarc = new Eventarc(mockApp); @@ -133,10 +141,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-central1/channels/firebase:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); @@ -151,10 +156,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-central1/channels/firebase:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED},${TEST_EVENT2_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); }); @@ -196,10 +198,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/other-project-id/locations/us-west1/channels/my-channel2:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); @@ -214,10 +213,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/other-project-id/locations/us-west1/channels/my-channel2:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED},${TEST_EVENT2_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); }); @@ -259,10 +255,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-west1/channels/my-channel:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); @@ -277,10 +270,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-west1/channels/my-channel:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED},${TEST_EVENT2_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); }); @@ -322,10 +312,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-central1/channels/my-channel:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); @@ -340,10 +327,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-central1/channels/my-channel:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED},${TEST_EVENT2_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); }); @@ -478,10 +462,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-central1/channels/firebase:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); @@ -498,10 +479,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-central1/channels/firebase:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); }); @@ -542,10 +520,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-central1/channels/firebase:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); @@ -562,10 +537,7 @@ describe('eventarc', () => { method: 'POST', url: 'https://eventarcpublishing.googleapis.com/v1/projects/project_id/locations/us-central1/channels/firebase:publishEvents', data: `{"events":[${TEST_EVENT1_SERIALIZED}]}`, - headers: { - 'X-Firebase-Client': 'fire-admin-node/' + getSdkVersion(), - Authorization: 'Bearer ' + mockAccessToken - } + headers: getExpectedHeaders(mockAccessToken) }); }); }); diff --git a/test/unit/extensions/extensions-api-client-internal.spec.ts b/test/unit/extensions/extensions-api-client-internal.spec.ts index a95baff154..32213b8068 100644 --- a/test/unit/extensions/extensions-api-client-internal.spec.ts +++ b/test/unit/extensions/extensions-api-client-internal.spec.ts @@ -22,8 +22,9 @@ import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { ExtensionsApiClient, FirebaseExtensionsError } from '../../../src/extensions/extensions-api-client-internal'; -import { HttpClient, HttpRequestConfig } from '../../../src/utils/api-request'; +import { HttpClient } from '../../../src/utils/api-request'; import { SettableProcessingState } from '../../../src/extensions/extensions-api'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils'; const testProjectId = 'test-project'; const testInstanceId = 'test-instance'; @@ -38,6 +39,13 @@ describe('Extension API client', () => { projectId: 'test-project', serviceAccountId: 'service-acct@email.com' }; + + const EXPECTED_HEADERS = { + 'Authorization': 'Bearer mock-token', + 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'x-goog-user-project': 'test-project', + 'X-Goog-Api-Client': getMetricsHeader(), + } before(() => { app = mocks.appWithOptions(mockOptions); @@ -71,14 +79,19 @@ describe('Extension API client', () => { detailMessage: 'done processing', }, } - const expected = sinon.match((req: HttpRequestConfig) => { - const url = 'https://firebaseextensions.googleapis.com/' + - 'v1beta/projects/test-project/instances/test-instance/runtimeData'; - return req.method == 'PATCH' && req.url == url && req.data == testRuntimeData; - }, 'Incorrect URL or Method'); - httpClientStub.withArgs(expected).resolves(utils.responseFrom(testRuntimeData, 200)); - await expect(apiClient.updateRuntimeData(testProjectId, testInstanceId, testRuntimeData)) - .to.eventually.deep.equal(testRuntimeData); + const url = 'https://firebaseextensions.googleapis.com/' + + 'v1beta/projects/test-project/instances/test-instance/runtimeData'; + httpClientStub = httpClientStub.resolves(utils.responseFrom(testRuntimeData, 200)); + return apiClient.updateRuntimeData(testProjectId, testInstanceId, testRuntimeData) + .then((runtimeData) => { + expect(runtimeData).to.deep.equal(testRuntimeData) + expect(httpClientStub).to.have.been.calledOnce.and.calledWith({ + method: 'PATCH', + url: url, + headers: EXPECTED_HEADERS, + data: testRuntimeData + }) + }) }); it('should convert errors in FirebaseErrors', async () => { diff --git a/test/unit/functions/functions-api-client-internal.spec.ts b/test/unit/functions/functions-api-client-internal.spec.ts index bb1ae0bfbd..40e24b1fea 100644 --- a/test/unit/functions/functions-api-client-internal.spec.ts +++ b/test/unit/functions/functions-api-client-internal.spec.ts @@ -22,7 +22,7 @@ import * as chai from 'chai'; import * as sinon from 'sinon'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; -import { getSdkVersion } from '../../../src/utils'; +import { getSdkVersion, getMetricsHeader } from '../../../src/utils'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { FirebaseFunctionsError, FunctionsApiClient, Task } from '../../../src/functions/functions-api-client-internal'; @@ -47,6 +47,7 @@ describe('FunctionsApiClient', () => { 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'Authorization': 'Bearer mock-token', 'x-goog-user-project': 'test-project', + 'X-Goog-Api-Client': getMetricsHeader(), }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' diff --git a/test/unit/installations/installations-request-handler.spec.ts b/test/unit/installations/installations-request-handler.spec.ts index 36e696dd2d..8baeaa3de8 100644 --- a/test/unit/installations/installations-request-handler.spec.ts +++ b/test/unit/installations/installations-request-handler.spec.ts @@ -29,6 +29,7 @@ import * as mocks from '../../resources/mocks'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { HttpClient } from '../../../src/utils/api-request'; import { FirebaseInstallationsRequestHandler } from '../../../src/installations/installations-request-handler'; +import { getMetricsHeader } from '../../../src/utils'; chai.should(); chai.use(sinonChai); @@ -57,6 +58,7 @@ describe('FirebaseInstallationsRequestHandler', () => { mockApp = mocks.app(); expectedHeaders = { Authorization: 'Bearer ' + mockAccessToken, + 'X-Goog-Api-Client': getMetricsHeader(), }; return mockApp.INTERNAL.getToken(); }); diff --git a/test/unit/machine-learning/machine-learning-api-client.spec.ts b/test/unit/machine-learning/machine-learning-api-client.spec.ts index 4d6873d200..c77380f2f3 100644 --- a/test/unit/machine-learning/machine-learning-api-client.spec.ts +++ b/test/unit/machine-learning/machine-learning-api-client.spec.ts @@ -25,7 +25,7 @@ import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; import { FirebaseAppError } from '../../../src/utils/error'; import { FirebaseApp } from '../../../src/app/firebase-app'; -import { getSdkVersion } from '../../../src/utils/index'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils/index'; import { MachineLearningApiClient } from '../../../src/machine-learning/machine-learning-api-client'; import { ListModelsOptions, ModelOptions } from '../../../src/machine-learning/index'; @@ -118,6 +118,7 @@ describe('MachineLearningApiClient', () => { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'x-goog-user-project': 'test-project', + 'X-Goog-Api-Client': getMetricsHeader(), }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' + 'account credentials, or set project ID as an app option. Alternatively, set the ' diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index 6a14f17171..488056488e 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -32,7 +32,7 @@ import { SendResponse, MulticastMessage, Messaging, TokenMessage, TopicMessage, ConditionMessage, } from '../../../src/messaging/index'; import { HttpClient } from '../../../src/utils/api-request'; -import { getSdkVersion } from '../../../src/utils/index'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils/index'; import * as utils from '../utils'; chai.should(); @@ -218,7 +218,7 @@ describe('Messaging', () => { const expectedHeaders = { 'Authorization': 'Bearer ' + mockAccessToken, 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'X-Goog-Api-Client': `gl-node/${process.versions.node} fire-admin/${getSdkVersion()}`, + 'X-Goog-Api-Client': getMetricsHeader(), 'access_token_auth': 'true', }; const emptyResponse = utils.responseFrom({}); diff --git a/test/unit/project-management/project-management-api-request.spec.ts b/test/unit/project-management/project-management-api-request.spec.ts index 772a33ad4c..58f15653b7 100644 --- a/test/unit/project-management/project-management-api-request.spec.ts +++ b/test/unit/project-management/project-management-api-request.spec.ts @@ -28,7 +28,7 @@ import { import { HttpClient } from '../../../src/utils/api-request'; import * as mocks from '../../resources/mocks'; import * as utils from '../utils'; -import { getSdkVersion } from '../../../src/utils/index'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils/index'; import { AppPlatform, ShaCertificate } from '../../../src/project-management/index'; chai.should(); @@ -76,6 +76,7 @@ describe('ProjectManagementRequestHandler', () => { expectedHeaders = { 'X-Client-Version': `Node/Admin/${getSdkVersion()}`, 'Authorization': 'Bearer ' + mockAccessToken, + 'X-Goog-Api-Client': getMetricsHeader(), }; requestHandler = new ProjectManagementRequestHandler(mockApp); return mockApp.INTERNAL.getToken(); diff --git a/test/unit/remote-config/remote-config-api-client.spec.ts b/test/unit/remote-config/remote-config-api-client.spec.ts index fa464c089a..9b6b8709bf 100644 --- a/test/unit/remote-config/remote-config-api-client.spec.ts +++ b/test/unit/remote-config/remote-config-api-client.spec.ts @@ -29,7 +29,7 @@ import * as mocks from '../../resources/mocks'; import { FirebaseAppError } from '../../../src/utils/error'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { deepCopy } from '../../../src/utils/deep-copy'; -import { getSdkVersion } from '../../../src/utils/index'; +import { getMetricsHeader, getSdkVersion } from '../../../src/utils/index'; import { RemoteConfigTemplate, Version, ListVersionsResult, } from '../../../src/remote-config/index'; @@ -58,6 +58,7 @@ describe('RemoteConfigApiClient', () => { 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'Accept-Encoding': 'gzip', 'x-goog-user-project': 'test-project', + 'X-Goog-Api-Client': getMetricsHeader(), }; const VERSION_INFO: Version = { diff --git a/test/unit/security-rules/security-rules-api-client.spec.ts b/test/unit/security-rules/security-rules-api-client.spec.ts index d4139fdb34..2c1c8d9ec0 100644 --- a/test/unit/security-rules/security-rules-api-client.spec.ts +++ b/test/unit/security-rules/security-rules-api-client.spec.ts @@ -26,7 +26,7 @@ import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; import { FirebaseAppError } from '../../../src/utils/error'; import { FirebaseApp } from '../../../src/app/firebase-app'; -import { getSdkVersion } from '../../../src/utils/index'; +import { getSdkVersion, getMetricsHeader } from '../../../src/utils/index'; const expect = chai.expect; @@ -45,6 +45,7 @@ describe('SecurityRulesApiClient', () => { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'x-goog-user-project': 'test-project', + 'X-Goog-Api-Client': getMetricsHeader(), }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' + 'account credentials, or set project ID as an app option. Alternatively, set the ' diff --git a/test/unit/utils/crypto-signer.spec.ts b/test/unit/utils/crypto-signer.spec.ts index efda058c02..024be3ecbe 100644 --- a/test/unit/utils/crypto-signer.spec.ts +++ b/test/unit/utils/crypto-signer.spec.ts @@ -29,6 +29,7 @@ import { ServiceAccountCredential } from '../../../src/app/credential-internal'; import { AuthorizedHttpClient, HttpClient } from '../../../src/utils/api-request'; import { FirebaseApp } from '../../../src/app/firebase-app'; import * as utils from '../utils'; +import { getMetricsHeader } from '../../../src/utils'; chai.should(); chai.use(sinonChai); @@ -103,7 +104,10 @@ describe('CryptoSigner', () => { const signRequest = { method: 'POST', url: 'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/test-service-account:signBlob', - headers: { Authorization: `Bearer ${mockAccessToken}` }, + headers: { + Authorization: `Bearer ${mockAccessToken}`, + 'X-Goog-Api-Client': getMetricsHeader() + }, data: { payload: input.toString('base64') }, }; let stub: sinon.SinonStub; @@ -158,7 +162,10 @@ describe('CryptoSigner', () => { const signRequest = { method: 'POST', url: 'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/discovered-service-account:signBlob', - headers: { Authorization: `Bearer ${mockAccessToken}` }, + headers: { + Authorization: `Bearer ${mockAccessToken}`, + 'X-Goog-Api-Client': getMetricsHeader() + }, data: { payload: input.toString('base64') }, }; let stub: sinon.SinonStub; From 4babb453fe09e7182714efce1204a69ba3cc32c6 Mon Sep 17 00:00:00 2001 From: Kevin Elko Date: Thu, 7 Nov 2024 16:54:09 -0500 Subject: [PATCH 204/323] change(rc): Update Remote Config condition evaluation hashing (#2760) * move from farmhash to sha256 * lint * add more special char test cases * another special char case * further refine test cases * clean up tests * Trigger CIs * fix newline --------- Co-authored-by: Kevin Elko --- .../condition-evaluator-internal.ts | 22 +- .../remote-config/condition-evaluator.spec.ts | 189 +++++++----------- 2 files changed, 83 insertions(+), 128 deletions(-) diff --git a/src/remote-config/condition-evaluator-internal.ts b/src/remote-config/condition-evaluator-internal.ts index 2e5c68371f..c0fc0484a8 100644 --- a/src/remote-config/condition-evaluator-internal.ts +++ b/src/remote-config/condition-evaluator-internal.ts @@ -27,7 +27,8 @@ import { CustomSignalCondition, CustomSignalOperator, } from './remote-config-api'; -import * as farmhash from 'farmhash-modern'; +import { createHash } from 'crypto'; + /** * Encapsulates condition evaluation logic to simplify organization and @@ -151,9 +152,8 @@ export class ConditionEvaluator { const seedPrefix = seed && seed.length > 0 ? `${seed}.` : ''; const stringToHash = `${seedPrefix}${context.randomizationId}`; - const hash64 = ConditionEvaluator.hashSeededRandomizationId(stringToHash) - - const instanceMicroPercentile = hash64 % BigInt(100 * 1_000_000); + const hash = ConditionEvaluator.hashSeededRandomizationId(stringToHash) + const instanceMicroPercentile = hash % BigInt(100 * 1_000_000); switch (percentOperator) { case PercentConditionOperator.LESS_OR_EQUAL: @@ -173,18 +173,8 @@ export class ConditionEvaluator { } static hashSeededRandomizationId(seededRandomizationId: string): bigint { - // For consistency with the Remote Config fetch endpoint's percent condition behavior - // we use Farmhash's fingerprint64 algorithm and interpret the resulting unsigned value - // as a signed value. - let hash64 = BigInt.asIntN(64, farmhash.fingerprint64(seededRandomizationId)); - - // Manually negate the hash if its value is less than 0, since Math.abs doesn't - // support BigInt. - if (hash64 < 0) { - hash64 = -hash64; - } - - return hash64; + const hex = createHash('sha256').update(seededRandomizationId).digest('hex'); + return BigInt(`0x${hex}`); } private evaluateCustomSignalCondition( diff --git a/test/unit/remote-config/condition-evaluator.spec.ts b/test/unit/remote-config/condition-evaluator.spec.ts index c1159238b4..8bfa168df6 100644 --- a/test/unit/remote-config/condition-evaluator.spec.ts +++ b/test/unit/remote-config/condition-evaluator.spec.ts @@ -28,7 +28,7 @@ import { } from '../../../src/remote-config/remote-config-api'; import { v4 as uuidv4 } from 'uuid'; import { clone } from 'lodash'; -import * as farmhash from 'farmhash-modern'; +import * as crypto from 'crypto'; const expect = chai.expect; @@ -251,9 +251,8 @@ describe('ConditionEvaluator', () => { it('should use zero for undefined microPercent', () => { // Stubs ID hasher to return a number larger than zero. - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(1n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns('1'); stubs.push(stub); const condition = { @@ -284,9 +283,8 @@ describe('ConditionEvaluator', () => { it('should use zeros for undefined microPercentRange', () => { // Stubs ID hasher to return a number in range. - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(1n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns('1'); stubs.push(stub); const condition = { @@ -317,9 +315,8 @@ describe('ConditionEvaluator', () => { it('should use zero for undefined microPercentUpperBound', () => { // Stubs ID hasher to return a number outside range. - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(1n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns('1'); stubs.push(stub); const condition = { @@ -353,9 +350,8 @@ describe('ConditionEvaluator', () => { it('should use zero for undefined microPercentLowerBound', () => { // Stubs ID hasher to return a number in range. - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(1n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns('1'); stubs.push(stub); const condition = { @@ -388,9 +384,9 @@ describe('ConditionEvaluator', () => { }); it('should evaluate 9 as less or equal to 10', () => { - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(9n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns('9'); + stubs.push(stub); stubs.push(stub); const condition = { @@ -419,9 +415,9 @@ describe('ConditionEvaluator', () => { }); it('should evaluate 10 as less or equal to 10', () => { - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(10n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns((10).toString(16)); + stubs.push(stub); stubs.push(stub); const condition = { @@ -450,9 +446,9 @@ describe('ConditionEvaluator', () => { }); it('should evaluate 11 as not less or equal to 10', () => { - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(11n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns((11).toString(16)); + stubs.push(stub); stubs.push(stub); const condition = { @@ -481,9 +477,9 @@ describe('ConditionEvaluator', () => { }); it('should negate -11 to 11 and evaluate as not less or equal to 10', () => { - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(-11n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns((11).toString(16)); + stubs.push(stub); stubs.push(stub); const condition = { @@ -540,9 +536,9 @@ describe('ConditionEvaluator', () => { }); it('should evaluate 11M as greater than 10M', () => { - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(11n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns((11).toString(16)); + stubs.push(stub); stubs.push(stub); const condition = { @@ -571,9 +567,8 @@ describe('ConditionEvaluator', () => { }); it('should evaluate 9 as not greater than 10', () => { - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(9n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns('9'); stubs.push(stub); const condition = { @@ -661,9 +656,8 @@ describe('ConditionEvaluator', () => { }); it('should evaluate 10 as between 9 and 11', () => { - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(10n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns((10).toString(16)); stubs.push(stub); const condition = { @@ -726,9 +720,8 @@ describe('ConditionEvaluator', () => { }); it('should evaluate 12 as not between 9 and 11', () => { - const stub = sinon - .stub(farmhash, 'fingerprint64') - .returns(12n); + const stub = sinon.stub(crypto.Hash.prototype, 'digest'); + stub.withArgs('hex').returns((12).toString(16)); stubs.push(stub); const condition = { @@ -759,6 +752,51 @@ describe('ConditionEvaluator', () => { expect(actual).to.be.false; }); + describe('known percent condition values', () => { + // This test is useful for ensuring consistency across all places we + // evaluate percent conditions. It creates a set of 10 conditions targeting 50% + // with randomizationIds 0-9 and a constant `seed` value. + const conditionEvaluator = new ConditionEvaluator(); + + const percentCondition = { + percentOperator: PercentConditionOperator.BETWEEN, + microPercentRange: { + microPercentLowerBound: 0, + microPercentUpperBound: 50_000_000 // 50% + }, + }; + + const testCases = [ + { seed: '1', randomizationId: 'one', result: false }, + { seed: '2', randomizationId: 'two', result: false }, + { seed: '3', randomizationId: 'three', result: true }, + { seed: '4', randomizationId: 'four', result: false }, + { seed: '5', randomizationId: 'five', result: true }, + { seed: '', randomizationId: '😊', result: true }, + { seed: '', randomizationId: '😀', result: false }, + { seed: 'hêl£o', randomizationId: 'wørlÐ', result: false }, + { seed: 'řemøťe', randomizationId: 'çōnfįġ', result: true }, + { seed: 'long', randomizationId: '.'.repeat(100), result: true }, + { seed: 'very-long', randomizationId: '.'.repeat(1000), result: false }, + ]; + + testCases.map(({ randomizationId, seed, result }) => { + + const idSummary = randomizationId.length > 25 + ? `a ${randomizationId.length} character randomizationID` + : `"${randomizationId}"`; + + it(`should evaluate ${idSummary} with seed "${seed}" to ${result}`, () => { + const context = { randomizationId }; + const evalResult = conditionEvaluator.evaluateConditions([{ + name: 'is_enabled', + condition: { percent: { ...percentCondition, seed } } + }], context); + expect(evalResult.get('is_enabled')).to.equal(result); + }); + }); + }); + // The following tests are probabilistic. They use tolerances based on // standard deviations to balance accuracy and flakiness. Random IDs will // hash to the target range + 3 standard deviations 99.7% of the time, @@ -958,7 +996,7 @@ describe('ConditionEvaluator', () => { describe('STRING_CONTAINS', () => { const testCases: CustomSignalTestCase[] = [ { targets: ['foo', 'biz'], actual: 'foobar', outcome: true }, - { targets: ['foo', 'biz'],actual: 'bar',outcome: false }, + { targets: ['foo', 'biz'], actual: 'bar', outcome: false }, ]; testCases.forEach(runCustomSignalTestCase(CustomSignalOperator.STRING_CONTAINS)); @@ -966,7 +1004,7 @@ describe('ConditionEvaluator', () => { describe('STRING_DOES_NOT_CONTAIN', () => { const testCases: CustomSignalTestCase[] = [ - { targets: ['foo', 'biz'],actual: 'bar',outcome: true }, + { targets: ['foo', 'biz'], actual: 'bar', outcome: true }, { targets: ['foo', 'biz'], actual: 'foobar', outcome: false }, ]; @@ -1135,77 +1173,4 @@ describe('ConditionEvaluator', () => { }); }); }); - - describe('hashSeededRandomizationId', () => { - // The Farmhash algorithm produces a 64 bit unsigned integer, - // which we convert to a signed integer for legacy compatibility. - // This has caused confusion in the past, so we explicitly - // test here. - it('should leave numbers <= 2^63-1 (max signed long) as is', function () { - if (nodeVersion.startsWith('14')) { - this.skip(); - } - - const stub = sinon - .stub(farmhash, 'fingerprint64') - // 2^63-1 = 9223372036854775807. - .returns(BigInt('9223372036854775807')); - stubs.push(stub); - - const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); - - expect(actual).to.equal(BigInt('9223372036854775807')) - }); - - it('should convert 2^63 to negative (min signed long) and then find the absolute value', function () { - if (nodeVersion.startsWith('14')) { - this.skip(); - } - - const stub = sinon - .stub(farmhash, 'fingerprint64') - // 2^63 = 9223372036854775808. - .returns(BigInt('9223372036854775808')); - stubs.push(stub); - - const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); - - // 2^63 is the negation of 2^63-1 - expect(actual).to.equal(BigInt('9223372036854775808')) - }); - - it('should convert 2^63+1 to negative and then find the absolute value', function () { - if (nodeVersion.startsWith('14')) { - this.skip(); - } - - const stub = sinon - .stub(farmhash, 'fingerprint64') - // 2^63+1 9223372036854775809. - .returns(BigInt('9223372036854775809')); - stubs.push(stub); - - const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); - - // 2^63+1 is larger than 2^63, so the absolute value is smaller - expect(actual).to.equal(BigInt('9223372036854775807')) - }); - - it('should handle the value that initially caused confusion', function () { - if (nodeVersion.startsWith('14')) { - this.skip(); - } - - const stub = sinon - .stub(farmhash, 'fingerprint64') - // We were initially confused about the nature of this value ... - .returns(BigInt('16081085603393958147')); - stubs.push(stub); - - const actual = ConditionEvaluator.hashSeededRandomizationId('anything'); - - // ... Now we know it's the unsigned equivalent of this absolute value. - expect(actual).to.equal(BigInt('2365658470315593469')) - }); - }); }); From 4ee1bb2486ef98171b9eb741895fcb4b1da21549 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Fri, 8 Nov 2024 11:35:53 -0500 Subject: [PATCH 205/323] fix: Set the Quota Project ID only for ADC human accounts (#2761) * fix: Set quota project ID for ADC human accounts * Add header to http/2 calls * add unit tests --- src/app/credential-internal.ts | 9 ++++ src/utils/api-request.ts | 21 ++++++++-- .../app-check-api-client-internal.spec.ts | 1 - .../data-connect-api-client-internal.spec.ts | 1 - .../extensions-api-client-internal.spec.ts | 1 - .../functions-api-client-internal.spec.ts | 1 - .../machine-learning-api-client.spec.ts | 1 - .../remote-config-api-client.spec.ts | 1 - .../security-rules-api-client.spec.ts | 1 - test/unit/utils/api-request.spec.ts | 41 +++++++++++++++++++ 10 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/app/credential-internal.ts b/src/app/credential-internal.ts index 2d240cc301..c8ce25b246 100644 --- a/src/app/credential-internal.ts +++ b/src/app/credential-internal.ts @@ -39,6 +39,7 @@ export class ApplicationDefaultCredential implements Credential { private readonly googleAuth: GoogleAuth; private authClient: AnyAuthClient; private projectId?: string; + private quotaProjectId?: string; private accountId?: string; constructor(httpAgent?: Agent) { @@ -58,6 +59,7 @@ export class ApplicationDefaultCredential implements Credential { } await this.authClient.getAccessToken(); const credentials = this.authClient.credentials; + this.quotaProjectId = this.authClient.quotaProjectId; return populateCredential(credentials); } @@ -68,6 +70,13 @@ export class ApplicationDefaultCredential implements Credential { return Promise.resolve(this.projectId); } + public getQuotaProjectId(): string | undefined { + if (!this.quotaProjectId) { + this.quotaProjectId = this.authClient?.quotaProjectId; + } + return this.quotaProjectId; + } + public async isComputeEngineCredential(): Promise { if (!this.authClient) { this.authClient = await this.googleAuth.getClient(); diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index d64e0a2762..c5e284e414 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -26,6 +26,7 @@ import url = require('url'); import { EventEmitter } from 'events'; import { Readable } from 'stream'; import * as zlibmod from 'zlib'; +import { ApplicationDefaultCredential } from '../app/credential-internal'; import { getMetricsHeader } from '../utils/index'; /** Http method type definition. */ @@ -1077,10 +1078,13 @@ export class AuthorizedHttpClient extends HttpClient { const authHeader = 'Authorization'; requestCopy.headers[authHeader] = `Bearer ${token}`; - // Fix issue where firebase-admin does not specify quota project that is - // necessary for use when utilizing human account with ADC (RSDF) - if (!requestCopy.headers['x-goog-user-project'] && this.app.options.projectId) { - requestCopy.headers['x-goog-user-project'] = this.app.options.projectId + let quotaProjectId: string | undefined; + if (this.app.options.credential instanceof ApplicationDefaultCredential) { + quotaProjectId = this.app.options.credential.getQuotaProjectId(); + } + quotaProjectId = process.env.GOOGLE_CLOUD_QUOTA_PROJECT || quotaProjectId; + if (!requestCopy.headers['x-goog-user-project'] && validator.isNonEmptyString(quotaProjectId)) { + requestCopy.headers['x-goog-user-project'] = quotaProjectId; } if (!requestCopy.httpAgent && this.app.options.httpAgent) { @@ -1112,6 +1116,15 @@ export class AuthorizedHttp2Client extends Http2Client { const authHeader = 'Authorization'; requestCopy.headers[authHeader] = `Bearer ${token}`; + let quotaProjectId: string | undefined; + if (this.app.options.credential instanceof ApplicationDefaultCredential) { + quotaProjectId = this.app.options.credential.getQuotaProjectId(); + } + quotaProjectId = process.env.GOOGLE_CLOUD_QUOTA_PROJECT || quotaProjectId; + if (!requestCopy.headers['x-goog-user-project'] && validator.isNonEmptyString(quotaProjectId)) { + requestCopy.headers['x-goog-user-project'] = quotaProjectId; + } + requestCopy.headers['X-Goog-Api-Client'] = getMetricsHeader() return super.send(requestCopy); diff --git a/test/unit/app-check/app-check-api-client-internal.spec.ts b/test/unit/app-check/app-check-api-client-internal.spec.ts index 3f2746cf59..743f6ed89f 100644 --- a/test/unit/app-check/app-check-api-client-internal.spec.ts +++ b/test/unit/app-check/app-check-api-client-internal.spec.ts @@ -45,7 +45,6 @@ describe('AppCheckApiClient', () => { const EXPECTED_HEADERS = { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'x-goog-user-project': 'test-project', 'X-Goog-Api-Client': getMetricsHeader(), }; diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index 0815515204..93b7120703 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -43,7 +43,6 @@ describe('DataConnectApiClient', () => { const EXPECTED_HEADERS = { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'x-goog-user-project': 'test-project', 'X-Goog-Api-Client': getMetricsHeader(), }; diff --git a/test/unit/extensions/extensions-api-client-internal.spec.ts b/test/unit/extensions/extensions-api-client-internal.spec.ts index 32213b8068..66f2e8198b 100644 --- a/test/unit/extensions/extensions-api-client-internal.spec.ts +++ b/test/unit/extensions/extensions-api-client-internal.spec.ts @@ -43,7 +43,6 @@ describe('Extension API client', () => { const EXPECTED_HEADERS = { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'x-goog-user-project': 'test-project', 'X-Goog-Api-Client': getMetricsHeader(), } diff --git a/test/unit/functions/functions-api-client-internal.spec.ts b/test/unit/functions/functions-api-client-internal.spec.ts index 40e24b1fea..15862d57b2 100644 --- a/test/unit/functions/functions-api-client-internal.spec.ts +++ b/test/unit/functions/functions-api-client-internal.spec.ts @@ -46,7 +46,6 @@ describe('FunctionsApiClient', () => { const EXPECTED_HEADERS = { 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'Authorization': 'Bearer mock-token', - 'x-goog-user-project': 'test-project', 'X-Goog-Api-Client': getMetricsHeader(), }; diff --git a/test/unit/machine-learning/machine-learning-api-client.spec.ts b/test/unit/machine-learning/machine-learning-api-client.spec.ts index c77380f2f3..2f4447c2da 100644 --- a/test/unit/machine-learning/machine-learning-api-client.spec.ts +++ b/test/unit/machine-learning/machine-learning-api-client.spec.ts @@ -117,7 +117,6 @@ describe('MachineLearningApiClient', () => { const EXPECTED_HEADERS = { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'x-goog-user-project': 'test-project', 'X-Goog-Api-Client': getMetricsHeader(), }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' diff --git a/test/unit/remote-config/remote-config-api-client.spec.ts b/test/unit/remote-config/remote-config-api-client.spec.ts index 9b6b8709bf..91783e9088 100644 --- a/test/unit/remote-config/remote-config-api-client.spec.ts +++ b/test/unit/remote-config/remote-config-api-client.spec.ts @@ -57,7 +57,6 @@ describe('RemoteConfigApiClient', () => { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, 'Accept-Encoding': 'gzip', - 'x-goog-user-project': 'test-project', 'X-Goog-Api-Client': getMetricsHeader(), }; diff --git a/test/unit/security-rules/security-rules-api-client.spec.ts b/test/unit/security-rules/security-rules-api-client.spec.ts index 2c1c8d9ec0..c4176540a6 100644 --- a/test/unit/security-rules/security-rules-api-client.spec.ts +++ b/test/unit/security-rules/security-rules-api-client.spec.ts @@ -44,7 +44,6 @@ describe('SecurityRulesApiClient', () => { const EXPECTED_HEADERS = { 'Authorization': 'Bearer mock-token', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, - 'x-goog-user-project': 'test-project', 'X-Goog-Api-Client': getMetricsHeader(), }; const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' diff --git a/test/unit/utils/api-request.spec.ts b/test/unit/utils/api-request.spec.ts index 4fcb5a397b..d64589f8c9 100644 --- a/test/unit/utils/api-request.spec.ts +++ b/test/unit/utils/api-request.spec.ts @@ -17,6 +17,7 @@ 'use strict'; +import * as _ from 'lodash'; import * as chai from 'chai'; import * as nock from 'nock'; import * as sinon from 'sinon'; @@ -35,6 +36,7 @@ import { import { deepCopy } from '../../../src/utils/deep-copy'; import { Agent } from 'http'; import * as zlib from 'zlib'; +import { getMetricsHeader } from '../../../src/utils'; chai.should(); chai.use(sinonChai); @@ -2648,6 +2650,45 @@ describe('AuthorizedHttpClient', () => { }); }); + describe('Quota Project', () => { + let stubs: sinon.SinonStub[] = []; + + afterEach(() => { + _.forEach(stubs, (stub) => stub.restore()); + stubs = []; + if (process.env.GOOGLE_CLOUD_QUOTA_PROJECT) { + delete process.env.GOOGLE_CLOUD_QUOTA_PROJECT; + } + }); + + it('should include quota project id in headers when GOOGLE_CLOUD_QUOTA_PROJECT is set', () => { + const reqData = { request: 'data' }; + const stub = sinon + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom({}, 200)); + stubs.push(stub); + process.env.GOOGLE_CLOUD_QUOTA_PROJECT = 'test-project-id'; + const client = new AuthorizedHttpClient(mockApp); + return client.send({ + method: 'POST', + url: mockUrl, + data: reqData, + }) + .then(() => { + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: mockUrl, + headers: { + ...requestHeaders.reqheaders, + 'x-goog-user-project': 'test-project-id', + 'X-Goog-Api-Client': getMetricsHeader(), + }, + data: reqData + }); + }); + }); + }); + it('should not mutate the arguments', () => { const reqData = { request: 'data' }; const options = { From 49a8e0b967b0d915cbbeaa74d204b9bed75d90b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:24:46 -0500 Subject: [PATCH 206/323] build(deps-dev): bump nock from 13.5.5 to 13.5.6 (#2766) Bumps [nock](https://github.com/nock/nock) from 13.5.5 to 13.5.6. - [Release notes](https://github.com/nock/nock/releases) - [Changelog](https://github.com/nock/nock/blob/main/CHANGELOG.md) - [Commits](https://github.com/nock/nock/compare/v13.5.5...v13.5.6) --- updated-dependencies: - dependency-name: nock dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 617d2f419a..f267a93254 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8044,11 +8044,10 @@ } }, "node_modules/nock": { - "version": "13.5.5", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.5.tgz", - "integrity": "sha512-XKYnqUrCwXC8DGG1xX4YH5yNIrlh9c065uaMZZHUoeUUINTOyt+x/G+ezYk0Ft6ExSREVIs+qBJDK503viTfFA==", + "version": "13.5.6", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.6.tgz", + "integrity": "sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", From 8b978e00fb8394f593aadebca230788772c32ee9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:29:59 +0000 Subject: [PATCH 207/323] build(deps): bump uuid from 11.0.2 to 11.0.3 (#2767) --- package-lock.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index f267a93254..b6a12a466b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11354,14 +11354,13 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.2.tgz", - "integrity": "sha512-14FfcOJmqdjbBPdDjFQyk/SdT4NySW4eM0zcG+HqbHP5jzuH56xO3J1DGhgs/cEMCfwYi3HQI1gnTO62iaG+tQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", + "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], - "license": "MIT", "bin": { "uuid": "dist/esm/bin/uuid" } From a6a930c0cec994f61ca1f4d2f75a5c74144e19e4 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 12 Nov 2024 10:35:21 -0500 Subject: [PATCH 208/323] [chore] Release 13.0.0 (#2764) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a56570a152..1c9e81cd21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "12.7.0", + "version": "13.0.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 380ef0ada793d873bd074a3def6431d4fcf5c78d Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 20 Nov 2024 11:49:23 -0500 Subject: [PATCH 209/323] fix: Fix the property names when initializing the SDK with ServiceAccount type (#2779) --- src/app/credential-internal.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/credential-internal.ts b/src/app/credential-internal.ts index c8ce25b246..2171d6e637 100644 --- a/src/app/credential-internal.ts +++ b/src/app/credential-internal.ts @@ -473,6 +473,10 @@ function populateGoogleAuth(keyFile: string | object, httpAgent?: Agent) 'Service account must be an object.', ); } + copyAttr(keyFile, keyFile, 'project_id', 'projectId'); + copyAttr(keyFile, keyFile, 'private_key', 'privateKey'); + copyAttr(keyFile, keyFile, 'client_email', 'clientEmail'); + client = auth.fromJSON(keyFile); } return { auth, client }; From 2b6a373d6262e7a9d1fc41533efc807e52ba59a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:00:30 +0000 Subject: [PATCH 210/323] build(deps-dev): bump @firebase/auth-types from 0.12.2 to 0.12.3 (#2775) --- package-lock.json | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index b6a12a466b..fd9d1741c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "12.7.0", + "version": "13.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "12.7.0", + "version": "13.0.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -619,6 +619,16 @@ "@firebase/app-compat": "0.x" } }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/auth-types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", + "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", + "dev": true, + "peerDependencies": { + "@firebase/app-types": "0.x", + "@firebase/util": "1.x" + } + }, "node_modules/@firebase/auth-interop-types": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", @@ -626,11 +636,10 @@ "license": "Apache-2.0" }, "node_modules/@firebase/auth-types": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", - "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.3.tgz", + "integrity": "sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A==", "dev": true, - "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" From 7249cd36373a78fd7ccb5e9844823c13e228c3f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:05:59 +0000 Subject: [PATCH 211/323] build(deps): bump @firebase/database-compat from 2.0.0 to 2.0.1 (#2774) --- package-lock.json | 156 +++++++++++++++++++++++++++++++++------------- 1 file changed, 114 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index fd9d1741c1..819c6ce751 100644 --- a/package-lock.json +++ b/package-lock.json @@ -546,10 +546,9 @@ } }, "node_modules/@firebase/app-check-interop-types": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz", - "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==", - "license": "Apache-2.0" + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==" }, "node_modules/@firebase/app-compat": { "version": "0.2.45", @@ -569,10 +568,9 @@ } }, "node_modules/@firebase/app-types": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", - "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==", - "license": "Apache-2.0" + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" }, "node_modules/@firebase/auth": { "version": "1.8.0", @@ -630,10 +628,9 @@ } }, "node_modules/@firebase/auth-interop-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", - "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==", - "license": "Apache-2.0" + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==" }, "node_modules/@firebase/auth-types": { "version": "0.12.3", @@ -649,6 +646,7 @@ "version": "0.6.10", "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@firebase/util": "1.10.1", @@ -659,16 +657,15 @@ } }, "node_modules/@firebase/database": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.9.tgz", - "integrity": "sha512-EkiPSKSu2TJJGtOjyISASf3UFpFJDil1lMbfqnxilfbmIsilvC8DzgjuLoYD+eOitcug4wtU9Fh1tt2vgBhskA==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.10.tgz", + "integrity": "sha512-sWp2g92u7xT4BojGbTXZ80iaSIaL6GAL0pwvM0CO/hb0nHSnABAqsH7AhnWGsGvXuEvbPr7blZylPaR9J+GSuQ==", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "faye-websocket": "0.11.4", "tslib": "^2.1.0" }, @@ -677,16 +674,49 @@ } }, "node_modules/@firebase/database-compat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.0.tgz", - "integrity": "sha512-2xlODKWwf/vNAxCmou0GFhymx2pqZKkhXMN9B5aiTjZ6+81sOxGim53ELY2lj+qKG2IvgiCYFc4X+ZJA2Ad5vg==", - "license": "Apache-2.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.1.tgz", + "integrity": "sha512-IsFivOjdE1GrjTeKoBU/ZMenESKDXidFDzZzHBPQ/4P20ptGdrl3oLlWrV/QJqJ9lND4IidE3z4Xr5JyfUW1vg==", + "dependencies": { + "@firebase/component": "0.6.11", + "@firebase/database": "1.0.10", + "@firebase/database-types": "1.0.7", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/@firebase/component": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", + "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", + "dependencies": { + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/@firebase/util": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", + "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/database": "1.0.9", - "@firebase/database-types": "1.0.6", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", "tslib": "^2.1.0" }, "engines": { @@ -694,19 +724,64 @@ } }, "node_modules/@firebase/database-types": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.6.tgz", - "integrity": "sha512-sMI7IynSZBsyGbUugc8PKE1jwKbnvaieAz/RxuM57PZQNCi6Rteiviwcw/jqZOX6igqYJwXWZ3UzKOZo2nUDRA==", - "license": "Apache-2.0", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.7.tgz", + "integrity": "sha512-I7zcLfJXrM0WM+ksFmFdAMdlq/DFmpeMNa+/GNsLyFo5u/lX5zzkPzGe3srVWqaBQBY5KprylDGxOsP6ETfL0A==", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.10.2" + } + }, + "node_modules/@firebase/database-types/node_modules/@firebase/util": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", + "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database/node_modules/@firebase/component": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", + "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", + "dependencies": { + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database/node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", "dependencies": { - "@firebase/app-types": "0.9.2", - "@firebase/util": "1.10.1" + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database/node_modules/@firebase/util": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", + "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@firebase/logger": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -719,6 +794,7 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", + "dev": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -4502,7 +4578,6 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -6171,8 +6246,7 @@ "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", - "license": "MIT" + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, "node_modules/http-proxy-agent": { "version": "5.0.0", @@ -11611,7 +11685,6 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -11625,7 +11698,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } From cc78a4afc85ff264d191678a297bc4ddc00c1f68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:11:34 +0000 Subject: [PATCH 212/323] build(deps): bump google-auth-library from 9.14.2 to 9.15.0 (#2773) --- package-lock.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 819c6ce751..47b303cc1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5425,10 +5425,9 @@ } }, "node_modules/google-auth-library": { - "version": "9.14.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.2.tgz", - "integrity": "sha512-R+FRIfk1GBo3RdlRYWPdwk8nmtVUOn6+BkDomAC46KoU8kzXzE1HLmOasSCbWUByMMAGkknVF0G5kQ69Vj7dlA==", - "license": "Apache-2.0", + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", + "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", From ef8b701d5a0d53f5ffbf1e9817706c9c71ab50fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:19:32 +0000 Subject: [PATCH 213/323] build(deps-dev): bump @firebase/auth-compat from 0.5.15 to 0.5.16 (#2776) --- package-lock.json | 94 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 47b303cc1b..a17e1a3fe2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -573,15 +573,14 @@ "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" }, "node_modules/@firebase/auth": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.0.tgz", - "integrity": "sha512-/O7UDWE5S5ux456fzNHSLx/0YN/Kykw/WyAzgDQ6wvkddZhSEmPX19EzxgsFldzhuFjsl5uOZTz8kzlosCiJjg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.1.tgz", + "integrity": "sha512-LX9N/Cf5Z35r5yqm2+5M3+2bRRe/+RFaa/+u4HDni7TA27C/Xm4XHLKcWcLg1BzjrS4zngSaBEOSODvp6RFOqQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -598,16 +597,15 @@ } }, "node_modules/@firebase/auth-compat": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.15.tgz", - "integrity": "sha512-jz6k1ridPiecKI8CBRiqCM6IMOhwYp2MD+YvoxnMiK8nQLSTm57GvHETlPNX3WlbyQnCjMCOvrAhe27whyxAEg==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.16.tgz", + "integrity": "sha512-YlYwJMBqAyv0ESy3jDUyshMhZlbUiwAm6B6+uUmigNDHU+uq7j4SFiDJEZlFFIz397yBzKn06SUdqutdQzGnCA==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@firebase/auth": "1.8.0", - "@firebase/auth-types": "0.12.2", - "@firebase/component": "0.6.10", - "@firebase/util": "1.10.1", + "@firebase/auth": "1.8.1", + "@firebase/auth-types": "0.12.3", + "@firebase/component": "0.6.11", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -617,14 +615,29 @@ "@firebase/app-compat": "0.x" } }, - "node_modules/@firebase/auth-compat/node_modules/@firebase/auth-types": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", - "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", + "node_modules/@firebase/auth-compat/node_modules/@firebase/component": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", + "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", "dev": true, - "peerDependencies": { - "@firebase/app-types": "0.x", - "@firebase/util": "1.x" + "dependencies": { + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/util": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", + "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@firebase/auth-interop-types": { @@ -642,6 +655,43 @@ "@firebase/util": "1.x" } }, + "node_modules/@firebase/auth/node_modules/@firebase/component": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", + "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", + "dev": true, + "dependencies": { + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/auth/node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/auth/node_modules/@firebase/util": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", + "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@firebase/component": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", From 90a8e5e6922c030a16c2b4af284ba12084cfdaa0 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 20 Nov 2024 13:37:39 -0500 Subject: [PATCH 214/323] [chore] Release 13.0.1 (#2780) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c9e81cd21..e94d4d44f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.0.0", + "version": "13.0.1", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From a1ba932f0e2c69237d9d4261bde9c61fb7c6e6c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:31:23 -0500 Subject: [PATCH 215/323] build(deps-dev): bump @microsoft/api-extractor from 7.47.11 to 7.48.0 (#2788) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.47.11 to 7.48.0. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.48.0/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 121 +++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index a17e1a3fe2..c2235cda82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.0.0", + "version": "13.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.0.0", + "version": "13.0.1", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -1228,19 +1228,18 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.47.11", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.47.11.tgz", - "integrity": "sha512-lrudfbPub5wzBhymfFtgZKuBvXxoSIAdrvS2UbHjoMT2TjIEddq6Z13pcve7A03BAouw0x8sW8G4txdgfiSwpQ==", + "version": "7.48.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.48.0.tgz", + "integrity": "sha512-FMFgPjoilMUWeZXqYRlJ3gCVRhB7WU/HN88n8OLqEsmsG4zBdX/KQdtJfhq95LQTQ++zfu0Em1LLb73NqRCLYQ==", "dev": true, - "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.29.8", - "@microsoft/tsdoc": "~0.15.0", - "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.9.0", + "@microsoft/api-extractor-model": "7.30.0", + "@microsoft/tsdoc": "~0.15.1", + "@microsoft/tsdoc-config": "~0.17.1", + "@rushstack/node-core-library": "5.10.0", "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.14.2", - "@rushstack/ts-command-line": "4.23.0", + "@rushstack/terminal": "0.14.3", + "@rushstack/ts-command-line": "4.23.1", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1253,30 +1252,27 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.29.8", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.29.8.tgz", - "integrity": "sha512-t3Z/xcO6TRbMcnKGVMs4uMzv/gd5j0NhMiJIGjD4cJMeFJ1Hf8wnLSx37vxlRlL0GWlGJhnFgxvnaL6JlS+73g==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.0.tgz", + "integrity": "sha512-26/LJZBrsWDKAkOWRiQbdVgcfd1F3nyJnAiJzsAgpouPk7LtOIj7PK9aJtBaw/pUXrkotEg27RrT+Jm/q0bbug==", "dev": true, - "license": "MIT", "dependencies": { - "@microsoft/tsdoc": "~0.15.0", - "@microsoft/tsdoc-config": "~0.17.0", - "@rushstack/node-core-library": "5.9.0" + "@microsoft/tsdoc": "~0.15.1", + "@microsoft/tsdoc-config": "~0.17.1", + "@rushstack/node-core-library": "5.10.0" } }, "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", - "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true, - "license": "MIT" + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", + "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "dev": true }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", - "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.0.tgz", + "integrity": "sha512-2pPLCuS/3x7DCd7liZkqOewGM0OzLyCacdvOe8j6Yrx9LkETGnxul1t7603bIaB8nUAooORcct9fFDOQMbWAgw==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", @@ -1301,7 +1297,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -1314,18 +1309,16 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@microsoft/tsdoc": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", - "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true, - "license": "MIT" + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", + "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "dev": true }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", - "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.0.tgz", + "integrity": "sha512-2pPLCuS/3x7DCd7liZkqOewGM0OzLyCacdvOe8j6Yrx9LkETGnxul1t7603bIaB8nUAooORcct9fFDOQMbWAgw==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", @@ -1346,13 +1339,12 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.0.tgz", - "integrity": "sha512-jYREBtsxduPV6ptNq8jOKp9+yx0ld1Tb/Tkdnlj8gTjazl1sF3DwX2VbluyYrNd0meWIL0bNeer7WDf5tKFjaQ==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.1.tgz", + "integrity": "sha512-40jTmYoiu/xlIpkkRsVfENtBq4CW3R4azbL0Vmda+fMwHWqss6wwf/Cy/UJmMqIzpfYc2OTnjYP1ZLD3CmyeCA==", "dev": true, - "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.14.2", + "@rushstack/terminal": "0.14.3", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1363,7 +1355,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -1397,24 +1388,22 @@ "license": "MIT" }, "node_modules/@microsoft/tsdoc-config": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz", - "integrity": "sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz", + "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==", "dev": true, - "license": "MIT", "dependencies": { - "@microsoft/tsdoc": "0.15.0", + "@microsoft/tsdoc": "0.15.1", "ajv": "~8.12.0", "jju": "~1.4.0", "resolve": "~1.22.2" } }, "node_modules/@microsoft/tsdoc-config/node_modules/@microsoft/tsdoc": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz", - "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==", - "dev": true, - "license": "MIT" + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", + "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "dev": true }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -1584,13 +1573,12 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.2.tgz", - "integrity": "sha512-2fC1wqu1VCExKC0/L+0noVcFQEXEnoBOtCIex1TOjBzEDWcw8KzJjjj7aTP6mLxepG0XIyn9OufeFb6SFsa+sg==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.3.tgz", + "integrity": "sha512-csXbZsAdab/v8DbU1sz7WC2aNaKArcdS/FPmXMOXEj/JBBZMvDK0+1b4Qao0kkG0ciB1Qe86/Mb68GjH6/TnMw==", "dev": true, - "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.9.0", + "@rushstack/node-core-library": "5.10.0", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -1603,11 +1591,10 @@ } }, "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.9.0.tgz", - "integrity": "sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.0.tgz", + "integrity": "sha512-2pPLCuS/3x7DCd7liZkqOewGM0OzLyCacdvOe8j6Yrx9LkETGnxul1t7603bIaB8nUAooORcct9fFDOQMbWAgw==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", @@ -1632,7 +1619,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -2355,7 +2341,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -2372,7 +2357,6 @@ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", "dev": true, - "license": "MIT", "peerDependencies": { "ajv": "^8.5.0" }, @@ -2387,7 +2371,6 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -7280,8 +7263,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -9778,7 +9760,6 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } From de540fc33aab264e67d2a15c1278bc1b4634b88d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:35:06 +0000 Subject: [PATCH 216/323] build(deps-dev): bump @firebase/app-compat from 0.2.45 to 0.2.46 (#2784) --- package-lock.json | 181 ++++------------------------------------------ 1 file changed, 16 insertions(+), 165 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2235cda82..e70b559df9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -529,15 +529,14 @@ } }, "node_modules/@firebase/app": { - "version": "0.10.15", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.15.tgz", - "integrity": "sha512-he6qlG3pmwL+LHdG/BrSMBQeJzzutciq4fpXN3lGa1uSwYSijJ24VtakS/bP2X9SiDf8jGywJ4u+OgXAenJsNg==", + "version": "0.10.16", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.16.tgz", + "integrity": "sha512-SUati2qH48gvVGnSsqMkZr1Iq7No52a3tJQ4itboSTM89Erezmw3v1RsfVymrDze9+KiOLmBpvLNKSvheITFjg==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -551,16 +550,15 @@ "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==" }, "node_modules/@firebase/app-compat": { - "version": "0.2.45", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.45.tgz", - "integrity": "sha512-5rYbXq1ndtMTg+07oH4WrkYuP+NZq61uzVwW1hlmybp/gr4cXq2SfaP9fc6/9IzTKmu3dh3H0fjj++HG7Z7o/w==", + "version": "0.2.46", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.46.tgz", + "integrity": "sha512-9hSHWE5LMqtKIm13CnH5OZeMPbkVV3y5vgNZ5EMFHcG2ceRrncyNjG9No5XfWQw8JponZdGs4HlE4aMD/jxcFA==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@firebase/app": "0.10.15", - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/app": "0.10.16", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -615,31 +613,6 @@ "@firebase/app-compat": "0.x" } }, - "node_modules/@firebase/auth-compat/node_modules/@firebase/component": { - "version": "0.6.11", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", - "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", - "dev": true, - "dependencies": { - "@firebase/util": "1.10.2", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/auth-compat/node_modules/@firebase/util": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", - "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@firebase/auth-interop-types": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", @@ -655,11 +628,10 @@ "@firebase/util": "1.x" } }, - "node_modules/@firebase/auth/node_modules/@firebase/component": { + "node_modules/@firebase/component": { "version": "0.6.11", "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", - "dev": true, "dependencies": { "@firebase/util": "1.10.2", "tslib": "^2.1.0" @@ -668,44 +640,6 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/auth/node_modules/@firebase/logger": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", - "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/auth/node_modules/@firebase/util": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", - "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/component": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", - "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@firebase/util": "1.10.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@firebase/database": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.10.tgz", @@ -739,40 +673,6 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/database-compat/node_modules/@firebase/component": { - "version": "0.6.11", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", - "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", - "dependencies": { - "@firebase/util": "1.10.2", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database-compat/node_modules/@firebase/logger": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", - "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database-compat/node_modules/@firebase/util": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", - "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@firebase/database-types": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.7.tgz", @@ -782,30 +682,7 @@ "@firebase/util": "1.10.2" } }, - "node_modules/@firebase/database-types/node_modules/@firebase/util": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", - "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database/node_modules/@firebase/component": { - "version": "0.6.11", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", - "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", - "dependencies": { - "@firebase/util": "1.10.2", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database/node_modules/@firebase/logger": { + "node_modules/@firebase/logger": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", @@ -816,7 +693,7 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/database/node_modules/@firebase/util": { + "node_modules/@firebase/util": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", @@ -827,32 +704,6 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/logger": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", - "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/util": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", - "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@google-cloud/firestore": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.10.0.tgz", From 1772ac7b2921febc232e69e78cc1aadb4f6c3487 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:38:57 +0000 Subject: [PATCH 217/323] build(deps): bump @types/node from 22.9.0 to 22.10.0 (#2790) --- package-lock.json | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index e70b559df9..30688d5ee9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1758,12 +1758,11 @@ } }, "node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", - "license": "MIT", + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", "dependencies": { - "undici-types": "~6.19.8" + "undici-types": "~6.20.0" } }, "node_modules/@types/qs": { @@ -11243,10 +11242,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" }, "node_modules/unique-stream": { "version": "2.3.1", From 83585498d9bd48b9ba715a882a3b9c951ca8422d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:43:09 +0000 Subject: [PATCH 218/323] build(deps-dev): bump @types/mocha from 10.0.9 to 10.0.10 (#2786) --- package-lock.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30688d5ee9..07802665a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1740,11 +1740,10 @@ "license": "MIT" }, "node_modules/@types/mocha": { - "version": "10.0.9", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.9.tgz", - "integrity": "sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==", - "dev": true, - "license": "MIT" + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true }, "node_modules/@types/nock": { "version": "11.1.0", From 79b78c47b5971d00193e1db268225eb696559dcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 09:58:25 -0500 Subject: [PATCH 219/323] build(deps): bump @types/node from 22.10.0 to 22.10.1 (#2798) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.10.0 to 22.10.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 07802665a2..d2286c76df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1757,9 +1757,9 @@ } }, "node_modules/@types/node": { - "version": "22.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", - "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dependencies": { "undici-types": "~6.20.0" } From 69d6494f590ac8732d7a4cd46e99b089f8bf6c4a Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 5 Dec 2024 14:53:47 -0500 Subject: [PATCH 220/323] chore: Add firebaseAdminVersion to Firestore settings (#2795) * chore: Add firebaseAdminVersion to Firestore options * bump @google-cloud/firestore to v7.11.0 --- package-lock.json | 9 ++++----- package.json | 2 +- src/firestore/firestore-internal.ts | 22 ++++++++++++++++------ test/unit/firestore/firestore.spec.ts | 21 ++++++++++++++++++--- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index d2286c76df..7c63c94dc7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,7 @@ "node": ">=18" }, "optionalDependencies": { - "@google-cloud/firestore": "^7.10.0", + "@google-cloud/firestore": "^7.11.0", "@google-cloud/storage": "^7.14.0" } }, @@ -705,10 +705,9 @@ } }, "node_modules/@google-cloud/firestore": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.10.0.tgz", - "integrity": "sha512-VFNhdHvfnmqcHHs6YhmSNHHxQqaaD64GwiL0c+e1qz85S8SWZPC2XFRf8p9yHRTF40Kow424s1KBU9f0fdQa+Q==", - "license": "Apache-2.0", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.0.tgz", + "integrity": "sha512-88uZ+jLsp1aVMj7gh3EKYH1aulTAMFAp8sH/v5a9w8q8iqSG27RiWLoxSAFr/XocZ9hGiWH1kEnBw+zl3xAgNA==", "optional": true, "dependencies": { "@opentelemetry/api": "^1.3.0", diff --git a/package.json b/package.json index e94d4d44f9..49e9840509 100644 --- a/package.json +++ b/package.json @@ -216,7 +216,7 @@ "uuid": "^11.0.2" }, "optionalDependencies": { - "@google-cloud/firestore": "^7.10.0", + "@google-cloud/firestore": "^7.11.0", "@google-cloud/storage": "^7.14.0" }, "devDependencies": { diff --git a/src/firestore/firestore-internal.ts b/src/firestore/firestore-internal.ts index 148d61e9f2..65cb123d85 100644 --- a/src/firestore/firestore-internal.ts +++ b/src/firestore/firestore-internal.ts @@ -113,7 +113,7 @@ export function getFirestoreOptions(app: App, firestoreSettings?: FirestoreSetti const projectId: string | null = utils.getExplicitProjectId(app); const credential = app.options.credential; // eslint-disable-next-line @typescript-eslint/no-var-requires - const { version: firebaseVersion } = require('../../package.json'); + const sdkVersion = utils.getSdkVersion(); const preferRest = firestoreSettings?.preferRest; if (credential instanceof ServiceAccountCredential) { return { @@ -124,7 +124,8 @@ export function getFirestoreOptions(app: App, firestoreSettings?: FirestoreSetti // When the SDK is initialized with ServiceAccountCredentials an explicit projectId is // guaranteed to be available. projectId: projectId!, - firebaseVersion, + firebaseVersion: sdkVersion, + firebaseAdminVersion: sdkVersion, preferRest, }; } else if (isApplicationDefault(app.options.credential)) { @@ -132,8 +133,17 @@ export function getFirestoreOptions(app: App, firestoreSettings?: FirestoreSetti // If an explicit project ID is not available, let Firestore client discover one from the // environment. This prevents the users from having to set GOOGLE_CLOUD_PROJECT in GCP runtimes. return validator.isNonEmptyString(projectId) - ? { projectId, firebaseVersion, preferRest } - : { firebaseVersion, preferRest }; + ? { + projectId, + firebaseVersion: sdkVersion, + firebaseAdminVersion: sdkVersion, + preferRest + } + : { + firebaseVersion: sdkVersion, + firebaseAdminVersion: sdkVersion, + preferRest + }; } throw new FirebaseFirestoreError({ @@ -155,8 +165,8 @@ function initFirestore(app: App, databaseId: string, firestoreSettings?: Firesto throw new FirebaseFirestoreError({ code: 'missing-dependencies', message: 'Failed to import the Cloud Firestore client library for Node.js. ' - + 'Make sure to install the "@google-cloud/firestore" npm package. ' - + `Original error: ${err}`, + + 'Make sure to install the "@google-cloud/firestore" npm package. ' + + `Original error: ${err}`, }); } diff --git a/test/unit/firestore/firestore.spec.ts b/test/unit/firestore/firestore.spec.ts index 146ba2c640..22f8f4d8df 100644 --- a/test/unit/firestore/firestore.spec.ts +++ b/test/unit/firestore/firestore.spec.ts @@ -27,6 +27,7 @@ import { RefreshTokenCredential } from '../../../src/app/credential-internal'; import { FirestoreService, getFirestoreOptions } from '../../../src/firestore/firestore-internal'; +import { getSdkVersion } from '../../../src/utils/index'; import { DEFAULT_DATABASE_ID } from '@google-cloud/firestore/build/src/path'; describe('Firestore', () => { @@ -44,7 +45,7 @@ describe('Firestore', () => { + 'credentials to use Cloud Firestore API.'; // eslint-disable-next-line @typescript-eslint/no-var-requires - const { version: firebaseVersion } = require('../../../package.json'); + const sdkVersion = getSdkVersion(); const defaultCredentialApps = [ { name: 'ComputeEngineCredentials', @@ -191,13 +192,27 @@ describe('Firestore', () => { describe('options.firebaseVersion', () => { it('should return firebaseVersion when using credential with service account certificate', () => { const options = getFirestoreOptions(mockApp); - expect(options.firebaseVersion).to.equal(firebaseVersion); + expect(options.firebaseVersion).to.equal(sdkVersion); }); defaultCredentialApps.forEach((config) => { it(`should return firebaseVersion when using default ${config.name}`, () => { const options = getFirestoreOptions(config.app); - expect(options.firebaseVersion).to.equal(firebaseVersion); + expect(options.firebaseVersion).to.equal(sdkVersion); + }); + }); + }); + + describe('options.firebaseAdminVersion', () => { + it('should return firebaseAdminVersion when using credential with service account certificate', () => { + const options = getFirestoreOptions(mockApp); + expect(options.firebaseAdminVersion).to.equal(sdkVersion); + }); + + defaultCredentialApps.forEach((config) => { + it(`should return firebaseAdminVersion when using default ${config.name}`, () => { + const options = getFirestoreOptions(config.app); + expect(options.firebaseAdminVersion).to.equal(sdkVersion); }); }); }); From 86094a75f2966814de5a047940a6f716a6eef94c Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 12 Dec 2024 11:30:27 -0500 Subject: [PATCH 221/323] fix(auth): Fix credentials issue in createToken() when using ADC (#2801) * fix(auth): Fix service account issue in createToken() using ADC * fix tests --- src/utils/crypto-signer.ts | 23 ++++++++++++++++------- test/unit/utils/crypto-signer.spec.ts | 12 ++++++------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/utils/crypto-signer.ts b/src/utils/crypto-signer.ts index 3123cee209..f2b8bcbafd 100644 --- a/src/utils/crypto-signer.ts +++ b/src/utils/crypto-signer.ts @@ -22,6 +22,7 @@ import { AuthorizedHttpClient, HttpRequestConfig, HttpClient, RequestResponseErr import { Algorithm } from 'jsonwebtoken'; import { ErrorInfo } from '../utils/error'; +import * as utils from '../utils/index'; import * as validator from '../utils/validator'; const ALGORITHM_RS256: Algorithm = 'RS256' as const; @@ -105,22 +106,23 @@ export class IAMSigner implements CryptoSigner { private readonly httpClient: AuthorizedHttpClient; private serviceAccountId?: string; + private app?: App; - constructor(httpClient: AuthorizedHttpClient, serviceAccountId?: string) { + constructor(httpClient: AuthorizedHttpClient, app?: App) { if (!httpClient) { throw new CryptoSignerError({ code: CryptoSignerErrorCode.INVALID_ARGUMENT, message: 'INTERNAL ASSERT: Must provide a HTTP client to initialize IAMSigner.', }); } - if (typeof serviceAccountId !== 'undefined' && !validator.isNonEmptyString(serviceAccountId)) { + if (app && (typeof app !== 'object' || app === null || !('options' in app))) { throw new CryptoSignerError({ code: CryptoSignerErrorCode.INVALID_ARGUMENT, - message: 'INTERNAL ASSERT: Service account ID must be undefined or a non-empty string.', + message: 'INTERNAL ASSERT: Must provide a valid Firebase app instance.', }); } this.httpClient = httpClient; - this.serviceAccountId = serviceAccountId; + this.app = app; } /** @@ -152,9 +154,16 @@ export class IAMSigner implements CryptoSigner { /** * @inheritDoc */ - public getAccountId(): Promise { + public async getAccountId(): Promise { if (validator.isNonEmptyString(this.serviceAccountId)) { - return Promise.resolve(this.serviceAccountId); + return this.serviceAccountId; + } + if (this.app) { + const accountId = await utils.findServiceAccountEmail(this.app!) + if (accountId) { + this.serviceAccountId = accountId; + return accountId; + } } const request: HttpRequestConfig = { method: 'GET', @@ -197,7 +206,7 @@ export function cryptoSignerFromApp(app: App): CryptoSigner { return new ServiceAccountSigner(credential); } - return new IAMSigner(new AuthorizedHttpClient(app as FirebaseApp), app.options.serviceAccountId); + return new IAMSigner(new AuthorizedHttpClient(app as FirebaseApp), app); } /** diff --git a/test/unit/utils/crypto-signer.spec.ts b/test/unit/utils/crypto-signer.spec.ts index 024be3ecbe..cf38160a2f 100644 --- a/test/unit/utils/crypto-signer.spec.ts +++ b/test/unit/utils/crypto-signer.spec.ts @@ -103,7 +103,7 @@ describe('CryptoSigner', () => { const input = Buffer.from('input'); const signRequest = { method: 'POST', - url: 'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/test-service-account:signBlob', + url: 'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/foo@project_id.iam.gserviceaccount.com:signBlob', headers: { Authorization: `Bearer ${mockAccessToken}`, 'X-Goog-Api-Client': getMetricsHeader() @@ -120,7 +120,7 @@ describe('CryptoSigner', () => { const expectedResult = utils.responseFrom(response); stub = sinon.stub(HttpClient.prototype, 'send').resolves(expectedResult); const requestHandler = new AuthorizedHttpClient(mockApp); - const signer = new IAMSigner(requestHandler, 'test-service-account'); + const signer = new IAMSigner(requestHandler, mockApp); return signer.sign(input).then((signature) => { expect(signature.toString('base64')).to.equal(response.signedBlob); expect(stub).to.have.been.calledOnce.and.calledWith(signRequest); @@ -136,7 +136,7 @@ describe('CryptoSigner', () => { }); stub = sinon.stub(HttpClient.prototype, 'send').rejects(expectedResult); const requestHandler = new AuthorizedHttpClient(mockApp); - const signer = new IAMSigner(requestHandler, 'test-service-account'); + const signer = new IAMSigner(requestHandler, mockApp); return signer.sign(input).catch((err) => { expect(err).to.be.instanceOf(CryptoSignerError); expect(err.message).to.equal('Server responded with status 500.'); @@ -145,9 +145,9 @@ describe('CryptoSigner', () => { }); }); - it('should return the explicitly specified service account', () => { - const signer = new IAMSigner(new AuthorizedHttpClient(mockApp), 'test-service-account'); - return signer.getAccountId().should.eventually.equal('test-service-account'); + it('should return the service account from the app', () => { + const signer = new IAMSigner(new AuthorizedHttpClient(mockApp), mockApp); + return signer.getAccountId().should.eventually.equal('foo@project_id.iam.gserviceaccount.com'); }); }); From ebd2164d68d97a51d1dc4f0375d498c771c6cf96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:35:51 +0000 Subject: [PATCH 222/323] build(deps): bump @fastify/busboy from 3.0.0 to 3.1.0 (#2805) --- package-lock.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7c63c94dc7..18f8d480df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -503,10 +503,9 @@ } }, "node_modules/@fastify/busboy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.0.0.tgz", - "integrity": "sha512-83rnH2nCvclWaPQQKvkJ2pdOjG4TZyEVuFDnlOF6KP08lDaaceVyw/W63mDuafQT+MKHCvXIPpE5uYWeM0rT4w==", - "license": "MIT" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.0.tgz", + "integrity": "sha512-yHmUtGwEbW6HsKpPqT140/L6GpHtquHogRLgtanJFep3UAfDkE0fQfC49U+F9irCAoJVlv3M7VSp4rrtO4LnfA==" }, "node_modules/@firebase/api-documenter": { "version": "0.4.0", From cb374ca396995d54acf25d3eb34da43eb313093a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 11:32:10 -0500 Subject: [PATCH 223/323] build(deps-dev): bump @microsoft/api-extractor from 7.48.0 to 7.48.1 (#2810) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.48.0 to 7.48.1. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.48.1/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 18f8d480df..aa172cbab7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1077,18 +1077,18 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.48.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.48.0.tgz", - "integrity": "sha512-FMFgPjoilMUWeZXqYRlJ3gCVRhB7WU/HN88n8OLqEsmsG4zBdX/KQdtJfhq95LQTQ++zfu0Em1LLb73NqRCLYQ==", + "version": "7.48.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.48.1.tgz", + "integrity": "sha512-HN9Osa1WxqLM66RaqB5nPAadx+nTIQmY/XtkFdaJvusjG8Tus++QqZtD7KPZDSkhEMGHsYeSyeU8qUzCDUXPjg==", "dev": true, "dependencies": { - "@microsoft/api-extractor-model": "7.30.0", + "@microsoft/api-extractor-model": "7.30.1", "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.10.0", + "@rushstack/node-core-library": "5.10.1", "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.14.3", - "@rushstack/ts-command-line": "4.23.1", + "@rushstack/terminal": "0.14.4", + "@rushstack/ts-command-line": "4.23.2", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1101,14 +1101,14 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.0.tgz", - "integrity": "sha512-26/LJZBrsWDKAkOWRiQbdVgcfd1F3nyJnAiJzsAgpouPk7LtOIj7PK9aJtBaw/pUXrkotEg27RrT+Jm/q0bbug==", + "version": "7.30.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.1.tgz", + "integrity": "sha512-CTS2PlASJHxVY8hqHORVb1HdECWOEMcMnM6/kDkPr0RZapAFSIHhg9D4jxuE8g+OWYHtPc10LCpmde5pylTRlA==", "dev": true, "dependencies": { "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.10.0" + "@rushstack/node-core-library": "5.10.1" } }, "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { @@ -1118,9 +1118,9 @@ "dev": true }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.0.tgz", - "integrity": "sha512-2pPLCuS/3x7DCd7liZkqOewGM0OzLyCacdvOe8j6Yrx9LkETGnxul1t7603bIaB8nUAooORcct9fFDOQMbWAgw==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz", + "integrity": "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==", "dev": true, "dependencies": { "ajv": "~8.13.0", @@ -1164,9 +1164,9 @@ "dev": true }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.0.tgz", - "integrity": "sha512-2pPLCuS/3x7DCd7liZkqOewGM0OzLyCacdvOe8j6Yrx9LkETGnxul1t7603bIaB8nUAooORcct9fFDOQMbWAgw==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz", + "integrity": "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==", "dev": true, "dependencies": { "ajv": "~8.13.0", @@ -1188,12 +1188,12 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.1.tgz", - "integrity": "sha512-40jTmYoiu/xlIpkkRsVfENtBq4CW3R4azbL0Vmda+fMwHWqss6wwf/Cy/UJmMqIzpfYc2OTnjYP1ZLD3CmyeCA==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.2.tgz", + "integrity": "sha512-JJ7XZX5K3ThBBva38aomgsPv1L7FV6XmSOcR6HtM7HDFZJkepqT65imw26h9ggGqMjsY0R9jcl30tzKcVj9aOQ==", "dev": true, "dependencies": { - "@rushstack/terminal": "0.14.3", + "@rushstack/terminal": "0.14.4", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1422,12 +1422,12 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.3.tgz", - "integrity": "sha512-csXbZsAdab/v8DbU1sz7WC2aNaKArcdS/FPmXMOXEj/JBBZMvDK0+1b4Qao0kkG0ciB1Qe86/Mb68GjH6/TnMw==", + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.4.tgz", + "integrity": "sha512-NxACqERW0PHq8Rpq1V6v5iTHEwkRGxenjEW+VWqRYQ8T9puUzgmGHmEZUaUEDHAe9Qyvp0/Ew04sAiQw9XjhJg==", "dev": true, "dependencies": { - "@rushstack/node-core-library": "5.10.0", + "@rushstack/node-core-library": "5.10.1", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -1440,9 +1440,9 @@ } }, "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.0.tgz", - "integrity": "sha512-2pPLCuS/3x7DCd7liZkqOewGM0OzLyCacdvOe8j6Yrx9LkETGnxul1t7603bIaB8nUAooORcct9fFDOQMbWAgw==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz", + "integrity": "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==", "dev": true, "dependencies": { "ajv": "~8.13.0", From 486ab165e6e9e94e8062d36b92e2c96464527cff Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 19 Dec 2024 12:31:24 -0500 Subject: [PATCH 224/323] [chore] Release 13.0.2 (#2813) Includes #2801 (fixes: #2800) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 49e9840509..c07a06424e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.0.1", + "version": "13.0.2", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 16c877c7cc3e6a3c7b8809706354f4dcd7e42818 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:35:52 +0000 Subject: [PATCH 225/323] build(deps): bump @types/node from 22.10.1 to 22.10.2 (#2811) --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa172cbab7..c446c8b05b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.0.1", + "version": "13.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.0.1", + "version": "13.0.2", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -1755,9 +1755,9 @@ } }, "node_modules/@types/node": { - "version": "22.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", - "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", "dependencies": { "undici-types": "~6.20.0" } From 10b880f12e6f83daf37ba6d72b59bb108ef67e3f Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 19 Dec 2024 12:46:39 -0500 Subject: [PATCH 226/323] Adding delayed response message for holidays (#2814) --- .github/ISSUE_TEMPLATE/general-bug-report.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/general-bug-report.md b/.github/ISSUE_TEMPLATE/general-bug-report.md index 82308572d5..3a5c8d7741 100644 --- a/.github/ISSUE_TEMPLATE/general-bug-report.md +++ b/.github/ISSUE_TEMPLATE/general-bug-report.md @@ -7,6 +7,11 @@ assignees: '' --- +--- +**Thank you for submitting your issue. We are operating at reduced capacity from Dec 23 2024 to Jan 6 2022. Please expect delayed responses. For more urgent requests please reach us via our support channels https://firebase.google.com/support** + +--- + ### [READ] Step 1: Are you in the right place? * For issues related to __the code in this repository__ file a Github issue. From e8db019f5fa99fa92a98e2c27ae811e10400be83 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:35:24 -0500 Subject: [PATCH 227/323] chore: Fix holiday template date (#2815) --- .github/ISSUE_TEMPLATE/general-bug-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/general-bug-report.md b/.github/ISSUE_TEMPLATE/general-bug-report.md index 3a5c8d7741..1f6cea8aac 100644 --- a/.github/ISSUE_TEMPLATE/general-bug-report.md +++ b/.github/ISSUE_TEMPLATE/general-bug-report.md @@ -8,7 +8,7 @@ assignees: '' --- --- -**Thank you for submitting your issue. We are operating at reduced capacity from Dec 23 2024 to Jan 6 2022. Please expect delayed responses. For more urgent requests please reach us via our support channels https://firebase.google.com/support** +**Thank you for submitting your issue. We are operating at reduced capacity from Dec 23 2024 to Jan 6 2025. Please expect delayed responses. For more urgent requests please reach us via our support channels https://firebase.google.com/support** --- From 94e41063e3d9840078b59958c45fb2fbcfd41307 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:00:30 -0500 Subject: [PATCH 228/323] chore: Revert holiday message (#2827) --- .github/ISSUE_TEMPLATE/general-bug-report.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/general-bug-report.md b/.github/ISSUE_TEMPLATE/general-bug-report.md index 1f6cea8aac..82308572d5 100644 --- a/.github/ISSUE_TEMPLATE/general-bug-report.md +++ b/.github/ISSUE_TEMPLATE/general-bug-report.md @@ -7,11 +7,6 @@ assignees: '' --- ---- -**Thank you for submitting your issue. We are operating at reduced capacity from Dec 23 2024 to Jan 6 2025. Please expect delayed responses. For more urgent requests please reach us via our support channels https://firebase.google.com/support** - ---- - ### [READ] Step 1: Are you in the right place? * For issues related to __the code in this repository__ file a Github issue. From 8040a820e8a37a2f6e3f43746e09daec26e1fadb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 17:17:28 +0000 Subject: [PATCH 229/323] build(deps-dev): bump @firebase/app-compat from 0.2.46 to 0.2.48 (#2834) --- package-lock.json | 78 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index c446c8b05b..f2353fd4a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -528,14 +528,15 @@ } }, "node_modules/@firebase/app": { - "version": "0.10.16", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.16.tgz", - "integrity": "sha512-SUati2qH48gvVGnSsqMkZr1Iq7No52a3tJQ4itboSTM89Erezmw3v1RsfVymrDze9+KiOLmBpvLNKSvheITFjg==", + "version": "0.10.18", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.18.tgz", + "integrity": "sha512-VuqEwD/QRisKd/zsFsqgvSAx34mZ3WEF47i97FD6Vw4GWAhdjepYf0Hmi6K0b4QMSgWcv/x0C30Slm5NjjERXg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.11", + "@firebase/component": "0.6.12", "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.2", + "@firebase/util": "1.10.3", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -549,15 +550,43 @@ "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==" }, "node_modules/@firebase/app-compat": { - "version": "0.2.46", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.46.tgz", - "integrity": "sha512-9hSHWE5LMqtKIm13CnH5OZeMPbkVV3y5vgNZ5EMFHcG2ceRrncyNjG9No5XfWQw8JponZdGs4HlE4aMD/jxcFA==", + "version": "0.2.48", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.48.tgz", + "integrity": "sha512-wVNU1foBIaJncUmiALyRxhHHHC3ZPMLIETTAk+2PG87eP9B/IDBsYUiTpHyboDPEI8CgBPat/zN2v+Snkz6lBw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@firebase/app": "0.10.16", - "@firebase/component": "0.6.11", + "@firebase/app": "0.10.18", + "@firebase/component": "0.6.12", "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.2", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/@firebase/component": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", + "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app-compat/node_modules/@firebase/util": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", + "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { "tslib": "^2.1.0" }, "engines": { @@ -569,6 +598,33 @@ "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" }, + "node_modules/@firebase/app/node_modules/@firebase/component": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", + "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/app/node_modules/@firebase/util": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", + "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@firebase/auth": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.1.tgz", From 8dda32dd8018cd8a712e65c6849d1bb7d253f208 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 17:22:02 +0000 Subject: [PATCH 230/323] build(deps): bump undici in /.github/actions/send-email (#2837) --- .github/actions/send-email/package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 2963ba307e..696d61945b 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -168,9 +168,10 @@ } }, "node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "version": "5.28.5", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz", + "integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==", + "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" }, From 7c54c08454fd5ee921d73c63b1cf4a1047e2f1a0 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 3 Feb 2025 18:49:39 -0500 Subject: [PATCH 231/323] chore: Update postcheck typescript version (#2840) Update typescript version in the post-check test. We use it to verify the build artifacts in staging. --- test/integration/postcheck/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/postcheck/package.json b/test/integration/postcheck/package.json index 2b7f8ac6f0..14e4f47125 100644 --- a/test/integration/postcheck/package.json +++ b/test/integration/postcheck/package.json @@ -14,6 +14,6 @@ "chai": "^4.2.0", "mocha": "^8.0.0", "ts-node": "^10.8.1", - "typescript": "^4.6.4" + "typescript": "^5.5.4" } } From 379bcff10c6e247e6c216d9db45c431e9a9d6d29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Feb 2025 17:54:05 +0000 Subject: [PATCH 232/323] build(deps): bump @fastify/busboy from 3.1.0 to 3.1.1 (#2817) --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f2353fd4a0..be856b7012 100644 --- a/package-lock.json +++ b/package-lock.json @@ -503,9 +503,10 @@ } }, "node_modules/@fastify/busboy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.0.tgz", - "integrity": "sha512-yHmUtGwEbW6HsKpPqT140/L6GpHtquHogRLgtanJFep3UAfDkE0fQfC49U+F9irCAoJVlv3M7VSp4rrtO4LnfA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz", + "integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==", + "license": "MIT" }, "node_modules/@firebase/api-documenter": { "version": "0.4.0", From 0ffa5fc61ec7b54479a7e3bb5405f7f813fc6cde Mon Sep 17 00:00:00 2001 From: Liubin Jiang <56564857+Xiaoshouzi-gh@users.noreply.github.com> Date: Tue, 4 Feb 2025 11:13:21 -0800 Subject: [PATCH 233/323] feat(auth): Added FDL deprecation support for Firebase Auth (#2752) Added linkDomain support for ActionCodeSettings deprecating dynamicLinkDomain. Added mobileLinksConfig support for updating project configs --------- Co-authored-by: Pavan Shankar --- etc/firebase-admin.auth.api.md | 17 ++ src/auth/action-code-settings-builder.ts | 22 ++ src/auth/auth-config.ts | 54 ++++ src/auth/base-auth.ts | 6 +- src/auth/index.ts | 2 + src/auth/project-config.ts | 30 ++ src/utils/error.ts | 7 + test/integration/auth.spec.ts | 267 +++++++++++++++++- .../auth/action-code-settings-builder.spec.ts | 21 ++ test/unit/auth/auth-api-request.spec.ts | 1 + test/unit/auth/auth-config.spec.ts | 29 ++ test/unit/auth/auth.spec.ts | 1 + test/unit/auth/project-config.spec.ts | 33 ++- 13 files changed, 484 insertions(+), 6 deletions(-) diff --git a/etc/firebase-admin.auth.api.md b/etc/firebase-admin.auth.api.md index 7962ca5baa..8713b1bda7 100644 --- a/etc/firebase-admin.auth.api.md +++ b/etc/firebase-admin.auth.api.md @@ -13,11 +13,13 @@ export interface ActionCodeSettings { installApp?: boolean; minimumVersion?: string; }; + // @deprecated dynamicLinkDomain?: string; handleCodeInApp?: boolean; iOS?: { bundleId: string; }; + linkDomain?: string; url: string; } @@ -221,6 +223,11 @@ export class AuthClientErrorCode { message: string; }; // (undocumented) + static INVALID_HOSTING_LINK_DOMAIN: { + code: string; + message: string; + }; + // (undocumented) static INVALID_ID_TOKEN: { code: string; message: string; @@ -757,6 +764,14 @@ export interface ListUsersResult { users: UserRecord[]; } +// @public +export interface MobileLinksConfig { + domain?: MobileLinksDomain; +} + +// @public +export type MobileLinksDomain = 'HOSTING_DOMAIN' | 'FIREBASE_DYNAMIC_LINK_DOMAIN'; + // @public export interface MultiFactorConfig { factorIds?: AuthFactorType[]; @@ -847,6 +862,7 @@ export class PhoneMultiFactorInfo extends MultiFactorInfo { // @public export class ProjectConfig { readonly emailPrivacyConfig?: EmailPrivacyConfig; + readonly mobileLinksConfig?: MobileLinksConfig; get multiFactorConfig(): MultiFactorConfig | undefined; readonly passwordPolicyConfig?: PasswordPolicyConfig; get recaptchaConfig(): RecaptchaConfig | undefined; @@ -996,6 +1012,7 @@ export interface UpdatePhoneMultiFactorInfoRequest extends BaseUpdateMultiFactor // @public export interface UpdateProjectConfigRequest { emailPrivacyConfig?: EmailPrivacyConfig; + mobileLinksConfig?: MobileLinksConfig; multiFactorConfig?: MultiFactorConfig; passwordPolicyConfig?: PasswordPolicyConfig; recaptchaConfig?: RecaptchaConfig; diff --git a/src/auth/action-code-settings-builder.ts b/src/auth/action-code-settings-builder.ts index 4ebc4df19c..13dbcbc725 100644 --- a/src/auth/action-code-settings-builder.ts +++ b/src/auth/action-code-settings-builder.ts @@ -94,8 +94,19 @@ export interface ActionCodeSettings { * configured per project. This field provides the ability to explicitly choose * configured per project. This fields provides the ability explicitly choose * one. If none is provided, the oldest domain is used by default. + * @deprecated use `linkDomain` instead */ dynamicLinkDomain?: string; + + /** + * Defines the custom Firebase Hosting domain to use when the link is to be opened + * via a specified mobile app, + * This is a replacement of Firebase Dynamic Link. + * If none is provided, + * a default hosting domain will be used (for example, `example.firebaseapp.com`) + */ + + linkDomain?: string; } /** Defines the email action code server request. */ @@ -103,6 +114,7 @@ interface EmailActionCodeRequest { continueUrl?: string; canHandleCodeInApp?: boolean; dynamicLinkDomain?: string; + linkDomain?: string; androidPackageName?: string; androidMinimumVersion: string; androidInstallApp?: boolean; @@ -123,6 +135,7 @@ export class ActionCodeSettingsBuilder { private ibi?: string; private canHandleCodeInApp?: boolean; private dynamicLinkDomain?: string; + private linkDomain?: string; /** * ActionCodeSettingsBuilder constructor. @@ -166,6 +179,14 @@ export class ActionCodeSettingsBuilder { } this.dynamicLinkDomain = actionCodeSettings.dynamicLinkDomain; + if (typeof actionCodeSettings.linkDomain !== 'undefined' && + !validator.isNonEmptyString(actionCodeSettings.linkDomain)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_HOSTING_LINK_DOMAIN, + ); + } + this.linkDomain = actionCodeSettings.linkDomain; + if (typeof actionCodeSettings.iOS !== 'undefined') { if (!validator.isNonNullObject(actionCodeSettings.iOS)) { throw new FirebaseAuthError( @@ -230,6 +251,7 @@ export class ActionCodeSettingsBuilder { continueUrl: this.continueUrl, canHandleCodeInApp: this.canHandleCodeInApp, dynamicLinkDomain: this.dynamicLinkDomain, + linkDomain: this.linkDomain, androidPackageName: this.apn, androidMinimumVersion: this.amv, androidInstallApp: this.installApp, diff --git a/src/auth/auth-config.ts b/src/auth/auth-config.ts index 23895d60f3..d2d07e9536 100644 --- a/src/auth/auth-config.ts +++ b/src/auth/auth-config.ts @@ -2137,6 +2137,60 @@ export interface PasswordPolicyConfig { constraints?: CustomStrengthOptionsConfig; } +/** + * Configuration for settings related to univeral links (iOS) + * and app links (Android). + */ +export interface MobileLinksConfig { + /** + * Use Firebase Hosting or dynamic link domain as the out-of-band code domain. + */ + domain?: MobileLinksDomain; +} + +/** + * Open code in app domain to use for app links and universal links. + */ +export type MobileLinksDomain = 'HOSTING_DOMAIN' | 'FIREBASE_DYNAMIC_LINK_DOMAIN'; + +/** + * Defines the MobileLinksAuthConfig class used for validation. + * + * @internal + */ +export class MobileLinksAuthConfig { + public static validate(options: MobileLinksConfig): void { + if (!validator.isNonNullObject(options)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"MobileLinksConfig" must be a non-null object.', + ); + } + + const validKeys = { + domain: true, + }; + + for (const key in options) { + if (!(key in validKeys)) { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + `"${key}" is not a valid "MobileLinksConfig" parameter.`, + ); + } + } + + if (typeof options.domain !== 'undefined' + && options.domain !== 'HOSTING_DOMAIN' + && options.domain !== 'FIREBASE_DYNAMIC_LINK_DOMAIN') { + throw new FirebaseAuthError( + AuthClientErrorCode.INVALID_CONFIG, + '"MobileLinksConfig.domain" must be either "HOSTING_DOMAIN" or "FIREBASE_DYNAMIC_LINK_DOMAIN".', + ); + } + } +} + /** * A password policy's enforcement state. */ diff --git a/src/auth/base-auth.ts b/src/auth/base-auth.ts index 6f77e088f8..56941056d9 100644 --- a/src/auth/base-auth.ts +++ b/src/auth/base-auth.ts @@ -749,7 +749,7 @@ export abstract class BaseAuth { * minimumVersion: '12' * }, * handleCodeInApp: true, - * dynamicLinkDomain: 'custom.page.link' + * linkDomain: 'project-id.firebaseapp.com' * }; * admin.auth() * .generatePasswordResetLink('user@example.com', actionCodeSettings) @@ -802,7 +802,7 @@ export abstract class BaseAuth { * minimumVersion: '12' * }, * handleCodeInApp: true, - * dynamicLinkDomain: 'custom.page.link' + * linkDomain: 'project-id.firebaseapp.com' * }; * admin.auth() * .generateEmailVerificationLink('user@example.com', actionCodeSettings) @@ -883,7 +883,7 @@ export abstract class BaseAuth { * minimumVersion: '12' * }, * handleCodeInApp: true, - * dynamicLinkDomain: 'custom.page.link' + * linkDomain: 'project-id.firebaseapp.com' * }; * admin.auth() * .generateEmailVerificationLink('user@example.com', actionCodeSettings) diff --git a/src/auth/index.ts b/src/auth/index.ts index 52538eb7d5..69cb95bf2a 100644 --- a/src/auth/index.ts +++ b/src/auth/index.ts @@ -104,6 +104,8 @@ export { PasswordPolicyEnforcementState, CustomStrengthOptionsConfig, EmailPrivacyConfig, + MobileLinksConfig, + MobileLinksDomain, } from './auth-config'; export { diff --git a/src/auth/project-config.ts b/src/auth/project-config.ts index 4a40e0c012..259f6eebb2 100644 --- a/src/auth/project-config.ts +++ b/src/auth/project-config.ts @@ -29,6 +29,8 @@ import { PasswordPolicyConfig, EmailPrivacyConfig, EmailPrivacyAuthConfig, + MobileLinksConfig, + MobileLinksAuthConfig, } from './auth-config'; import { deepCopy } from '../utils/deep-copy'; @@ -60,6 +62,11 @@ export interface UpdateProjectConfigRequest { * The email privacy configuration to update on the project */ emailPrivacyConfig?: EmailPrivacyConfig; + + /** + * The mobile links configuration for the project + */ + mobileLinksConfig?: MobileLinksConfig; } /** @@ -71,6 +78,7 @@ export interface ProjectConfigServerResponse { recaptchaConfig?: RecaptchaAuthServerConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; emailPrivacyConfig?: EmailPrivacyConfig; + mobileLinksConfig?: MobileLinksConfig; } /** @@ -82,6 +90,7 @@ export interface ProjectConfigClientRequest { recaptchaConfig?: RecaptchaAuthServerConfig; passwordPolicyConfig?: PasswordPolicyAuthServerConfig; emailPrivacyConfig?: EmailPrivacyConfig; + mobileLinksConfig?: MobileLinksConfig; } /** @@ -128,6 +137,11 @@ export class ProjectConfig { */ public readonly emailPrivacyConfig?: EmailPrivacyConfig; + /** + * The mobile links configuration for the project + */ + public readonly mobileLinksConfig?: MobileLinksConfig + /** * Validates a project config options object. Throws an error on failure. * @@ -146,6 +160,7 @@ export class ProjectConfig { recaptchaConfig: true, passwordPolicyConfig: true, emailPrivacyConfig: true, + mobileLinksConfig: true, } // Check for unsupported top level attributes. for (const key in request) { @@ -179,6 +194,11 @@ export class ProjectConfig { if (typeof request.emailPrivacyConfig !== 'undefined') { EmailPrivacyAuthConfig.validate(request.emailPrivacyConfig); } + + // Validate Mobile Links Config if provided. + if (typeof request.mobileLinksConfig !== 'undefined') { + MobileLinksAuthConfig.validate(request.mobileLinksConfig); + } } /** @@ -206,6 +226,9 @@ export class ProjectConfig { if (typeof configOptions.emailPrivacyConfig !== 'undefined') { request.emailPrivacyConfig = configOptions.emailPrivacyConfig; } + if (typeof configOptions.mobileLinksConfig !== 'undefined') { + request.mobileLinksConfig = configOptions.mobileLinksConfig; + } return request; } @@ -234,6 +257,9 @@ export class ProjectConfig { if (typeof response.emailPrivacyConfig !== 'undefined') { this.emailPrivacyConfig = response.emailPrivacyConfig; } + if (typeof response.mobileLinksConfig !== 'undefined') { + this.mobileLinksConfig = response.mobileLinksConfig; + } } /** * Returns a JSON-serializable representation of this object. @@ -248,6 +274,7 @@ export class ProjectConfig { recaptchaConfig: deepCopy(this.recaptchaConfig), passwordPolicyConfig: deepCopy(this.passwordPolicyConfig), emailPrivacyConfig: deepCopy(this.emailPrivacyConfig), + mobileLinksConfig: deepCopy(this.mobileLinksConfig), }; if (typeof json.smsRegionConfig === 'undefined') { delete json.smsRegionConfig; @@ -264,6 +291,9 @@ export class ProjectConfig { if (typeof json.emailPrivacyConfig === 'undefined') { delete json.emailPrivacyConfig; } + if (typeof json.mobileLinksConfig === 'undefined') { + delete json.mobileLinksConfig; + } return json; } } diff --git a/src/utils/error.ts b/src/utils/error.ts index ef56431a03..cf3736adcb 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -471,6 +471,11 @@ export class AuthClientErrorCode { message: 'The provided dynamic link domain is not configured or authorized ' + 'for the current project.', }; + public static INVALID_HOSTING_LINK_DOMAIN = { + code: 'invalid-hosting-link-domain', + message: 'The provided hosting link domain is not configured in Firebase ' + + 'Hosting or is not owned by the current project.', + }; public static INVALID_EMAIL_VERIFIED = { code: 'invalid-email-verified', message: 'The emailVerified field must be a boolean.', @@ -933,6 +938,8 @@ const AUTH_SERVER_TO_CLIENT_CODE: ServerToClientCode = { INVALID_CONTINUE_URI: 'INVALID_CONTINUE_URI', // Dynamic link domain in provided ActionCodeSettings is not authorized. INVALID_DYNAMIC_LINK_DOMAIN: 'INVALID_DYNAMIC_LINK_DOMAIN', + // Hosting link domain in provided ActionCodeSettings is not owned by the current project. + INVALID_HOSTING_LINK_DOMAIN: 'INVALID_HOSTING_LINK_DOMAIN', // uploadAccount provides an email that already exists. DUPLICATE_EMAIL: 'EMAIL_ALREADY_EXISTS', // uploadAccount provides a localId that already exists. diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 8a6374363d..560cd47005 100644 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -32,7 +32,7 @@ import { AuthProviderConfig, CreateTenantRequest, DeleteUsersResult, PhoneMultiFactorInfo, TenantAwareAuth, UpdatePhoneMultiFactorInfoRequest, UpdateTenantRequest, UserImportOptions, UserImportRecord, UserRecord, getAuth, UpdateProjectConfigRequest, UserMetadata, MultiFactorConfig, - PasswordPolicyConfig, SmsRegionConfig, RecaptchaConfig, + PasswordPolicyConfig, SmsRegionConfig, RecaptchaConfig, ActionCodeSettings, } from '../../lib/auth/index'; import * as sinon from 'sinon'; import * as sinonChai from 'sinon-chai'; @@ -75,10 +75,25 @@ const mockUserData = { photoURL: 'http://www.example.com/' + newUserUid + '/photo.png', disabled: false, }; -const actionCodeSettings = { +const actionCodeSettings : ActionCodeSettings = { url: 'http://localhost/?a=1&b=2#c=3', handleCodeInApp: false, }; +const actionCodeSettingsWithCustomDomain: ActionCodeSettings = { + url: 'http://localhost/?a=1&b=2#c=3', + handleCodeInApp: true, + linkDomain: 'kobayashimaru.testdomaindonotuse.com', + iOS: { + bundleId: 'testBundleId', + }, +} +const actionCodeSettingsForFdlLinks: ActionCodeSettings = { + url: 'http://localhost/?a=1&b=2#c=3', + handleCodeInApp: true, + iOS: { + bundleId: 'testBundleId', + }, +} let deleteQueue = Promise.resolve(); interface UserImportTest { @@ -1095,6 +1110,7 @@ describe('admin.auth', () => { const uid = generateRandomString(20).toLowerCase(); const email = uid + '@example.com'; const newEmail = uid + 'new@example.com'; + const newEmail2 = uid + 'new2@example.com'; const newPassword = 'newPassword'; const userData = { uid, @@ -1105,6 +1121,13 @@ describe('admin.auth', () => { // Create the test user before running this suite of tests. before(() => { + // Update project config to have HOSTING_DOMAIN as mobileLinksConfig after each test + const updateMobileLinksRequest: UpdateProjectConfigRequest = { + mobileLinksConfig: { + domain: 'HOSTING_DOMAIN', + }, + }; + getAuth().projectConfigManager().updateProjectConfig(updateMobileLinksRequest); return getAuth().createUser(userData); }); @@ -1199,6 +1222,162 @@ describe('admin.auth', () => { expect(result.user!.emailVerified).to.be.true; }); }); + + it('generateSignInWithEmailLink() with custom linkDomain should return error in case of invalid hosting domain', + function () { + if (authEmulatorHost) { + return this.skip(); // Not yet supported in Auth Emulator. + } + const actionCodeSettingsWithInvalidLinkDomain = deepCopy(actionCodeSettings); + actionCodeSettingsWithInvalidLinkDomain.linkDomain = 'invaliddomain.firebaseapp.com'; + return getAuth().generateSignInWithEmailLink(email, actionCodeSettingsWithInvalidLinkDomain) + .catch((error) => { + expect(error.code).to.equal('auth/invalid-hosting-link-domain'); + }); + }); + + it('generatePasswordResetLink() should return a password reset link with custom domain', function () { + if (authEmulatorHost) { + return this.skip(); // Not yet supported in Auth Emulator. + } + // Ensure old password set on created user. + return getAuth().updateUser(uid, { password: 'password' }) + .then(() => { + return getAuth().generatePasswordResetLink(newEmail, actionCodeSettingsWithCustomDomain); + }) + .then((link) => { + const code = getActionCodeForInAppRequest(link); + expect(getContinueUrlForInAppRequest(link)).equal(actionCodeSettings.url); + expect(getHostName(link)).equal(actionCodeSettingsWithCustomDomain.linkDomain); + return clientAuth().confirmPasswordReset(code, newPassword); + }) + .then(() => { + return clientAuth().signInWithEmailAndPassword(newEmail, newPassword); + }) + .then((result) => { + expect(result.user).to.exist; + expect(result.user!.email).to.equal(newEmail); + // Password reset also verifies the user's email. + expect(result.user!.emailVerified).to.be.true; + }); + }); + + it('generateEmailVerificationLink() should return a verification link with custom domain', function () { + if (authEmulatorHost) { + return this.skip(); // Not yet supported in Auth Emulator. + } + // Ensure the user's email is unverified. + return getAuth().updateUser(uid, { password: 'password', emailVerified: false }) + .then((userRecord) => { + expect(userRecord.emailVerified).to.be.false; + return getAuth().generateEmailVerificationLink(newEmail, actionCodeSettingsWithCustomDomain); + }) + .then((link) => { + const code = getActionCodeForInAppRequest(link); + expect(getContinueUrlForInAppRequest(link)).equal(actionCodeSettings.url); + expect(getHostName(link)).equal(actionCodeSettingsWithCustomDomain.linkDomain); + return clientAuth().applyActionCode(code); + }) + .then(() => { + return clientAuth().signInWithEmailAndPassword(newEmail, userData.password); + }) + .then((result) => { + expect(result.user).to.exist; + expect(result.user!.email).to.equal(newEmail); + expect(result.user!.emailVerified).to.be.true; + }); + }); + + it('generateSignInWithEmailLink() should return a sign-in link with custom domain', function () { + if (authEmulatorHost) { + return this.skip(); // Not yet supported in Auth Emulator. + } + return getAuth().generateSignInWithEmailLink(email, actionCodeSettingsWithCustomDomain) + .then((link) => { + expect(getContinueUrlForInAppRequest(link)).equal(actionCodeSettingsWithCustomDomain.url); + expect(getHostName(link)).equal(actionCodeSettingsWithCustomDomain.linkDomain); + return clientAuth().signInWithEmailLink(email, link); + }) + .then((result) => { + expect(result.user).to.exist; + expect(result.user!.email).to.equal(email); + expect(result.user!.emailVerified).to.be.true; + }); + }); + + it('generateVerifyAndChangeEmailLink() should return a verification link with custom domain', function () { + if (authEmulatorHost) { + return this.skip(); // Not yet supported in Auth Emulator. + } + // Ensure the user's email is verified. + return getAuth().updateUser(uid, { password: 'password', emailVerified: true }) + .then((userRecord) => { + expect(userRecord.emailVerified).to.be.true; + return getAuth().generateVerifyAndChangeEmailLink(newEmail, newEmail2, actionCodeSettingsWithCustomDomain); + }) + .then((link) => { + const code = getActionCodeForInAppRequest(link); + expect(getContinueUrlForInAppRequest(link)).equal(actionCodeSettings.url); + expect(getHostName(link)).equal(actionCodeSettingsWithCustomDomain.linkDomain); + return clientAuth().applyActionCode(code); + }) + .then(() => { + return clientAuth().signInWithEmailAndPassword(newEmail2, 'password'); + }) + .then((result) => { + expect(result.user).to.exist; + expect(result.user!.email).to.equal(newEmail2); + expect(result.user!.emailVerified).to.be.true; + }); + }); + + it('generateSignInWithEmailLink() should return a FDL sign-in' + + 'link with mobileLinksConfig set to FIREBASE_DYNAMIC_LINK_DOMAIN', function () { + if (authEmulatorHost) { + return this.skip(); // Not yet supported in Auth Emulator. + } + + const updateMobileLinksRequest: UpdateProjectConfigRequest = { + mobileLinksConfig: { + domain: 'FIREBASE_DYNAMIC_LINK_DOMAIN', + } + }; + return getAuth().projectConfigManager().updateProjectConfig(updateMobileLinksRequest) + .then((projectConfig) => { + expect(projectConfig?.mobileLinksConfig?.domain).equal('FIREBASE_DYNAMIC_LINK_DOMAIN'); + return getAuth().generateSignInWithEmailLink(email, actionCodeSettingsForFdlLinks); + }).then((link) => { + expectFDLLink(link); + return clientAuth().signInWithEmailLink(email, link); + }).then((result) => { + expect(result.user).to.exist; + expect(result.user!.email).to.equal(email); + expect(result.user!.emailVerified).to.be.true; + }); + }); + + it('generateSignInWithEmailLink() should return a FDL sign-in link with empty mobileLinksConfig', function () { + if (authEmulatorHost) { + return this.skip(); // Not yet supported in Auth Emulator. + } + + const updateMobileLinksRequest: UpdateProjectConfigRequest = { + mobileLinksConfig: { + } + }; + return getAuth().projectConfigManager().updateProjectConfig(updateMobileLinksRequest) + .then((projectConfig) => { + expect(projectConfig.mobileLinksConfig).is.empty; + return getAuth().generateSignInWithEmailLink(email, actionCodeSettingsForFdlLinks); + }).then((link) => { + expectFDLLink(link); + return clientAuth().signInWithEmailLink(email, link); + }).then((result) => { + expect(result.user).to.exist; + expect(result.user!.email).to.equal(email); + expect(result.user!.emailVerified).to.be.true; + }); + }); }); describe('Project config management operations', () => { @@ -1302,6 +1481,9 @@ describe('admin.auth', () => { recaptchaConfig: recaptchaStateAuditConfig, emailPrivacyConfig: { enableImprovedEmailPrivacy: true, + }, + mobileLinksConfig: { + domain: 'HOSTING_DOMAIN', } }; const projectConfigOption2: UpdateProjectConfigRequest = { @@ -1323,6 +1505,9 @@ describe('admin.auth', () => { emailPrivacyConfig: { enableImprovedEmailPrivacy: true, }, + mobileLinksConfig: { + domain: 'HOSTING_DOMAIN', + }, }; const expectedRecaptchaOffConfig: any = { @@ -1350,6 +1535,9 @@ describe('admin.auth', () => { passwordPolicyConfig: passwordConfig, recaptchaConfig: expectedRecaptchaOffConfig, emailPrivacyConfig: {}, + mobileLinksConfig: { + domain: 'HOSTING_DOMAIN', + }, }; const expectedProjectConfigSmsEnabledTotpDisabled: any = { @@ -1358,6 +1546,9 @@ describe('admin.auth', () => { passwordPolicyConfig: passwordConfig, recaptchaConfig: expectedRecaptchaOffConfig, emailPrivacyConfig: {}, + mobileLinksConfig: { + domain: 'HOSTING_DOMAIN', + }, }; it('updateProjectConfig() should resolve with the updated project config', () => { @@ -3231,6 +3422,78 @@ function getContinueUrl(link: string): string { return continueUrl!; } +/** + * Returns the host name corresponding to the link. + * + * @param link The link to parse for hostname + * @returns Hostname in the link + */ +function getHostName(link: string): string { + const parsedUrl = new url.URL(link); + return parsedUrl.hostname; +} + +/** + * Returns continue URL for handling in app requests. + * URL will be of the form, http://abc/__/auth/link?link= + * Coninue URL will be part of action link url + * + * @param link The link to parse for continue url + * @returns Link's corresponding continueUrl + */ +function getContinueUrlForInAppRequest(link: string): string { + const actionUrl = extractLinkUrl(link); + const continueUrl = actionUrl.searchParams.get('continueUrl'); + expect(continueUrl).to.exist; + return continueUrl!; +} + +/** + * Returns the action code corresponding to the link for in app requests. + * URL will be of the form, http://abc/__/auth/link?link= + * oobCode will be part of action link url + * + * @param link The link to parse for the action code. + * @return The link's corresponding action code. + */ +function getActionCodeForInAppRequest(link: string): string { + const actionUrl = extractLinkUrl(link); + const oobCode = actionUrl.searchParams.get('oobCode'); + expect(oobCode).to.exist; + return oobCode!; +} + +/** + * Extract URL in link parameter from the full link + * URL will be of the form, http://abc/__/auth/link?link= + * + * @param link The link to parse for the param + * @returns URL inside link param + */ +function extractLinkUrl(link: string): url.URL { + // Extract action url from link param + const parsedUrl = new url.URL(link); + const linkParam = parsedUrl.searchParams.get('link') ?? ''; + expect(linkParam).is.not.empty; + + return new url.URL(linkParam); +} + +/** + * Verify if the generated link is generated by FDL + * We leverage the params created by FDL to test whether a given link is FDL + * + * @param link Link to check whether it is FDL + */ +function expectFDLLink(link: string): void { + const parsedUrl = new url.URL(link); + // For ios, FDL creates a fallback url with param ifl + // We leverage that to test whether a given link is FDL link + // Note: This param does not exist when the link is generated for HOSTING_DOMAIN + const iflParam = parsedUrl.searchParams.get('ifl'); + expect(iflParam).is.not.null; +} + /** * Returns the tenant ID corresponding to the link. * diff --git a/test/unit/auth/action-code-settings-builder.spec.ts b/test/unit/auth/action-code-settings-builder.spec.ts index ceadde3e9b..4608f711f1 100644 --- a/test/unit/auth/action-code-settings-builder.spec.ts +++ b/test/unit/auth/action-code-settings-builder.spec.ts @@ -28,6 +28,7 @@ chai.use(sinonChai); chai.use(chaiAsPromised); const expect = chai.expect; +const TEST_LINK_DOMAIN = 'project-id.firebaseapp.com'; describe('ActionCodeSettingsBuilder', () => { describe('constructor', () => { @@ -43,7 +44,10 @@ describe('ActionCodeSettingsBuilder', () => { installApp: true, minimumVersion: '6', }, + // not removing this test since we are going to accept both dynamicLinkDomain + // and linkDomain for the onboarding phase. dynamicLinkDomain: 'custom.page.link', + linkDomain: TEST_LINK_DOMAIN, })).not.to.throw; }); @@ -69,6 +73,7 @@ describe('ActionCodeSettingsBuilder', () => { minimumVersion: '6', }, dynamicLinkDomain: 'custom.page.link', + linkDomain: TEST_LINK_DOMAIN, } as any); }).to.throw(AuthClientErrorCode.MISSING_CONTINUE_URI.message); }); @@ -109,6 +114,20 @@ describe('ActionCodeSettingsBuilder', () => { }); }); + const invalidHostingDomains = [null, NaN, 0, 1, true, false, '', + [TEST_LINK_DOMAIN], [], {}, { a: 1 }, _.noop]; + invalidHostingDomains.forEach((domain) => { + it('should throw on invalid linkDomain:' + JSON.stringify(domain), () => { + expect(() => { + return new ActionCodeSettingsBuilder({ + url: 'https://www.example.com/path/file?a=1&b=2', + handleCodeInApp: true, + linkDomain: domain, + } as any); + }).to.throw(AuthClientErrorCode.INVALID_HOSTING_LINK_DOMAIN.message); + }); + }); + const invalidIOSSettings = [null, NaN, 0, 1, true, false, '', 'a', [], [1, 'a'], _.noop]; invalidIOSSettings.forEach((settings) => { it('should throw on invalid iOS object:' + JSON.stringify(settings), () => { @@ -228,11 +247,13 @@ describe('ActionCodeSettingsBuilder', () => { minimumVersion: '6', }, dynamicLinkDomain: 'custom.page.link', + linkDomain: TEST_LINK_DOMAIN, }); const expectedRequest = { continueUrl: 'https://www.example.com/path/file?a=1&b=2', canHandleCodeInApp: true, dynamicLinkDomain: 'custom.page.link', + linkDomain: TEST_LINK_DOMAIN, androidPackageName: 'com.example.android', androidMinimumVersion: '6', androidInstallApp: true, diff --git a/test/unit/auth/auth-api-request.spec.ts b/test/unit/auth/auth-api-request.spec.ts index bd789421b8..9a6d624b88 100644 --- a/test/unit/auth/auth-api-request.spec.ts +++ b/test/unit/auth/auth-api-request.spec.ts @@ -3081,6 +3081,7 @@ AUTH_REQUEST_HANDLER_TESTS.forEach((handler) => { minimumVersion: '6', }, dynamicLinkDomain: 'custom.page.link', + linkDomain: 'project-id.firebaseapp.com', }; const expectedActionCodeSettingsRequest = new ActionCodeSettingsBuilder(actionCodeSettings).buildRequest(); const expectedLink = 'https://custom.page.link?link=' + diff --git a/test/unit/auth/auth-config.spec.ts b/test/unit/auth/auth-config.spec.ts index 8894bdc5ff..c5bdb7c445 100644 --- a/test/unit/auth/auth-config.spec.ts +++ b/test/unit/auth/auth-config.spec.ts @@ -28,6 +28,8 @@ import { MAXIMUM_TEST_PHONE_NUMBERS, PasswordPolicyAuthConfig, CustomStrengthOptionsConfig, + MobileLinksAuthConfig, + MobileLinksConfig, } from '../../../src/auth/auth-config'; import { SAMLUpdateAuthProviderRequest, OIDCUpdateAuthProviderRequest, @@ -1322,3 +1324,30 @@ describe('PasswordPolicyAuthConfig',() => { }); }); }); + +describe('MobileLinksAuthConfig',() => { + describe('validate',() => { + it('should throw an error on invalid MobileLinksConfig key',() => { + const config: any = { + link: 'HOSTING_DOMAIN' + }; + expect(() => + MobileLinksAuthConfig.validate(config) + ).to.throw('"link" is not a valid "MobileLinksConfig" parameter.'); + }); + + it('should throw an error on invalid MobileLinksDomain',() => { + const config: any = { + domain: 'WRONG_DOMAIN' + }; + expect(() => MobileLinksAuthConfig.validate(config)) + .to.throw('"MobileLinksConfig.domain" must be either "HOSTING_DOMAIN" or "FIREBASE_DYNAMIC_LINK_DOMAIN".'); + });// + it('should now throw an error on valid MobileLinksConfig',() => { + const config: MobileLinksConfig = { + domain: 'HOSTING_DOMAIN' + }; + expect(() => MobileLinksAuthConfig.validate(config)).not.to.throw(); + }); + }); +}); diff --git a/test/unit/auth/auth.spec.ts b/test/unit/auth/auth.spec.ts index 4924cb5b12..34d4c3d9a6 100644 --- a/test/unit/auth/auth.spec.ts +++ b/test/unit/auth/auth.spec.ts @@ -2887,6 +2887,7 @@ AUTH_CONFIGS.forEach((testConfig) => { minimumVersion: '6', }, dynamicLinkDomain: 'custom.page.link', + linkDomain: 'project-id.firebaseapp.com', }; const expectedLink = 'https://custom.page.link?link=' + encodeURIComponent('https://projectId.firebaseapp.com/__/auth/action?oobCode=CODE') + diff --git a/test/unit/auth/project-config.spec.ts b/test/unit/auth/project-config.spec.ts index f116647568..7857deb398 100644 --- a/test/unit/auth/project-config.spec.ts +++ b/test/unit/auth/project-config.spec.ts @@ -87,7 +87,10 @@ describe('ProjectConfig', () => { useAccountDefender: true, useSmsBotScore: true, useSmsTollFraudProtection: true, - } + }, + mobileLinksConfig: { + domain: 'FIREBASE_DYNAMIC_LINK_DOMAIN', + }, }; const updateProjectConfigRequest1: UpdateProjectConfigRequest = { @@ -111,6 +114,9 @@ describe('ProjectConfig', () => { emailPrivacyConfig: { enableImprovedEmailPrivacy: false, }, + mobileLinksConfig: { + domain: 'HOSTING_DOMAIN' + }, }; const updateProjectConfigRequest2: UpdateProjectConfigRequest = { @@ -550,6 +556,22 @@ describe('ProjectConfig', () => { }).to.throw('"EmailPrivacyConfig.enableImprovedEmailPrivacy" must be a valid boolean value.'); }); + it('should throw on invalid MobileLinksConfig attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.mobileLinksConfig.invalidParameter = 'invalid'; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"invalidParameter" is not a valid "MobileLinksConfig" parameter.'); + }); + + it('should throw on invalid domain attribute', () => { + const configOptionsClientRequest = deepCopy(updateProjectConfigRequest1) as any; + configOptionsClientRequest.mobileLinksConfig.domain = 'random domain'; + expect(() => { + ProjectConfig.buildServerRequest(configOptionsClientRequest); + }).to.throw('"MobileLinksConfig.domain" must be either "HOSTING_DOMAIN" or "FIREBASE_DYNAMIC_LINK_DOMAIN".'); + }); + const nonObjects = [null, NaN, 0, 1, true, false, '', 'a', [], [1, 'a'], _.noop]; nonObjects.forEach((request) => { it('should throw on invalid UpdateProjectConfigRequest:' + JSON.stringify(request), () => { @@ -647,6 +669,13 @@ describe('ProjectConfig', () => { }; expect(projectConfig.emailPrivacyConfig).to.deep.equal(expectedEmailPrivacyConfig); }); + + it('should set readonly property mobileLinksConfig', () => { + const expectedMobileLinksConfig = { + domain: 'FIREBASE_DYNAMIC_LINK_DOMAIN', + }; + expect(projectConfig.mobileLinksConfig).to.deep.equal(expectedMobileLinksConfig); + }); }); describe('toJSON()', () => { @@ -704,6 +733,7 @@ describe('ProjectConfig', () => { emailPrivacyConfig: { enableImprovedEmailPrivacy: true, }, + mobileLinksConfig: deepCopy(serverResponse.mobileLinksConfig), }); }); @@ -720,6 +750,7 @@ describe('ProjectConfig', () => { delete serverResponseOptionalCopy.recaptchaConfig?.useSmsTollFraudProtection delete serverResponseOptionalCopy.passwordPolicyConfig; delete serverResponseOptionalCopy.emailPrivacyConfig; + delete serverResponseOptionalCopy.mobileLinksConfig; expect(new ProjectConfig(serverResponseOptionalCopy).toJSON()).to.deep.equal({ recaptchaConfig: { recaptchaKeys: deepCopy(serverResponse.recaptchaConfig?.recaptchaKeys), From b26d13a0d3bf7f75c35cab45153a64727fc47c4d Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 6 Feb 2025 12:24:51 -0500 Subject: [PATCH 234/323] [chore] Release 13.1.0 (#2841) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c07a06424e..0251f72b70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.0.2", + "version": "13.1.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From cb2b92f942389f58555dfe33d1b88e5f2454f848 Mon Sep 17 00:00:00 2001 From: Namya LG <53875297+Namyalg@users.noreply.github.com> Date: Mon, 10 Feb 2025 22:40:52 +0530 Subject: [PATCH 235/323] fix: equality comparison for semantic version when number of segments = max allowed segments (#2794) * fix: equality comparison for semantic version comparison when number of segments = max allowed segments * minor refactor * Update condition-evaluator-internal.ts * chore:update UT --- src/remote-config/condition-evaluator-internal.ts | 10 ++++++---- test/unit/remote-config/condition-evaluator.spec.ts | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/remote-config/condition-evaluator-internal.ts b/src/remote-config/condition-evaluator-internal.ts index c0fc0484a8..b49b35dc8d 100644 --- a/src/remote-config/condition-evaluator-internal.ts +++ b/src/remote-config/condition-evaluator-internal.ts @@ -302,14 +302,15 @@ function compareSemanticVersions( const version1 = String(actualValue).split('.').map(Number); const version2 = targetValue.split('.').map(Number); + if (version1.length > MAX_LENGTH || version2.length > MAX_LENGTH) { + return false; + } + for (let i = 0; i < MAX_LENGTH; i++) { // Check to see if segments are present. Note that these may be present and be NaN. const version1HasSegment = version1[i] !== undefined; const version2HasSegment = version2[i] !== undefined; - // If both are undefined, we've consumed everything and they're equal. - if (!version1HasSegment && !version2HasSegment) return predicateFn(0) - // Insert zeros if undefined for easier comparison. if (!version1HasSegment) version1[i] = 0; if (!version2HasSegment) version2[i] = 0; @@ -321,5 +322,6 @@ function compareSemanticVersions( if (version1[i] < version2[i]) return predicateFn(-1); if (version1[i] > version2[i]) return predicateFn(1); } - return false; + // If this point is reached, the semantic versions are equal. + return predicateFn(0); } diff --git a/test/unit/remote-config/condition-evaluator.spec.ts b/test/unit/remote-config/condition-evaluator.spec.ts index 8bfa168df6..7368457fcf 100644 --- a/test/unit/remote-config/condition-evaluator.spec.ts +++ b/test/unit/remote-config/condition-evaluator.spec.ts @@ -1114,6 +1114,7 @@ describe('ConditionEvaluator', () => { { targets: ['5.12.3'], actual: '5.11.9', outcome: true }, { targets: ['5.12.3'], actual: '5.12.3', outcome: true }, { targets: ['5.12.3'], actual: '5.12.9', outcome: false }, + { targets: ['5.6.7.8.9'], actual: '5.6.7.8.9', outcome: true }, invalidNumericSignalTestCase, ]; @@ -1127,6 +1128,9 @@ describe('ConditionEvaluator', () => { { targets: ['5.0'], actual: 5.0, outcome: true }, { targets: ['5.12.3'], actual: '5.12.9', outcome: false }, { targets: ['5.12.3'], actual: '5.12.3.0.0.0.0', outcome: false }, + { targets: ['5.6.7.8.9'], actual: '5.6.7.8.9', outcome: true }, + { targets: ['5.6.7.8.9'], actual: '4.5.6.7.8', outcome: false }, + { targets: ['5.6.7.8.9.0'], actual: '5.6.7.8.9.0', outcome: false }, invalidNumericSignalTestCase, ]; @@ -1166,6 +1170,7 @@ describe('ConditionEvaluator', () => { { targets: ['5'], actual: 5.0, outcome: true }, { targets: ['5.0'], actual: 5.0, outcome: true }, { targets: ['5.12.3'], actual: '5.11.9', outcome: false }, + { targets: ['5.6.7.8.9'], actual: '5.6.7.8.9', outcome: true }, invalidNumericSignalTestCase ]; From 5fb1357b755a4f73b5d70cbb01e8df5fa2df2c4f Mon Sep 17 00:00:00 2001 From: Kevin Elko Date: Tue, 11 Feb 2025 17:00:11 -0500 Subject: [PATCH 236/323] Adds support for exporting a serialized config response from the RC server side SDK. (#2829) * add serialization method to server side remote config * update with latest changes * restructure as a class, add documentation * more tests for server config * run apidocs * Refine api and rerun docs * add back the newline * Apply suggestions from review * Make eTag optional in fetch response * rerun doc generator --------- Co-authored-by: Kevin Elko --- etc/firebase-admin.remote-config.api.md | 19 ++++ src/remote-config/index.ts | 3 +- src/remote-config/remote-config-api.ts | 38 ++++++- src/remote-config/remote-config.ts | 68 ++++++++++- test/unit/remote-config/remote-config.spec.ts | 107 ++++++++++++++++-- 5 files changed, 223 insertions(+), 12 deletions(-) diff --git a/etc/firebase-admin.remote-config.api.md b/etc/firebase-admin.remote-config.api.md index 68d760468c..cf7eb32b93 100644 --- a/etc/firebase-admin.remote-config.api.md +++ b/etc/firebase-admin.remote-config.api.md @@ -52,6 +52,15 @@ export interface ExplicitParameterValue { value: string; } +// @public +export interface FetchResponseData { + config?: { + [key: string]: string; + }; + eTag?: string; + status: number; +} + // Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts // // @public @@ -162,6 +171,13 @@ export interface RemoteConfigCondition { tagColor?: TagColor; } +// @public +export class RemoteConfigFetchResponse { + constructor(app: App, serverConfig: ServerConfig, requestEtag?: string); + // (undocumented) + toJSON(): FetchResponseData; +} + // @public export interface RemoteConfigParameter { conditionalValues?: { @@ -205,6 +221,9 @@ export interface RemoteConfigUser { // @public export interface ServerConfig { + getAll(): { + [key: string]: Value; + }; getBoolean(key: string): boolean; getNumber(key: string): number; getString(key: string): string; diff --git a/src/remote-config/index.ts b/src/remote-config/index.ts index 7b66c44ee9..42a2573227 100644 --- a/src/remote-config/index.ts +++ b/src/remote-config/index.ts @@ -31,6 +31,7 @@ export { DefaultConfig, EvaluationContext, ExplicitParameterValue, + FetchResponseData, GetServerTemplateOptions, InAppDefaultValue, InitServerTemplateOptions, @@ -60,7 +61,7 @@ export { ValueSource, Version, } from './remote-config-api'; -export { RemoteConfig } from './remote-config'; +export { RemoteConfig, RemoteConfigFetchResponse } from './remote-config'; /** * Gets the {@link RemoteConfig} service for the default app or a given app. diff --git a/src/remote-config/remote-config-api.ts b/src/remote-config/remote-config-api.ts index 4dfa1da023..d315572192 100644 --- a/src/remote-config/remote-config-api.ts +++ b/src/remote-config/remote-config-api.ts @@ -236,7 +236,7 @@ export enum CustomSignalOperator { /** * Matches a numeric value less than or equal to the target value. */ - NUMERIC_LESS_EQUAL ='NUMERIC_LESS_EQUAL', + NUMERIC_LESS_EQUAL = 'NUMERIC_LESS_EQUAL', /** * Matches a numeric value equal to the target value. @@ -537,7 +537,7 @@ export interface ServerTemplate { /** * Generic map of developer-defined signals used as evaluation input signals. */ -export type UserProvidedSignals = {[key: string]: string|number}; +export type UserProvidedSignals = { [key: string]: string | number }; /** * Predefined template evaluation input signals. @@ -727,6 +727,40 @@ export interface ServerConfig { * @returns The value for the given key. */ getValue(key: string): Value; + + /** + * Returns all config values. + * + * @returns A map of all config keys to their values. + */ + getAll(): { [key: string]: Value } +} + +/** + * JSON-serializable representation of evaluated config values. This can be consumed by + * Remote Config web client SDKs. + */ +export interface FetchResponseData { + /** + * The HTTP status, which is useful for differentiating success responses with data from + * those without. + * + * This use of 200 and 304 response codes is consistent with Remote Config's server + * implementation. + */ + status: number; + + /** + * Defines the ETag response header value. Only defined for 200 and 304 responses. + * + * This is consistent with Remote Config's server eTag implementation. + */ + eTag?: string; + + /** + * Defines the map of parameters returned as "entries" in the fetch response body. + */ + config?: { [key: string]: string }; } /** diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index c529501315..a984d67e1f 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -15,6 +15,7 @@ */ import { App } from '../app'; +import * as utils from '../utils/index'; import * as validator from '../utils/validator'; import { FirebaseRemoteConfigError, RemoteConfigApiClient } from './remote-config-api-client-internal'; import { ConditionEvaluator } from './condition-evaluator-internal'; @@ -41,6 +42,7 @@ import { GetServerTemplateOptions, InitServerTemplateOptions, ServerTemplateDataType, + FetchResponseData, } from './remote-config-api'; /** @@ -298,7 +300,7 @@ class RemoteConfigTemplateImpl implements RemoteConfigTemplate { */ class ServerTemplateImpl implements ServerTemplate { private cache: ServerTemplateData; - private stringifiedDefaultConfig: {[key: string]: string} = {}; + private stringifiedDefaultConfig: { [key: string]: string } = {}; constructor( private readonly apiClient: RemoteConfigApiClient, @@ -425,7 +427,7 @@ class ServerTemplateImpl implements ServerTemplate { class ServerConfigImpl implements ServerConfig { constructor( private readonly configValues: { [key: string]: Value }, - ){} + ) { } getBoolean(key: string): boolean { return this.getValue(key).asBoolean(); } @@ -438,6 +440,9 @@ class ServerConfigImpl implements ServerConfig { getValue(key: string): Value { return this.configValues[key] || new ValueImpl('static'); } + getAll(): { [key: string]: Value } { + return { ...this.configValues }; + } } /** @@ -613,3 +618,62 @@ class VersionImpl implements Version { return validator.isNonEmptyString(timestamp) && (new Date(timestamp)).getTime() > 0; } } + +const HTTP_NOT_MODIFIED = 304; +const HTTP_OK = 200; + +/** + * Represents a fetch response that can be used to interact with RC's client SDK. + */ +export class RemoteConfigFetchResponse { + private response: FetchResponseData; + + /** + * @param app - The app for this RemoteConfig service. + * @param serverConfig - The server config for which to generate a fetch response. + * @param requestEtag - A request eTag with which to compare the current response. + */ + constructor(app: App, serverConfig: ServerConfig, requestEtag?: string) { + const config: { [key: string]: string } = {}; + for (const [param, value] of Object.entries(serverConfig.getAll())) { + config[param] = value.asString(); + } + + const currentEtag = this.processEtag(config, app); + + if (currentEtag === requestEtag) { + this.response = { + status: HTTP_NOT_MODIFIED, + eTag: currentEtag, + }; + } else { + this.response = { + status: HTTP_OK, + eTag: currentEtag, + config, + } + } + } + + /** + * @returns JSON representation of the fetch response that can be consumed + * by the RC client SDK. + */ + public toJSON(): FetchResponseData { + return this.response; + } + + private processEtag(config: { [key: string]: string }, app: App): string { + const configJson = JSON.stringify(config); + let hash = 0; + // Mimics Java's `String.hashCode()` which is used in RC's servers. + for (let i = 0; i < configJson.length; i++) { + const char = configJson.charCodeAt(i); + hash = (hash << 5) - hash + char; + hash |= 0; + } + const projectId = utils.getExplicitProjectId(app); + const parts = ['etag', projectId, 'firebase-server', 'fetch', hash]; + return parts.filter(a => !!a).join('-'); + } +} diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index 526dc0699e..976266e5ab 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -26,6 +26,7 @@ import { RemoteConfigCondition, TagColor, ListVersionsResult, + RemoteConfigFetchResponse, } from '../../../src/remote-config/index'; import { FirebaseApp } from '../../../src/app/firebase-app'; import * as mocks from '../../resources/mocks'; @@ -1001,14 +1002,14 @@ describe('RemoteConfig', () => { describe('should throw error if there are any JSON or tempalte parsing errors', () => { const INVALID_PARAMETERS: any[] = [null, '', 'abc', 1, true, []]; const INVALID_CONDITIONS: any[] = [null, '', 'abc', 1, true, {}]; - + let sourceTemplate = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); const jsonString = '{invalidJson: null}'; it('should throw if template is an invalid JSON', () => { expect(() => remoteConfig.initServerTemplate({ template: jsonString })) .to.throw(/Failed to parse the JSON string: ([\D\w]*)\./); }); - + INVALID_PARAMETERS.forEach((invalidParameter) => { sourceTemplate.parameters = invalidParameter; const jsonString = JSON.stringify(sourceTemplate); @@ -1017,7 +1018,7 @@ describe('RemoteConfig', () => { .to.throw('Remote Config parameters must be a non-null object'); }); }); - + sourceTemplate = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE); INVALID_CONDITIONS.forEach((invalidConditions) => { sourceTemplate.conditions = invalidConditions; @@ -1292,20 +1293,53 @@ describe('RemoteConfig', () => { // Note the static source is set in the getValue() method, but the other sources // are set in the evaluate() method, so these tests span a couple layers. describe('ServerConfig', () => { + describe('getAll', () => { + it('should return all values', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + templateData.parameters = { + dog_type: { + defaultValue: { + value: 'pug' + } + }, + dog_type_enabled: { + defaultValue: { + value: 'true' + } + }, + dog_age: { + defaultValue: { + value: '22' + } + }, + dog_use_inapp_default: { + defaultValue: { + useInAppDefault: true + } + }, + }; + const template = remoteConfig.initServerTemplate({ template: templateData }); + const config = template.evaluate().getAll(); + expect(Object.keys(config)).deep.equal(['dog_type', 'dog_type_enabled', 'dog_age']); + expect(config['dog_type'].asString()).to.equal('pug'); + expect(config['dog_type_enabled'].asBoolean()).to.equal(true); + expect(config['dog_age'].asNumber()).to.equal(22); + }); + }); + describe('getValue', () => { it('should return static when default and remote are not defined', () => { const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; // Omits remote parameter values. templateData.parameters = { - }; - // Omits in-app default values. + } const template = remoteConfig.initServerTemplate({ template: templateData }); const config = template.evaluate(); const value = config.getValue('dog_type'); expect(value.asString()).to.equal(''); expect(value.getSource()).to.equal('static'); }); - + it('should return default value when it is defined', () => { const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; // Omits remote parameter values. @@ -1323,7 +1357,7 @@ describe('RemoteConfig', () => { expect(value.asString()).to.equal('shiba'); expect(value.getSource()).to.equal('default'); }); - + it('should return remote value when it is defined', () => { const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; // Defines remote parameter values. @@ -1391,6 +1425,65 @@ describe('RemoteConfig', () => { }); }); + describe('RemoteConfigFetchResponse', () => { + it('should return a 200 response when supplied with no etag', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + // Defines remote parameter values. + templateData.parameters = { + dog_type: { + defaultValue: { + value: 'beagle' + } + } + }; + const template = remoteConfig.initServerTemplate({ template: templateData }); + const fetchResponse = new RemoteConfigFetchResponse(mockApp, template.evaluate()); + expect(fetchResponse.toJSON()).deep.equals({ + status: 200, + eTag: 'etag-project_id-firebase-server-fetch--2039110429', + config: { 'dog_type': 'beagle' } + }); + }); + + it('should return a 200 response when supplied with a stale etag', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + // Defines remote parameter values. + templateData.parameters = { + dog_type: { + defaultValue: { + value: 'beagle' + } + } + }; + const template = remoteConfig.initServerTemplate({ template: templateData }); + const fetchResponse = new RemoteConfigFetchResponse(mockApp, template.evaluate(), 'fake-etag'); + expect(fetchResponse.toJSON()).deep.equals({ + status: 200, + eTag: 'etag-project_id-firebase-server-fetch--2039110429', + config: { 'dog_type': 'beagle' } + }); + }); + + it('should return a 304 repsonse with matching etag', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + // Defines remote parameter values. + templateData.parameters = { + dog_type: { + defaultValue: { + value: 'beagle' + } + } + }; + const template = remoteConfig.initServerTemplate({ template: templateData }); + const fetchResponse = new RemoteConfigFetchResponse( + mockApp, template.evaluate(), 'etag-project_id-firebase-server-fetch--2039110429'); + expect(fetchResponse.toJSON()).deep.equals({ + status: 304, + eTag: 'etag-project_id-firebase-server-fetch--2039110429' + }); + }); + }); + function runInvalidResponseTests(rcOperation: () => Promise, operationName: any): void { it('should propagate API errors', () => { From 2a9dce82375b029d6ce2515e6c831c7faae4ff98 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 18 Feb 2025 09:38:40 -0500 Subject: [PATCH 237/323] fix(dc): Use emulated credentials with Data Connect Emulator (#2853) --- .../data-connect-api-client-internal.ts | 61 +++++++++++++++---- .../data-connect-api-client-internal.spec.ts | 4 +- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts index 969c8492f5..1f7b2da05c 100644 --- a/src/data-connect/data-connect-api-client-internal.ts +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -25,10 +25,15 @@ import * as utils from '../utils/index'; import * as validator from '../utils/validator'; import { ConnectorConfig, ExecuteGraphqlResponse, GraphqlOptions } from './data-connect-api'; -// Data Connect backend constants -const DATA_CONNECT_HOST = 'https://firebasedataconnect.googleapis.com'; -const DATA_CONNECT_API_URL_FORMAT = - '{host}/v1alpha/projects/{projectId}/locations/{locationId}/services/{serviceId}:{endpointId}'; +const API_VERSION = 'v1alpha'; + +/** The Firebase Data Connect backend base URL format. */ +const FIREBASE_DATA_CONNECT_BASE_URL_FORMAT = + 'https://firebasedataconnect.googleapis.com/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}:{endpointId}'; + +/** Firebase Data Connect base URl format when using the Data Connect emultor. */ +const FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT = + 'http://{host}/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}:{endpointId}'; const EXECUTE_GRAPH_QL_ENDPOINT = 'executeGraphql'; const EXECUTE_GRAPH_QL_READ_ENDPOINT = 'executeGraphqlRead'; @@ -52,7 +57,7 @@ export class DataConnectApiClient { DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, 'First argument passed to getDataConnect() must be a valid Firebase app instance.'); } - this.httpClient = new AuthorizedHttpClient(app as FirebaseApp); + this.httpClient = new DataConnectHttpClient(app as FirebaseApp); } /** @@ -101,13 +106,12 @@ export class DataConnectApiClient { 'GraphqlOptions must be a non-null object'); } } - const host = (process.env.DATA_CONNECT_EMULATOR_HOST || DATA_CONNECT_HOST); const data = { query, ...(options?.variables && { variables: options?.variables }), ...(options?.operationName && { operationName: options?.operationName }), }; - return this.getUrl(host, this.connectorConfig.location, this.connectorConfig.serviceId, endpoint) + return this.getUrl(API_VERSION, this.connectorConfig.location, this.connectorConfig.serviceId, endpoint) .then(async (url) => { const request: HttpRequestConfig = { method: 'POST', @@ -133,18 +137,25 @@ export class DataConnectApiClient { }); } - private async getUrl(host: string, locationId: string, serviceId: string, endpointId: string): Promise { + private async getUrl(version: string, locationId: string, serviceId: string, endpointId: string): Promise { return this.getProjectId() .then((projectId) => { const urlParams = { - host, + version, projectId, locationId, serviceId, endpointId }; - const baseUrl = utils.formatString(DATA_CONNECT_API_URL_FORMAT, urlParams); - return utils.formatString(baseUrl); + let urlFormat: string; + if (useEmulator()) { + urlFormat = utils.formatString(FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT, { + host: emulatorHost() + }); + } else { + urlFormat = FIREBASE_DATA_CONNECT_BASE_URL_FORMAT; + } + return utils.formatString(urlFormat, urlParams); }); } @@ -188,6 +199,34 @@ export class DataConnectApiClient { } } +/** + * Data Connect-specific HTTP client which uses the special "owner" token + * when communicating with the Data Connect Emulator. + */ +class DataConnectHttpClient extends AuthorizedHttpClient { + + protected getToken(): Promise { + if (useEmulator()) { + return Promise.resolve('owner'); + } + + return super.getToken(); + } + +} + +function emulatorHost(): string | undefined { + return process.env.DATA_CONNECT_EMULATOR_HOST +} + +/** + * When true the SDK should communicate with the Data Connect Emulator for all API + * calls and also produce unsigned tokens. + */ +export function useEmulator(): boolean { + return !!emulatorHost(); +} + interface ErrorResponse { error?: ServerError; } diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index 93b7120703..9787a2d7c9 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -209,7 +209,7 @@ describe('DataConnectApiClient', () => { }); it('should use DATA_CONNECT_EMULATOR_HOST if set', () => { - process.env.DATA_CONNECT_EMULATOR_HOST = 'http://localhost:9000'; + process.env.DATA_CONNECT_EMULATOR_HOST = 'localhost:9399'; const stub = sandbox .stub(HttpClient.prototype, 'send') .resolves(utils.responseFrom(TEST_RESPONSE, 200)); @@ -217,7 +217,7 @@ describe('DataConnectApiClient', () => { .then(() => { expect(stub).to.have.been.calledOnce.and.calledWith({ method: 'POST', - url: `http://localhost:9000/v1alpha/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, + url: `http://localhost:9399/v1alpha/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, headers: EXPECTED_HEADERS, data: { query: 'query' } }); From cd00a846d0058e0f319dfeb7f0ccb19c38d0abef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 17:29:36 +0000 Subject: [PATCH 238/323] build(deps): bump google-auth-library from 9.15.0 to 9.15.1 (#2847) --- package-lock.json | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index be856b7012..d2c79f3bf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.0.2", + "version": "13.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.0.2", + "version": "13.1.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -5362,9 +5362,10 @@ } }, "node_modules/google-auth-library": { - "version": "9.15.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", - "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", From 38a38cc852a15556c13276b6bc01e190157956e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 17:33:37 +0000 Subject: [PATCH 239/323] build(deps-dev): bump @types/lodash from 4.17.13 to 4.17.15 (#2848) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d2c79f3bf0..c1af3cb51c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1761,9 +1761,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", - "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==", "dev": true, "license": "MIT" }, From 63d615f469ed72c116cad936fd661b9353aeaddf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Feb 2025 17:38:23 +0000 Subject: [PATCH 240/323] build(deps): bump @firebase/database-compat from 2.0.1 to 2.0.3 (#2849) --- package-lock.json | 115 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 94 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index c1af3cb51c..161d03d281 100644 --- a/package-lock.json +++ b/package-lock.json @@ -548,7 +548,8 @@ "node_modules/@firebase/app-check-interop-types": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", - "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==" + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" }, "node_modules/@firebase/app-compat": { "version": "0.2.48", @@ -672,7 +673,8 @@ "node_modules/@firebase/auth-interop-types": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", - "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==" + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" }, "node_modules/@firebase/auth-types": { "version": "0.12.3", @@ -688,6 +690,7 @@ "version": "0.6.11", "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", + "dev": true, "dependencies": { "@firebase/util": "1.10.2", "tslib": "^2.1.0" @@ -697,15 +700,16 @@ } }, "node_modules/@firebase/database": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.10.tgz", - "integrity": "sha512-sWp2g92u7xT4BojGbTXZ80iaSIaL6GAL0pwvM0CO/hb0nHSnABAqsH7AhnWGsGvXuEvbPr7blZylPaR9J+GSuQ==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.12.tgz", + "integrity": "sha512-psFl5t6rSFHq3i3fnU1QQlc4BB9Hnhh8TgEqvQlPPm8kDLw8gYxvjqYw3c5CZW0+zKR837nwT6im/wtJUivMKw==", + "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.11", + "@firebase/component": "0.6.12", "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.2", + "@firebase/util": "1.10.3", "faye-websocket": "0.11.4", "tslib": "^2.1.0" }, @@ -714,15 +718,41 @@ } }, "node_modules/@firebase/database-compat": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.1.tgz", - "integrity": "sha512-IsFivOjdE1GrjTeKoBU/ZMenESKDXidFDzZzHBPQ/4P20ptGdrl3oLlWrV/QJqJ9lND4IidE3z4Xr5JyfUW1vg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.3.tgz", + "integrity": "sha512-uHGQrSUeJvsDfA+IyHW5O4vdRPsCksEzv4T4Jins+bmQgYy20ZESU4x01xrQCn/nzqKHuQMEW99CoCO7D+5NiQ==", + "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.11", - "@firebase/database": "1.0.10", - "@firebase/database-types": "1.0.7", + "@firebase/component": "0.6.12", + "@firebase/database": "1.0.12", + "@firebase/database-types": "1.0.8", "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.2", + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/@firebase/component": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", + "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/@firebase/util": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", + "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "license": "Apache-2.0", + "dependencies": { "tslib": "^2.1.0" }, "engines": { @@ -730,12 +760,50 @@ } }, "node_modules/@firebase/database-types": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.7.tgz", - "integrity": "sha512-I7zcLfJXrM0WM+ksFmFdAMdlq/DFmpeMNa+/GNsLyFo5u/lX5zzkPzGe3srVWqaBQBY5KprylDGxOsP6ETfL0A==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.8.tgz", + "integrity": "sha512-6lPWIGeufhUq1heofZULyVvWFhD01TUrkkB9vyhmksjZ4XF7NaivQp9rICMk7QNhqwa+uDCaj4j+Q8qqcSVZ9g==", + "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.3", - "@firebase/util": "1.10.2" + "@firebase/util": "1.10.3" + } + }, + "node_modules/@firebase/database-types/node_modules/@firebase/util": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", + "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database/node_modules/@firebase/component": { + "version": "0.6.12", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", + "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.10.3", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database/node_modules/@firebase/util": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", + "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@firebase/logger": { @@ -753,6 +821,7 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", + "dev": true, "dependencies": { "tslib": "^2.1.0" }, @@ -4515,6 +4584,7 @@ "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -6181,9 +6251,10 @@ } }, "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", + "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==", + "license": "MIT" }, "node_modules/http-proxy-agent": { "version": "5.0.0", @@ -11619,6 +11690,7 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -11632,6 +11704,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } From 2379e15f0c0bd248f19230b91a17e0cbfbc3bdcd Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 25 Feb 2025 12:47:21 -0500 Subject: [PATCH 241/323] fix(functions): Use emulated credentials when connecting to the emulator (#2857) * fix(functions): Use emulated credentials when connecting to the emulator * fix tests --- src/functions/functions-api-client-internal.ts | 15 ++++++++++++++- .../functions-api-client-internal.spec.ts | 14 ++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/functions/functions-api-client-internal.ts b/src/functions/functions-api-client-internal.ts index c3c3859c0d..e1fd04ee6d 100644 --- a/src/functions/functions-api-client-internal.ts +++ b/src/functions/functions-api-client-internal.ts @@ -54,7 +54,7 @@ export class FunctionsApiClient { 'invalid-argument', 'First argument passed to getFunctions() must be a valid Firebase app instance.'); } - this.httpClient = new AuthorizedHttpClient(app as FirebaseApp); + this.httpClient = new FunctionsHttpClient(app as FirebaseApp); } /** * Deletes a task from a queue. @@ -362,6 +362,19 @@ export class FunctionsApiClient { } } +/** + * Functions-specific HTTP client which uses the special "owner" token + * when communicating with the Emulator. + */ +class FunctionsHttpClient extends AuthorizedHttpClient { + protected getToken(): Promise { + if (process.env.CLOUD_TASKS_EMULATOR_HOST) { + return Promise.resolve('owner'); + } + return super.getToken(); + } +} + interface ErrorResponse { error?: Error; } diff --git a/test/unit/functions/functions-api-client-internal.spec.ts b/test/unit/functions/functions-api-client-internal.spec.ts index 15862d57b2..f1332b2e30 100644 --- a/test/unit/functions/functions-api-client-internal.spec.ts +++ b/test/unit/functions/functions-api-client-internal.spec.ts @@ -49,6 +49,12 @@ describe('FunctionsApiClient', () => { 'X-Goog-Api-Client': getMetricsHeader(), }; + const EXPECTED_HEADERS_EMULATOR = { + 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'Authorization': 'Bearer owner', + 'X-Goog-Api-Client': getMetricsHeader(), + }; + const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' + 'account credentials or set project ID as an app option. Alternatively, set the ' + 'GOOGLE_CLOUD_PROJECT environment variable.'; @@ -498,7 +504,7 @@ describe('FunctionsApiClient', () => { expect(stub).to.have.been.calledOnce.and.calledWith({ method: 'POST', url: CLOUD_TASKS_URL_EMULATOR, - headers: EXPECTED_HEADERS, + headers: EXPECTED_HEADERS_EMULATOR, data: { task: expectedPayload } @@ -519,7 +525,7 @@ describe('FunctionsApiClient', () => { expect(stub).to.have.been.calledOnce.and.calledWith({ method: 'POST', url: CLOUD_TASKS_URL_EMULATOR, - headers: EXPECTED_HEADERS, + headers: EXPECTED_HEADERS_EMULATOR, data: { task: expectedPayload } @@ -547,7 +553,7 @@ describe('FunctionsApiClient', () => { expect(stub).to.have.been.calledOnce.and.calledWith({ method: 'POST', url: CLOUD_TASKS_URL_EMULATOR, - headers: EXPECTED_HEADERS, + headers: EXPECTED_HEADERS_EMULATOR, data: { task: expectedPayload } @@ -603,7 +609,7 @@ describe('FunctionsApiClient', () => { expect(stub).to.have.been.calledWith({ method: 'DELETE', url: CLOUD_TASKS_URL_EMULATOR.concat('/', 'mock-task'), - headers: EXPECTED_HEADERS, + headers: EXPECTED_HEADERS_EMULATOR, }); }); From 3bf49396f8c4c6ed93feac14dc7f86bff6a18887 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:48:54 -0500 Subject: [PATCH 242/323] feat(fdc): Add support for Data Connect Impersonation (#2844) * Add support for Data Connect Impersonation * Add integration tests for impersonation * fix: export new interfaces and regenerate apidocs * fix: remove link to DecodedIdToken * remove test service id * Export alias type and update test descriptions * Revert accidental rebase * Export alias type `AuthClaims` and update test descriptions * Change token format link * Update tests to check each index values * Equality checks for tests * More equality checks --------- --- etc/firebase-admin.data-connect.api.md | 18 ++ .../data-connect-api-client-internal.ts | 1 + src/data-connect/data-connect-api.ts | 50 ++++ src/data-connect/index.ts | 3 + test/integration/data-connect.spec.ts | 271 +++++++++++++++--- 5 files changed, 301 insertions(+), 42 deletions(-) diff --git a/etc/firebase-admin.data-connect.api.md b/etc/firebase-admin.data-connect.api.md index bf3f3b6b19..3650368734 100644 --- a/etc/firebase-admin.data-connect.api.md +++ b/etc/firebase-admin.data-connect.api.md @@ -6,6 +6,11 @@ import { Agent } from 'http'; +// Warning: (ae-forgotten-export) The symbol "DecodedIdToken" needs to be exported by the entry point index.d.ts +// +// @public +export type AuthClaims = Partial; + // @public export interface ConnectorConfig { location: string; @@ -36,8 +41,21 @@ export function getDataConnect(connectorConfig: ConnectorConfig, app?: App): Dat // @public export interface GraphqlOptions { + impersonate?: ImpersonateAuthenticated | ImpersonateUnauthenticated; operationName?: string; variables?: Variables; } +// @public +export interface ImpersonateAuthenticated { + authClaims: AuthClaims; + unauthenticated?: never; +} + +// @public +export interface ImpersonateUnauthenticated { + authClaims?: never; + unauthenticated: true; +} + ``` diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts index 1f7b2da05c..b6082b91f5 100644 --- a/src/data-connect/data-connect-api-client-internal.ts +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -110,6 +110,7 @@ export class DataConnectApiClient { query, ...(options?.variables && { variables: options?.variables }), ...(options?.operationName && { operationName: options?.operationName }), + ...(options?.impersonate && { extensions: { impersonate: options?.impersonate } }), }; return this.getUrl(API_VERSION, this.connectorConfig.location, this.connectorConfig.serviceId, endpoint) .then(async (url) => { diff --git a/src/data-connect/data-connect-api.ts b/src/data-connect/data-connect-api.ts index df997a1dbe..1073437032 100644 --- a/src/data-connect/data-connect-api.ts +++ b/src/data-connect/data-connect-api.ts @@ -15,6 +15,8 @@ * limitations under the License. */ +import { DecodedIdToken } from '../auth/token-verifier'; + /** * Interface representing a Data Connect connector configuration. */ @@ -53,4 +55,52 @@ export interface GraphqlOptions { * The name of the GraphQL operation. Required only if `query` contains multiple operations. */ operationName?: string; + + /** + * If set, impersonate a request with given Firebase Auth context and evaluate the auth + * policies on the operation. If omitted, bypass any defined auth policies. + */ + impersonate?: ImpersonateAuthenticated | ImpersonateUnauthenticated; +} + +/** + * Type representing the partial claims of a Firebase Auth token used to evaluate the + * Data Connect auth policy. + */ +export type AuthClaims = Partial; + +/** + * Interface representing the impersonation of an authenticated user. + */ +export interface ImpersonateAuthenticated { + /** + * Evaluate the auth policy with a customized JWT auth token. Should follow the Firebase Auth token format. + * https://firebase.google.com/docs/data-connect/cel-reference#auth-token-contents + * + * @example A verified user may have the following `authClaims`: + * ```json + * { "sub": "uid", "email_verified": true } + * ``` + */ + authClaims: AuthClaims; + + /** + * Both `authClaims` and `unauthenticated` are mutually exclusive fields and should not be both set. + */ + unauthenticated?: never; +} + +/** + * Interface representing the impersonation of an unauthenticated user. + */ +export interface ImpersonateUnauthenticated { + /** + * Both `authClaims` and `unauthenticated` are mutually exclusive fields and should not be both set. + */ + authClaims?: never; + + /** + * Evaluates the auth policy as an unauthenticated request. Can only be set to true. + */ + unauthenticated: true; } diff --git a/src/data-connect/index.ts b/src/data-connect/index.ts index 77b9ab1e38..ab262682f2 100644 --- a/src/data-connect/index.ts +++ b/src/data-connect/index.ts @@ -30,6 +30,9 @@ export { GraphqlOptions, ExecuteGraphqlResponse, ConnectorConfig, + ImpersonateAuthenticated, + ImpersonateUnauthenticated, + AuthClaims } from './data-connect-api' export { DataConnect, diff --git a/test/integration/data-connect.spec.ts b/test/integration/data-connect.spec.ts index 32ea83cb87..f9ced89ece 100644 --- a/test/integration/data-connect.spec.ts +++ b/test/integration/data-connect.spec.ts @@ -16,7 +16,7 @@ import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { getDataConnect, ConnectorConfig } from '../../lib/data-connect/index'; +import { getDataConnect, ConnectorConfig, GraphqlOptions } from '../../lib/data-connect/index'; chai.should(); chai.use(chaiAsPromised); @@ -26,56 +26,59 @@ const expect = chai.expect; /* // Schema type User @table(key: "uid") { - uid: String! - name: String! - address: String! + uid: String! + name: String! + address: String! } +*/ +type User = { + uid?: string; + name?: string; + address?: string; + // Generated + emails_on_from?: Email[]; +}; +/* +// Schema type Email @table { - subject: String! - date: Date! - text: String! - from: User! + subject: String! + date: Date! + text: String! + from: User! } */ +type Email = { + subject?: string; + date?: string; + text?: string; + from?: User; + // Generated + id?: string; +}; interface UserResponse { - user: { - name: string; - uid: string; - } + user: User; } interface UsersResponse { - users: [ - user: { - id: string; - name: string; - address: string; - } - ]; + users: User[]; +} + +interface UserUpsertResponse { + user_upsert: { uid: string; }; } interface UserUpdateResponse { - user_upsert: { uid: string } + user_update: { uid: string; }; } interface EmailsResponse { - emails: [ - email: { - text: string; - subject: string; - id: string; - date: string; - from: { - name: string; - } - } - ]; + emails: Email[]; } interface UserVariables { - id: { uid: string }; + id: { uid: string; }; } const connectorConfig: ConnectorConfig = { @@ -90,17 +93,45 @@ describe('getDataConnect()', () => { const queryListUsers = 'query ListUsers @auth(level: PUBLIC) { users { uid, name, address } }'; const queryListEmails = 'query ListEmails @auth(level: NO_ACCESS) { emails { id subject text date from { name } } }'; const queryGetUserById = 'query GetUser($id: User_Key!) { user(key: $id) { uid name } }'; + + const queryListUsersImpersonation = ` + query ListUsers @auth(level: USER) { + users(where: { uid: { eq_expr: "auth.uid" } }) { uid, name, address } + }`; + const multipleQueries = ` ${queryListUsers} ${queryListEmails} `; + const mutation = `mutation user { user_insert(data: {uid: "${userId}", address: "32 St", name: "Fred Car"}) }`; + + const updateImpersonatedUser = ` + mutation UpdateUser @auth(level: USER) { + user_update(key: { uid_expr: "auth.uid" }, data: { address: "32 Elm St.", name: "Fredrick" }) + }`; + const upsertUser = `mutation UpsertUser($id: String) { user_upsert(data: { uid: $id, address: "32 St.", name: "Fred" }) }`; + const testUser = { + name: 'Fred', + address: '32 St.', + uid: userId + } + + const expectedUsers = [ + testUser, + { + name: 'Jeff', + address: '99 Oak St. N', + uid: 'QVBJcy5ndXJ1' + } + ]; + describe('executeGraphql()', () => { it('executeGraphql() successfully executes a GraphQL mutation', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( + const resp = await getDataConnect(connectorConfig).executeGraphql( upsertUser, { variables: { id: userId } } ); //{ data: { user_insert: { uid: 'QVBJcy5ndXJ3' } } } @@ -111,18 +142,21 @@ describe('getDataConnect()', () => { it('executeGraphql() successfully executes a GraphQL', async () => { const resp = await getDataConnect(connectorConfig).executeGraphql(queryListUsers); expect(resp.data.users).to.be.not.empty; - expect(resp.data.users[0].name).to.be.not.undefined; - expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users.length).to.be.greaterThan(1); + expectedUsers.forEach((expectedUser) => { + expect(resp.data.users).to.deep.include(expectedUser); + }); }); it('executeGraphql() use the operationName when multiple queries are provided', async () => { const resp = await getDataConnect(connectorConfig).executeGraphql( - multipleQueries, + multipleQueries, { operationName: 'ListEmails' } ); expect(resp.data.emails).to.be.not.empty; + expect(resp.data.emails.length).equals(1); expect(resp.data.emails[0].id).to.be.not.undefined; - expect(resp.data.emails[0].from.name).to.be.not.undefined; + expect(resp.data.emails[0].from?.name).to.equal('Jeff'); }); it('executeGraphql() should throw for a query error', async () => { @@ -135,8 +169,9 @@ describe('getDataConnect()', () => { queryGetUserById, { variables: { id: { uid: userId } } } ); - expect(resp.data.user.name).to.be.not.undefined; - expect(resp.data.user.uid).equals(userId); + expect(resp.data.user.uid).to.equal(testUser.uid); + expect(resp.data.user.name).to.equal(testUser.name); + expect(resp.data.user.address).to.be.undefined; }); }); @@ -145,13 +180,165 @@ describe('getDataConnect()', () => { const resp = await getDataConnect(connectorConfig).executeGraphqlRead(queryListUsers); expect(resp.data.users).to.be.not.empty; - expect(resp.data.users[0].name).to.be.not.undefined; - expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users.length).to.be.greaterThan(1); + expectedUsers.forEach((expectedUser) => { + expect(resp.data.users).to.deep.include(expectedUser); + }); }); it('executeGraphqlRead() should throw for a GraphQL mutation', async () => { return getDataConnect(connectorConfig).executeGraphqlRead(mutation) - .should.eventually.be.rejected; + .should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + }); + + describe('Impersonation', () => { + const optsAuthorizedClaims: GraphqlOptions = { + impersonate: { + authClaims: { + sub: userId, + email_verified: true + } + } + }; + + const optsNonExistingClaims: GraphqlOptions = { + impersonate: { + authClaims: { + sub: 'non-exisiting-id', + email_verified: true + } + } + }; + + const optsUnauthorizedClaims: GraphqlOptions = { + impersonate: { + unauthenticated: true + } + }; + + describe('USER Auth Policy', () => { + it('executeGraphqlRead() successfully executes an impersonated query with authenticated claims', async () => { + const resp = + await getDataConnect(connectorConfig).executeGraphqlRead( + queryListUsersImpersonation, optsAuthorizedClaims); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users.length).equals(1); + expect(resp.data.users[0]).to.deep.equal(testUser); + }); + + it('executeGraphqlRead() should throw for impersonated query with unauthenticated claims', async () => { + return getDataConnect(connectorConfig).executeGraphqlRead(queryListUsersImpersonation, optsUnauthorizedClaims) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('executeGraphql() successfully executes an impersonated query with authenticated claims', async () => { + const resp = + await getDataConnect(connectorConfig).executeGraphqlRead( + queryListUsersImpersonation, optsAuthorizedClaims); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users.length).equals(1); + expect(resp.data.users[0]).to.deep.equal(testUser); + }); + + it('executeGraphql() should throw for impersonated query with unauthenticated claims', async () => { + return getDataConnect(connectorConfig).executeGraphql(queryListUsersImpersonation, optsUnauthorizedClaims) + .should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated'); + }); + + it('executeGraphql() should return an empty list for an impersonated query with non-existing authenticated ' + + 'claims', + async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsersImpersonation, optsNonExistingClaims); + // Should find no data + expect(resp.data.users).to.be.empty; + }); + + it('executeGraphql() successfully executes an impersonated mutation with authenticated claims', + async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + updateImpersonatedUser, optsAuthorizedClaims); + // Fred -> Fredrick + expect(resp.data.user_update.uid).equals(userId); + }); + + it('executeGraphql() should throw for impersonated mutation with unauthenticated claims', async () => { + return getDataConnect(connectorConfig).executeGraphql(updateImpersonatedUser, optsUnauthorizedClaims) + .should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated'); + }); + + it('executeGraphql() should return null for an impersonated mutation with non-existing authenticated claims', + async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + updateImpersonatedUser, optsNonExistingClaims); + // Should mutate no data + expect(resp.data.user_update).to.be.null; + }); + }); + + describe('PUBLIC Auth Policy', () => { + const expectedUsers = [ + { + name: 'Fredrick', + address: '32 Elm St.', + uid: userId + }, + { + name: 'Jeff', + address: '99 Oak St. N', + uid: 'QVBJcy5ndXJ1' + } + ]; + + it('executeGraphql() successfully executes an impersonated query with authenticated claims', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsers, optsAuthorizedClaims); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users.length).to.be.greaterThan(1); + expectedUsers.forEach((expectedUser) => { + expect(resp.data.users).to.deep.include(expectedUser); + }) + }); + + it('executeGraphql() successfully executes an impersonated query with unauthenticated claims', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsers, optsUnauthorizedClaims); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users.length).to.be.greaterThan(1); + expectedUsers.forEach((expectedUser) => { + expect(resp.data.users).to.deep.include(expectedUser); + }); + }); + + it('executeGraphql() successfully executes an impersonated query with non-existing authenticated claims', + async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsers, optsNonExistingClaims); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users.length).to.be.greaterThan(1); + expectedUsers.forEach((expectedUser) => { + expect(resp.data.users).to.deep.include(expectedUser); + }); + }); + }); + + describe('NO_ACCESS Auth Policy', () => { + it('executeGraphql() should throw for an impersonated query with authenticated claims', async () => { + return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsAuthorizedClaims) + .should.eventually.be.rejected.and.has.property('code', 'data-connect/permission-denied'); + }); + + it('executeGraphql() should throw for an impersonated query with unauthenticated claims', async () => { + return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsUnauthorizedClaims) + .should.eventually.be.rejected.and.has.property('code', 'data-connect/permission-denied'); + }); + + it('executeGraphql() should throw for an impersonated query with non-existing authenticated claims', + async () => { + return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsNonExistingClaims) + .should.eventually.be.rejected.and.has.property('code', 'data-connect/permission-denied'); + }); }); }); }); From 2717cf7109c142db642878444f13391d6500c3eb Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 5 Mar 2025 13:10:02 -0500 Subject: [PATCH 243/323] [chore] Release 13.2.0 (#2866) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0251f72b70..09dd872eba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.1.0", + "version": "13.2.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 8beb1a33672bcefaa3cdb57239ebd5c4072179fb Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 5 Mar 2025 14:18:05 -0500 Subject: [PATCH 244/323] [chore] Release 13.2.0 Take 2 (#2867) --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dab28224c2..e2a7eb9cea 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -101,6 +101,8 @@ jobs: startsWith(github.event.pull_request.title, '[chore] Release ') runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Checkout source for publish From 4003298cbd2ba412995744d4b9ad4d7c9c78c6a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 16:00:58 +0000 Subject: [PATCH 245/323] build(deps-dev): bump @microsoft/api-extractor from 7.48.1 to 7.52.1 (#2877) --- package-lock.json | 212 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 172 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 161d03d281..9a8c72646f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.1.0", + "version": "13.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.1.0", + "version": "13.2.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -1203,56 +1203,60 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.48.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.48.1.tgz", - "integrity": "sha512-HN9Osa1WxqLM66RaqB5nPAadx+nTIQmY/XtkFdaJvusjG8Tus++QqZtD7KPZDSkhEMGHsYeSyeU8qUzCDUXPjg==", + "version": "7.52.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.1.tgz", + "integrity": "sha512-m3I5uAwE05orsu3D1AGyisX5KxsgVXB+U4bWOOaX/Z7Ftp/2Cy41qsNhO6LPvSxHBaapyser5dVorF1t5M6tig==", "dev": true, + "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.30.1", + "@microsoft/api-extractor-model": "7.30.4", "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.10.1", + "@rushstack/node-core-library": "5.12.0", "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.14.4", - "@rushstack/ts-command-line": "4.23.2", + "@rushstack/terminal": "0.15.1", + "@rushstack/ts-command-line": "4.23.6", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", - "typescript": "5.4.2" + "typescript": "5.8.2" }, "bin": { "api-extractor": "bin/api-extractor" } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.30.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.1.tgz", - "integrity": "sha512-CTS2PlASJHxVY8hqHORVb1HdECWOEMcMnM6/kDkPr0RZapAFSIHhg9D4jxuE8g+OWYHtPc10LCpmde5pylTRlA==", + "version": "7.30.4", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.4.tgz", + "integrity": "sha512-RobC0gyVYsd2Fao9MTKOfTdBm41P/bCMUmzS5mQ7/MoAKEqy0FOBph3JOYdq4X4BsEnMEiSHc+0NUNmdzxCpjA==", "dev": true, + "license": "MIT", "dependencies": { "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.10.1" + "@rushstack/node-core-library": "5.12.0" } }, "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz", - "integrity": "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.12.0.tgz", + "integrity": "sha512-QSwwzgzWoil1SCQse+yCHwlhRxNv2dX9siPnAb9zR/UmMhac4mjMrlMZpk64BlCeOFi1kJKgXRkihSwRMbboAQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", - "fs-extra": "~7.0.1", + "fs-extra": "~11.3.0", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", @@ -1272,6 +1276,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -1283,6 +1288,44 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@microsoft/api-extractor-model/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@microsoft/api-extractor-model/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@microsoft/api-extractor-model/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@microsoft/api-extractor/node_modules/@microsoft/tsdoc": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", @@ -1290,15 +1333,16 @@ "dev": true }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz", - "integrity": "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.12.0.tgz", + "integrity": "sha512-QSwwzgzWoil1SCQse+yCHwlhRxNv2dX9siPnAb9zR/UmMhac4mjMrlMZpk64BlCeOFi1kJKgXRkihSwRMbboAQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", - "fs-extra": "~7.0.1", + "fs-extra": "~11.3.0", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", @@ -1314,12 +1358,13 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.2.tgz", - "integrity": "sha512-JJ7XZX5K3ThBBva38aomgsPv1L7FV6XmSOcR6HtM7HDFZJkepqT65imw26h9ggGqMjsY0R9jcl30tzKcVj9aOQ==", + "version": "4.23.6", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.6.tgz", + "integrity": "sha512-7WepygaF3YPEoToh4MAL/mmHkiIImQq3/uAkQX46kVoKTNOOlCtFGyNnze6OYuWw2o9rxsyrHVfIBKxq/am2RA==", "dev": true, + "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.14.4", + "@rushstack/terminal": "0.15.1", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1330,6 +1375,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -1341,10 +1387,38 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@microsoft/api-extractor/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1355,6 +1429,16 @@ "node": ">=14.17" } }, + "node_modules/@microsoft/api-extractor/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@microsoft/tsdoc": { "version": "0.12.24", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz", @@ -1367,6 +1451,7 @@ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz", "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==", "dev": true, + "license": "MIT", "dependencies": { "@microsoft/tsdoc": "0.15.1", "ajv": "~8.12.0", @@ -1378,7 +1463,8 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -1548,12 +1634,13 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.4.tgz", - "integrity": "sha512-NxACqERW0PHq8Rpq1V6v5iTHEwkRGxenjEW+VWqRYQ8T9puUzgmGHmEZUaUEDHAe9Qyvp0/Ew04sAiQw9XjhJg==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.1.tgz", + "integrity": "sha512-3vgJYwumcjoDOXU3IxZfd616lqOdmr8Ezj4OWgJZfhmiBK4Nh7eWcv8sU8N/HdzXcuHDXCRGn/6O2Q75QvaZMA==", "dev": true, + "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.10.1", + "@rushstack/node-core-library": "5.12.0", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -1566,15 +1653,16 @@ } }, "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz", - "integrity": "sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.12.0.tgz", + "integrity": "sha512-QSwwzgzWoil1SCQse+yCHwlhRxNv2dX9siPnAb9zR/UmMhac4mjMrlMZpk64BlCeOFi1kJKgXRkihSwRMbboAQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", - "fs-extra": "~7.0.1", + "fs-extra": "~11.3.0", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", @@ -1594,6 +1682,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -1605,6 +1694,44 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@rushstack/terminal/node_modules/fs-extra": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@rushstack/terminal/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@rushstack/terminal/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@rushstack/ts-command-line": { "version": "4.15.2", "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz", @@ -2314,6 +2441,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -2330,6 +2458,7 @@ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^8.5.0" }, @@ -2344,6 +2473,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -7239,7 +7369,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -9736,6 +9867,7 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } From a58ef0a11c544341d3b8feda035332800da7a1f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 16:05:18 +0000 Subject: [PATCH 246/323] build(deps-dev): bump @firebase/app-compat from 0.2.48 to 0.2.51 (#2872) --- package-lock.json | 52 ++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9a8c72646f..33bbc28c0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -529,15 +529,15 @@ } }, "node_modules/@firebase/app": { - "version": "0.10.18", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.18.tgz", - "integrity": "sha512-VuqEwD/QRisKd/zsFsqgvSAx34mZ3WEF47i97FD6Vw4GWAhdjepYf0Hmi6K0b4QMSgWcv/x0C30Slm5NjjERXg==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.11.2.tgz", + "integrity": "sha512-bFee0hPJZBzNtiizRxdgsu8C9DW3mn1y0OJJ4zHQsccjDYzGOfvN0G3CMGyBIiwNctsFpQa8orbp2IKywoUeqA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.12", + "@firebase/component": "0.6.13", "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", + "@firebase/util": "1.11.0", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -552,16 +552,16 @@ "license": "Apache-2.0" }, "node_modules/@firebase/app-compat": { - "version": "0.2.48", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.48.tgz", - "integrity": "sha512-wVNU1foBIaJncUmiALyRxhHHHC3ZPMLIETTAk+2PG87eP9B/IDBsYUiTpHyboDPEI8CgBPat/zN2v+Snkz6lBw==", + "version": "0.2.51", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.51.tgz", + "integrity": "sha512-pxF1+coABt+ugqNI0YXDlmkKv4kh3pjI5BqIJJ1VXBo42OZbKMsQbFeos14YBrWwiqqSjUvQ70FBNsv5E2wuxg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@firebase/app": "0.10.18", - "@firebase/component": "0.6.12", + "@firebase/app": "0.11.2", + "@firebase/component": "0.6.13", "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", + "@firebase/util": "1.11.0", "tslib": "^2.1.0" }, "engines": { @@ -569,13 +569,13 @@ } }, "node_modules/@firebase/app-compat/node_modules/@firebase/component": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", - "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.13.tgz", + "integrity": "sha512-I/Eg1NpAtZ8AAfq8mpdfXnuUpcLxIDdCDtTzWSh+FXnp/9eCKJ3SNbOCKrUCyhLzNa2SiPJYruei0sxVjaOTeg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.10.3", + "@firebase/util": "1.11.0", "tslib": "^2.1.0" }, "engines": { @@ -583,10 +583,11 @@ } }, "node_modules/@firebase/app-compat/node_modules/@firebase/util": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", - "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.0.tgz", + "integrity": "sha512-PzSrhIr++KI6y4P6C/IdgBNMkEx0Ex6554/cYd0Hm+ovyFSJtJXqb/3OSIdnBoa2cpwZT1/GW56EmRc5qEc5fQ==", "dev": true, + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -601,13 +602,13 @@ "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" }, "node_modules/@firebase/app/node_modules/@firebase/component": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", - "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.13.tgz", + "integrity": "sha512-I/Eg1NpAtZ8AAfq8mpdfXnuUpcLxIDdCDtTzWSh+FXnp/9eCKJ3SNbOCKrUCyhLzNa2SiPJYruei0sxVjaOTeg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.10.3", + "@firebase/util": "1.11.0", "tslib": "^2.1.0" }, "engines": { @@ -615,10 +616,11 @@ } }, "node_modules/@firebase/app/node_modules/@firebase/util": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", - "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.0.tgz", + "integrity": "sha512-PzSrhIr++KI6y4P6C/IdgBNMkEx0Ex6554/cYd0Hm+ovyFSJtJXqb/3OSIdnBoa2cpwZT1/GW56EmRc5qEc5fQ==", "dev": true, + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" From d0d40bf19a14a424de6ea17373e17c4ee4f21599 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Tue, 18 Mar 2025 15:26:04 -0400 Subject: [PATCH 247/323] fix(fcm): Wrap HTTP/2 session errors in promise (#2868) * Promise based option * Throw session errors and bundle with a promise to a BatchResponse if one exists * Cleaned up implementation and updated session error types * Added unit test * rebuild apidocs * Wrap session errors in a new `FirebaseMessagingSessionError` --- src/messaging/messaging.ts | 95 +++++++++++++++++---------- src/utils/api-request.ts | 31 +++++++-- src/utils/error.ts | 33 ++++++++++ test/resources/mocks.ts | 18 +++-- test/unit/messaging/messaging.spec.ts | 31 +++++++++ test/unit/utils/api-request.spec.ts | 44 ++++++++++++- 6 files changed, 201 insertions(+), 51 deletions(-) diff --git a/src/messaging/messaging.ts b/src/messaging/messaging.ts index 1c1e2a5887..8e61cd679a 100644 --- a/src/messaging/messaging.ts +++ b/src/messaging/messaging.ts @@ -17,7 +17,9 @@ import { App } from '../app'; import { deepCopy } from '../utils/deep-copy'; -import { ErrorInfo, MessagingClientErrorCode, FirebaseMessagingError } from '../utils/error'; +import { + ErrorInfo, MessagingClientErrorCode, FirebaseMessagingError, FirebaseMessagingSessionError +} from '../utils/error'; import * as utils from '../utils'; import * as validator from '../utils/validator'; import { validateMessage } from './messaging-internal'; @@ -206,48 +208,71 @@ export class Messaging { MessagingClientErrorCode.INVALID_ARGUMENT, 'dryRun must be a boolean'); } - const http2SessionHandler = this.useLegacyTransport ? undefined : new Http2SessionHandler(`https://${FCM_SEND_HOST}`) + const http2SessionHandler = this.useLegacyTransport ? undefined : new Http2SessionHandler(`https://${FCM_SEND_HOST}`); return this.getUrlPath() .then((urlPath) => { - const requests: Promise[] = copy.map(async (message) => { - validateMessage(message); - const request: { message: Message; validate_only?: boolean } = { message }; - if (dryRun) { - request.validate_only = true; - } - - if (http2SessionHandler){ - return this.messagingRequestHandler.invokeHttp2RequestHandlerForSendResponse( - FCM_SEND_HOST, urlPath, request, http2SessionHandler); - } - return this.messagingRequestHandler.invokeHttpRequestHandlerForSendResponse(FCM_SEND_HOST, urlPath, request); - }); - return Promise.allSettled(requests); - }) - .then((results) => { - const responses: SendResponse[] = []; - results.forEach(result => { - if (result.status === 'fulfilled') { - responses.push(result.value); - } else { // rejected - responses.push({ success: false, error: result.reason }) - } - }) - const successCount: number = responses.filter((resp) => resp.success).length; - return { - responses, - successCount, - failureCount: responses.length - successCount, - }; + if (http2SessionHandler) { + let sendResponsePromise: Promise[]>; + return new Promise((resolve: (result: PromiseSettledResult[]) => void, reject) => { + // Start session listeners + http2SessionHandler.invoke().catch((error) => { + const pendingBatchResponse = + sendResponsePromise ? sendResponsePromise.then(this.parseSendResponses) : undefined; + reject(new FirebaseMessagingSessionError(error, undefined, pendingBatchResponse)); + }); + + // Start making requests + const requests: Promise[] = copy.map(async (message) => { + validateMessage(message); + const request: { message: Message; validate_only?: boolean; } = { message }; + if (dryRun) { + request.validate_only = true; + } + return this.messagingRequestHandler.invokeHttp2RequestHandlerForSendResponse( + FCM_SEND_HOST, urlPath, request, http2SessionHandler); + }); + + // Resolve once all requests have completed + sendResponsePromise = Promise.allSettled(requests); + sendResponsePromise.then(resolve); + }); + } else { + const requests: Promise[] = copy.map(async (message) => { + validateMessage(message); + const request: { message: Message; validate_only?: boolean; } = { message }; + if (dryRun) { + request.validate_only = true; + } + return this.messagingRequestHandler.invokeHttpRequestHandlerForSendResponse( + FCM_SEND_HOST, urlPath, request); + }); + return Promise.allSettled(requests); + } }) + .then(this.parseSendResponses) .finally(() => { - if (http2SessionHandler){ - http2SessionHandler.close() - } + http2SessionHandler?.close(); }); } + private parseSendResponses(results: PromiseSettledResult[]): BatchResponse { + const responses: SendResponse[] = []; + results.forEach(result => { + if (result.status === 'fulfilled') { + responses.push(result.value); + } else { // rejected + responses.push({ success: false, error: result.reason }); + } + }); + const successCount: number = responses.filter((resp) => resp.success).length; + return { + responses, + successCount, + failureCount: responses.length - successCount, + }; + } + /** * Sends the given multicast message to all the FCM registration tokens * specified in it. diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index c5e284e414..ca3140a27d 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -1054,6 +1054,7 @@ class Http2RequestConfigImpl extends BaseRequestConfigImpl implements Http2Reque public buildRequestOptions(): https.RequestOptions { const parsed = this.buildUrl(); + // TODO(b/401051826) const protocol = parsed.protocol; return { @@ -1315,9 +1316,16 @@ export class ExponentialBackoffPoller extends EventEmitter { export class Http2SessionHandler { private http2Session: http2.ClientHttp2Session + protected promise: Promise + protected resolve: () => void; + protected reject: (_: any) => void; constructor(url: string){ - this.http2Session = this.createSession(url) + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + this.http2Session = this.createSession(url) + }); } public createSession(url: string): http2.ClientHttp2Session { @@ -1330,23 +1338,32 @@ export class Http2SessionHandler { const http2Session = http2.connect(url, opts) http2Session.on('goaway', (errorCode, _, opaqueData) => { - throw new FirebaseAppError( + this.reject(new FirebaseAppError( AppErrorCodes.NETWORK_ERROR, - `Error while making requests: GOAWAY - ${opaqueData.toString()}, Error code: ${errorCode}` - ); + `Error while making requests: GOAWAY - ${opaqueData?.toString()}, Error code: ${errorCode}` + )); }) http2Session.on('error', (error) => { - throw new FirebaseAppError( + this.reject(new FirebaseAppError( AppErrorCodes.NETWORK_ERROR, - `Error while making requests: ${error}` - ); + `Session error while making requests: ${error}` + )); }) + + http2Session.on('close', () => { + // Resolve current promise + this.resolve() + }); return http2Session } return this.http2Session } + public invoke(): Promise { + return this.promise + } + get session(): http2.ClientHttp2Session { return this.http2Session } diff --git a/src/utils/error.ts b/src/utils/error.ts index cf3736adcb..a80254b5b8 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -16,6 +16,7 @@ */ import { FirebaseError as FirebaseErrorInterface } from '../app'; +import { BatchResponse } from '../messaging/messaging-api'; import { deepCopy } from '../utils/deep-copy'; /** @@ -344,6 +345,38 @@ export class FirebaseMessagingError extends PrefixedFirebaseError { } } +export class FirebaseMessagingSessionError extends FirebaseMessagingError { + public pendingBatchResponse?: Promise; + /** + * + * @param info - The error code info. + * @param message - The error message. This will override the default message if provided. + * @param pendingBatchResponse - BatchResponse for pending messages when session error occured. + * @constructor + * @internal + */ + constructor(info: ErrorInfo, message?: string, pendingBatchResponse?: Promise) { + // Override default message if custom message provided. + super(info, message || info.message); + this.pendingBatchResponse = pendingBatchResponse; + + /* tslint:disable:max-line-length */ + // Set the prototype explicitly. See the following link for more details: + // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work + /* tslint:enable:max-line-length */ + (this as any).__proto__ = FirebaseMessagingSessionError.prototype; + } + + /** @returns The object representation of the error. */ + public toJSON(): object { + return { + code: this.code, + message: this.message, + pendingBatchResponse: this.pendingBatchResponse, + }; + } +} + /** * Firebase project management error code structure. This extends PrefixedFirebaseError. */ diff --git a/test/resources/mocks.ts b/test/resources/mocks.ts index d4afddd879..f9d08023d2 100644 --- a/test/resources/mocks.ts +++ b/test/resources/mocks.ts @@ -322,10 +322,11 @@ export interface MockHttp2Request { } export interface MockHttp2Response { - headers: http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader, - data: Buffer, + headers?: http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader, + data?: Buffer, delay?: number, - error?: any + sessionError?: any + streamError?: any, } export class Http2Mocker { @@ -340,12 +341,12 @@ export class Http2Mocker { this.connectStub = sinon.stub(http2, 'connect'); this.connectStub.callsFake((_target: any, options: any) => { const session = this.originalConnect('https://www.example.com', options); - session.request = this.createMockRequest() + session.request = this.createMockRequest(session) return session; }) } - private createMockRequest() { + private createMockRequest(session:http2.ClientHttp2Session) { return (requestHeaders: http2.OutgoingHttpHeaders) => { // Create a mock ClientHttp2Stream to return const mockStream = new stream.Readable({ @@ -365,8 +366,11 @@ export class Http2Mocker { const mockRes = this.mockResponses.shift(); if (mockRes) { this.timeouts.push(setTimeout(() => { - if (mockRes.error) { - mockStream.emit('error', mockRes.error) + if (mockRes.sessionError) { + session.emit('error', mockRes.sessionError) + } + if (mockRes.streamError) { + mockStream.emit('error', mockRes.streamError) } else { mockStream.emit('response', mockRes.headers); diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index 488056488e..1ea0c059de 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -34,6 +34,7 @@ import { import { HttpClient } from '../../../src/utils/api-request'; import { getMetricsHeader, getSdkVersion } from '../../../src/utils/index'; import * as utils from '../utils'; +import { FirebaseMessagingSessionError } from '../../../src/utils/error'; chai.should(); chai.use(sinonChai); @@ -121,6 +122,12 @@ function mockHttp2SendRequestError( } as mocks.MockHttp2Response } +function mockHttp2Error(streamError?: any, sessionError?:any): mocks.MockHttp2Response { + return { + streamError: streamError, + sessionError: sessionError + } as mocks.MockHttp2Response +} function mockErrorResponse( path: string, @@ -906,6 +913,30 @@ describe('Messaging', () => { }); }); + it('should throw error with BatchResponse promise on session error event using HTTP/2', () => { + mockedHttp2Responses.push(mockHttp2SendRequestResponse('projects/projec_id/messages/1')) + const sessionError = 'MOCK_SESSION_ERROR' + mockedHttp2Responses.push(mockHttp2Error( + new Error(`MOCK_STREAM_ERROR caused by ${sessionError}`), + new Error(sessionError) + )); + http2Mocker.http2Stub(mockedHttp2Responses) + + return messaging.sendEach( + [validMessage, validMessage], true + ).catch(async (error: FirebaseMessagingSessionError) => { + expect(error.code).to.equal('messaging/app/network-error'); + expect(error.pendingBatchResponse).to.not.be.undefined; + await error.pendingBatchResponse?.then((response: BatchResponse) => { + expect(http2Mocker.requests.length).to.equal(2); + expect(response.failureCount).to.equal(1); + const responses = response.responses; + checkSendResponseSuccess(responses[0], 'projects/projec_id/messages/1'); + checkSendResponseFailure(responses[1], 'app/network-error'); + }) + }); + }) + // This test was added to also verify https://github.com/firebase/firebase-admin-node/issues/1146 it('should be fulfilled when called with different message types using HTTP/2', () => { const messageIds = [ diff --git a/test/unit/utils/api-request.spec.ts b/test/unit/utils/api-request.spec.ts index d64589f8c9..691f0f89e0 100644 --- a/test/unit/utils/api-request.spec.ts +++ b/test/unit/utils/api-request.spec.ts @@ -140,12 +140,14 @@ function mockHttp2SendRequestError( } as mocks.MockHttp2Response } -function mockHttp2Error(err: any): mocks.MockHttp2Response { +function mockHttp2Error(streamError?: any, sessionError?:any): mocks.MockHttp2Response { return { - error: err + streamError: streamError, + sessionError: sessionError } as mocks.MockHttp2Response } + /** * Returns a new RetryConfig instance for testing. This is same as the default * RetryConfig, with the backOffFactor set to 0 to avoid delays. @@ -2500,6 +2502,44 @@ describe('Http2Client', () => { http2SessionHandler: http2SessionHandler }).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error'); }); + + it('should fail on session and stream errors', async () => { + const reqData = { request: 'data' }; + const streamError = 'Error while making request: test stream error. Error code: AWFUL_STREAM_ERROR'; + const sessionError = 'Session error while making requests: Error: AWFUL_SESSION_ERROR' + mockedHttp2Responses.push(mockHttp2Error( + { message: 'test stream error', code: 'AWFUL_STREAM_ERROR' }, + new Error('AWFUL_SESSION_ERROR') + )); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl) + + await client.send({ + method: 'POST', + url: mockUrl, + headers: { + 'authorization': 'Bearer token', + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(streamError).and.have.property('code', 'app/network-error') + .then(() => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('POST'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(JSON.parse(http2Mocker.requests[0].data)).to.deep.equal(reqData); + expect(http2Mocker.requests[0].headers.authorization).to.equal('Bearer token'); + expect(http2Mocker.requests[0].headers['content-type']).to.contain('application/json'); + expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue'); + }); + + await http2SessionHandler.invoke().should.eventually.be.rejectedWith(sessionError) + .and.have.property('code', 'app/network-error') + }); }); describe('AuthorizedHttpClient', () => { From a46086b61f58f07426a6ca103e00385ae216691d Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:42:05 -0400 Subject: [PATCH 248/323] feat(fcm): Support `proxy` field in FCM `AndroidNotification` (#2874) * feat(fcm): Support `proxy` field on `AndroidNotification` * update doc string * fix: Update `proxy` and `visibility` doc string with TW suggestion --- etc/firebase-admin.messaging.api.md | 1 + src/messaging/messaging-api.ts | 10 +++++++++- src/messaging/messaging-internal.ts | 5 +++++ test/integration/messaging.spec.ts | 1 + test/unit/messaging/messaging.spec.ts | 4 ++++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index b4ee30a9f0..f0adaa0f35 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -43,6 +43,7 @@ export interface AndroidNotification { localOnly?: boolean; notificationCount?: number; priority?: ('min' | 'low' | 'default' | 'high' | 'max'); + proxy?: ('allow' | 'deny' | 'if_priority_lowered'); sound?: string; sticky?: boolean; tag?: string; diff --git a/src/messaging/messaging-api.ts b/src/messaging/messaging-api.ts index 01c20c7291..69c16382d5 100644 --- a/src/messaging/messaging-api.ts +++ b/src/messaging/messaging-api.ts @@ -593,7 +593,8 @@ export interface AndroidNotification { /** * Sets the visibility of the notification. Must be either `private`, `public`, - * or `secret`. If unspecified, defaults to `private`. + * or `secret`. If unspecified, it remains undefined in the Admin SDK, and + * defers to the FCM backend's default mapping. */ visibility?: ('private' | 'public' | 'secret'); @@ -608,6 +609,13 @@ export interface AndroidNotification { * displayed on the long-press menu each time a new notification arrives. */ notificationCount?: number; + + /** + * Sets if this notification should attempt to be proxied. Must be either + * `allow`, `deny` or `if_priority_lowered`. If unspecified, it remains + * undefined in the Admin SDK, and defers to the FCM backend's default mapping. + */ + proxy?: ('allow' | 'deny' | 'if_priority_lowered'); } /** diff --git a/src/messaging/messaging-internal.ts b/src/messaging/messaging-internal.ts index 6f1f7a3c74..725769bb32 100644 --- a/src/messaging/messaging-internal.ts +++ b/src/messaging/messaging-internal.ts @@ -475,6 +475,11 @@ function validateAndroidNotification(notification: AndroidNotification | undefin (notification as any).priority = priority; } + if (typeof notification.proxy !== 'undefined') { + const proxy = notification.proxy.toUpperCase(); + (notification as any).proxy = proxy; + } + if (typeof notification.visibility !== 'undefined') { const visibility = notification.visibility.toUpperCase(); (notification as any).visibility = visibility; diff --git a/test/integration/messaging.spec.ts b/test/integration/messaging.spec.ts index 409261f6aa..97adc8e008 100644 --- a/test/integration/messaging.spec.ts +++ b/test/integration/messaging.spec.ts @@ -64,6 +64,7 @@ const message: Message = { }, defaultLightSettings: false, notificationCount: 1, + proxy: 'if_priority_lowered', }, }, apns: { diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index 1ea0c059de..79942f73d2 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -1855,6 +1855,7 @@ describe('Messaging', () => { ticker: 'test.ticker', sticky: true, visibility: 'private', + proxy: 'deny', }, }, }, @@ -1871,6 +1872,7 @@ describe('Messaging', () => { ticker: 'test.ticker', sticky: true, visibility: 'PRIVATE', + proxy: 'DENY' }, }, }, @@ -2001,6 +2003,7 @@ describe('Messaging', () => { }, defaultLightSettings: false, notificationCount: 1, + proxy: 'if_priority_lowered', }, fcmOptions: { analyticsLabel: 'test.analytics', @@ -2053,6 +2056,7 @@ describe('Messaging', () => { }, default_light_settings: false, notification_count: 1, + proxy: 'IF_PRIORITY_LOWERED', }, fcmOptions: { analyticsLabel: 'test.analytics', From 43e5860ee6dc41d622a707b77339b96a5bbc86fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Apr 2025 16:48:53 +0000 Subject: [PATCH 249/323] build(deps): bump jwks-rsa from 3.1.0 to 3.2.0 (#2885) --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 33bbc28c0a..81d207924f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7489,15 +7489,15 @@ } }, "node_modules/jwks-rsa": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", - "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", + "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", "license": "MIT", "dependencies": { - "@types/express": "^4.17.17", - "@types/jsonwebtoken": "^9.0.2", + "@types/express": "^4.17.20", + "@types/jsonwebtoken": "^9.0.4", "debug": "^4.3.4", - "jose": "^4.14.6", + "jose": "^4.15.4", "limiter": "^1.1.5", "lru-memoizer": "^2.2.0" }, From 1636b5bf57fde57ad2636bf6e971755b4019c372 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 16 Apr 2025 12:53:21 -0400 Subject: [PATCH 250/323] fix(fcm): Provide inner errors from a session `AggregateError` to remove ambiguity (#2879) --- src/utils/api-request.ts | 9 ++++- test/unit/utils/api-request.spec.ts | 52 +++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index ca3140a27d..f26fcf9326 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -1345,9 +1345,16 @@ export class Http2SessionHandler { }) http2Session.on('error', (error) => { + let errorMessage: any; + if (error.name == 'AggregateError' && error.errors) { + errorMessage = `Session error while making requests: ${error.code} - ${error.name}: ` + + `[${error.errors.map((error: any) => error.message).join(', ')}]` + } else { + errorMessage = `Session error while making requests: ${error.code} - ${error.message} ` + } this.reject(new FirebaseAppError( AppErrorCodes.NETWORK_ERROR, - `Session error while making requests: ${error}` + errorMessage )); }) diff --git a/test/unit/utils/api-request.spec.ts b/test/unit/utils/api-request.spec.ts index 691f0f89e0..642d011460 100644 --- a/test/unit/utils/api-request.spec.ts +++ b/test/unit/utils/api-request.spec.ts @@ -140,7 +140,7 @@ function mockHttp2SendRequestError( } as mocks.MockHttp2Response } -function mockHttp2Error(streamError?: any, sessionError?:any): mocks.MockHttp2Response { +function mockHttp2Error(streamError: any, sessionError?:any): mocks.MockHttp2Response { return { streamError: streamError, sessionError: sessionError @@ -2506,10 +2506,10 @@ describe('Http2Client', () => { it('should fail on session and stream errors', async () => { const reqData = { request: 'data' }; const streamError = 'Error while making request: test stream error. Error code: AWFUL_STREAM_ERROR'; - const sessionError = 'Session error while making requests: Error: AWFUL_SESSION_ERROR' + const sessionError = 'Session error while making requests: AWFUL_SESSION_ERROR - test session error' mockedHttp2Responses.push(mockHttp2Error( { message: 'test stream error', code: 'AWFUL_STREAM_ERROR' }, - new Error('AWFUL_SESSION_ERROR') + { message: 'test session error', code: 'AWFUL_SESSION_ERROR' } )); http2Mocker.http2Stub(mockedHttp2Responses); @@ -2540,6 +2540,52 @@ describe('Http2Client', () => { await http2SessionHandler.invoke().should.eventually.be.rejectedWith(sessionError) .and.have.property('code', 'app/network-error') }); + + it('should unwrap aggregate session errors', async () => { + const reqData = { request: 'data' }; + const streamError = { message: 'test stream error', code: 'AWFUL_STREAM_ERROR' } + const expectedStreamErrorMessage = 'Error while making request: test stream error. Error code: AWFUL_STREAM_ERROR'; + const aggregateSessionError = { + name: 'AggregateError', + code: 'AWFUL_SESSION_ERROR', + errors: [ + { message: 'Error message 1' }, + { message: 'Error message 2' }, + ] + } + const expectedAggregateErrorMessage = 'Session error while making requests: AWFUL_SESSION_ERROR - ' + + 'AggregateError: [Error message 1, Error message 2]' + + mockedHttp2Responses.push(mockHttp2Error(streamError, aggregateSessionError)); + http2Mocker.http2Stub(mockedHttp2Responses); + + const client = new Http2Client(); + http2SessionHandler = new Http2SessionHandler(mockHostUrl) + + await client.send({ + method: 'POST', + url: mockUrl, + headers: { + 'authorization': 'Bearer token', + 'My-Custom-Header': 'CustomValue', + }, + data: reqData, + http2SessionHandler: http2SessionHandler, + }).should.eventually.be.rejectedWith(expectedStreamErrorMessage).and.have.property('code', 'app/network-error') + .then(() => { + expect(http2Mocker.requests.length).to.equal(1); + expect(http2Mocker.requests[0].headers[':method']).to.equal('POST'); + expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:'); + expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath); + expect(JSON.parse(http2Mocker.requests[0].data)).to.deep.equal(reqData); + expect(http2Mocker.requests[0].headers.authorization).to.equal('Bearer token'); + expect(http2Mocker.requests[0].headers['content-type']).to.contain('application/json'); + expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue'); + }); + + await http2SessionHandler.invoke().should.eventually.be.rejectedWith(expectedAggregateErrorMessage) + .and.have.property('code', 'app/network-error') + }); }); describe('AuthorizedHttpClient', () => { From 446843bbaf5fce2f81052839fec88ebcfcc0ec1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Apr 2025 17:02:06 +0000 Subject: [PATCH 251/323] build(deps): bump axios in /.github/actions/send-email (#2899) --- .github/actions/send-email/package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 696d61945b..1cf636f147 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -57,9 +57,10 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", From c3090575682fd09957ae675ea6024ddab2d09406 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Tue, 22 Apr 2025 14:20:54 -0400 Subject: [PATCH 252/323] [chore] Release 13.3.0 (#2904) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 09dd872eba..453a29e675 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.2.0", + "version": "13.3.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 8e3290e3378d469be89a2a7a4a7e5f6a98f1865d Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Fri, 9 May 2025 15:25:33 -0400 Subject: [PATCH 253/323] feat(fdc): Data Connect Bulk Import (#2905) Add new API interfaces for insert, insertMany, upsert, upsertMany operations. --- etc/firebase-admin.data-connect.api.md | 8 + .../data-connect-api-client-internal.ts | 197 +++++++++ src/data-connect/data-connect.ts | 94 ++++- .../data-connect-api-client-internal.spec.ts | 382 +++++++++++++++++- test/unit/data-connect/index.spec.ts | 71 ++++ test/unit/index.spec.ts | 4 + 6 files changed, 737 insertions(+), 19 deletions(-) diff --git a/etc/firebase-admin.data-connect.api.md b/etc/firebase-admin.data-connect.api.md index 3650368734..2284d14b65 100644 --- a/etc/firebase-admin.data-connect.api.md +++ b/etc/firebase-admin.data-connect.api.md @@ -29,6 +29,14 @@ export class DataConnect { executeGraphql(query: string, options?: GraphqlOptions): Promise>; // @beta executeGraphqlRead(query: string, options?: GraphqlOptions): Promise>; + // @beta + insert(tableName: string, variables: Variables): Promise>; + // @beta + insertMany>(tableName: string, variables: Variables): Promise>; + // @beta + upsert(tableName: string, variables: Variables): Promise>; + // @beta + upsertMany>(tableName: string, variables: Variables): Promise>; } // @public diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts index b6082b91f5..e12005b8bb 100644 --- a/src/data-connect/data-connect-api-client-internal.ts +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -198,6 +198,203 @@ export class DataConnectApiClient { const message = error.message || `Unknown server error: ${response.text}`; return new FirebaseDataConnectError(code, message); } + + /** + * Converts JSON data into a GraphQL literal string. + * Handles nested objects, arrays, strings, numbers, and booleans. + * Ensures strings are properly escaped. + */ + private objectToString(data: unknown): string { + if (typeof data === 'string') { + const escapedString = data + .replace(/\\/g, '\\\\') // Replace \ with \\ + .replace(/"/g, '\\"'); // Replace " with \" + return `"${escapedString}"`; + } + if (typeof data === 'number' || typeof data === 'boolean' || data === null) { + return String(data); + } + if (validator.isArray(data)) { + const elements = data.map(item => this.objectToString(item)).join(', '); + return `[${elements}]`; + } + if (typeof data === 'object' && data !== null) { + // Filter out properties where the value is undefined BEFORE mapping + const kvPairs = Object.entries(data) + .filter(([, val]) => val !== undefined) + .map(([key, val]) => { + // GraphQL object keys are typically unquoted. + return `${key}: ${this.objectToString(val)}`; + }); + + if (kvPairs.length === 0) { + return '{}'; // Represent an object with no defined properties as {} + } + return `{ ${kvPairs.join(', ')} }`; + } + + // If value is undefined (and not an object property, which is handled above, + // e.g., if objectToString(undefined) is called directly or for an array element) + // it should be represented as 'null'. + if (typeof data === 'undefined') { + return 'null'; + } + + // Fallback for any other types (e.g., Symbol, BigInt - though less common in GQL contexts) + // Consider how these should be handled or if an error should be thrown. + // For now, simple string conversion. + return String(data); + } + + private formatTableName(tableName: string): string { + // Format tableName: first character to lowercase + if (tableName && tableName.length > 0) { + return tableName.charAt(0).toLowerCase() + tableName.slice(1); + } + return tableName; + } + + private handleBulkImportErrors(err: FirebaseDataConnectError): never { + if (err.code === `data-connect/${DATA_CONNECT_ERROR_CODE_MAPPING.QUERY_ERROR}`){ + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.QUERY_ERROR, + `${err.message}. Make sure that your table name passed in matches the type name in your GraphQL schema file.`); + } + throw err; + } + + /** + * Insert a single row into the specified table. + */ + public async insert( + tableName: string, + data: Variables, + ): Promise> { + if (!validator.isNonEmptyString(tableName)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`tableName` must be a non-empty string.'); + } + if (validator.isArray(data)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`data` must be an object, not an array, for single insert. For arrays, please use `insertMany` function.'); + } + if (!validator.isNonNullObject(data)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`data` must be a non-null object.'); + } + + try { + tableName = this.formatTableName(tableName); + const gqlDataString = this.objectToString(data); + const mutation = `mutation { ${tableName}_insert(data: ${gqlDataString}) }`; + // Use internal executeGraphql + return this.executeGraphql(mutation).catch(this.handleBulkImportErrors); + } catch (e: any) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INTERNAL, + `Failed to construct insert mutation: ${e.message}`); + } + } + + /** + * Insert multiple rows into the specified table. + */ + public async insertMany>( + tableName: string, + data: Variables, + ): Promise> { + if (!validator.isNonEmptyString(tableName)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`tableName` must be a non-empty string.'); + } + if (!validator.isNonEmptyArray(data)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`data` must be a non-empty array for insertMany.'); + } + + try { + tableName = this.formatTableName(tableName); + const gqlDataString = this.objectToString(data); + const mutation = `mutation { ${tableName}_insertMany(data: ${gqlDataString}) }`; + // Use internal executeGraphql + return this.executeGraphql(mutation).catch(this.handleBulkImportErrors); + } catch (e: any) { + throw new FirebaseDataConnectError(DATA_CONNECT_ERROR_CODE_MAPPING.INTERNAL, + `Failed to construct insertMany mutation: ${e.message}`); + } + } + + /** + * Insert a single row into the specified table, or update it if it already exists. + */ + public async upsert( + tableName: string, + data: Variables, + ): Promise> { + if (!validator.isNonEmptyString(tableName)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`tableName` must be a non-empty string.'); + } + if (validator.isArray(data)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`data` must be an object, not an array, for single upsert. For arrays, please use `upsertMany` function.'); + } + if (!validator.isNonNullObject(data)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`data` must be a non-null object.'); + } + + try { + tableName = this.formatTableName(tableName); + const gqlDataString = this.objectToString(data); + const mutation = `mutation { ${tableName}_upsert(data: ${gqlDataString}) }`; + // Use internal executeGraphql + return this.executeGraphql(mutation).catch(this.handleBulkImportErrors); + } catch (e: any) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INTERNAL, + `Failed to construct upsert mutation: ${e.message}`); + } + } + + /** + * Insert multiple rows into the specified table, or update them if they already exist. + */ + public async upsertMany>( + tableName: string, + data: Variables, + ): Promise> { + if (!validator.isNonEmptyString(tableName)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`tableName` must be a non-empty string.'); + } + if (!validator.isNonEmptyArray(data)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`data` must be a non-empty array for upsertMany.'); + } + + try { + tableName = this.formatTableName(tableName); + const gqlDataString = this.objectToString(data); + const mutation = `mutation { ${tableName}_upsertMany(data: ${gqlDataString}) }`; + // Use internal executeGraphql + return this.executeGraphql(mutation).catch(this.handleBulkImportErrors); + } catch (e: any) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INTERNAL, + `Failed to construct upsertMany mutation: ${e.message}`); + } + } } /** diff --git a/src/data-connect/data-connect.ts b/src/data-connect/data-connect.ts index dbded00042..671bfe4b73 100644 --- a/src/data-connect/data-connect.ts +++ b/src/data-connect/data-connect.ts @@ -46,10 +46,10 @@ export class DataConnectService { } /** - * Returns the app associated with this `DataConnectService` instance. - * - * @returns The app associated with this `DataConnectService` instance. - */ + * Returns the app associated with this `DataConnectService` instance. + * + * @returns The app associated with this `DataConnectService` instance. + */ get app(): App { return this.appInternal; } @@ -63,24 +63,24 @@ export class DataConnect { private readonly client: DataConnectApiClient; /** - * @param connectorConfig - The connector configuration. - * @param app - The app for this `DataConnect` service. - * @constructor - * @internal - */ + * @param connectorConfig - The connector configuration. + * @param app - The app for this `DataConnect` service. + * @constructor + * @internal + */ constructor(readonly connectorConfig: ConnectorConfig, readonly app: App) { this.client = new DataConnectApiClient(connectorConfig, app); } /** - * Execute an arbitrary GraphQL query or mutation - * - * @param query - The GraphQL query or mutation. - * @param options - Optional {@link GraphqlOptions} when executing a GraphQL query or mutation. - * - * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. - * @beta - */ + * Execute an arbitrary GraphQL query or mutation + * + * @param query - The GraphQL query or mutation. + * @param options - Optional {@link GraphqlOptions} when executing a GraphQL query or mutation. + * + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + * @beta + */ public executeGraphql( query: string, options?: GraphqlOptions, @@ -103,4 +103,64 @@ export class DataConnect { ): Promise> { return this.client.executeGraphqlRead(query, options); } + + /** + * Insert a single row into the specified table. + * + * @param tableName - The name of the table to insert data into. + * @param variables - The data object to insert. The keys should correspond to the column names. + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + * @beta + */ + public insert( + tableName: string, + variables: Variables, + ): Promise> { + return this.client.insert(tableName, variables); + } + + /** + * Insert multiple rows into the specified table. + * + * @param tableName - The name of the table to insert data into. + * @param variables - An array of data objects to insert. Each object's keys should correspond to the column names. + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + * @beta + */ + public insertMany>( + tableName: string, + variables: Variables, + ): Promise> { + return this.client.insertMany(tableName, variables); + } + + /** + * Insert a single row into the specified table, or update it if it already exists. + * + * @param tableName - The name of the table to upsert data into. + * @param variables - The data object to upsert. The keys should correspond to the column names. + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + * @beta + */ + public upsert( + tableName: string, + variables: Variables, + ): Promise> { + return this.client.upsert(tableName, variables); + } + + /** + * Insert multiple rows into the specified table, or update them if they already exist. + * + * @param tableName - The name of the table to upsert data into. + * @param variables - An array of data objects to upsert. Each object's keys should correspond to the column names. + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + * @beta + */ + public upsertMany>( + tableName: string, + variables: Variables, + ): Promise> { + return this.client.upsertMany(tableName, variables); + } } diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index 9787a2d7c9..a5798703e5 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -24,7 +24,7 @@ import { } from '../../../src/utils/api-request'; import * as utils from '../utils'; import * as mocks from '../../resources/mocks'; -import { DataConnectApiClient, FirebaseDataConnectError } +import { DATA_CONNECT_ERROR_CODE_MAPPING, DataConnectApiClient, FirebaseDataConnectError } from '../../../src/data-connect/data-connect-api-client-internal'; import { FirebaseApp } from '../../../src/app/firebase-app'; import { ConnectorConfig } from '../../../src/data-connect'; @@ -46,6 +46,12 @@ describe('DataConnectApiClient', () => { 'X-Goog-Api-Client': getMetricsHeader(), }; + const EMULATOR_EXPECTED_HEADERS = { + 'Authorization': 'Bearer owner', + 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'X-Goog-Api-Client': getMetricsHeader(), + }; + const noProjectId = 'Failed to determine project ID. Initialize the SDK with service ' + 'account credentials or set project ID as an app option. Alternatively, set the ' + 'GOOGLE_CLOUD_PROJECT environment variable.'; @@ -218,10 +224,382 @@ describe('DataConnectApiClient', () => { expect(stub).to.have.been.calledOnce.and.calledWith({ method: 'POST', url: `http://localhost:9399/v1alpha/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, - headers: EXPECTED_HEADERS, + headers: EMULATOR_EXPECTED_HEADERS, data: { query: 'query' } }); }); }); }); }); + +describe('DataConnectApiClient CRUD helpers', () => { + let mockApp: FirebaseApp; + let apiClient: DataConnectApiClient; + let apiClientQueryError: DataConnectApiClient; + let executeGraphqlStub: sinon.SinonStub; + + const connectorConfig: ConnectorConfig = { + location: 'us-west1', + serviceId: 'my-crud-service', + }; + + const mockOptions = { + credential: new mocks.MockCredential(), + projectId: 'test-project-crud', + }; + + const tableName = 'TestTable'; + const formatedTableName = 'testTable'; + + const dataWithUndefined = { + genre: 'Action', + title: 'Die Hard', + ratings: null, + director: { + name: undefined, + age: undefined + }, + notes: undefined, + releaseYear: undefined, + extras: [1, undefined, 'hello', undefined, { a: 1, b: undefined }] + }; + + const tableNames = ['movie', 'Movie', 'MOVIE', 'mOvIE', 'toybox', 'toyBox', 'toyBOX', 'ToyBox', 'TOYBOX']; + const formatedTableNames = ['movie', 'movie', 'mOVIE', 'mOvIE', 'toybox', 'toyBox', 'toyBOX', 'toyBox', 'tOYBOX']; + + const serverErrorString = 'Server error response'; + const additionalErrorMessageForBulkImport = + 'Make sure that your table name passed in matches the type name in your GraphQL schema file.'; + + const expectedQueryError = new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.QUERY_ERROR, + serverErrorString + ); + + // Helper function to normalize GraphQL strings + const normalizeGraphQLString = (str: string): string => { + return str + .replace(/\s*\n\s*/g, '\n') // Remove leading/trailing whitespace around newlines + .replace(/\s+/g, ' ') // Replace multiple spaces with a single space + .trim(); // Remove leading/trailing whitespace from the whole string + }; + + beforeEach(() => { + mockApp = mocks.appWithOptions(mockOptions); + apiClient = new DataConnectApiClient(connectorConfig, mockApp); + apiClientQueryError = new DataConnectApiClient(connectorConfig, mockApp); + // Stub the instance's executeGraphql method + executeGraphqlStub = sinon.stub(apiClient, 'executeGraphql').resolves({ data: {} }); + sinon.stub(apiClientQueryError, 'executeGraphql').rejects(expectedQueryError); + }); + + afterEach(() => { + sinon.restore(); + return mockApp.delete(); + }); + + // --- INSERT TESTS --- + describe('insert()', () => { + tableNames.forEach((tableName, index) => { + const expectedMutation = `mutation { ${formatedTableNames[index]}_insert(data: { name: "a" }) }`; + it(`should use the formatted tableName in the gql query: "${tableName}" as "${formatedTableNames[index]}"`, + async () => { + await apiClient.insert(tableName, { name: 'a' }); + await expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + }); + + it('should call executeGraphql with the correct mutation for simple data', async () => { + const simpleData = { name: 'test', value: 123 }; + const expectedMutation = ` + mutation { + ${formatedTableName}_insert(data: { + name: "test", + value: 123 + }) + }`; + await apiClient.insert(tableName, simpleData); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should call executeGraphql with the correct mutation for complex data', async () => { + const complexData = { id: 'abc', active: true, scores: [10, 20], info: { nested: 'yes/no "quote" \\slash\\' } }; + const expectedMutation = ` + mutation { + ${formatedTableName}_insert(data: { + id: "abc", active: true, scores: [10, 20], + info: { nested: "yes/no \\"quote\\" \\\\slash\\\\" } + }) + }`; + await apiClient.insert(tableName, complexData); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should call executeGraphql with the correct mutation for undefined and null values', async () => { + const expectedMutation = ` + mutation { + ${formatedTableName}_insert(data: { + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] + }) + }`; + await apiClient.insert(tableName, dataWithUndefined); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should throw FirebaseDataConnectError for invalid tableName', async () => { + await expect(apiClient.insert('', { data: 1 })) + .to.be.rejectedWith(FirebaseDataConnectError, /`tableName` must be a non-empty string./); + }); + + it('should throw FirebaseDataConnectError for null data', async () => { + await expect(apiClient.insert(tableName, null as any)) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-null object./); + }); + + it('should throw FirebaseDataConnectError for array data', async() => { + await expect(apiClient.insert(tableName, [])) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be an object, not an array, for single insert./); + }); + + it('should amend the message for query errors', async () => { + await expect(apiClientQueryError.insert(tableName, { data: 1 })) + .to.be.rejectedWith(FirebaseDataConnectError, `${serverErrorString}. ${additionalErrorMessageForBulkImport}`); + }); + }); + + // --- INSERT MANY TESTS --- + describe('insertMany()', () => { + tableNames.forEach((tableName, index) => { + const expectedMutation = `mutation { ${formatedTableNames[index]}_insertMany(data: [{ name: "a" }]) }`; + it(`should use the formatted tableName in the gql query: "${tableName}" as "${formatedTableNames[index]}"`, + async () => { + await apiClient.insertMany(tableName, [{ name: 'a' }]); + await expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + }); + + it('should call executeGraphql with the correct mutation for simple data array', async () => { + const simpleDataArray = [{ name: 'test1' }, { name: 'test2', value: 456 }]; + const expectedMutation = ` + mutation { + ${formatedTableName}_insertMany(data: [{ name: "test1" }, { name: "test2", value: 456 }]) }`; + await apiClient.insertMany(tableName, simpleDataArray); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should call executeGraphql with the correct mutation for complex data array', async () => { + const complexDataArray = [ + { id: 'a', active: true, info: { nested: 'n1 "quote"' } }, + { id: 'b', scores: [1, 2], info: { nested: 'n2/\\' } } + ]; + const expectedMutation = ` + mutation { + ${formatedTableName}_insertMany(data: + [{ id: "a", active: true, info: { nested: "n1 \\"quote\\"" } }, { id: "b", scores: [1, 2], + info: { nested: "n2/\\\\" } }]) }`; + await apiClient.insertMany(tableName, complexDataArray); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should call executeGraphql with the correct mutation for undefined and null', async () => { + const dataArray = [ + dataWithUndefined, + dataWithUndefined + ] + const expectedMutation = ` + mutation { + ${formatedTableName}_insertMany(data: [{ + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] + }, + { + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] + }]) + }`; + await apiClient.insertMany(tableName, dataArray); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should throw FirebaseDataConnectError for invalid tableName', async () => { + await expect(apiClient.insertMany('', [{ data: 1 }])) + .to.be.rejectedWith(FirebaseDataConnectError, /`tableName` must be a non-empty string./); + }); + + it('should throw FirebaseDataConnectError for null data', () => { + expect(apiClient.insertMany(tableName, null as any)) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-empty array for insertMany./); + }); + + it('should throw FirebaseDataConnectError for empty array data', () => { + expect(apiClient.insertMany(tableName, [])) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-empty array for insertMany./); + }); + + it('should throw FirebaseDataConnectError for non-array data', () => { + expect(apiClient.insertMany(tableName, { data: 1 } as any)) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-empty array for insertMany./); + }); + + it('should amend the message for query errors', async () => { + await expect(apiClientQueryError.insertMany(tableName, [{ data: 1 }])) + .to.be.rejectedWith(FirebaseDataConnectError, `${serverErrorString}. ${additionalErrorMessageForBulkImport}`); + }); + }); + + // --- UPSERT TESTS --- + describe('upsert()', () => { + tableNames.forEach((tableName, index) => { + const expectedMutation = `mutation { ${formatedTableNames[index]}_upsert(data: { name: "a" }) }`; + it(`should use the formatted tableName in the gql query: "${tableName}" as "${formatedTableNames[index]}"`, + async () => { + await apiClient.upsert(tableName, { name: 'a' }); + await expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + }); + + it('should call executeGraphql with the correct mutation for simple data', async () => { + const simpleData = { id: 'key1', value: 'updated' }; + const expectedMutation = `mutation { ${formatedTableName}_upsert(data: { id: "key1", value: "updated" }) }`; + await apiClient.upsert(tableName, simpleData); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(expectedMutation); + }); + + it('should call executeGraphql with the correct mutation for complex data', async () => { + const complexData = { id: 'key2', active: false, items: [1, null], detail: { status: 'done/\\' } }; + const expectedMutation = ` + mutation { ${formatedTableName}_upsert(data: + { id: "key2", active: false, items: [1, null], detail: { status: "done/\\\\" } }) }`; + await apiClient.upsert(tableName, complexData); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should call executeGraphql with the correct mutation for undefined and null values', async () => { + const expectedMutation = ` + mutation { + ${formatedTableName}_upsert(data: { + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] + }) + }`; + await apiClient.upsert(tableName, dataWithUndefined); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should throw FirebaseDataConnectError for invalid tableName', async () => { + await expect(apiClient.upsert('', { data: 1 })) + .to.be.rejectedWith(FirebaseDataConnectError, /`tableName` must be a non-empty string./); + }); + + it('should throw FirebaseDataConnectError for null data', async () => { + await expect(apiClient.upsert(tableName, null as any)) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-null object./); + }); + + it('should throw FirebaseDataConnectError for array data', async () => { + await expect(apiClient.upsert(tableName, [{ data: 1 }])) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be an object, not an array, for single upsert./); + }); + + it('should amend the message for query errors', async () => { + await expect(apiClientQueryError.upsert(tableName, { data: 1 })) + .to.be.rejectedWith(FirebaseDataConnectError, `${serverErrorString}. ${additionalErrorMessageForBulkImport}`); + }); + }); + + // --- UPSERT MANY TESTS --- + describe('upsertMany()', () => { + tableNames.forEach((tableName, index) => { + const expectedMutation = `mutation { ${formatedTableNames[index]}_upsertMany(data: [{ name: "a" }]) }`; + it(`should use the formatted tableName in the gql query: "${tableName}" as "${formatedTableNames[index]}"`, + async () => { + await apiClient.upsertMany(tableName, [{ name: 'a' }]); + await expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + }); + + it('should call executeGraphql with the correct mutation for simple data array', async () => { + const simpleDataArray = [{ id: 'k1' }, { id: 'k2', value: 99 }]; + const expectedMutation = ` + mutation { ${formatedTableName}_upsertMany(data: [{ id: "k1" }, { id: "k2", value: 99 }]) }`; + await apiClient.upsertMany(tableName, simpleDataArray); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should call executeGraphql with the correct mutation for complex data array', async () => { + const complexDataArray = [ + { id: 'x', active: true, info: { nested: 'n1/\\"x' } }, + { id: 'y', scores: [null, 2] } + ]; + const expectedMutation = ` + mutation { ${formatedTableName}_upsertMany(data: + [{ id: "x", active: true, info: { nested: "n1/\\\\\\"x" } }, { id: "y", scores: [null, 2] }]) }`; + await apiClient.upsertMany(tableName, complexDataArray); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should call executeGraphql with the correct mutation for undefined and null', async () => { + const dataArray = [ + dataWithUndefined, + dataWithUndefined + ] + const expectedMutation = ` + mutation { + ${formatedTableName}_upsertMany(data: [{ + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] + }, + { + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] + }]) + }`; + await apiClient.upsertMany(tableName, dataArray); + expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); + }); + + it('should throw FirebaseDataConnectError for invalid tableName', async () => { + expect(apiClient.upsertMany('', [{ data: 1 }])) + .to.be.rejectedWith(FirebaseDataConnectError, /`tableName` must be a non-empty string./); + }); + + it('should throw FirebaseDataConnectError for null data', async () => { + expect(apiClient.upsertMany(tableName, null as any)) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-empty array for upsertMany./); + }); + + it('should throw FirebaseDataConnectError for empty array data', async () => { + expect(apiClient.upsertMany(tableName, [])) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-empty array for upsertMany./); + }); + + it('should throw FirebaseDataConnectError for non-array data', async () => { + await expect(apiClient.upsertMany(tableName, { data: 1 } as any)) + .to.be.rejectedWith(FirebaseDataConnectError, /`data` must be a non-empty array for upsertMany./); + }); + + it('should amend the message for query errors', async () => { + await expect(apiClientQueryError.upsertMany(tableName, [{ data: 1 }])) + .to.be.rejectedWith(FirebaseDataConnectError, `${serverErrorString}. ${additionalErrorMessageForBulkImport}`); + }); + }); +}); diff --git a/test/unit/data-connect/index.spec.ts b/test/unit/data-connect/index.spec.ts index 228cafbf84..b71670544b 100644 --- a/test/unit/data-connect/index.spec.ts +++ b/test/unit/data-connect/index.spec.ts @@ -18,12 +18,14 @@ 'use strict'; import * as chai from 'chai'; +import * as sinon from 'sinon'; import * as sinonChai from 'sinon-chai'; import * as chaiAsPromised from 'chai-as-promised'; import * as mocks from '../../resources/mocks'; import { App } from '../../../src/app/index'; import { getDataConnect, DataConnect } from '../../../src/data-connect/index'; +import { DataConnectApiClient } from '../../../src/data-connect/data-connect-api-client-internal'; chai.should(); chai.use(sinonChai); @@ -84,3 +86,72 @@ describe('DataConnect', () => { }); }); }); + +describe('DataConnect CRUD helpers delegation', () => { + let mockApp: App; + let dataConnect: DataConnect; + // Stubs for the client methods + let clientInsertStub: sinon.SinonStub; + let clientInsertManyStub: sinon.SinonStub; + let clientUpsertStub: sinon.SinonStub; + let clientUpsertManyStub: sinon.SinonStub; + + const connectorConfig = { + location: 'us-west1', + serviceId: 'my-crud-service', + }; + + const testTableName = 'TestTable'; + + beforeEach(() => { + mockApp = mocks.app(); + + dataConnect = getDataConnect(connectorConfig, mockApp); + + // Stub the DataConnectApiClient prototype methods + clientInsertStub = sinon.stub(DataConnectApiClient.prototype, 'insert').resolves({ data: {} }); + clientInsertManyStub = sinon.stub(DataConnectApiClient.prototype, 'insertMany').resolves({ data: {} }); + clientUpsertStub = sinon.stub(DataConnectApiClient.prototype, 'upsert').resolves({ data: {} }); + clientUpsertManyStub = sinon.stub(DataConnectApiClient.prototype, 'upsertMany').resolves({ data: {} }); + }); + + afterEach(() => { + sinon.restore(); + }); + + // --- INSERT TESTS --- + describe('insert()', () => { + it('should delegate insert call to the client', async () => { + const simpleData = { name: 'test', value: 123 }; + await dataConnect.insert(testTableName, simpleData); + expect(clientInsertStub).to.have.been.calledOnceWithExactly(testTableName, simpleData); + }); + }); + + // --- INSERT MANY TESTS --- + describe('insertMany()', () => { + it('should delegate insertMany call to the client', async () => { + const simpleDataArray = [{ name: 'test1' }, { name: 'test2' }]; + await dataConnect.insertMany(testTableName, simpleDataArray); + expect(clientInsertManyStub).to.have.been.calledOnceWithExactly(testTableName, simpleDataArray); + }); + }); + + // --- UPSERT TESTS --- + describe('upsert()', () => { + it('should delegate upsert call to the client', async () => { + const simpleData = { id: 'key1', value: 'updated' }; + await dataConnect.upsert(testTableName, simpleData); + expect(clientUpsertStub).to.have.been.calledOnceWithExactly(testTableName, simpleData); + }); + }); + + // --- UPSERT MANY TESTS --- + describe('upsertMany()', () => { + it('should delegate upsertMany call to the client', async () => { + const simpleDataArray = [{ id: 'k1' }, { id: 'k2' }]; + await dataConnect.upsertMany(testTableName, simpleDataArray); + expect(clientUpsertManyStub).to.have.been.calledOnceWithExactly(testTableName, simpleDataArray); + }); + }); +}); diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index 53847f6d62..f6bfb1b39a 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -117,3 +117,7 @@ import './functions/functions-api-client-internal.spec'; // Extensions import './extensions/extensions.spec'; import './extensions/extensions-api-client-internal.spec'; + +// Data Connect +import './data-connect/index.spec'; +import './data-connect/data-connect-api-client-internal.spec'; From a2e92f4f2508f927a9891d42d22ed130c2f570b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 16:21:55 +0000 Subject: [PATCH 254/323] build(deps-dev): bump @microsoft/api-extractor from 7.52.1 to 7.52.7 (#2912) --- package-lock.json | 60 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 81d207924f..4986c9888b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.2.0", + "version": "13.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.2.0", + "version": "13.3.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -1205,19 +1205,19 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.52.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.1.tgz", - "integrity": "sha512-m3I5uAwE05orsu3D1AGyisX5KxsgVXB+U4bWOOaX/Z7Ftp/2Cy41qsNhO6LPvSxHBaapyser5dVorF1t5M6tig==", + "version": "7.52.7", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.7.tgz", + "integrity": "sha512-YLdPS644MfbLJt4hArP1WcldcaEUBh9wnFjcLEcQnVG0AMznbLh2sdE0F5Wr+w6+Lyp5/XUPvRAg3sYGSP3GCw==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.30.4", + "@microsoft/api-extractor-model": "7.30.6", "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.12.0", + "@rushstack/node-core-library": "5.13.1", "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.15.1", - "@rushstack/ts-command-line": "4.23.6", + "@rushstack/terminal": "0.15.3", + "@rushstack/ts-command-line": "5.0.1", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", @@ -1230,15 +1230,15 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.30.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.4.tgz", - "integrity": "sha512-RobC0gyVYsd2Fao9MTKOfTdBm41P/bCMUmzS5mQ7/MoAKEqy0FOBph3JOYdq4X4BsEnMEiSHc+0NUNmdzxCpjA==", + "version": "7.30.6", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.6.tgz", + "integrity": "sha512-znmFn69wf/AIrwHya3fxX6uB5etSIn6vg4Q4RB/tb5VDDs1rqREc+AvMC/p19MUN13CZ7+V/8pkYPTj7q8tftg==", "dev": true, "license": "MIT", "dependencies": { "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.12.0" + "@rushstack/node-core-library": "5.13.1" } }, "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { @@ -1249,9 +1249,9 @@ "license": "MIT" }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.12.0.tgz", - "integrity": "sha512-QSwwzgzWoil1SCQse+yCHwlhRxNv2dX9siPnAb9zR/UmMhac4mjMrlMZpk64BlCeOFi1kJKgXRkihSwRMbboAQ==", + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz", + "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1335,9 +1335,9 @@ "dev": true }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.12.0.tgz", - "integrity": "sha512-QSwwzgzWoil1SCQse+yCHwlhRxNv2dX9siPnAb9zR/UmMhac4mjMrlMZpk64BlCeOFi1kJKgXRkihSwRMbboAQ==", + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz", + "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1360,13 +1360,13 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "4.23.6", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.6.tgz", - "integrity": "sha512-7WepygaF3YPEoToh4MAL/mmHkiIImQq3/uAkQX46kVoKTNOOlCtFGyNnze6OYuWw2o9rxsyrHVfIBKxq/am2RA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.0.1.tgz", + "integrity": "sha512-bsbUucn41UXrQK7wgM8CNM/jagBytEyJqXw/umtI8d68vFm1Jwxh1OtLrlW7uGZgjCWiiPH6ooUNa1aVsuVr3Q==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.15.1", + "@rushstack/terminal": "0.15.3", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1636,13 +1636,13 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.1.tgz", - "integrity": "sha512-3vgJYwumcjoDOXU3IxZfd616lqOdmr8Ezj4OWgJZfhmiBK4Nh7eWcv8sU8N/HdzXcuHDXCRGn/6O2Q75QvaZMA==", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.3.tgz", + "integrity": "sha512-DGJ0B2Vm69468kZCJkPj3AH5nN+nR9SPmC0rFHtzsS4lBQ7/dgOwtwVxYP7W9JPDMuRBkJ4KHmWKr036eJsj9g==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.12.0", + "@rushstack/node-core-library": "5.13.1", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -1655,9 +1655,9 @@ } }, "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.12.0.tgz", - "integrity": "sha512-QSwwzgzWoil1SCQse+yCHwlhRxNv2dX9siPnAb9zR/UmMhac4mjMrlMZpk64BlCeOFi1kJKgXRkihSwRMbboAQ==", + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz", + "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==", "dev": true, "license": "MIT", "dependencies": { From 7ba9fd2e01f0212f390eb89a851de88a1a3d5fd9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 16:36:01 +0000 Subject: [PATCH 255/323] build(deps): bump @firebase/database-compat from 2.0.3 to 2.0.5 (#2901) --- package-lock.json | 75 ++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4986c9888b..e9ddc7a6e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -702,16 +702,16 @@ } }, "node_modules/@firebase/database": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.12.tgz", - "integrity": "sha512-psFl5t6rSFHq3i3fnU1QQlc4BB9Hnhh8TgEqvQlPPm8kDLw8gYxvjqYw3c5CZW0+zKR837nwT6im/wtJUivMKw==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.15.tgz", + "integrity": "sha512-xmeTqKoIB2u1AXvLc1jq3Val0QAHUr49YycAr6feoDD7zM9dCjSk8rq9s1ESTv+tbbqS2BRoTpjIvxwXRTKhQQ==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.12", + "@firebase/component": "0.6.14", "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", + "@firebase/util": "1.11.1", "faye-websocket": "0.11.4", "tslib": "^2.1.0" }, @@ -720,16 +720,16 @@ } }, "node_modules/@firebase/database-compat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.3.tgz", - "integrity": "sha512-uHGQrSUeJvsDfA+IyHW5O4vdRPsCksEzv4T4Jins+bmQgYy20ZESU4x01xrQCn/nzqKHuQMEW99CoCO7D+5NiQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.6.tgz", + "integrity": "sha512-vv15b1E59sLwoVdjGKvJ75ok9Qu1VRJC/7KXAQGnXvURAL199Ndy1YEw6/GA9twoFlLCYnd2ltxxB2pPiL1Vqw==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.12", - "@firebase/database": "1.0.12", - "@firebase/database-types": "1.0.8", + "@firebase/component": "0.6.14", + "@firebase/database": "1.0.15", + "@firebase/database-types": "1.0.11", "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.3", + "@firebase/util": "1.11.1", "tslib": "^2.1.0" }, "engines": { @@ -737,12 +737,12 @@ } }, "node_modules/@firebase/database-compat/node_modules/@firebase/component": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", - "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "version": "0.6.14", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.14.tgz", + "integrity": "sha512-kf/zAT8GQJ9nYoHuj0mv7twp1QzifKYrO+GsmsVHHM+Hi9KkmI7E3B3J0CtihHpb34vinl4gbJrYJ2p2wfvc9A==", "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.10.3", + "@firebase/util": "1.11.1", "tslib": "^2.1.0" }, "engines": { @@ -750,9 +750,10 @@ } }, "node_modules/@firebase/database-compat/node_modules/@firebase/util": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", - "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.1.tgz", + "integrity": "sha512-RXg4WE8C2LUrvoV/TMGRTu223zZf9Dq9MR8yHZio9nF9TpLnpCPURw9VWWB2WATDl6HfIdWfl2x2SJYtHkN4hw==", + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -762,19 +763,20 @@ } }, "node_modules/@firebase/database-types": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.8.tgz", - "integrity": "sha512-6lPWIGeufhUq1heofZULyVvWFhD01TUrkkB9vyhmksjZ4XF7NaivQp9rICMk7QNhqwa+uDCaj4j+Q8qqcSVZ9g==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.11.tgz", + "integrity": "sha512-LBZG/nT6GbntbIdGxBNvu9PBtj4xUEE9wX8AFF6njFK/MufYBESiKqT+jhDwmbcM4zAha9U0Pcca8FvJ1z1bYw==", "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.3", - "@firebase/util": "1.10.3" + "@firebase/util": "1.11.1" } }, "node_modules/@firebase/database-types/node_modules/@firebase/util": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", - "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.1.tgz", + "integrity": "sha512-RXg4WE8C2LUrvoV/TMGRTu223zZf9Dq9MR8yHZio9nF9TpLnpCPURw9VWWB2WATDl6HfIdWfl2x2SJYtHkN4hw==", + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -784,12 +786,12 @@ } }, "node_modules/@firebase/database/node_modules/@firebase/component": { - "version": "0.6.12", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.12.tgz", - "integrity": "sha512-YnxqjtohLbnb7raXt2YuA44cC1wA9GiehM/cmxrsoxKlFxBLy2V0OkRSj9gpngAE0UoJ421Wlav9ycO7lTPAUw==", + "version": "0.6.14", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.14.tgz", + "integrity": "sha512-kf/zAT8GQJ9nYoHuj0mv7twp1QzifKYrO+GsmsVHHM+Hi9KkmI7E3B3J0CtihHpb34vinl4gbJrYJ2p2wfvc9A==", "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.10.3", + "@firebase/util": "1.11.1", "tslib": "^2.1.0" }, "engines": { @@ -797,9 +799,10 @@ } }, "node_modules/@firebase/database/node_modules/@firebase/util": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.3.tgz", - "integrity": "sha512-wfoF5LTy0m2ufUapV0ZnpcGQvuavTbJ5Qr1Ze9OJGL70cSMvhDyjS4w2121XdA3lGZSTOsDOyGhpoDtYwck85A==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.1.tgz", + "integrity": "sha512-RXg4WE8C2LUrvoV/TMGRTu223zZf9Dq9MR8yHZio9nF9TpLnpCPURw9VWWB2WATDl6HfIdWfl2x2SJYtHkN4hw==", + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -6383,9 +6386,9 @@ } }, "node_modules/http-parser-js": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz", - "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==", + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", "license": "MIT" }, "node_modules/http-proxy-agent": { From a00d40979b08b1f3631e779a79e2782ed468b40d Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 12 May 2025 15:54:35 -0400 Subject: [PATCH 256/323] chore(fdc): remove tags from Data Connect APIs (#2918) --- etc/firebase-admin.data-connect.api.md | 6 ------ src/data-connect/data-connect.ts | 6 ------ 2 files changed, 12 deletions(-) diff --git a/etc/firebase-admin.data-connect.api.md b/etc/firebase-admin.data-connect.api.md index 2284d14b65..8a1e7a042c 100644 --- a/etc/firebase-admin.data-connect.api.md +++ b/etc/firebase-admin.data-connect.api.md @@ -25,17 +25,11 @@ export class DataConnect { readonly app: App; // (undocumented) readonly connectorConfig: ConnectorConfig; - // @beta executeGraphql(query: string, options?: GraphqlOptions): Promise>; - // @beta executeGraphqlRead(query: string, options?: GraphqlOptions): Promise>; - // @beta insert(tableName: string, variables: Variables): Promise>; - // @beta insertMany>(tableName: string, variables: Variables): Promise>; - // @beta upsert(tableName: string, variables: Variables): Promise>; - // @beta upsertMany>(tableName: string, variables: Variables): Promise>; } diff --git a/src/data-connect/data-connect.ts b/src/data-connect/data-connect.ts index 671bfe4b73..aa7d9d7e19 100644 --- a/src/data-connect/data-connect.ts +++ b/src/data-connect/data-connect.ts @@ -79,7 +79,6 @@ export class DataConnect { * @param options - Optional {@link GraphqlOptions} when executing a GraphQL query or mutation. * * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. - * @beta */ public executeGraphql( query: string, @@ -95,7 +94,6 @@ export class DataConnect { * @param options - Optional {@link GraphqlOptions} when executing a read-only GraphQL query. * * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. - * @beta */ public executeGraphqlRead( query: string, @@ -110,7 +108,6 @@ export class DataConnect { * @param tableName - The name of the table to insert data into. * @param variables - The data object to insert. The keys should correspond to the column names. * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. - * @beta */ public insert( tableName: string, @@ -125,7 +122,6 @@ export class DataConnect { * @param tableName - The name of the table to insert data into. * @param variables - An array of data objects to insert. Each object's keys should correspond to the column names. * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. - * @beta */ public insertMany>( tableName: string, @@ -140,7 +136,6 @@ export class DataConnect { * @param tableName - The name of the table to upsert data into. * @param variables - The data object to upsert. The keys should correspond to the column names. * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. - * @beta */ public upsert( tableName: string, @@ -155,7 +150,6 @@ export class DataConnect { * @param tableName - The name of the table to upsert data into. * @param variables - An array of data objects to upsert. Each object's keys should correspond to the column names. * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. - * @beta */ public upsertMany>( tableName: string, From 3c2cb9f0265ae836469198a7ff18d5454f18aefd Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 12 May 2025 17:08:39 -0400 Subject: [PATCH 257/323] [chore] Release 13.4.0 (#2917) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 453a29e675..1401c8ce6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.3.0", + "version": "13.4.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From d7624640b035cdec2457c5a0ad6027c5c36edb93 Mon Sep 17 00:00:00 2001 From: Jano <33382708+janodetzel@users.noreply.github.com> Date: Tue, 3 Jun 2025 21:54:19 +0200 Subject: [PATCH 258/323] feat(fcm): Support `apns.live_activity_token` field in FCM `ApnsConfig` (#2891) * feat(fcm): Support `apns.live_activity_token` field in FCM `ApnsConfig` * feat(fcm): Support `live_activity_token` field on `ApnsConfig` * added validation * update documentation * feat(fcm): Rename `apns.live_activity_token` to lowerCamelCase --- etc/firebase-admin.messaging.api.md | 1 + src/messaging/messaging-api.ts | 4 + src/messaging/messaging-internal.ts | 23 ++++ test/unit/messaging/messaging.spec.ts | 165 ++++++++++++++++++++++++++ 4 files changed, 193 insertions(+) diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index f0adaa0f35..1ad50f85f6 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -61,6 +61,7 @@ export interface ApnsConfig { headers?: { [key: string]: string; }; + liveActivityToken?: string; payload?: ApnsPayload; } diff --git a/src/messaging/messaging-api.ts b/src/messaging/messaging-api.ts index 69c16382d5..d0c5d5af7e 100644 --- a/src/messaging/messaging-api.ts +++ b/src/messaging/messaging-api.ts @@ -241,6 +241,10 @@ export interface WebpushNotification { * Apple documentation} for various headers and payload fields supported by APNs. */ export interface ApnsConfig { + /** + * APN `pushToStartToken` or `pushToken` to start or update live activities. + */ + liveActivityToken?: string; /** * A collection of APNs headers. Header values must be strings. */ diff --git a/src/messaging/messaging-internal.ts b/src/messaging/messaging-internal.ts index 725769bb32..c41f93a923 100644 --- a/src/messaging/messaging-internal.ts +++ b/src/messaging/messaging-internal.ts @@ -123,9 +123,32 @@ function validateApnsConfig(config: ApnsConfig | undefined): void { throw new FirebaseMessagingError( MessagingClientErrorCode.INVALID_PAYLOAD, 'apns must be a non-null object'); } + validateApnsLiveActivityToken(config.liveActivityToken); validateStringMap(config.headers, 'apns.headers'); validateApnsPayload(config.payload); validateApnsFcmOptions(config.fcmOptions); + + const propertyMappings = { + liveActivityToken: 'live_activity_token' + } + + renameProperties(config, propertyMappings) +} + +function validateApnsLiveActivityToken(liveActivityToken: ApnsConfig['liveActivityToken']): void { + if (typeof liveActivityToken === 'undefined') { + return; + } else if (!validator.isString(liveActivityToken)) { + throw new FirebaseMessagingError( + MessagingClientErrorCode.INVALID_PAYLOAD, + 'apns.liveActivityToken must be a string value', + ); + } else if (!validator.isNonEmptyString(liveActivityToken)) { + throw new FirebaseMessagingError( + MessagingClientErrorCode.INVALID_PAYLOAD, + 'apns.liveActivityToken must be a non-empty string', + ); + } } /** diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index 79942f73d2..9e8d1ea814 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -1725,6 +1725,21 @@ describe('Messaging', () => { }); }); + const invalidApnsLiveActivityTokens: any[] = [null, NaN, 0, 1, true, false] + invalidApnsLiveActivityTokens.forEach((arg) => { + it(`should throw given invalid apns live activity token: ${JSON.stringify(arg)}`, () => { + expect(() => { + messaging.send({ apns: { liveActivityToken: arg }, topic: 'test' }); + }).to.throw('apns.liveActivityToken must be a string value'); + }); + }) + + it('should throw given empty apns live activity token', () => { + expect(() => { + messaging.send({ apns: { liveActivityToken: '' }, topic: 'test' }); + }).to.throw('apns.liveActivityToken must be a non-empty string'); + }); + const invalidApnsPayloads: any[] = [null, '', 'payload', true, 1.23]; invalidApnsPayloads.forEach((payload) => { it(`should throw given APNS payload with invalid object: ${JSON.stringify(payload)}`, () => { @@ -2388,6 +2403,155 @@ describe('Messaging', () => { }, }, }, + { + label: 'APNS Start LiveActivity', + req: { + apns: { + liveActivityToken: 'live-activity-token', + headers:{ + 'apns-priority': '10' + }, + payload: { + aps: { + timestamp: 1746475860808, + event: 'start', + 'content-state': { + 'demo': 1 + }, + 'attributes-type': 'DemoAttributes', + 'attributes': { + 'demoAttribute': 1, + }, + 'alert': { + 'title': 'test title', + 'body': 'test body' + } + }, + }, + }, + }, + expectedReq: { + apns: { + live_activity_token: 'live-activity-token', + headers:{ + 'apns-priority': '10' + }, + payload: { + aps: { + timestamp: 1746475860808, + event: 'start', + 'content-state': { + 'demo': 1 + }, + 'attributes-type': 'DemoAttributes', + 'attributes': { + 'demoAttribute': 1, + }, + 'alert': { + 'title': 'test title', + 'body': 'test body' + } + }, + }, + }, + }, + }, + { + label: 'APNS Update LiveActivity', + req: { + apns: { + liveActivityToken: 'live-activity-token', + headers:{ + 'apns-priority': '10' + }, + payload: { + aps: { + timestamp: 1746475860808, + event: 'update', + 'content-state': { + 'test1': 100, + 'test2': 'demo' + }, + 'alert': { + 'title': 'test title', + 'body': 'test body' + } + }, + }, + }, + }, + expectedReq: { + apns: { + live_activity_token: 'live-activity-token', + headers:{ + 'apns-priority': '10' + }, + payload: { + aps: { + timestamp: 1746475860808, + event: 'update', + 'content-state': { + 'test1': 100, + 'test2': 'demo' + }, + 'alert': { + 'title': 'test title', + 'body': 'test body' + } + }, + }, + }, + }, + }, + { + label: 'APNS End LiveActivity', + req: { + apns: { + liveActivityToken: 'live-activity-token', + 'headers':{ + 'apns-priority': '10' + }, + payload: { + aps: { + timestamp: 1746475860808, + 'dismissal-date': 1746475860808 + 60, + event: 'end', + 'content-state': { + 'test1': 100, + 'test2': 'demo' + }, + 'alert': { + 'title': 'test title', + 'body': 'test body' + } + }, + }, + }, + }, + expectedReq: { + apns: { + live_activity_token: 'live-activity-token', + 'headers':{ + 'apns-priority': '10' + }, + payload: { + aps: { + timestamp: 1746475860808, + 'dismissal-date': 1746475860808 + 60, + event: 'end', + 'content-state': { + 'test1': 100, + 'test2': 'demo' + }, + 'alert': { + 'title': 'test title', + 'body': 'test body' + } + }, + }, + }, + }, + }, ]; validMessages.forEach((config) => { @@ -2404,6 +2568,7 @@ describe('Messaging', () => { .then(() => { const expectedReq = config.expectedReq || config.req; expectedReq.token = 'mock-token'; + expect(httpsRequestStub).to.have.been.calledOnce.and.calledWith({ method: 'POST', data: { message: expectedReq }, From 18f185197c632845b6d4ed14e85ad8c256120ea7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Jun 2025 20:19:04 +0000 Subject: [PATCH 259/323] build(deps): bump undici in /.github/actions/send-email (#2922) --- .github/actions/send-email/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 1cf636f147..48ddb2fb7a 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -169,9 +169,9 @@ } }, "node_modules/undici": { - "version": "5.28.5", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz", - "integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", + "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" From 26b884f70300ef8e3213dfbbd72351ce7f68c695 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:02:36 +0000 Subject: [PATCH 260/323] build(deps-dev): bump @types/lodash from 4.17.15 to 4.17.18 (#2942) --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index e9ddc7a6e0..fc2251b97e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.3.0", + "version": "13.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.3.0", + "version": "13.4.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -1962,9 +1962,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==", + "version": "4.17.18", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.18.tgz", + "integrity": "sha512-KJ65INaxqxmU6EoCiJmRPZC9H9RVWCRd349tXM2M3O5NA7cY6YL7c0bHAHQ93NOfTObEQ004kd2QVHs/r0+m4g==", "dev": true, "license": "MIT" }, From d0b704ea53232bee33fec2c90850fffa672b3791 Mon Sep 17 00:00:00 2001 From: DellaBitta Date: Wed, 6 Aug 2025 16:05:37 -0400 Subject: [PATCH 261/323] feat: initializeApp idempotency (#2947) Update `initializeApp` to return an existing app if one exists with the same name and the same `AppOptions`. However, due to their inabilty to be compared, `initializeApp` will throw if an existing app has a configured `Credential` or `httpAgent`. --- etc/firebase-admin.app.api.md | 6 +- package-lock.json | 205 ++++++++++++++++++----- package.json | 1 + src/app/firebase-app.ts | 27 ++- src/app/lifecycle.ts | 202 ++++++++++++++++++---- test/resources/mocks.ts | 11 +- test/unit/app/firebase-app.spec.ts | 13 +- test/unit/app/firebase-namespace.spec.ts | 122 +++++++++++--- 8 files changed, 487 insertions(+), 100 deletions(-) diff --git a/etc/firebase-admin.app.api.md b/etc/firebase-admin.app.api.md index 97ab9667ce..f653df5a7b 100644 --- a/etc/firebase-admin.app.api.md +++ b/etc/firebase-admin.app.api.md @@ -83,10 +83,10 @@ export interface FirebaseError { toJSON(): object; } -// @public (undocumented) +// @public export function getApp(appName?: string): App; -// @public (undocumented) +// @public export function getApps(): App[]; // @public @@ -97,7 +97,7 @@ export interface GoogleOAuthAccessToken { expires_in: number; } -// @public (undocumented) +// @public export function initializeApp(options?: AppOptions, appName?: string): App; // @public diff --git a/package-lock.json b/package-lock.json index fc2251b97e..bc43fd2ed4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@firebase/database-types": "^1.0.6", "@types/node": "^22.8.7", "farmhash-modern": "^1.1.0", + "fast-deep-equal": "^3.1.1", "google-auth-library": "^9.14.2", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", @@ -3317,6 +3318,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4062,6 +4094,21 @@ "node": ">=6.0.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexify": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", @@ -4205,14 +4252,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -4228,9 +4272,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { @@ -4618,7 +4662,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "devOptional": true, "license": "MIT" }, "node_modules/fast-fifo": { @@ -5312,17 +5355,22 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -5348,6 +5396,20 @@ "dev": true, "license": "MIT" }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-symbol-description": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", @@ -5622,13 +5684,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6236,9 +6298,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -6561,15 +6623,15 @@ "license": "ISC" }, "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -7934,6 +7996,16 @@ "dev": true, "license": "MIT" }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -8847,9 +8919,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, "license": "MIT", "engines": { @@ -10402,16 +10474,73 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index 1401c8ce6a..c7409d1cd0 100644 --- a/package.json +++ b/package.json @@ -209,6 +209,7 @@ "@firebase/database-types": "^1.0.6", "@types/node": "^22.8.7", "farmhash-modern": "^1.1.0", + "fast-deep-equal": "^3.1.1", "google-auth-library": "^9.14.2", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", diff --git a/src/app/firebase-app.ts b/src/app/firebase-app.ts index a0ee93e1fe..982c8d14e8 100644 --- a/src/app/firebase-app.ts +++ b/src/app/firebase-app.ts @@ -118,7 +118,7 @@ export class FirebaseAppInternals { } private shouldRefresh(): boolean { - return (!this.cachedToken_ || (this.cachedToken_.expirationTime - Date.now()) <= TOKEN_EXPIRY_THRESHOLD_MILLIS) + return (!this.cachedToken_ || (this.cachedToken_.expirationTime - Date.now()) <= TOKEN_EXPIRY_THRESHOLD_MILLIS) && !this.isRefreshing; } @@ -157,10 +157,13 @@ export class FirebaseApp implements App { private options_: AppOptions; private services_: {[name: string]: unknown} = {}; private isDeleted_ = false; + private autoInit_ = false; + private customCredential_ = true; - constructor(options: AppOptions, name: string, private readonly appStore?: AppStore) { + constructor(options: AppOptions, name: string, autoInit: boolean = false, private readonly appStore?: AppStore) { this.name_ = name; this.options_ = deepCopy(options); + this.autoInit_ = autoInit; if (!validator.isNonNullObject(this.options_)) { throw new FirebaseAppError( @@ -172,6 +175,7 @@ export class FirebaseApp implements App { const hasCredential = ('credential' in this.options_); if (!hasCredential) { + this.customCredential_ = false; this.options_.credential = getApplicationDefault(this.options_.httpAgent); } @@ -215,6 +219,25 @@ export class FirebaseApp implements App { return this.ensureService_(name, () => init(this)); } + /** + * Returns `true` if this app was initialized with auto-initialization. + * + * @internal + */ + public autoInit(): boolean { + return this.autoInit_; + } + + /** + * Returns `true` if the `FirebaseApp` instance was initialized with a custom + * `Credential`. + * + * @internal + */ + public customCredential() : boolean { + return this.customCredential_; + } + /** * Deletes the FirebaseApp instance. * diff --git a/src/app/lifecycle.ts b/src/app/lifecycle.ts index 9c7cfdd31d..5160e51f5c 100644 --- a/src/app/lifecycle.ts +++ b/src/app/lifecycle.ts @@ -22,6 +22,7 @@ import { AppErrorCodes, FirebaseAppError } from '../utils/error'; import { App, AppOptions } from './core'; import { getApplicationDefault } from './credential-internal'; import { FirebaseApp } from './firebase-app'; +const fastDeepEqual = require('fast-deep-equal'); const DEFAULT_APP_NAME = '[DEFAULT]'; @@ -30,48 +31,60 @@ export class AppStore { private readonly appStore = new Map(); public initializeApp(options?: AppOptions, appName: string = DEFAULT_APP_NAME): App { + validateAppNameFormat(appName); + + let autoInit = false; if (typeof options === 'undefined') { + autoInit = true options = loadOptionsFromEnvVar(); options.credential = getApplicationDefault(); } - if (typeof appName !== 'string' || appName === '') { + // Check if an app already exists and, if so, ensure its `AppOptions` match + // those of this `initializeApp` request. + if (!this.appStore.has(appName)) { + const app = new FirebaseApp(options, appName, autoInit, this); + this.appStore.set(app.name, app); + return app; + } + + const currentApp = this.appStore.get(appName)!; + // Ensure the `autoInit` state matches the existing app's. If not, throw. + if (currentApp.autoInit() !== autoInit) { throw new FirebaseAppError( - AppErrorCodes.INVALID_APP_NAME, - `Invalid Firebase app name "${appName}" provided. App name must be a non-empty string.`, + AppErrorCodes.INVALID_APP_OPTIONS, + `A Firebase app named "${appName}" already exists with a different configuration.` + ) + } + + if (autoInit) { + // Auto-initialization is triggered when no options were passed to + // `initializeApp`. With no options to compare, simply return the App. + return currentApp; + } + + // Ensure the options objects don't break deep equal comparisons. + validateAppOptionsSupportDeepEquals(options, currentApp); + + // `FirebaseApp()` adds a synthesized `Credential` to `app.options` upon + // app construction. Run a comparison w/o `Credential` to see if the base + // configurations match. Return the existing app if so. + const currentAppOptions = { ...currentApp.options }; + delete currentAppOptions.credential; + if (!fastDeepEqual(options, currentAppOptions)) { + throw new FirebaseAppError( + AppErrorCodes.DUPLICATE_APP, + `A Firebase app named "${appName}" already exists with a different configuration.` ); - } else if (this.appStore.has(appName)) { - if (appName === DEFAULT_APP_NAME) { - throw new FirebaseAppError( - AppErrorCodes.DUPLICATE_APP, - 'The default Firebase app already exists. This means you called initializeApp() ' + - 'more than once without providing an app name as the second argument. In most cases ' + - 'you only need to call initializeApp() once. But if you do want to initialize ' + - 'multiple apps, pass a second argument to initializeApp() to give each app a unique ' + - 'name.', - ); - } else { - throw new FirebaseAppError( - AppErrorCodes.DUPLICATE_APP, - `Firebase app named "${appName}" already exists. This means you called initializeApp() ` + - 'more than once with the same app name as the second argument. Make sure you provide a ' + - 'unique name every time you call initializeApp().', - ); - } + } - const app = new FirebaseApp(options, appName, this); - this.appStore.set(app.name, app); - return app; + return currentApp; } public getApp(appName: string = DEFAULT_APP_NAME): App { - if (typeof appName !== 'string' || appName === '') { - throw new FirebaseAppError( - AppErrorCodes.INVALID_APP_NAME, - `Invalid Firebase app name "${appName}" provided. App name must be a non-empty string.`, - ); - } else if (!this.appStore.has(appName)) { + validateAppNameFormat(appName); + if (!this.appStore.has(appName)) { let errorMessage: string = (appName === DEFAULT_APP_NAME) ? 'The default Firebase app does not exist. ' : `Firebase app named "${appName}" does not exist. `; errorMessage += 'Make sure you call initializeApp() before using any of the Firebase services.'; @@ -119,16 +132,145 @@ export class AppStore { } } +/** + * Validates that the `requestedOptions` and the `existingApp` options objects + * do not have fields that would break deep equals comparisons. + * + * @param requestedOptions The incoming `AppOptions` of a new `initailizeApp` + * request. + * @param existingApp An existing `FirebaseApp` with internal `options` to + * compare against. + * + * @throws FirebaseAppError if the objects cannot be deeply compared. + * + * @internal + */ +function validateAppOptionsSupportDeepEquals( + requestedOptions: AppOptions, + existingApp: FirebaseApp): void { + + // http.Agent checks. + if (typeof requestedOptions.httpAgent !== 'undefined') { + throw new FirebaseAppError( + AppErrorCodes.INVALID_APP_OPTIONS, + `Firebase app named "${existingApp.name}" already exists and initializeApp was` + + ' invoked with an optional http.Agent. The SDK cannot confirm the equality' + + ' of http.Agent objects with the existing app. Please use getApp or getApps to reuse' + + ' the existing app instead.' + ); + } else if (typeof existingApp.options.httpAgent !== 'undefined') { + throw new FirebaseAppError( + AppErrorCodes.INVALID_APP_OPTIONS, + `An existing app named "${existingApp.name}" already exists with a different` + + ' options configuration: httpAgent.' + ); + } + + // Credential checks. + if (typeof requestedOptions.credential !== 'undefined') { + throw new FirebaseAppError( + AppErrorCodes.INVALID_APP_OPTIONS, + `Firebase app named "${existingApp.name}" already exists and initializeApp was` + + ' invoked with an optional Credential. The SDK cannot confirm the equality' + + ' of Credential objects with the existing app. Please use getApp or getApps' + + ' to reuse the existing app instead.' + ); + } + + if (existingApp.customCredential()) { + throw new FirebaseAppError( + AppErrorCodes.INVALID_APP_OPTIONS, + `An existing app named "${existingApp.name}" already exists with a different` + + ' options configuration: Credential.' + ); + } +} + +/** + * Checks to see if the provided appName is a non-empty string and throws if it + * is not. + * + * @param appName A string representation of an App name. + * + * @throws FirebaseAppError if appName is not of type string or is empty. + * + * @internal + */ +function validateAppNameFormat(appName: string): void { + if (!validator.isNonEmptyString(appName)) { + throw new FirebaseAppError( + AppErrorCodes.INVALID_APP_NAME, + `Invalid Firebase app name "${appName}" provided. App name must be a non-empty string.`, + ); + } +} + export const defaultAppStore = new AppStore(); +/** + * Initializes the `App` instance. + * + * Creates a new instance of {@link App} if one doesn't exist, or returns an existing + * `App` instance if one exists with the same `appName` and `options`. + * + * Note, due to the inablity to compare `http.Agent` objects and `Credential` objects, + * this function cannot support idempotency if either of `options.httpAgent` or + * `options.credential` are defined. When either is defined, subsequent invocations will + * throw a `FirebaseAppError` instead of returning an `App` object. + * + * For example, to safely initialize an app that may already exist: + * + * ```javascript + * let app; + * try { + * app = getApp("myApp"); + * } catch (error) { + * app = initializeApp({ credential: myCredential }, "myApp"); + * } + * ``` + * + * @param options - Optional A set of {@link AppOptions} for the `App` instance. + * If not present, `initializeApp` will try to initialize with the options from the + * `FIREBASE_CONFIG` environment variable. If the environment variable contains a + * string that starts with `{` it will be parsed as JSON, otherwise it will be + * assumed to be pointing to a file. + * @param appName - Optional name of the `App` instance. + * + * @returns A new App instance, or the existing App if the instance already exists with + * the provided configuration. + * + * @throws FirebaseAppError if an `App` with the same name has already been + * initialized with a different set of `AppOptions`. + * @throws FirebaseAppError if an existing `App` exists and `options.httpAgent` + * or `options.credential` are defined. This is due to the function's inability to + * determine if the existing `App`'s `options` equate to the `options` parameter + * of this function. It's recommended to use {@link getApp} or {@link getApps} if your + * implementation uses either of these two fields in `AppOptions`. + */ export function initializeApp(options?: AppOptions, appName: string = DEFAULT_APP_NAME): App { return defaultAppStore.initializeApp(options, appName); } +/** + * Returns an existing {@link App} instance for the provided name. If no name + * is provided the the default app name is used. + * + * @param appName - Optional name of the `App` instance. + * + * @returns An existing `App` instance that matches the name provided. + * + * @throws FirebaseAppError if no `App` exists for the given name. + * @throws FirebaseAppError if the `appName` is malformed. + */ export function getApp(appName: string = DEFAULT_APP_NAME): App { return defaultAppStore.getApp(appName); } +/** + * A (read-only) array of all initialized apps. + * + * @returns An array containing all initialized apps. + */ export function getApps(): App[] { return defaultAppStore.getApps(); } diff --git a/test/resources/mocks.ts b/test/resources/mocks.ts index f9d08023d2..c6b86886a0 100644 --- a/test/resources/mocks.ts +++ b/test/resources/mocks.ts @@ -57,10 +57,15 @@ export const storageBucket = 'bucketName.appspot.com'; export const credential = cert(path.resolve(__dirname, './mock.key.json')); -export const appOptions: AppOptions = { - credential, +export const appOptionsWithoutCredential: AppOptions = { databaseURL, - storageBucket, + storageBucket +}; + +export const appOptions: AppOptions = { + ...appOptionsWithoutCredential, + credential + }; export const appOptionsWithOverride: AppOptions = { diff --git a/test/unit/app/firebase-app.spec.ts b/test/unit/app/firebase-app.spec.ts index df4fc84a67..a99e15d8f0 100644 --- a/test/unit/app/firebase-app.spec.ts +++ b/test/unit/app/firebase-app.spec.ts @@ -33,7 +33,7 @@ import { FirebaseNamespace } from '../../../src/app/firebase-namespace'; import { AppStore, FIREBASE_CONFIG_VAR } from '../../../src/app/lifecycle'; import { auth, messaging, machineLearning, storage, firestore, database, - instanceId, installations, projectManagement, securityRules , remoteConfig, appCheck, + instanceId, installations, projectManagement, securityRules, remoteConfig, appCheck, } from '../../../src/firebase-namespace-api'; import { FirebaseAppError, AppErrorCodes } from '../../../src/utils/error'; @@ -269,6 +269,15 @@ describe('FirebaseApp', () => { expect(app.options.storageBucket).to.be.undefined; }); + it('should not throw if initializeApp invoked with the same options', () => { + process.env[FIREBASE_CONFIG_VAR] = './test/resources/firebase_config.json'; + expect(() => { + const app = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential, mocks.appName); + const app2 = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential, mocks.appName); + expect(app2).to.equal(app); + }).to.not.throw(); + }); + it('should init with application default creds when no options provided and env variable is not set', () => { const app = firebaseNamespace.initializeApp(); expect(app.options.credential).to.not.be.undefined; @@ -324,7 +333,7 @@ describe('FirebaseApp', () => { it('should call removeApp() on the Firebase namespace internals', () => { const store = new AppStore(); const stub = sinon.stub(store, 'removeApp').resolves(); - const app = new FirebaseApp(mockApp.options, mockApp.name, store); + const app = new FirebaseApp(mockApp.options, mockApp.name, /*autoInit=*/false, store); return app.delete().then(() => { expect(stub).to.have.been.calledOnce.and.calledWith(mocks.appName); }); diff --git a/test/unit/app/firebase-namespace.spec.ts b/test/unit/app/firebase-namespace.spec.ts index ee3cb951fb..38a4c49886 100644 --- a/test/unit/app/firebase-namespace.spec.ts +++ b/test/unit/app/firebase-namespace.spec.ts @@ -17,6 +17,7 @@ 'use strict'; +import http = require('http'); import path = require('path'); import * as _ from 'lodash'; @@ -49,7 +50,7 @@ import { getSdkVersion } from '../../../src/utils/index'; import { app, auth, messaging, machineLearning, storage, firestore, database, - instanceId, installations, projectManagement, securityRules , remoteConfig, appCheck, + instanceId, installations, projectManagement, securityRules, remoteConfig, appCheck, } from '../../../src/firebase-namespace-api'; import { AppCheck as AppCheckImpl } from '../../../src/app-check/app-check'; import { Auth as AuthImpl } from '../../../src/auth/auth'; @@ -89,6 +90,20 @@ const expect = chai.expect; const DEFAULT_APP_NAME = '[DEFAULT]'; const DEFAULT_APP_NOT_FOUND = 'The default Firebase app does not exist. Make sure you call initializeApp() ' + 'before using any of the Firebase services.'; +const INITIALIZE_APP_CREDENTIAL_EXISTANCE_MISMATCH = 'An existing app named "mock-app-name" already ' + + 'exists with a different options configuration: Credential'; +const INITIALIZE_APP_HTTP_AGENT_EXISTANCE_MISMATCH = 'An existing app named "mock-app-name" already ' + + 'exists with a different options configuration: httpAgent'; +const INITIALIZE_APP_NOT_IDEMPOTENT_CREDENTIAL = 'Firebase app named "mock-app-name" already exists and ' + + 'initializeApp was invoked with an optional Credential. The SDK cannot confirm the equality ' + + 'of Credential objects with the existing app. Please use getApp or getApps to reuse the ' + + 'existing app instead.' +const INITIALIZE_APP_NOT_IDEMPOTENT_HTTP_AGENT = 'Firebase app named "mock-app-name" already exists and ' + + 'initializeApp was invoked with an optional http.Agent. The SDK cannot confirm the equality ' + + 'of http.Agent objects with the existing app. Please use getApp or getApps to reuse the ' + + 'existing app instead.' + + describe('FirebaseNamespace', () => { let firebaseNamespace: FirebaseNamespace; @@ -207,33 +222,94 @@ describe('FirebaseNamespace', () => { }).to.throw('Invalid Firebase app name "" provided. App name must be a non-empty string.'); }); - it('should throw given a name corresponding to an existing app', () => { + it('should not throw given a name corresponding to an existing app', () => { + let app1: App | undefined; + let app2: App | undefined; expect(() => { - firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); - firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); - }).to.throw(`Firebase app named "${mocks.appName}" already exists.`); + app1 = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential, mocks.appName); + app2 = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential, mocks.appName); + }).to.not.throw(); + expect(app1).to.equal(app2); }); - it('should throw given no app name if the default app already exists', () => { + it('should not throw given no app name if the default app already exists', () => { + let app1: App | undefined; + let app2: App | undefined; expect(() => { - firebaseNamespace.initializeApp(mocks.appOptions); - firebaseNamespace.initializeApp(mocks.appOptions); - }).to.throw('The default Firebase app already exists.'); + app1 = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential); + app2 = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential); + }).to.not.throw(); + expect(app1).to.equal(app2); + }); + + it('should throw due to the Credential option being not supported by idemopotency', () => { + let app1: App | undefined; + let app2: App | undefined; + expect(() => { + app1 = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); + app2 = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); + }).to.throw(INITIALIZE_APP_NOT_IDEMPOTENT_CREDENTIAL); + expect(app1).to.not.be.undefined; + expect(app2).to.be.undefined; + }); + + it('should throw due to idempotency check on Credential option on second app.', () => { + let app1: App | undefined; + let app2: App | undefined; + expect(() => { + app1 = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); + app2 = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential, mocks.appName); + }).to.throw(INITIALIZE_APP_CREDENTIAL_EXISTANCE_MISMATCH); + expect(app1).to.not.be.undefined; + expect(app2).to.be.undefined; + }); + it('should throw due to the httpAgent option being not supported by idemopotency', () => { + let app1: App | undefined; + let app2: App | undefined; + const httpAgent = new http.Agent(); + const appOptions = { + ...mocks.appOptionsWithoutCredential, + httpAgent + } expect(() => { - firebaseNamespace.initializeApp(mocks.appOptions); - firebaseNamespace.initializeApp(mocks.appOptions, DEFAULT_APP_NAME); - }).to.throw('The default Firebase app already exists.'); + app1 = firebaseNamespace.initializeApp(appOptions, mocks.appName); + app2 = firebaseNamespace.initializeApp(appOptions, mocks.appName); + }).to.throw(INITIALIZE_APP_NOT_IDEMPOTENT_HTTP_AGENT); + expect(app1).to.not.be.undefined; + expect(app2).to.be.undefined; + }); + it('should throw due to idempotency check on httpAgent option on second app.', () => { + let app1: App | undefined; + let app2: App | undefined; + const httpAgent = new http.Agent(); + const appOptions = { + ...mocks.appOptionsWithoutCredential, + httpAgent + } expect(() => { - firebaseNamespace.initializeApp(mocks.appOptions, DEFAULT_APP_NAME); - firebaseNamespace.initializeApp(mocks.appOptions); - }).to.throw('The default Firebase app already exists.'); + app1 = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential, mocks.appName); + app2 = firebaseNamespace.initializeApp(appOptions, mocks.appName); + }).to.throw(INITIALIZE_APP_NOT_IDEMPOTENT_HTTP_AGENT); + expect(app1).to.not.be.undefined; + expect(app2).to.be.undefined; + }); + it('should throw due to idempotency check on httpAgent option on first app but not second app.', () => { + let app1: App | undefined; + let app2: App | undefined; + const httpAgent = new http.Agent(); + const appOptions = { + ...mocks.appOptionsWithoutCredential, + httpAgent + } expect(() => { - firebaseNamespace.initializeApp(mocks.appOptions, DEFAULT_APP_NAME); - firebaseNamespace.initializeApp(mocks.appOptions, DEFAULT_APP_NAME); - }).to.throw('The default Firebase app already exists.'); + app1 = firebaseNamespace.initializeApp(appOptions, mocks.appName); + app2 = firebaseNamespace.initializeApp(mocks.appOptionsWithoutCredential, mocks.appName); + }).to.throw(INITIALIZE_APP_HTTP_AGENT_EXISTANCE_MISMATCH); + expect(app1).to.not.be.undefined; + expect(app2).to.be.undefined; }); it('should return a new app with the provided options and app name', () => { @@ -248,10 +324,12 @@ describe('FirebaseNamespace', () => { }); it('should allow re-use of a deleted app name', () => { - let app = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); - return app.delete().then(() => { - app = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); - expect(firebaseNamespace.app(mocks.appName)).to.deep.equal(app); + const app1 = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); + let app2: App | undefined; + return app1.delete().then(() => { + app2 = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); + expect(firebaseNamespace.app(mocks.appName)).to.deep.equal(app2); + expect(app2).to.not.equal(app1); }); }); From 5b0c5c15e61058e37d5ec3d92dd68f61bb7c7375 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 11:38:33 -0400 Subject: [PATCH 262/323] build(deps-dev): bump @microsoft/api-extractor from 7.52.7 to 7.52.10 (#2955) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.52.7 to 7.52.10. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.52.10/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-version: 7.52.10 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 115 +++++++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index bc43fd2ed4..08c878de84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1016,6 +1016,29 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1209,21 +1232,21 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.52.7", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.7.tgz", - "integrity": "sha512-YLdPS644MfbLJt4hArP1WcldcaEUBh9wnFjcLEcQnVG0AMznbLh2sdE0F5Wr+w6+Lyp5/XUPvRAg3sYGSP3GCw==", + "version": "7.52.10", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.10.tgz", + "integrity": "sha512-LhKytJM5ZJkbHQVfW/3o747rZUNs/MGg6j/wt/9qwwqEOfvUDTYXXxIBuMgrRXhJ528p41iyz4zjBVHZU74Odg==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.30.6", + "@microsoft/api-extractor-model": "7.30.7", "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.13.1", + "@rushstack/node-core-library": "5.14.0", "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.15.3", - "@rushstack/ts-command-line": "5.0.1", + "@rushstack/terminal": "0.15.4", + "@rushstack/ts-command-line": "5.0.2", "lodash": "~4.17.15", - "minimatch": "~3.0.3", + "minimatch": "10.0.3", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", @@ -1234,15 +1257,15 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.30.6", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.6.tgz", - "integrity": "sha512-znmFn69wf/AIrwHya3fxX6uB5etSIn6vg4Q4RB/tb5VDDs1rqREc+AvMC/p19MUN13CZ7+V/8pkYPTj7q8tftg==", + "version": "7.30.7", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.7.tgz", + "integrity": "sha512-TBbmSI2/BHpfR9YhQA7nH0nqVmGgJ0xH0Ex4D99/qBDAUpnhA2oikGmdXanbw9AWWY/ExBYIpkmY8dBHdla3YQ==", "dev": true, "license": "MIT", "dependencies": { "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.13.1" + "@rushstack/node-core-library": "5.14.0" } }, "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { @@ -1253,9 +1276,9 @@ "license": "MIT" }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz", - "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.14.0.tgz", + "integrity": "sha512-eRong84/rwQUlATGFW3TMTYVyqL1vfW9Lf10PH+mVGfIb9HzU3h5AASNIw+axnBLjnD0n3rT5uQBwu9fvzATrg==", "dev": true, "license": "MIT", "dependencies": { @@ -1295,9 +1318,9 @@ } }, "node_modules/@microsoft/api-extractor-model/node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", "dev": true, "license": "MIT", "dependencies": { @@ -1339,9 +1362,9 @@ "dev": true }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz", - "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.14.0.tgz", + "integrity": "sha512-eRong84/rwQUlATGFW3TMTYVyqL1vfW9Lf10PH+mVGfIb9HzU3h5AASNIw+axnBLjnD0n3rT5uQBwu9fvzATrg==", "dev": true, "license": "MIT", "dependencies": { @@ -1364,13 +1387,13 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.0.1.tgz", - "integrity": "sha512-bsbUucn41UXrQK7wgM8CNM/jagBytEyJqXw/umtI8d68vFm1Jwxh1OtLrlW7uGZgjCWiiPH6ooUNa1aVsuVr3Q==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.0.2.tgz", + "integrity": "sha512-+AkJDbu1GFMPIU8Sb7TLVXDv/Q7Mkvx+wAjEl8XiXVVq+p1FmWW6M3LYpJMmoHNckSofeMecgWg5lfMwNAAsEQ==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.15.3", + "@rushstack/terminal": "0.15.4", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1394,9 +1417,9 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", "dev": true, "license": "MIT", "dependencies": { @@ -1421,6 +1444,22 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/@microsoft/api-extractor/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { "version": "5.8.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", @@ -1640,13 +1679,13 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.3.tgz", - "integrity": "sha512-DGJ0B2Vm69468kZCJkPj3AH5nN+nR9SPmC0rFHtzsS4lBQ7/dgOwtwVxYP7W9JPDMuRBkJ4KHmWKr036eJsj9g==", + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.4.tgz", + "integrity": "sha512-OQSThV0itlwVNHV6thoXiAYZlQh4Fgvie2CzxFABsbO2MWQsI4zOh3LRNigYSTrmS+ba2j0B3EObakPzf/x6Zg==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.13.1", + "@rushstack/node-core-library": "5.14.0", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -1659,9 +1698,9 @@ } }, "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz", - "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.14.0.tgz", + "integrity": "sha512-eRong84/rwQUlATGFW3TMTYVyqL1vfW9Lf10PH+mVGfIb9HzU3h5AASNIw+axnBLjnD0n3rT5uQBwu9fvzATrg==", "dev": true, "license": "MIT", "dependencies": { @@ -1701,9 +1740,9 @@ } }, "node_modules/@rushstack/terminal/node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", "dev": true, "license": "MIT", "dependencies": { From be214b4af15b1ef3ac231b35561fb0b1d0518559 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 18 Aug 2025 16:18:48 -0400 Subject: [PATCH 263/323] chore: Fix strip-only mode issues in Node.js 22.18 (#2958) * fix import syntax issue in Node.js 22.x * update mocha * update emulator test path * update emulator test path * update emulator test path * add Node 24.x to CIs * Trigger Staging --- .github/workflows/ci.yml | 4 +- .github/workflows/nightly.yml | 2 +- package-lock.json | 376 ++++++++++++++++++++++++++-------- package.json | 2 +- test/unit/firebase.spec.ts | 2 +- 5 files changed, 300 insertions(+), 86 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f629d6da10..ba8a5896b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: - node-version: [18.x, 20.x, 22.x] + node-version: [18.x, 20.x, 22.x, 24.x] steps: - uses: actions/checkout@v4 @@ -30,4 +30,4 @@ jobs: run: | npm install -g firebase-tools@11.30.0 firebase emulators:exec --project fake-project-id --only auth,database,firestore \ - 'npx mocha \"test/integration/{auth,database,firestore}.spec.ts\" --slow 5000 --timeout 20000 --require ts-node/register' + 'npx mocha test/integration/auth.spec.ts test/integration/database.spec.ts test/integration/firestore.spec.ts --slow 5000 --timeout 20000 --require ts-node/register' diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 17533e318d..e3ce768cb5 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -54,7 +54,7 @@ jobs: run: | npm install -g firebase-tools@11.30.0 firebase emulators:exec --project fake-project-id --only auth,database,firestore \ - 'npx mocha \"test/integration/{auth,database,firestore}.spec.ts\" --slow 5000 --timeout 20000 --require ts-node/register' + 'npx mocha test/integration/auth.spec.ts test/integration/database.spec.ts test/integration/firestore.spec.ts --slow 5000 --timeout 20000 --require ts-node/register' - name: Run integration tests run: ./.github/scripts/run_integration_tests.sh diff --git a/package-lock.json b/package-lock.json index 08c878de84..5fb0b2b435 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,7 @@ "http-message-parser": "^0.0.34", "lodash": "^4.17.15", "minimist": "^1.2.6", - "mocha": "^10.0.0", + "mocha": "^11.0.0", "mz": "^2.7.0", "nock": "^13.0.0", "npm-run-all": "^4.1.5", @@ -1039,6 +1039,102 @@ "node": "20 || >=22" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1559,6 +1655,16 @@ "node": ">=8.0.0" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -4175,6 +4281,12 @@ "node": ">= 10.13.0" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -5478,21 +5590,20 @@ } }, "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, - "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": ">=12" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5546,26 +5657,36 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" } }, "node_modules/global-modules": { @@ -7378,6 +7499,21 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jju": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", @@ -8195,31 +8331,30 @@ } }, "node_modules/mocha": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", - "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.1.tgz", + "integrity": "sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A==", "dev": true, - "license": "MIT", "dependencies": { - "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", + "chokidar": "^4.0.1", "debug": "^4.3.5", - "diff": "^5.2.0", + "diff": "^7.0.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", - "glob": "^8.1.0", + "glob": "^10.4.5", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", + "minimatch": "^9.0.5", "ms": "^2.1.3", + "picocolors": "^1.1.1", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", "yargs-unparser": "^2.0.0" }, "bin": { @@ -8227,71 +8362,77 @@ "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/mocha/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/mocha/node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "engines": { + "node": ">=0.3.1" } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "node_modules/mocha/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "engines": { + "node": ">= 14.18.0" }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/ms": { @@ -9173,6 +9314,12 @@ "node": ">=8" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -9302,6 +9449,28 @@ "node": ">=0.10.0" } }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/path-to-regexp": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", @@ -10917,6 +11086,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.padend": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", @@ -11001,6 +11185,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -12102,11 +12299,10 @@ } }, "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true, - "license": "Apache-2.0" + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.3.tgz", + "integrity": "sha512-slxCaKbYjEdFT/o2rH9xS1hf4uRDch1w7Uo+apxhZ+sf/1d9e0ZVkn42kPNGP2dgjIx6YFvSevj0zHvbWe2jdw==", + "dev": true }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -12126,6 +12322,24 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index c7409d1cd0..379f640bf0 100644 --- a/package.json +++ b/package.json @@ -258,7 +258,7 @@ "http-message-parser": "^0.0.34", "lodash": "^4.17.15", "minimist": "^1.2.6", - "mocha": "^10.0.0", + "mocha": "^11.0.0", "mz": "^2.7.0", "nock": "^13.0.0", "npm-run-all": "^4.1.5", diff --git a/test/unit/firebase.spec.ts b/test/unit/firebase.spec.ts index 3bd63209f8..9a1ca5820e 100644 --- a/test/unit/firebase.spec.ts +++ b/test/unit/firebase.spec.ts @@ -18,7 +18,7 @@ 'use strict'; // Use untyped import syntax for Node built-ins -import path = require('path'); +import * as path from 'path'; import * as _ from 'lodash'; import * as sinon from 'sinon'; From f861260ed3035cf3a8a0af285ccc755d926f242a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 20:23:13 +0000 Subject: [PATCH 264/323] build(deps): bump form-data in /.github/actions/send-email (#2951) --- .github/actions/send-email/package-lock.json | 187 ++++++++++++++++++- 1 file changed, 184 insertions(+), 3 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 48ddb2fb7a..2b2d9b2449 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -72,6 +72,19 @@ "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -91,6 +104,65 @@ "node": ">=0.4.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -111,18 +183,118 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { "node": ">= 6" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mailgun.js": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-10.1.0.tgz", @@ -136,6 +308,15 @@ "node": ">=18.0.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", From 0776fba3d319061e37c40bf4ab238f5cdb97c821 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Aug 2025 15:45:58 +0000 Subject: [PATCH 265/323] build(deps-dev): bump @types/request from 2.48.12 to 2.48.13 (#2959) --- package-lock.json | 59 +++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5fb0b2b435..95430e9367 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2179,16 +2179,16 @@ "license": "MIT" }, "node_modules/@types/request": { - "version": "2.48.12", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", - "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "version": "2.48.13", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.13.tgz", + "integrity": "sha512-FGJ6udDNUCjd19pp0Q3iTiDkwhYup7J8hpMW9c4k53NrccQFFWKRho6hvtPPEhnXWKvukfwAlB6DbDz4yhH5Gg==", "devOptional": true, "license": "MIT", "dependencies": { "@types/caseless": "*", "@types/node": "*", "@types/tough-cookie": "*", - "form-data": "^2.5.0" + "form-data": "^2.5.5" } }, "node_modules/@types/request-promise": { @@ -3467,7 +3467,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4243,7 +4243,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -4406,7 +4406,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4416,7 +4416,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4426,7 +4426,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -4436,15 +4436,16 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "devOptional": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5220,15 +5221,17 @@ } }, "node_modules/form-data": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", - "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", + "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", "devOptional": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35", "safe-buffer": "^5.2.1" }, "engines": { @@ -5344,7 +5347,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, + "devOptional": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5509,7 +5512,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -5551,7 +5554,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -5847,7 +5850,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -6461,7 +6464,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -6474,7 +6477,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -6524,7 +6527,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -8175,7 +8178,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" From 9cad09ebb82a91a740a8e4c2d656aeac768bb1e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 19:29:02 +0000 Subject: [PATCH 266/323] build(deps): bump uuid from 11.0.3 to 11.1.0 (#2946) --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 95430e9367..7732631a71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11947,13 +11947,14 @@ "license": "MIT" }, "node_modules/uuid": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", - "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/esm/bin/uuid" } From 8888958c5d9cbafd8280e1a2598a8e4e0892615c Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 26 Aug 2025 16:58:42 -0400 Subject: [PATCH 267/323] chore: Upgrade @firebase/auth-compat and @firebase/auth-types (#2964) --- package-lock.json | 71 ++++++++++++++++++++++++++++------------------- package.json | 4 +-- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7732631a71..5d6cea5157 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,8 +24,8 @@ "devDependencies": { "@firebase/api-documenter": "^0.4.0", "@firebase/app-compat": "^0.2.1", - "@firebase/auth-compat": "^0.5.13", - "@firebase/auth-types": "^0.12.0", + "@firebase/auth-compat": "^0.6.0", + "@firebase/auth-types": "^0.13.0", "@microsoft/api-extractor": "^7.11.2", "@types/bcrypt": "^5.0.0", "@types/chai": "^4.0.0", @@ -631,18 +631,18 @@ } }, "node_modules/@firebase/auth": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.1.tgz", - "integrity": "sha512-LX9N/Cf5Z35r5yqm2+5M3+2bRRe/+RFaa/+u4HDni7TA27C/Xm4XHLKcWcLg1BzjrS4zngSaBEOSODvp6RFOqQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.11.0.tgz", + "integrity": "sha512-5j7+ua93X+IRcJ1oMDTClTo85l7Xe40WSkoJ+shzPrX7OISlVWLdE1mKC57PSD+/LfAbdhJmvKixINBw2ESK6w==", "dev": true, "dependencies": { - "@firebase/component": "0.6.11", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.10.2", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", "tslib": "^2.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "peerDependencies": { "@firebase/app": "0.x", @@ -655,19 +655,19 @@ } }, "node_modules/@firebase/auth-compat": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.16.tgz", - "integrity": "sha512-YlYwJMBqAyv0ESy3jDUyshMhZlbUiwAm6B6+uUmigNDHU+uq7j4SFiDJEZlFFIz397yBzKn06SUdqutdQzGnCA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.6.0.tgz", + "integrity": "sha512-J0lGSxXlG/lYVi45wbpPhcWiWUMXevY4fvLZsN1GHh+po7TZVng+figdHBVhFheaiipU8HZyc7ljw1jNojM2nw==", "dev": true, "dependencies": { - "@firebase/auth": "1.8.1", - "@firebase/auth-types": "0.12.3", - "@firebase/component": "0.6.11", - "@firebase/util": "1.10.2", + "@firebase/auth": "1.11.0", + "@firebase/auth-types": "0.13.0", + "@firebase/component": "0.7.0", + "@firebase/util": "1.13.0", "tslib": "^2.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "peerDependencies": { "@firebase/app-compat": "0.x" @@ -680,26 +680,38 @@ "license": "Apache-2.0" }, "node_modules/@firebase/auth-types": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.3.tgz", - "integrity": "sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", + "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", "dev": true, "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, + "node_modules/@firebase/auth/node_modules/@firebase/logger": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", + "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@firebase/component": { - "version": "0.6.11", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", - "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", + "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", "dev": true, "dependencies": { - "@firebase/util": "1.10.2", + "@firebase/util": "1.13.0", "tslib": "^2.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@firebase/database": { @@ -824,15 +836,16 @@ } }, "node_modules/@firebase/util": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", - "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", + "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", "dev": true, + "hasInstallScript": true, "dependencies": { "tslib": "^2.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@google-cloud/firestore": { diff --git a/package.json b/package.json index 379f640bf0..508b5b32dc 100644 --- a/package.json +++ b/package.json @@ -223,8 +223,8 @@ "devDependencies": { "@firebase/api-documenter": "^0.4.0", "@firebase/app-compat": "^0.2.1", - "@firebase/auth-compat": "^0.5.13", - "@firebase/auth-types": "^0.12.0", + "@firebase/auth-compat": "^0.6.0", + "@firebase/auth-types": "^0.13.0", "@microsoft/api-extractor": "^7.11.2", "@types/bcrypt": "^5.0.0", "@types/chai": "^4.0.0", From 450f07961a176a38a3f9f90e5b409f1dabb80830 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 28 Aug 2025 09:01:19 -0400 Subject: [PATCH 268/323] [chore] Release 13.5.0 (#2969) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 508b5b32dc..ffd2a8da9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.4.0", + "version": "13.5.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 34422519ffa0a5a14f9832d73d016fda54b7b078 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 16 Sep 2025 13:09:53 -0400 Subject: [PATCH 269/323] chore: update copyright headers from Google Inc. to Google LLC (#2974) Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- .eslintrc.js | 2 +- .github/actions/send-email/action.yml | 2 +- .github/actions/send-email/index.js | 2 +- .github/actions/send-tweet/action.yml | 2 +- .github/actions/send-tweet/index.js | 2 +- .github/scripts/publish_package.sh | 2 +- .github/scripts/publish_preflight_check.sh | 2 +- .github/scripts/run_integration_tests.sh | 2 +- .github/scripts/verify_package.sh | 2 +- .github/workflows/nightly.yml | 2 +- .github/workflows/release.yml | 2 +- docgen/post-process.js | 2 +- generate-esm-wrapper.js | 2 +- generate-reports.js | 2 +- gulpfile.js | 2 +- src/app-check/app-check-api-client-internal.ts | 2 +- src/app-check/app-check-api.ts | 2 +- src/app-check/app-check-namespace.ts | 2 +- src/app-check/app-check.ts | 2 +- src/app-check/index.ts | 2 +- src/app-check/token-generator.ts | 2 +- src/app-check/token-verifier.ts | 2 +- src/app/core.ts | 2 +- src/app/credential-factory.ts | 2 +- src/app/credential-internal.ts | 2 +- src/app/credential.ts | 2 +- src/app/firebase-app.ts | 2 +- src/app/firebase-namespace.ts | 2 +- src/app/index.ts | 2 +- src/app/lifecycle.ts | 2 +- src/auth/action-code-settings-builder.ts | 2 +- src/auth/auth-api-request.ts | 2 +- src/auth/auth-config.ts | 2 +- src/auth/auth-namespace.ts | 2 +- src/auth/auth.ts | 2 +- src/auth/base-auth.ts | 2 +- src/auth/identifier.ts | 2 +- src/auth/index.ts | 2 +- src/auth/project-config-manager.ts | 2 +- src/auth/project-config.ts | 2 +- src/auth/tenant-manager.ts | 2 +- src/auth/tenant.ts | 2 +- src/auth/token-generator.ts | 2 +- src/auth/token-verifier.ts | 2 +- src/auth/user-import-builder.ts | 2 +- src/auth/user-record.ts | 2 +- src/credential/index.ts | 2 +- src/data-connect/data-connect-api-client-internal.ts | 2 +- src/data-connect/data-connect-api.ts | 2 +- src/data-connect/data-connect.ts | 2 +- src/data-connect/index.ts | 2 +- src/database/database-namespace.ts | 2 +- src/database/database.ts | 2 +- src/database/index.ts | 2 +- src/default-namespace.d.ts | 2 +- src/default-namespace.ts | 2 +- src/eventarc/cloudevent.ts | 2 +- src/eventarc/eventarc-client-internal.ts | 2 +- src/eventarc/eventarc-utils.ts | 2 +- src/eventarc/eventarc.ts | 2 +- src/eventarc/index.ts | 2 +- src/extensions/extensions-api-client-internal.ts | 2 +- src/extensions/extensions-api.ts | 2 +- src/extensions/extensions.ts | 2 +- src/extensions/index.ts | 2 +- src/firebase-namespace-api.ts | 2 +- src/firestore/firestore-internal.ts | 2 +- src/firestore/firestore-namespace.ts | 2 +- src/firestore/index.ts | 2 +- src/functions/functions-api-client-internal.ts | 2 +- src/functions/functions-api.ts | 2 +- src/functions/functions.ts | 2 +- src/functions/index.ts | 2 +- src/index.d.ts | 2 +- src/index.ts | 2 +- src/installations/index.ts | 2 +- src/installations/installations-namespace.ts | 2 +- src/installations/installations-request-handler.ts | 2 +- src/installations/installations.ts | 2 +- src/instance-id/index.ts | 2 +- src/instance-id/instance-id.ts | 2 +- src/machine-learning/index.ts | 2 +- src/machine-learning/machine-learning-api-client.ts | 2 +- src/machine-learning/machine-learning-namespace.ts | 2 +- src/machine-learning/machine-learning-utils.ts | 2 +- src/machine-learning/machine-learning.ts | 2 +- src/messaging/index.ts | 2 +- src/messaging/messaging-api-request-internal.ts | 2 +- src/messaging/messaging-api.ts | 2 +- src/messaging/messaging-errors-internal.ts | 2 +- src/messaging/messaging-internal.ts | 2 +- src/messaging/messaging-namespace.ts | 2 +- src/messaging/messaging.ts | 2 +- src/project-management/android-app.ts | 2 +- src/project-management/app-metadata.ts | 2 +- src/project-management/index.ts | 2 +- src/project-management/ios-app.ts | 2 +- .../project-management-api-request-internal.ts | 2 +- src/project-management/project-management-namespace.ts | 2 +- src/project-management/project-management.ts | 2 +- src/remote-config/condition-evaluator-internal.ts | 2 +- src/remote-config/index.ts | 2 +- src/remote-config/internal/value-impl.ts | 2 +- src/remote-config/remote-config-api-client-internal.ts | 2 +- src/remote-config/remote-config-api.ts | 2 +- src/remote-config/remote-config-namespace.ts | 2 +- src/remote-config/remote-config.ts | 2 +- src/security-rules/index.ts | 2 +- src/security-rules/security-rules-api-client-internal.ts | 2 +- src/security-rules/security-rules-internal.ts | 2 +- src/security-rules/security-rules-namespace.ts | 2 +- src/security-rules/security-rules.ts | 2 +- src/storage/index.ts | 2 +- src/storage/storage-namespace.ts | 2 +- src/storage/storage.ts | 2 +- src/utils/api-request.ts | 2 +- src/utils/crypto-signer.ts | 2 +- src/utils/deep-copy.ts | 2 +- src/utils/error.ts | 2 +- src/utils/index.ts | 2 +- src/utils/jwt.ts | 2 +- src/utils/validator.ts | 2 +- test/integration/app-check.spec.ts | 2 +- test/integration/app.spec.ts | 2 +- test/integration/auth.spec.ts | 2 +- test/integration/data-connect.spec.ts | 2 +- test/integration/database.spec.ts | 2 +- test/integration/firestore.spec.ts | 2 +- test/integration/functions.spec.ts | 2 +- test/integration/installations.spec.ts | 2 +- test/integration/instance-id.spec.ts | 2 +- test/integration/machine-learning.spec.ts | 2 +- test/integration/messaging.spec.ts | 2 +- test/integration/postcheck/esm/example.test.js | 2 +- test/integration/postcheck/typescript/example-modular.test.ts | 2 +- test/integration/postcheck/typescript/example.test.ts | 2 +- test/integration/postcheck/typescript/example.ts | 2 +- test/integration/project-management.spec.ts | 2 +- test/integration/remote-config.spec.ts | 2 +- test/integration/security-rules.spec.ts | 2 +- test/integration/setup.ts | 2 +- test/integration/storage.spec.ts | 2 +- test/resources/mocks.ts | 2 +- test/unit/app-check/app-check-api-client-internal.spec.ts | 2 +- test/unit/app-check/app-check.spec.ts | 2 +- test/unit/app-check/token-generator.spec.ts | 2 +- test/unit/app-check/token-verifier.spec.ts | 2 +- test/unit/app/credential-internal.spec.ts | 2 +- test/unit/app/firebase-app.spec.ts | 2 +- test/unit/app/firebase-namespace.spec.ts | 2 +- test/unit/app/index.spec.ts | 2 +- test/unit/auth/action-code-settings-builder.spec.ts | 2 +- test/unit/auth/auth-api-request.spec.ts | 2 +- test/unit/auth/auth-config.spec.ts | 2 +- test/unit/auth/auth.spec.ts | 2 +- test/unit/auth/index.spec.ts | 2 +- test/unit/auth/project-config-manager.spec.ts | 2 +- test/unit/auth/project-config.spec.ts | 2 +- test/unit/auth/tenant-manager.spec.ts | 2 +- test/unit/auth/tenant.spec.ts | 2 +- test/unit/auth/token-generator.spec.ts | 2 +- test/unit/auth/token-verifier.spec.ts | 2 +- test/unit/auth/user-import-builder.spec.ts | 2 +- test/unit/auth/user-record.spec.ts | 2 +- test/unit/data-connect/data-connect-api-client-internal.spec.ts | 2 +- test/unit/data-connect/index.spec.ts | 2 +- test/unit/database/database.spec.ts | 2 +- test/unit/database/index.spec.ts | 2 +- test/unit/eventarc/eventarc-utils.spec.ts | 2 +- test/unit/eventarc/eventarc.spec.ts | 2 +- test/unit/extensions/extensions-api-client-internal.spec.ts | 2 +- test/unit/extensions/extensions.spec.ts | 2 +- test/unit/firebase.spec.ts | 2 +- test/unit/firestore/firestore.spec.ts | 2 +- test/unit/firestore/index.spec.ts | 2 +- test/unit/functions/functions-api-client-internal.spec.ts | 2 +- test/unit/functions/functions.spec.ts | 2 +- test/unit/functions/index.spec.ts | 2 +- test/unit/index.spec.ts | 2 +- test/unit/installations/installations-request-handler.spec.ts | 2 +- test/unit/installations/installations.spec.ts | 2 +- test/unit/instance-id/index.spec.ts | 2 +- test/unit/instance-id/instance-id.spec.ts | 2 +- test/unit/machine-learning/index.spec.ts | 2 +- test/unit/machine-learning/machine-learning-api-client.spec.ts | 2 +- test/unit/machine-learning/machine-learning.spec.ts | 2 +- test/unit/messaging/index.spec.ts | 2 +- test/unit/messaging/messaging.spec.ts | 2 +- test/unit/project-management/android-app.spec.ts | 2 +- test/unit/project-management/index.spec.ts | 2 +- test/unit/project-management/ios-app.spec.ts | 2 +- .../project-management/project-management-api-request.spec.ts | 2 +- test/unit/project-management/project-management.spec.ts | 2 +- test/unit/remote-config/condition-evaluator.spec.ts | 2 +- test/unit/remote-config/index.spec.ts | 2 +- test/unit/remote-config/internal/value-impl.spec.ts | 2 +- test/unit/remote-config/remote-config-api-client.spec.ts | 2 +- test/unit/remote-config/remote-config.spec.ts | 2 +- test/unit/security-rules/index.spec.ts | 2 +- test/unit/security-rules/security-rules-api-client.spec.ts | 2 +- test/unit/security-rules/security-rules.spec.ts | 2 +- test/unit/storage/index.spec.ts | 2 +- test/unit/storage/storage.spec.ts | 2 +- test/unit/utils.ts | 2 +- test/unit/utils/api-request.spec.ts | 2 +- test/unit/utils/crypto-signer.spec.ts | 2 +- test/unit/utils/error.spec.ts | 2 +- test/unit/utils/index.spec.ts | 2 +- test/unit/utils/jwt.spec.ts | 2 +- test/unit/utils/validator.spec.ts | 2 +- 210 files changed, 210 insertions(+), 210 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 64a352ee2a..c462e7c05a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/.github/actions/send-email/action.yml b/.github/actions/send-email/action.yml index eca721b842..98364e6cca 100644 --- a/.github/actions/send-email/action.yml +++ b/.github/actions/send-email/action.yml @@ -1,4 +1,4 @@ -# Copyright 2021 Google Inc. +# Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/actions/send-email/index.js b/.github/actions/send-email/index.js index 38be9f04fc..9fefbe8f1e 100644 --- a/.github/actions/send-email/index.js +++ b/.github/actions/send-email/index.js @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/.github/actions/send-tweet/action.yml b/.github/actions/send-tweet/action.yml index bb45748d4b..853273f54b 100644 --- a/.github/actions/send-tweet/action.yml +++ b/.github/actions/send-tweet/action.yml @@ -1,4 +1,4 @@ -# Copyright 2020 Google Inc. +# Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/actions/send-tweet/index.js b/.github/actions/send-tweet/index.js index aa6140ba8b..6a90a92218 100644 --- a/.github/actions/send-tweet/index.js +++ b/.github/actions/send-tweet/index.js @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/.github/scripts/publish_package.sh b/.github/scripts/publish_package.sh index 42d40c199e..d4a7bb4e0b 100755 --- a/.github/scripts/publish_package.sh +++ b/.github/scripts/publish_package.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2020 Google Inc. +# Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/scripts/publish_preflight_check.sh b/.github/scripts/publish_preflight_check.sh index 8d2f4a14cd..d52b49a531 100755 --- a/.github/scripts/publish_preflight_check.sh +++ b/.github/scripts/publish_preflight_check.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2020 Google Inc. +# Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/scripts/run_integration_tests.sh b/.github/scripts/run_integration_tests.sh index 37dc7d1216..414fbab6f2 100755 --- a/.github/scripts/run_integration_tests.sh +++ b/.github/scripts/run_integration_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2020 Google Inc. +# Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/scripts/verify_package.sh b/.github/scripts/verify_package.sh index 2b295a63b9..8bfdf295ca 100755 --- a/.github/scripts/verify_package.sh +++ b/.github/scripts/verify_package.sh @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. +# Copyright 2017 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index e3ce768cb5..277f1449e4 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,4 +1,4 @@ -# Copyright 2021 Google Inc. +# Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e2a7eb9cea..0589a5f669 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -# Copyright 2020 Google Inc. +# Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/docgen/post-process.js b/docgen/post-process.js index 9c0a79bdcd..8b350d5a10 100644 --- a/docgen/post-process.js +++ b/docgen/post-process.js @@ -1,6 +1,6 @@ /** * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/generate-esm-wrapper.js b/generate-esm-wrapper.js index 3d47c709d1..753927bb0b 100644 --- a/generate-esm-wrapper.js +++ b/generate-esm-wrapper.js @@ -1,6 +1,6 @@ /** * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/generate-reports.js b/generate-reports.js index 129c06e542..8d92b0d2b8 100644 --- a/generate-reports.js +++ b/generate-reports.js @@ -1,6 +1,6 @@ /** * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/gulpfile.js b/gulpfile.js index 749b6ff517..f5c2e06acd 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app-check/app-check-api-client-internal.ts b/src/app-check/app-check-api-client-internal.ts index 6e896044f6..8a1afa872e 100644 --- a/src/app-check/app-check-api-client-internal.ts +++ b/src/app-check/app-check-api-client-internal.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app-check/app-check-api.ts b/src/app-check/app-check-api.ts index de44a5a854..7766299fcd 100644 --- a/src/app-check/app-check-api.ts +++ b/src/app-check/app-check-api.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app-check/app-check-namespace.ts b/src/app-check/app-check-namespace.ts index 13e5beb3a7..85ac284bb4 100644 --- a/src/app-check/app-check-namespace.ts +++ b/src/app-check/app-check-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app-check/app-check.ts b/src/app-check/app-check.ts index c81a04acf5..c7e6cadbd1 100644 --- a/src/app-check/app-check.ts +++ b/src/app-check/app-check.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app-check/index.ts b/src/app-check/index.ts index 54cd9291d8..7b4ba04709 100644 --- a/src/app-check/index.ts +++ b/src/app-check/index.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app-check/token-generator.ts b/src/app-check/token-generator.ts index 0ae7032d64..be3383d9d0 100644 --- a/src/app-check/token-generator.ts +++ b/src/app-check/token-generator.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app-check/token-verifier.ts b/src/app-check/token-verifier.ts index cde4878a42..074e556307 100644 --- a/src/app-check/token-verifier.ts +++ b/src/app-check/token-verifier.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app/core.ts b/src/app/core.ts index f37e3c112c..c229b20408 100644 --- a/src/app/core.ts +++ b/src/app/core.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app/credential-factory.ts b/src/app/credential-factory.ts index 9bb32a8869..e6bbdfcd44 100644 --- a/src/app/credential-factory.ts +++ b/src/app/credential-factory.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app/credential-internal.ts b/src/app/credential-internal.ts index 2171d6e637..8ce61b4edd 100644 --- a/src/app/credential-internal.ts +++ b/src/app/credential-internal.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app/credential.ts b/src/app/credential.ts index b5857903f8..4bd1fa3705 100644 --- a/src/app/credential.ts +++ b/src/app/credential.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app/firebase-app.ts b/src/app/firebase-app.ts index 982c8d14e8..dcd30d8a1d 100644 --- a/src/app/firebase-app.ts +++ b/src/app/firebase-app.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app/firebase-namespace.ts b/src/app/firebase-namespace.ts index ef5e17f0eb..edc022dd62 100644 --- a/src/app/firebase-namespace.ts +++ b/src/app/firebase-namespace.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app/index.ts b/src/app/index.ts index 5308e414e2..b10323b8f9 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/app/lifecycle.ts b/src/app/lifecycle.ts index 5160e51f5c..d2b5898451 100644 --- a/src/app/lifecycle.ts +++ b/src/app/lifecycle.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/action-code-settings-builder.ts b/src/auth/action-code-settings-builder.ts index 13dbcbc725..5ffd72d048 100644 --- a/src/auth/action-code-settings-builder.ts +++ b/src/auth/action-code-settings-builder.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index cd9c145b1e..8e979d1aed 100644 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/auth-config.ts b/src/auth/auth-config.ts index d2d07e9536..1dd5565a88 100644 --- a/src/auth/auth-config.ts +++ b/src/auth/auth-config.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/auth-namespace.ts b/src/auth/auth-namespace.ts index 486c0b488a..7c450e8a61 100644 --- a/src/auth/auth-namespace.ts +++ b/src/auth/auth-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/auth.ts b/src/auth/auth.ts index 4808fbbdc0..75848a3731 100644 --- a/src/auth/auth.ts +++ b/src/auth/auth.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/base-auth.ts b/src/auth/base-auth.ts index 56941056d9..25e1a3db2b 100644 --- a/src/auth/base-auth.ts +++ b/src/auth/base-auth.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/identifier.ts b/src/auth/identifier.ts index 8bae483d1d..424dc77df1 100644 --- a/src/auth/identifier.ts +++ b/src/auth/identifier.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/index.ts b/src/auth/index.ts index 69cb95bf2a..4650b25e27 100644 --- a/src/auth/index.ts +++ b/src/auth/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/project-config-manager.ts b/src/auth/project-config-manager.ts index 847aa7d982..f956bac7e7 100644 --- a/src/auth/project-config-manager.ts +++ b/src/auth/project-config-manager.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/project-config.ts b/src/auth/project-config.ts index 259f6eebb2..1695ec3a0d 100644 --- a/src/auth/project-config.ts +++ b/src/auth/project-config.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/tenant-manager.ts b/src/auth/tenant-manager.ts index 71a505ecc7..19da5b4c83 100644 --- a/src/auth/tenant-manager.ts +++ b/src/auth/tenant-manager.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/tenant.ts b/src/auth/tenant.ts index 4b66cace3e..19812c02e6 100644 --- a/src/auth/tenant.ts +++ b/src/auth/tenant.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/token-generator.ts b/src/auth/token-generator.ts index ce6e21fbb6..3df1dcebe2 100644 --- a/src/auth/token-generator.ts +++ b/src/auth/token-generator.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/token-verifier.ts b/src/auth/token-verifier.ts index 73fc8f678c..64da8ac516 100644 --- a/src/auth/token-verifier.ts +++ b/src/auth/token-verifier.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/user-import-builder.ts b/src/auth/user-import-builder.ts index 23e4e5aba3..f396066b49 100644 --- a/src/auth/user-import-builder.ts +++ b/src/auth/user-import-builder.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/auth/user-record.ts b/src/auth/user-record.ts index 5b00151401..2310968849 100644 --- a/src/auth/user-record.ts +++ b/src/auth/user-record.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/credential/index.ts b/src/credential/index.ts index f83adcc148..f8a9cc47a7 100644 --- a/src/credential/index.ts +++ b/src/credential/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts index e12005b8bb..c100abd023 100644 --- a/src/data-connect/data-connect-api-client-internal.ts +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/data-connect/data-connect-api.ts b/src/data-connect/data-connect-api.ts index 1073437032..c60ef5a2eb 100644 --- a/src/data-connect/data-connect-api.ts +++ b/src/data-connect/data-connect-api.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/data-connect/data-connect.ts b/src/data-connect/data-connect.ts index aa7d9d7e19..a689423257 100644 --- a/src/data-connect/data-connect.ts +++ b/src/data-connect/data-connect.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/data-connect/index.ts b/src/data-connect/index.ts index ab262682f2..43ca313c90 100644 --- a/src/data-connect/index.ts +++ b/src/data-connect/index.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database-namespace.ts b/src/database/database-namespace.ts index 0bb190bc27..03d116b7d2 100644 --- a/src/database/database-namespace.ts +++ b/src/database/database-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/database.ts b/src/database/database.ts index 144f08d430..355c43b33a 100644 --- a/src/database/database.ts +++ b/src/database/database.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/database/index.ts b/src/database/index.ts index 7a17deb751..c078893d2c 100644 --- a/src/database/index.ts +++ b/src/database/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/default-namespace.d.ts b/src/default-namespace.d.ts index 5405cc67c6..c5c826a1e6 100644 --- a/src/default-namespace.d.ts +++ b/src/default-namespace.d.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/default-namespace.ts b/src/default-namespace.ts index 12e855e2d8..bd250cd79c 100644 --- a/src/default-namespace.ts +++ b/src/default-namespace.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/eventarc/cloudevent.ts b/src/eventarc/cloudevent.ts index 9fa0749f2e..1a5396868a 100644 --- a/src/eventarc/cloudevent.ts +++ b/src/eventarc/cloudevent.ts @@ -1,7 +1,7 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/eventarc/eventarc-client-internal.ts b/src/eventarc/eventarc-client-internal.ts index 3aecbdcc96..e4e5bda0a4 100644 --- a/src/eventarc/eventarc-client-internal.ts +++ b/src/eventarc/eventarc-client-internal.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/eventarc/eventarc-utils.ts b/src/eventarc/eventarc-utils.ts index 6bf6531285..3737e5a906 100644 --- a/src/eventarc/eventarc-utils.ts +++ b/src/eventarc/eventarc-utils.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/eventarc/eventarc.ts b/src/eventarc/eventarc.ts index a1edc4a011..c27e0b3acf 100644 --- a/src/eventarc/eventarc.ts +++ b/src/eventarc/eventarc.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/eventarc/index.ts b/src/eventarc/index.ts index d1e6fc79bd..f3bb023947 100644 --- a/src/eventarc/index.ts +++ b/src/eventarc/index.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/extensions/extensions-api-client-internal.ts b/src/extensions/extensions-api-client-internal.ts index a51c001304..a90c5b34fd 100644 --- a/src/extensions/extensions-api-client-internal.ts +++ b/src/extensions/extensions-api-client-internal.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/extensions/extensions-api.ts b/src/extensions/extensions-api.ts index ce0c18f89d..e95a02c6de 100644 --- a/src/extensions/extensions-api.ts +++ b/src/extensions/extensions-api.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/extensions/extensions.ts b/src/extensions/extensions.ts index e16f893aa0..f148d68dcb 100644 --- a/src/extensions/extensions.ts +++ b/src/extensions/extensions.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/extensions/index.ts b/src/extensions/index.ts index 486ad645d0..e96401a774 100644 --- a/src/extensions/index.ts +++ b/src/extensions/index.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/firebase-namespace-api.ts b/src/firebase-namespace-api.ts index 5358e5bd2c..3808876910 100644 --- a/src/firebase-namespace-api.ts +++ b/src/firebase-namespace-api.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/firestore/firestore-internal.ts b/src/firestore/firestore-internal.ts index 65cb123d85..95c6e74414 100644 --- a/src/firestore/firestore-internal.ts +++ b/src/firestore/firestore-internal.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/firestore/firestore-namespace.ts b/src/firestore/firestore-namespace.ts index 67733fb8f6..84ffe51ab5 100644 --- a/src/firestore/firestore-namespace.ts +++ b/src/firestore/firestore-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/firestore/index.ts b/src/firestore/index.ts index f906f382e2..c41fd5ea1a 100644 --- a/src/firestore/index.ts +++ b/src/firestore/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/functions/functions-api-client-internal.ts b/src/functions/functions-api-client-internal.ts index e1fd04ee6d..d68a0b1c72 100644 --- a/src/functions/functions-api-client-internal.ts +++ b/src/functions/functions-api-client-internal.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/functions/functions-api.ts b/src/functions/functions-api.ts index a0473baee2..e685aeb99b 100644 --- a/src/functions/functions-api.ts +++ b/src/functions/functions-api.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/functions/functions.ts b/src/functions/functions.ts index f5a3ce6153..c8c0a30a71 100644 --- a/src/functions/functions.ts +++ b/src/functions/functions.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/functions/index.ts b/src/functions/index.ts index 11e05c6782..bd86d88c2d 100644 --- a/src/functions/index.ts +++ b/src/functions/index.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/index.d.ts b/src/index.d.ts index b893c88183..cb5413cd2d 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/index.ts b/src/index.ts index eb121bc023..cdc5b6c64d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/installations/index.ts b/src/installations/index.ts index 1d6a39dc35..e7fc00ab78 100644 --- a/src/installations/index.ts +++ b/src/installations/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/installations/installations-namespace.ts b/src/installations/installations-namespace.ts index 1bdca2fbce..f2bd180205 100644 --- a/src/installations/installations-namespace.ts +++ b/src/installations/installations-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/installations/installations-request-handler.ts b/src/installations/installations-request-handler.ts index 5314642d55..67c0f6f46f 100644 --- a/src/installations/installations-request-handler.ts +++ b/src/installations/installations-request-handler.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/installations/installations.ts b/src/installations/installations.ts index c5408299da..fb2bb5fa15 100644 --- a/src/installations/installations.ts +++ b/src/installations/installations.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/instance-id/index.ts b/src/instance-id/index.ts index 1a9c06d3bc..0486a927af 100644 --- a/src/instance-id/index.ts +++ b/src/instance-id/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/instance-id/instance-id.ts b/src/instance-id/instance-id.ts index e5dc2102b0..3a5baac09f 100644 --- a/src/instance-id/instance-id.ts +++ b/src/instance-id/instance-id.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/machine-learning/index.ts b/src/machine-learning/index.ts index 433832c358..2945c43d35 100644 --- a/src/machine-learning/index.ts +++ b/src/machine-learning/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/machine-learning/machine-learning-api-client.ts b/src/machine-learning/machine-learning-api-client.ts index c3ea7cee4f..b8fd5301f7 100644 --- a/src/machine-learning/machine-learning-api-client.ts +++ b/src/machine-learning/machine-learning-api-client.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/machine-learning/machine-learning-namespace.ts b/src/machine-learning/machine-learning-namespace.ts index 7c5786fdbb..5131390a67 100644 --- a/src/machine-learning/machine-learning-namespace.ts +++ b/src/machine-learning/machine-learning-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/machine-learning/machine-learning-utils.ts b/src/machine-learning/machine-learning-utils.ts index 1202314e93..3e2236975c 100644 --- a/src/machine-learning/machine-learning-utils.ts +++ b/src/machine-learning/machine-learning-utils.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/machine-learning/machine-learning.ts b/src/machine-learning/machine-learning.ts index 98b956c85c..a83bda71cc 100644 --- a/src/machine-learning/machine-learning.ts +++ b/src/machine-learning/machine-learning.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/messaging/index.ts b/src/messaging/index.ts index d0a39df2fb..16054c2c38 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/messaging/messaging-api-request-internal.ts b/src/messaging/messaging-api-request-internal.ts index 830fbed568..3c4e124d44 100644 --- a/src/messaging/messaging-api-request-internal.ts +++ b/src/messaging/messaging-api-request-internal.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/messaging/messaging-api.ts b/src/messaging/messaging-api.ts index d0c5d5af7e..a305ec68b3 100644 --- a/src/messaging/messaging-api.ts +++ b/src/messaging/messaging-api.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/messaging/messaging-errors-internal.ts b/src/messaging/messaging-errors-internal.ts index a04e4cfb2b..41aa667b1d 100644 --- a/src/messaging/messaging-errors-internal.ts +++ b/src/messaging/messaging-errors-internal.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/messaging/messaging-internal.ts b/src/messaging/messaging-internal.ts index c41f93a923..311d2af4be 100644 --- a/src/messaging/messaging-internal.ts +++ b/src/messaging/messaging-internal.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/messaging/messaging-namespace.ts b/src/messaging/messaging-namespace.ts index 40ca3a3ed2..43627c60ed 100644 --- a/src/messaging/messaging-namespace.ts +++ b/src/messaging/messaging-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/messaging/messaging.ts b/src/messaging/messaging.ts index 8e61cd679a..05367128f4 100644 --- a/src/messaging/messaging.ts +++ b/src/messaging/messaging.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/project-management/android-app.ts b/src/project-management/android-app.ts index 667b8be4d6..e4e503e946 100644 --- a/src/project-management/android-app.ts +++ b/src/project-management/android-app.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/project-management/app-metadata.ts b/src/project-management/app-metadata.ts index 8fd69255d2..0f07f89dca 100644 --- a/src/project-management/app-metadata.ts +++ b/src/project-management/app-metadata.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/project-management/index.ts b/src/project-management/index.ts index cc23066681..87a6d570ce 100644 --- a/src/project-management/index.ts +++ b/src/project-management/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/project-management/ios-app.ts b/src/project-management/ios-app.ts index 0789265f29..775d19a120 100644 --- a/src/project-management/ios-app.ts +++ b/src/project-management/ios-app.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/project-management/project-management-api-request-internal.ts b/src/project-management/project-management-api-request-internal.ts index d4a38cb2bc..bc502a5ebd 100644 --- a/src/project-management/project-management-api-request-internal.ts +++ b/src/project-management/project-management-api-request-internal.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/project-management/project-management-namespace.ts b/src/project-management/project-management-namespace.ts index f3d48d1fe7..ac58bc215e 100644 --- a/src/project-management/project-management-namespace.ts +++ b/src/project-management/project-management-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/project-management/project-management.ts b/src/project-management/project-management.ts index ac74004555..c29589be86 100644 --- a/src/project-management/project-management.ts +++ b/src/project-management/project-management.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/remote-config/condition-evaluator-internal.ts b/src/remote-config/condition-evaluator-internal.ts index b49b35dc8d..73a878109f 100644 --- a/src/remote-config/condition-evaluator-internal.ts +++ b/src/remote-config/condition-evaluator-internal.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/remote-config/index.ts b/src/remote-config/index.ts index 42a2573227..790568735e 100644 --- a/src/remote-config/index.ts +++ b/src/remote-config/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/remote-config/internal/value-impl.ts b/src/remote-config/internal/value-impl.ts index 6d71476538..92dc79e0c9 100644 --- a/src/remote-config/internal/value-impl.ts +++ b/src/remote-config/internal/value-impl.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/remote-config/remote-config-api-client-internal.ts b/src/remote-config/remote-config-api-client-internal.ts index 30a0b10a54..199c974c7d 100644 --- a/src/remote-config/remote-config-api-client-internal.ts +++ b/src/remote-config/remote-config-api-client-internal.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/remote-config/remote-config-api.ts b/src/remote-config/remote-config-api.ts index d315572192..ed7da05496 100644 --- a/src/remote-config/remote-config-api.ts +++ b/src/remote-config/remote-config-api.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/remote-config/remote-config-namespace.ts b/src/remote-config/remote-config-namespace.ts index 4efb3baee1..159204d316 100644 --- a/src/remote-config/remote-config-namespace.ts +++ b/src/remote-config/remote-config-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index a984d67e1f..91eebfa0cb 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/security-rules/index.ts b/src/security-rules/index.ts index b3b78a265a..23d6ed10fd 100644 --- a/src/security-rules/index.ts +++ b/src/security-rules/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/security-rules/security-rules-api-client-internal.ts b/src/security-rules/security-rules-api-client-internal.ts index 7f10a27b93..33ad1ee886 100644 --- a/src/security-rules/security-rules-api-client-internal.ts +++ b/src/security-rules/security-rules-api-client-internal.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/security-rules/security-rules-internal.ts b/src/security-rules/security-rules-internal.ts index d21f5a0f0e..539359cb63 100644 --- a/src/security-rules/security-rules-internal.ts +++ b/src/security-rules/security-rules-internal.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/security-rules/security-rules-namespace.ts b/src/security-rules/security-rules-namespace.ts index 52ffc592a7..d61ba294fb 100644 --- a/src/security-rules/security-rules-namespace.ts +++ b/src/security-rules/security-rules-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/security-rules/security-rules.ts b/src/security-rules/security-rules.ts index 135e32459b..8dcd55c836 100644 --- a/src/security-rules/security-rules.ts +++ b/src/security-rules/security-rules.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/storage/index.ts b/src/storage/index.ts index 7b963593e8..2638192690 100644 --- a/src/storage/index.ts +++ b/src/storage/index.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/storage/storage-namespace.ts b/src/storage/storage-namespace.ts index f0dd80725d..29c88068cc 100644 --- a/src/storage/storage-namespace.ts +++ b/src/storage/storage-namespace.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/storage/storage.ts b/src/storage/storage.ts index 6e155b379e..b78898fb34 100644 --- a/src/storage/storage.ts +++ b/src/storage/storage.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index f26fcf9326..3e5aa754d8 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utils/crypto-signer.ts b/src/utils/crypto-signer.ts index f2b8bcbafd..a4b1f20be5 100644 --- a/src/utils/crypto-signer.ts +++ b/src/utils/crypto-signer.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utils/deep-copy.ts b/src/utils/deep-copy.ts index 1dde902c03..e4c2bddf85 100644 --- a/src/utils/deep-copy.ts +++ b/src/utils/deep-copy.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utils/error.ts b/src/utils/error.ts index a80254b5b8..db013b8967 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utils/index.ts b/src/utils/index.ts index c7c331206d..7754e59b01 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utils/jwt.ts b/src/utils/jwt.ts index 1b1fea6af9..9a66494482 100644 --- a/src/utils/jwt.ts +++ b/src/utils/jwt.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/utils/validator.ts b/src/utils/validator.ts index d63d14772c..fb738904e1 100644 --- a/src/utils/validator.ts +++ b/src/utils/validator.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/app-check.spec.ts b/test/integration/app-check.spec.ts index 83a71a6f53..89a920daea 100644 --- a/test/integration/app-check.spec.ts +++ b/test/integration/app-check.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/app.spec.ts b/test/integration/app.spec.ts index 3470ae088a..d679dc5766 100644 --- a/test/integration/app.spec.ts +++ b/test/integration/app.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 560cd47005..3c538d3319 100644 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/data-connect.spec.ts b/test/integration/data-connect.spec.ts index f9ced89ece..8ab24925df 100644 --- a/test/integration/data-connect.spec.ts +++ b/test/integration/data-connect.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/database.spec.ts b/test/integration/database.spec.ts index 40b35484eb..7f4dce576f 100644 --- a/test/integration/database.spec.ts +++ b/test/integration/database.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/firestore.spec.ts b/test/integration/firestore.spec.ts index 9127ef2e17..18cb9e75a8 100644 --- a/test/integration/firestore.spec.ts +++ b/test/integration/firestore.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/functions.spec.ts b/test/integration/functions.spec.ts index 9b1f5277f9..ef65176935 100644 --- a/test/integration/functions.spec.ts +++ b/test/integration/functions.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/installations.spec.ts b/test/integration/installations.spec.ts index 98eb3ad72a..3dd68b72e7 100644 --- a/test/integration/installations.spec.ts +++ b/test/integration/installations.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/instance-id.spec.ts b/test/integration/instance-id.spec.ts index 2155205990..fe3cccc935 100644 --- a/test/integration/instance-id.spec.ts +++ b/test/integration/instance-id.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/machine-learning.spec.ts b/test/integration/machine-learning.spec.ts index b44ebdc1e2..e7a5b42567 100644 --- a/test/integration/machine-learning.spec.ts +++ b/test/integration/machine-learning.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/messaging.spec.ts b/test/integration/messaging.spec.ts index 97adc8e008..94304edce8 100644 --- a/test/integration/messaging.spec.ts +++ b/test/integration/messaging.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/postcheck/esm/example.test.js b/test/integration/postcheck/esm/example.test.js index 29d0654374..6ac8540196 100644 --- a/test/integration/postcheck/esm/example.test.js +++ b/test/integration/postcheck/esm/example.test.js @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/postcheck/typescript/example-modular.test.ts b/test/integration/postcheck/typescript/example-modular.test.ts index c5ccf3c8a2..67332e01af 100644 --- a/test/integration/postcheck/typescript/example-modular.test.ts +++ b/test/integration/postcheck/typescript/example-modular.test.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/postcheck/typescript/example.test.ts b/test/integration/postcheck/typescript/example.test.ts index 2d97196477..5de1eadae0 100644 --- a/test/integration/postcheck/typescript/example.test.ts +++ b/test/integration/postcheck/typescript/example.test.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/postcheck/typescript/example.ts b/test/integration/postcheck/typescript/example.ts index b44dbcc163..f626ba374c 100644 --- a/test/integration/postcheck/typescript/example.ts +++ b/test/integration/postcheck/typescript/example.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/project-management.spec.ts b/test/integration/project-management.spec.ts index 0d24566394..b2eaa24b32 100644 --- a/test/integration/project-management.spec.ts +++ b/test/integration/project-management.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/remote-config.spec.ts b/test/integration/remote-config.spec.ts index 79689a64e6..0818bf0ab7 100644 --- a/test/integration/remote-config.spec.ts +++ b/test/integration/remote-config.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/security-rules.spec.ts b/test/integration/security-rules.spec.ts index eda5f000f4..85bae9dd47 100644 --- a/test/integration/security-rules.spec.ts +++ b/test/integration/security-rules.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/setup.ts b/test/integration/setup.ts index 8c700d4c41..5c23270f3b 100644 --- a/test/integration/setup.ts +++ b/test/integration/setup.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/integration/storage.spec.ts b/test/integration/storage.spec.ts index 78d1c731b5..406cfa94bf 100644 --- a/test/integration/storage.spec.ts +++ b/test/integration/storage.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/resources/mocks.ts b/test/resources/mocks.ts index c6b86886a0..e0f2ed00a9 100644 --- a/test/resources/mocks.ts +++ b/test/resources/mocks.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/app-check/app-check-api-client-internal.spec.ts b/test/unit/app-check/app-check-api-client-internal.spec.ts index 743f6ed89f..b6a5060bb5 100644 --- a/test/unit/app-check/app-check-api-client-internal.spec.ts +++ b/test/unit/app-check/app-check-api-client-internal.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/app-check/app-check.spec.ts b/test/unit/app-check/app-check.spec.ts index 62b8eeac64..e849be9850 100644 --- a/test/unit/app-check/app-check.spec.ts +++ b/test/unit/app-check/app-check.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/app-check/token-generator.spec.ts b/test/unit/app-check/token-generator.spec.ts index f892c9fa08..a2e72e9f08 100644 --- a/test/unit/app-check/token-generator.spec.ts +++ b/test/unit/app-check/token-generator.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/app-check/token-verifier.spec.ts b/test/unit/app-check/token-verifier.spec.ts index ecc664783b..38d42ac897 100644 --- a/test/unit/app-check/token-verifier.spec.ts +++ b/test/unit/app-check/token-verifier.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/app/credential-internal.spec.ts b/test/unit/app/credential-internal.spec.ts index f37716e998..d57cc5e91a 100644 --- a/test/unit/app/credential-internal.spec.ts +++ b/test/unit/app/credential-internal.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/app/firebase-app.spec.ts b/test/unit/app/firebase-app.spec.ts index a99e15d8f0..56a7edae39 100644 --- a/test/unit/app/firebase-app.spec.ts +++ b/test/unit/app/firebase-app.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/app/firebase-namespace.spec.ts b/test/unit/app/firebase-namespace.spec.ts index 38a4c49886..694c6f5ffe 100644 --- a/test/unit/app/firebase-namespace.spec.ts +++ b/test/unit/app/firebase-namespace.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/app/index.spec.ts b/test/unit/app/index.spec.ts index 896fd2534e..af0d0ebf75 100644 --- a/test/unit/app/index.spec.ts +++ b/test/unit/app/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/action-code-settings-builder.spec.ts b/test/unit/auth/action-code-settings-builder.spec.ts index 4608f711f1..f8eed33d74 100644 --- a/test/unit/auth/action-code-settings-builder.spec.ts +++ b/test/unit/auth/action-code-settings-builder.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/auth-api-request.spec.ts b/test/unit/auth/auth-api-request.spec.ts index 9a6d624b88..5f8e45b458 100644 --- a/test/unit/auth/auth-api-request.spec.ts +++ b/test/unit/auth/auth-api-request.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/auth-config.spec.ts b/test/unit/auth/auth-config.spec.ts index c5bdb7c445..e33c6f7f24 100644 --- a/test/unit/auth/auth-config.spec.ts +++ b/test/unit/auth/auth-config.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/auth.spec.ts b/test/unit/auth/auth.spec.ts index 34d4c3d9a6..b9675e720b 100644 --- a/test/unit/auth/auth.spec.ts +++ b/test/unit/auth/auth.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/index.spec.ts b/test/unit/auth/index.spec.ts index 099bb00cd4..beb0b784d7 100644 --- a/test/unit/auth/index.spec.ts +++ b/test/unit/auth/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/project-config-manager.spec.ts b/test/unit/auth/project-config-manager.spec.ts index 3fc0770b36..be7df54d99 100644 --- a/test/unit/auth/project-config-manager.spec.ts +++ b/test/unit/auth/project-config-manager.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/project-config.spec.ts b/test/unit/auth/project-config.spec.ts index 7857deb398..a447bf28ed 100644 --- a/test/unit/auth/project-config.spec.ts +++ b/test/unit/auth/project-config.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/tenant-manager.spec.ts b/test/unit/auth/tenant-manager.spec.ts index 8a8f0617f2..782e4f96bb 100644 --- a/test/unit/auth/tenant-manager.spec.ts +++ b/test/unit/auth/tenant-manager.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/tenant.spec.ts b/test/unit/auth/tenant.spec.ts index 05c8bbf6aa..62ef31478b 100644 --- a/test/unit/auth/tenant.spec.ts +++ b/test/unit/auth/tenant.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/token-generator.spec.ts b/test/unit/auth/token-generator.spec.ts index acb89b13e8..1cc9bd44ab 100644 --- a/test/unit/auth/token-generator.spec.ts +++ b/test/unit/auth/token-generator.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/token-verifier.spec.ts b/test/unit/auth/token-verifier.spec.ts index 2d01678ef7..3dae6817cd 100644 --- a/test/unit/auth/token-verifier.spec.ts +++ b/test/unit/auth/token-verifier.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/user-import-builder.spec.ts b/test/unit/auth/user-import-builder.spec.ts index 859265a03a..6be38ebe28 100644 --- a/test/unit/auth/user-import-builder.spec.ts +++ b/test/unit/auth/user-import-builder.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/auth/user-record.spec.ts b/test/unit/auth/user-record.spec.ts index dc332c13b9..0a6a7c0357 100644 --- a/test/unit/auth/user-record.spec.ts +++ b/test/unit/auth/user-record.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index a5798703e5..b23c5e144d 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/data-connect/index.spec.ts b/test/unit/data-connect/index.spec.ts index b71670544b..98dd6dea42 100644 --- a/test/unit/data-connect/index.spec.ts +++ b/test/unit/data-connect/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/database/database.spec.ts b/test/unit/database/database.spec.ts index 5032deb3c3..941793ebab 100644 --- a/test/unit/database/database.spec.ts +++ b/test/unit/database/database.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/database/index.spec.ts b/test/unit/database/index.spec.ts index 382a1d96d3..82b8250915 100644 --- a/test/unit/database/index.spec.ts +++ b/test/unit/database/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/eventarc/eventarc-utils.spec.ts b/test/unit/eventarc/eventarc-utils.spec.ts index d2f18b7d96..b46cc53ca2 100644 --- a/test/unit/eventarc/eventarc-utils.spec.ts +++ b/test/unit/eventarc/eventarc-utils.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/eventarc/eventarc.spec.ts b/test/unit/eventarc/eventarc.spec.ts index 94587cde16..93ca71d28a 100644 --- a/test/unit/eventarc/eventarc.spec.ts +++ b/test/unit/eventarc/eventarc.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/extensions/extensions-api-client-internal.spec.ts b/test/unit/extensions/extensions-api-client-internal.spec.ts index 66f2e8198b..62cb8eafca 100644 --- a/test/unit/extensions/extensions-api-client-internal.spec.ts +++ b/test/unit/extensions/extensions-api-client-internal.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/extensions/extensions.spec.ts b/test/unit/extensions/extensions.spec.ts index 0b3ffb3004..6f2d75a2de 100644 --- a/test/unit/extensions/extensions.spec.ts +++ b/test/unit/extensions/extensions.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/firebase.spec.ts b/test/unit/firebase.spec.ts index 9a1ca5820e..815fb1a5db 100644 --- a/test/unit/firebase.spec.ts +++ b/test/unit/firebase.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/firestore/firestore.spec.ts b/test/unit/firestore/firestore.spec.ts index 22f8f4d8df..065b058b99 100644 --- a/test/unit/firestore/firestore.spec.ts +++ b/test/unit/firestore/firestore.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/firestore/index.spec.ts b/test/unit/firestore/index.spec.ts index 11c5c24936..dd78c7fe53 100644 --- a/test/unit/firestore/index.spec.ts +++ b/test/unit/firestore/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/functions/functions-api-client-internal.spec.ts b/test/unit/functions/functions-api-client-internal.spec.ts index f1332b2e30..34cc0ffab9 100644 --- a/test/unit/functions/functions-api-client-internal.spec.ts +++ b/test/unit/functions/functions-api-client-internal.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 36e6098d42..48ed21c886 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2022 Google Inc. + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/functions/index.spec.ts b/test/unit/functions/index.spec.ts index 8bfcaa5dfe..8244741040 100644 --- a/test/unit/functions/index.spec.ts +++ b/test/unit/functions/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index f6bfb1b39a..c75bf0dc8b 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/installations/installations-request-handler.spec.ts b/test/unit/installations/installations-request-handler.spec.ts index 8baeaa3de8..f9cca78d25 100644 --- a/test/unit/installations/installations-request-handler.spec.ts +++ b/test/unit/installations/installations-request-handler.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/installations/installations.spec.ts b/test/unit/installations/installations.spec.ts index 6a38c8413c..71d0eeae9d 100644 --- a/test/unit/installations/installations.spec.ts +++ b/test/unit/installations/installations.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/instance-id/index.spec.ts b/test/unit/instance-id/index.spec.ts index 2f1d690e6a..a33da021c7 100644 --- a/test/unit/instance-id/index.spec.ts +++ b/test/unit/instance-id/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/instance-id/instance-id.spec.ts b/test/unit/instance-id/instance-id.spec.ts index a610d7678d..f43d19d9d0 100644 --- a/test/unit/instance-id/instance-id.spec.ts +++ b/test/unit/instance-id/instance-id.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/machine-learning/index.spec.ts b/test/unit/machine-learning/index.spec.ts index 1937f5387d..0e1f7faa18 100644 --- a/test/unit/machine-learning/index.spec.ts +++ b/test/unit/machine-learning/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/machine-learning/machine-learning-api-client.spec.ts b/test/unit/machine-learning/machine-learning-api-client.spec.ts index 2f4447c2da..ce99b85177 100644 --- a/test/unit/machine-learning/machine-learning-api-client.spec.ts +++ b/test/unit/machine-learning/machine-learning-api-client.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/machine-learning/machine-learning.spec.ts b/test/unit/machine-learning/machine-learning.spec.ts index 58e424484d..ef2ec15239 100644 --- a/test/unit/machine-learning/machine-learning.spec.ts +++ b/test/unit/machine-learning/machine-learning.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/messaging/index.spec.ts b/test/unit/messaging/index.spec.ts index 56374ff1a6..0063437677 100644 --- a/test/unit/messaging/index.spec.ts +++ b/test/unit/messaging/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index 9e8d1ea814..d51c186c48 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/project-management/android-app.spec.ts b/test/unit/project-management/android-app.spec.ts index 94ccacbbd3..84807737cb 100644 --- a/test/unit/project-management/android-app.spec.ts +++ b/test/unit/project-management/android-app.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/project-management/index.spec.ts b/test/unit/project-management/index.spec.ts index 6848494c96..9760f9b8fe 100644 --- a/test/unit/project-management/index.spec.ts +++ b/test/unit/project-management/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/project-management/ios-app.spec.ts b/test/unit/project-management/ios-app.spec.ts index f250ed5f10..58865dd821 100644 --- a/test/unit/project-management/ios-app.spec.ts +++ b/test/unit/project-management/ios-app.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/project-management/project-management-api-request.spec.ts b/test/unit/project-management/project-management-api-request.spec.ts index 58f15653b7..8040f58f81 100644 --- a/test/unit/project-management/project-management-api-request.spec.ts +++ b/test/unit/project-management/project-management-api-request.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/project-management/project-management.spec.ts b/test/unit/project-management/project-management.spec.ts index b818bdb1c8..c0acea8027 100644 --- a/test/unit/project-management/project-management.spec.ts +++ b/test/unit/project-management/project-management.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2018 Google Inc. + * Copyright 2018 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/remote-config/condition-evaluator.spec.ts b/test/unit/remote-config/condition-evaluator.spec.ts index 7368457fcf..764d1b76ef 100644 --- a/test/unit/remote-config/condition-evaluator.spec.ts +++ b/test/unit/remote-config/condition-evaluator.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/remote-config/index.spec.ts b/test/unit/remote-config/index.spec.ts index f2fd51a141..5484bde18e 100644 --- a/test/unit/remote-config/index.spec.ts +++ b/test/unit/remote-config/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/remote-config/internal/value-impl.spec.ts b/test/unit/remote-config/internal/value-impl.spec.ts index b344d0c9d1..c8ba45c0b5 100644 --- a/test/unit/remote-config/internal/value-impl.spec.ts +++ b/test/unit/remote-config/internal/value-impl.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Google Inc. + * Copyright 2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/remote-config/remote-config-api-client.spec.ts b/test/unit/remote-config/remote-config-api-client.spec.ts index 91783e9088..b5aa644d43 100644 --- a/test/unit/remote-config/remote-config-api-client.spec.ts +++ b/test/unit/remote-config/remote-config-api-client.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index 976266e5ab..e7e4f84e57 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2020 Google Inc. + * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/security-rules/index.spec.ts b/test/unit/security-rules/index.spec.ts index ad6a0b05de..96f3c37b59 100644 --- a/test/unit/security-rules/index.spec.ts +++ b/test/unit/security-rules/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/security-rules/security-rules-api-client.spec.ts b/test/unit/security-rules/security-rules-api-client.spec.ts index c4176540a6..c3599af8d0 100644 --- a/test/unit/security-rules/security-rules-api-client.spec.ts +++ b/test/unit/security-rules/security-rules-api-client.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/security-rules/security-rules.spec.ts b/test/unit/security-rules/security-rules.spec.ts index 380583d4cd..e35b2d07b6 100644 --- a/test/unit/security-rules/security-rules.spec.ts +++ b/test/unit/security-rules/security-rules.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2019 Google Inc. + * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/storage/index.spec.ts b/test/unit/storage/index.spec.ts index 7924f8a61c..7fe4161cf8 100644 --- a/test/unit/storage/index.spec.ts +++ b/test/unit/storage/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/storage/storage.spec.ts b/test/unit/storage/storage.spec.ts index ea656a1e92..14653985fb 100644 --- a/test/unit/storage/storage.spec.ts +++ b/test/unit/storage/storage.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/utils.ts b/test/unit/utils.ts index 6ff00d5e26..033015b96b 100644 --- a/test/unit/utils.ts +++ b/test/unit/utils.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/utils/api-request.spec.ts b/test/unit/utils/api-request.spec.ts index 642d011460..4636878f6b 100644 --- a/test/unit/utils/api-request.spec.ts +++ b/test/unit/utils/api-request.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/utils/crypto-signer.spec.ts b/test/unit/utils/crypto-signer.spec.ts index cf38160a2f..a964f00f7b 100644 --- a/test/unit/utils/crypto-signer.spec.ts +++ b/test/unit/utils/crypto-signer.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/utils/error.spec.ts b/test/unit/utils/error.spec.ts index c2321005ee..3bc58c9173 100644 --- a/test/unit/utils/error.spec.ts +++ b/test/unit/utils/error.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/utils/index.spec.ts b/test/unit/utils/index.spec.ts index 5226353107..d6e0ddc06c 100644 --- a/test/unit/utils/index.spec.ts +++ b/test/unit/utils/index.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/utils/jwt.spec.ts b/test/unit/utils/jwt.spec.ts index 8dd49dfaf6..987faf5e47 100644 --- a/test/unit/utils/jwt.spec.ts +++ b/test/unit/utils/jwt.spec.ts @@ -1,5 +1,5 @@ /*! - * Copyright 2021 Google Inc. + * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/unit/utils/validator.spec.ts b/test/unit/utils/validator.spec.ts index a2f86c83c2..f059839ca9 100644 --- a/test/unit/utils/validator.spec.ts +++ b/test/unit/utils/validator.spec.ts @@ -1,6 +1,6 @@ /*! * @license - * Copyright 2017 Google Inc. + * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 40325df56f44b03de5ae03507fd15072805e8f7c Mon Sep 17 00:00:00 2001 From: Stephen Rosa <84193009+stephenarosaj@users.noreply.github.com> Date: Wed, 17 Sep 2025 11:50:16 -0700 Subject: [PATCH 270/323] FDC: update api version, integration tests, and CONTRIBUTING.md (#2972) * update integration tests and CONTRIBUTING.md * make test data more readable, tweak contributing instructions * update api to v1 * check in dataconnect folder * address comments * remove .dataconnect folder * update .gitignore * make integration tests more robust, explicitly setting and clearing database state --- .gitignore | 3 + CONTRIBUTING.md | 16 + .../data-connect-api-client-internal.ts | 2 +- test/integration/data-connect.spec.ts | 348 +++++++++++------- .../dataconnect/dataconnect/dataconnect.yaml | 13 + .../dataconnect/my-connector/connector.yaml | 1 + .../dataconnect/my-connector/mutations.gql | 95 +++++ .../dataconnect/my-connector/queries.gql | 74 ++++ .../dataconnect/dataconnect/schema/schema.gql | 13 + test/integration/dataconnect/firebase.json | 5 + .../data-connect-api-client-internal.spec.ts | 4 +- 11 files changed, 438 insertions(+), 136 deletions(-) create mode 100644 test/integration/dataconnect/dataconnect/dataconnect.yaml create mode 100644 test/integration/dataconnect/dataconnect/my-connector/connector.yaml create mode 100644 test/integration/dataconnect/dataconnect/my-connector/mutations.gql create mode 100644 test/integration/dataconnect/dataconnect/my-connector/queries.gql create mode 100644 test/integration/dataconnect/dataconnect/schema/schema.gql create mode 100644 test/integration/dataconnect/firebase.json diff --git a/.gitignore b/.gitignore index 9331c650de..141eeb7f06 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ test/resources/appid.txt firebase-admin-*.tgz docgen/markdown/ + +# Dataconnect integration test artifacts should not be checked in +test/integration/dataconnect/dataconnect/.dataconnect \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 28d15bf290..4a7df3f715 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -245,6 +245,22 @@ to ensure that exported user records contain the password hashes of the user acc 3. Click **ADD ANOTHER ROLE** and choose **Firebase Authentication Admin**. 4. Click **SAVE**. +9. Setup your project for Firebase Data Connect integration tests: + 1. Set up Data Connect in the Firebase Console: + 1. Go to the Firebase Console, and select **Data Connect** from the **Build** menu. + 2. Click on **Get Started**. You can skip any Gemini generation. + 3. Select **Create a new Cloud SQL instance**. + 4. Set your **Location** to `us-west2` + 5. Set your **Cloud SQL instance ID** to `my-instance` + 6. Set your **Database name** to `my-database` + 7. Set your **Service ID** to `my-service` + 8. Click **Submit**. This operation may take up to 10 minutes to complete - you may + continue setting up while this completes. + 2. Run the following command from the root of the Node Admin SDK repo: + ```bash + $ firebase deploy --only dataconnect:my-service:my-connector --config ./test/integration/dataconnect/firebase.json --project + ``` + 1. If you're asked if you'd like to execute changes, select `Execute all`. Finally, to run the integration test suite: diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts index c100abd023..3ef99bacea 100644 --- a/src/data-connect/data-connect-api-client-internal.ts +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -25,7 +25,7 @@ import * as utils from '../utils/index'; import * as validator from '../utils/validator'; import { ConnectorConfig, ExecuteGraphqlResponse, GraphqlOptions } from './data-connect-api'; -const API_VERSION = 'v1alpha'; +const API_VERSION = 'v1'; /** The Firebase Data Connect backend base URL format. */ const FIREBASE_DATA_CONNECT_BASE_URL_FORMAT = diff --git a/test/integration/data-connect.spec.ts b/test/integration/data-connect.spec.ts index 8ab24925df..4cf74549cf 100644 --- a/test/integration/data-connect.spec.ts +++ b/test/integration/data-connect.spec.ts @@ -17,68 +17,79 @@ import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import { getDataConnect, ConnectorConfig, GraphqlOptions } from '../../lib/data-connect/index'; +import firebase from '@firebase/app-compat'; +import { apiKey, projectId } from './setup'; chai.should(); chai.use(chaiAsPromised); const expect = chai.expect; -/* -// Schema -type User @table(key: "uid") { - uid: String! - name: String! - address: String! -} -*/ +/** + * // Schema + * type User @table(key: ["id"]) { + * id: String! + * name: String! + * address: String! + * } + */ type User = { - uid?: string; - name?: string; - address?: string; + id: string; + name: string; + address: string; // Generated emails_on_from?: Email[]; }; -/* -// Schema -type Email @table { - subject: String! - date: Date! - text: String! - from: User! -} +/** + * // Schema + * type Email @table { + * id: String! + * subject: String! + * date: Date! + * text: String! + * from: User! + * } */ type Email = { - subject?: string; - date?: string; - text?: string; - from?: User; - // Generated - id?: string; + subject: string; + date: string; + text: string; + from: User; + id: string; }; -interface UserResponse { +interface GetUserResponse { user: User; } -interface UsersResponse { +interface ListUsersResponse { users: User[]; } interface UserUpsertResponse { - user_upsert: { uid: string; }; + user_upsert: { id: string; }; } interface UserUpdateResponse { - user_update: { uid: string; }; + user_update: { id: string; }; } -interface EmailsResponse { +interface EmailUpsertResponse { + email_upsert: { id: string; }; +} + +interface ListEmailsResponse { emails: Email[]; } -interface UserVariables { - id: { uid: string; }; +interface GetUserVariables { + id: { id: string; }; +} + +interface DeleteResponse { + email_deleteMany: number + user_deleteMany: number } const connectorConfig: ConnectorConfig = { @@ -86,117 +97,195 @@ const connectorConfig: ConnectorConfig = { serviceId: 'my-service', }; -const userId = 'QVBJcy5ndXJ3'; +const fredUser = { id: 'fred_id', address: '32 Elm St.', name: 'Fred' } +const fredrickUser = { id: fredUser.id, address: '64 Elm St. North', name: 'Fredrick' } + +const jeffUser = { id: 'jeff_id', address: '99 Oak St.', name: 'Jeff' } + +const fredEmail = { + id: 'email_id', + subject: 'free bitcoin inside', + date: '1999-12-31', + text: 'get pranked! LOL!', + from: { id: fredUser.id } +} describe('getDataConnect()', () => { - const queryListUsers = 'query ListUsers @auth(level: PUBLIC) { users { uid, name, address } }'; - const queryListEmails = 'query ListEmails @auth(level: NO_ACCESS) { emails { id subject text date from { name } } }'; - const queryGetUserById = 'query GetUser($id: User_Key!) { user(key: $id) { uid name } }'; + before(() => { + firebase.initializeApp({ + apiKey, + authDomain: projectId + '.firebaseapp.com', + }); + }); + + afterEach(async () => { + await cleanupDatabase(); + }) + + beforeEach(async () => { + await initializeDatabase(); + }); + + /** initial state of database after calling initializeDatabase() */ + const initialState = { users: [fredUser, jeffUser], emails: [fredEmail] }; + + /** helper function which sets initial state of the database before each test */ + async function initializeDatabase(): Promise { + await getDataConnect(connectorConfig).executeGraphql( + upsertFredUser + ); + await getDataConnect(connectorConfig).executeGraphql( + upsertJeffUser + ); + await getDataConnect(connectorConfig).executeGraphql( + upsertFredEmail + ); + } + /** helper function which clears state of the database after each test */ + async function cleanupDatabase(): Promise { + await getDataConnect(connectorConfig).executeGraphql(deleteAll); + } + /** @auth(level: PUBLIC) */ + const queryListUsers = 'query ListUsers @auth(level: PUBLIC) { users { id, name, address } }'; + /** @auth(level: NO_ACCESS) */ + const queryListEmails = + 'query ListEmails @auth(level: NO_ACCESS) { emails { id subject text date from { id } } }'; + /** no @auth specified - default permissions */ + const queryGetUserById = 'query GetUser($id: User_Key!) { user(key: $id) { id name address } }'; + + /** @auth(level: USER) */ const queryListUsersImpersonation = ` query ListUsers @auth(level: USER) { - users(where: { uid: { eq_expr: "auth.uid" } }) { uid, name, address } + users(where: { id: { eq_expr: "auth.uid" } }) { id, name, address } }`; - + const multipleQueries = ` - ${queryListUsers} - ${queryListEmails} + ${queryListUsers} + ${queryListEmails} `; - const mutation = `mutation user { user_insert(data: {uid: "${userId}", address: "32 St", name: "Fred Car"}) }`; - - const updateImpersonatedUser = ` - mutation UpdateUser @auth(level: USER) { - user_update(key: { uid_expr: "auth.uid" }, data: { address: "32 Elm St.", name: "Fredrick" }) + /** hardcoded upsert fredUser query, with non-impersonateable id */ + const upsertFredUser = + `mutation user { + user_upsert(data: {id: "${fredUser.id}", address: "${fredUser.address}", name: "${fredUser.name}"}) }`; - const upsertUser = `mutation UpsertUser($id: String) { - user_upsert(data: { uid: $id, address: "32 St.", name: "Fred" }) }`; - - const testUser = { - name: 'Fred', - address: '32 St.', - uid: userId - } + /** hardcoded upsert fredrickUser query, with impersonateable id */ + const updateFredrickUserImpersonated = + `mutation upsertFredrickUserImpersonated @auth(level: USER) { + user_update( + key: { id_expr: "auth.uid" }, + data: { address: "${fredrickUser.address}", name: "${fredrickUser.name}" } + ) + }`; + + /** hardcoded upsert jeffUser query, with non-impersonateable id */ + const upsertJeffUser = + `mutation user { + user_upsert(data: {id: "${jeffUser.id}", address: "${jeffUser.address}", name: "${jeffUser.name}"}) + }`; - const expectedUsers = [ - testUser, - { - name: 'Jeff', - address: '99 Oak St. N', - uid: 'QVBJcy5ndXJ1' - } - ]; + /** hardcoded upsert fredEmail query, with non-impersonateable id */ + const upsertFredEmail = `mutation email { + email_upsert(data: { + id:"${fredEmail.id}", + subject: "${fredEmail.subject}", + date: "${fredEmail.date}", + text: "${fredEmail.text}", + fromId: "${fredEmail.from.id}" + }) + }`; + + /** hardcoded delete all mutation, for cleanup */ + const deleteAll = `mutation delete { + email_deleteMany(all: true) + user_deleteMany(all: true) + }` describe('executeGraphql()', () => { it('executeGraphql() successfully executes a GraphQL mutation', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - upsertUser, { variables: { id: userId } } + const fredResponse = await getDataConnect(connectorConfig).executeGraphql( + upsertFredUser + ); + //{ data: { user_insert: { id: 'fred_id' } } } + expect(fredResponse.data.user_upsert.id).to.be.not.empty; + expect(fredResponse.data.user_upsert.id).equals(fredUser.id); + + const jeffResponse = await getDataConnect(connectorConfig).executeGraphql( + upsertJeffUser + ); + //{ data: { user_insert: { id: 'jeff_id' } } } + expect(jeffResponse.data.user_upsert.id).to.be.not.empty; + expect(jeffResponse.data.user_upsert.id).equals(jeffUser.id); + + const emailResponse = await getDataConnect(connectorConfig).executeGraphql( + upsertFredEmail ); - //{ data: { user_insert: { uid: 'QVBJcy5ndXJ3' } } } - expect(resp.data.user_upsert.uid).to.be.not.empty; - expect(resp.data.user_upsert.uid).equals(userId); + //{ data: { email_upsert: { id: 'email_id' } } } + expect(emailResponse.data.email_upsert.id).to.be.not.empty; + + const deleteResponse = await getDataConnect(connectorConfig).executeGraphql(deleteAll); + expect(deleteResponse.data.email_deleteMany).to.be.greaterThan(0); + expect(deleteResponse.data.user_deleteMany).to.be.greaterThan(0); }); - it('executeGraphql() successfully executes a GraphQL', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql(queryListUsers); + it('executeGraphql() successfully executes a GraphQL query', async () => { + const resp = await getDataConnect(connectorConfig) + .executeGraphql(queryListUsers); expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.be.greaterThan(1); - expectedUsers.forEach((expectedUser) => { - expect(resp.data.users).to.deep.include(expectedUser); + expect(resp.data.users.length).to.equal(initialState.users.length); + resp.data.users.forEach((user) => { + expect(initialState.users).to.deep.include(user); }); }); it('executeGraphql() use the operationName when multiple queries are provided', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( + const resp = await getDataConnect(connectorConfig).executeGraphql( multipleQueries, { operationName: 'ListEmails' } ); - expect(resp.data.emails).to.be.not.empty; - expect(resp.data.emails.length).equals(1); - expect(resp.data.emails[0].id).to.be.not.undefined; - expect(resp.data.emails[0].from?.name).to.equal('Jeff'); + expect(resp.data.emails).to.not.be.empty; + expect(resp.data.emails).to.deep.equal(initialState.emails); }); - it('executeGraphql() should throw for a query error', async () => { - return getDataConnect(connectorConfig).executeGraphql(mutation) + it('executeGraphql() should throw for a query error when no variables are provided', async () => { + return getDataConnect(connectorConfig).executeGraphql(queryGetUserById) .should.eventually.be.rejected.and.have.property('code', 'data-connect/query-error'); }); it('executeGraphql() successfully executes a GraphQL query with variables', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( + const resp = await getDataConnect(connectorConfig).executeGraphql( queryGetUserById, - { variables: { id: { uid: userId } } } + { variables: { id: { id: initialState.users[0].id } } } ); - expect(resp.data.user.uid).to.equal(testUser.uid); - expect(resp.data.user.name).to.equal(testUser.name); - expect(resp.data.user.address).to.be.undefined; + expect(resp.data.user).to.deep.equal(initialState.users[0]); }); }); describe('executeGraphqlRead()', () => { it('executeGraphqlRead() successfully executes a read-only GraphQL', async () => { - const resp = - await getDataConnect(connectorConfig).executeGraphqlRead(queryListUsers); + const resp = await getDataConnect(connectorConfig) + .executeGraphqlRead(queryListUsers); expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.be.greaterThan(1); - expectedUsers.forEach((expectedUser) => { - expect(resp.data.users).to.deep.include(expectedUser); + expect(resp.data.users.length).to.equal(initialState.users.length); + resp.data.users.forEach((user) => { + expect(initialState.users).to.deep.include(user); }); }); it('executeGraphqlRead() should throw for a GraphQL mutation', async () => { - return getDataConnect(connectorConfig).executeGraphqlRead(mutation) + return getDataConnect(connectorConfig).executeGraphqlRead(upsertFredUser) .should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); }); }); describe('Impersonation', () => { - const optsAuthorizedClaims: GraphqlOptions = { + const optsAuthorizedFredClaims: GraphqlOptions = { impersonate: { authClaims: { - sub: userId, + sub: fredUser.id, email_verified: true } } @@ -220,25 +309,27 @@ describe('getDataConnect()', () => { describe('USER Auth Policy', () => { it('executeGraphqlRead() successfully executes an impersonated query with authenticated claims', async () => { const resp = - await getDataConnect(connectorConfig).executeGraphqlRead( - queryListUsersImpersonation, optsAuthorizedClaims); + await getDataConnect(connectorConfig).executeGraphqlRead( + queryListUsersImpersonation, optsAuthorizedFredClaims); expect(resp.data.users).to.be.not.empty; expect(resp.data.users.length).equals(1); - expect(resp.data.users[0]).to.deep.equal(testUser); + expect(resp.data.users[0]).to.deep.equal(fredUser); }); it('executeGraphqlRead() should throw for impersonated query with unauthenticated claims', async () => { - return getDataConnect(connectorConfig).executeGraphqlRead(queryListUsersImpersonation, optsUnauthorizedClaims) + return getDataConnect(connectorConfig).executeGraphqlRead( + queryListUsersImpersonation, + optsUnauthorizedClaims + ) .should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); }); it('executeGraphql() successfully executes an impersonated query with authenticated claims', async () => { - const resp = - await getDataConnect(connectorConfig).executeGraphqlRead( - queryListUsersImpersonation, optsAuthorizedClaims); + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsersImpersonation, optsAuthorizedFredClaims); expect(resp.data.users).to.be.not.empty; expect(resp.data.users.length).equals(1); - expect(resp.data.users[0]).to.deep.equal(testUser); + expect(resp.data.users[0]).to.deep.equal(fredUser); }); it('executeGraphql() should throw for impersonated query with unauthenticated claims', async () => { @@ -249,7 +340,7 @@ describe('getDataConnect()', () => { it('executeGraphql() should return an empty list for an impersonated query with non-existing authenticated ' + 'claims', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( + const resp = await getDataConnect(connectorConfig).executeGraphql( queryListUsersImpersonation, optsNonExistingClaims); // Should find no data expect(resp.data.users).to.be.empty; @@ -257,75 +348,66 @@ describe('getDataConnect()', () => { it('executeGraphql() successfully executes an impersonated mutation with authenticated claims', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - updateImpersonatedUser, optsAuthorizedClaims); + const updateResp = await getDataConnect(connectorConfig).executeGraphql( + updateFredrickUserImpersonated, optsAuthorizedFredClaims); // Fred -> Fredrick - expect(resp.data.user_update.uid).equals(userId); + expect(updateResp.data.user_update.id).equals(fredUser.id); + const queryResp = await getDataConnect(connectorConfig).executeGraphql( + queryGetUserById, { variables: { id: { id: fredUser.id } } }); + expect(queryResp.data.user).to.not.be.empty; + expect(queryResp.data.user).to.deep.equal(fredrickUser); }); it('executeGraphql() should throw for impersonated mutation with unauthenticated claims', async () => { - return getDataConnect(connectorConfig).executeGraphql(updateImpersonatedUser, optsUnauthorizedClaims) + return getDataConnect(connectorConfig).executeGraphql(updateFredrickUserImpersonated, optsUnauthorizedClaims) .should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated'); }); it('executeGraphql() should return null for an impersonated mutation with non-existing authenticated claims', async () => { const resp = await getDataConnect(connectorConfig).executeGraphql( - updateImpersonatedUser, optsNonExistingClaims); + updateFredrickUserImpersonated, optsNonExistingClaims); // Should mutate no data expect(resp.data.user_update).to.be.null; }); }); describe('PUBLIC Auth Policy', () => { - const expectedUsers = [ - { - name: 'Fredrick', - address: '32 Elm St.', - uid: userId - }, - { - name: 'Jeff', - address: '99 Oak St. N', - uid: 'QVBJcy5ndXJ1' - } - ]; - it('executeGraphql() successfully executes an impersonated query with authenticated claims', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - queryListUsers, optsAuthorizedClaims); + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsers, optsAuthorizedFredClaims); expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.be.greaterThan(1); - expectedUsers.forEach((expectedUser) => { - expect(resp.data.users).to.deep.include(expectedUser); - }) + expect(resp.data.users.length).to.equal(initialState.users.length); + resp.data.users.forEach((user) => { + expect(initialState.users).to.deep.include(user); + }); }); it('executeGraphql() successfully executes an impersonated query with unauthenticated claims', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( + const resp = await getDataConnect(connectorConfig).executeGraphql( queryListUsers, optsUnauthorizedClaims); expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.be.greaterThan(1); - expectedUsers.forEach((expectedUser) => { - expect(resp.data.users).to.deep.include(expectedUser); + expect(resp.data.users.length).to.equal(initialState.users.length); + resp.data.users.forEach((user) => { + expect(initialState.users).to.deep.include(user); }); }); it('executeGraphql() successfully executes an impersonated query with non-existing authenticated claims', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( + const resp = await getDataConnect(connectorConfig).executeGraphql( queryListUsers, optsNonExistingClaims); expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.be.greaterThan(1); - expectedUsers.forEach((expectedUser) => { - expect(resp.data.users).to.deep.include(expectedUser); + expect(resp.data.users.length).to.equal(initialState.users.length); + resp.data.users.forEach((user) => { + expect(initialState.users).to.deep.include(user); }); }); }); describe('NO_ACCESS Auth Policy', () => { it('executeGraphql() should throw for an impersonated query with authenticated claims', async () => { - return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsAuthorizedClaims) + return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsAuthorizedFredClaims) .should.eventually.be.rejected.and.has.property('code', 'data-connect/permission-denied'); }); diff --git a/test/integration/dataconnect/dataconnect/dataconnect.yaml b/test/integration/dataconnect/dataconnect/dataconnect.yaml new file mode 100644 index 0000000000..2f5b815b88 --- /dev/null +++ b/test/integration/dataconnect/dataconnect/dataconnect.yaml @@ -0,0 +1,13 @@ +specVersion: "v1" +serviceId: "my-service" +location: "us-west2" +schema: + source: "./schema" + datasource: + postgresql: + database: "my-database" + cloudSql: + instanceId: "my-instance" + # schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly. + # schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect. +connectorDirs: ["./my-connector"] diff --git a/test/integration/dataconnect/dataconnect/my-connector/connector.yaml b/test/integration/dataconnect/dataconnect/my-connector/connector.yaml new file mode 100644 index 0000000000..3b1bcdcc91 --- /dev/null +++ b/test/integration/dataconnect/dataconnect/my-connector/connector.yaml @@ -0,0 +1 @@ +connectorId: "my-connector" diff --git a/test/integration/dataconnect/dataconnect/my-connector/mutations.gql b/test/integration/dataconnect/dataconnect/my-connector/mutations.gql new file mode 100644 index 0000000000..10a870880e --- /dev/null +++ b/test/integration/dataconnect/dataconnect/my-connector/mutations.gql @@ -0,0 +1,95 @@ +mutation upsertFredUser @auth(level: NO_ACCESS) { + user_upsert(data: { id: "fred_id", address: "32 Elm St.", name: "Fred" }) +} +mutation updateFredrickUserImpersonation @auth(level: USER) { + user_update( + key: { id_expr: "auth.uid" } + data: { address: "64 Elm St. North", name: "Fredrick" } + ) +} +mutation upsertJeffUser @auth(level: NO_ACCESS) { + user_upsert(data: { id: "jeff_id", address: "99 Oak St.", name: "Jeff" }) +} + +mutation upsertJeffEmail @auth(level: NO_ACCESS) { + email_upsert( + data: { + id: "jeff_email_id" + subject: "free bitcoin inside" + date: "1999-12-31" + text: "get pranked! LOL!" + fromId: "jeff_id" + } + ) +} + +mutation InsertEmailPublic($id: String!) +@auth(level: PUBLIC, insecureReason: "test") { + email_insert( + data: { + id: $id + subject: "PublicEmail" + date: "1999-12-31" + text: "PublicEmail" + fromId: "jeff_id" + } + ) +} +mutation InsertEmailUserAnon($id: String!) +@auth(level: USER_ANON, insecureReason: "test") { + email_insert( + data: { + id: $id + subject: "UserAnonEmail" + date: "1999-12-31" + text: "UserAnonEmail" + fromId: "jeff_id" + } + ) +} +mutation InsertEmailUser($id: String!) +@auth(level: USER, insecureReason: "test") { + email_insert( + data: { + id: $id + subject: "UserEmail" + date: "1999-12-31" + text: "UserEmail" + fromId: "jeff_id" + } + ) +} +mutation InsertEmailUserEmailVerified($id: String!) +@auth(level: USER_EMAIL_VERIFIED, insecureReason: "test") { + email_insert( + data: { + id: $id + subject: "UserEmailVerifiedEmail" + date: "1999-12-31" + text: "UserEmailVerifiedEmail" + fromId: "jeff_id" + } + ) +} +mutation InsertEmailNoAccess($id: String!) @auth(level: NO_ACCESS) { + email_insert( + data: { + id: $id + subject: "NoAccessEmail" + date: "1999-12-31" + text: "NoAccessEmail" + fromId: "jeff_id" + } + ) +} +mutation InsertEmailImpersonation($id: String!) @auth(level: NO_ACCESS) { + email_insert( + data: { + id: $id + subject: "ImpersonatedEmail" + date: "1999-12-31" + text: "ImpersonatedEmail" + fromId_expr: "auth.uid" + } + ) +} diff --git a/test/integration/dataconnect/dataconnect/my-connector/queries.gql b/test/integration/dataconnect/dataconnect/my-connector/queries.gql new file mode 100644 index 0000000000..b93da41828 --- /dev/null +++ b/test/integration/dataconnect/dataconnect/my-connector/queries.gql @@ -0,0 +1,74 @@ +query ListUsersPublic @auth(level: PUBLIC, insecureReason: "test") { + users { + id + name + address + } +} +query ListUsersUserAnon @auth(level: USER_ANON, insecureReason: "test") { + users { + id + name + address + } +} +query ListUsersUser @auth(level: USER, insecureReason: "test") { + users { + id + name + address + } +} +query ListUsersUserEmailVerified +@auth(level: USER_EMAIL_VERIFIED, insecureReason: "test") { + users { + id + name + address + } +} +query ListUsersNoAccess @auth(level: NO_ACCESS) { + users { + id + name + address + } +} +query ListUsersImpersonationAnon @auth(level: USER_ANON) { + users(where: { id: { eq_expr: "auth.uid" } }) { + id + name + address + } +} +query GetUser($id: User_Key!) @auth(level: NO_ACCESS) { + user(key: $id) { + id + name + } +} + +query ListEmails @auth(level: NO_ACCESS) { + emails { + id + subject + text + date + from { + name + } + } +} +query GetEmail($id: String!) @auth(level: NO_ACCESS) { + email(id: $id) { + id + subject + date + text + from { + id + name + address + } + } +} diff --git a/test/integration/dataconnect/dataconnect/schema/schema.gql b/test/integration/dataconnect/dataconnect/schema/schema.gql new file mode 100644 index 0000000000..1f390b316e --- /dev/null +++ b/test/integration/dataconnect/dataconnect/schema/schema.gql @@ -0,0 +1,13 @@ +type User @table(key: ["id"]) { + id: String! + name: String! + address: String! +} + +type Email @table { + id: String! + subject: String! + date: Date! + text: String! + from: User! +} diff --git a/test/integration/dataconnect/firebase.json b/test/integration/dataconnect/firebase.json new file mode 100644 index 0000000000..73f599717a --- /dev/null +++ b/test/integration/dataconnect/firebase.json @@ -0,0 +1,5 @@ +{ + "dataconnect": { + "source": "dataconnect" + } +} diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index b23c5e144d..8086802861 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -207,7 +207,7 @@ describe('DataConnectApiClient', () => { expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); expect(stub).to.have.been.calledOnce.and.calledWith({ method: 'POST', - url: `https://firebasedataconnect.googleapis.com/v1alpha/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, + url: `https://firebasedataconnect.googleapis.com/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, headers: EXPECTED_HEADERS, data: { query: 'query' } }); @@ -223,7 +223,7 @@ describe('DataConnectApiClient', () => { .then(() => { expect(stub).to.have.been.calledOnce.and.calledWith({ method: 'POST', - url: `http://localhost:9399/v1alpha/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, + url: `http://localhost:9399/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, headers: EMULATOR_EXPECTED_HEADERS, data: { query: 'query' } }); From e72c0cd40cf1c5f1288a0f2c2d44184440b13dbb Mon Sep 17 00:00:00 2001 From: Maneesh Tewani Date: Thu, 2 Oct 2025 10:53:41 -0700 Subject: [PATCH 271/323] chore(dc): Implement gen tracking (#2985) --- package.json | 2 ++ .../data-connect-api-client-internal.ts | 25 ++++++++++--- src/data-connect/data-connect.ts | 8 +++++ src/utils/api-request.ts | 8 +++-- .../data-connect-api-client-internal.spec.ts | 35 +++++++++++++++++++ 5 files changed, 72 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index ffd2a8da9e..bf0126d792 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,9 @@ "test:integration": "mocha test/integration/*.ts --slow 5000 --timeout 20000 --require ts-node/register", "test:coverage": "nyc npm run test:unit", "lint:src": "eslint src/ --ext .ts", + "lint:src:fix": "eslint src/ --ext .ts --fix", "lint:test": "eslint test/ --ext .ts", + "lint:test:fix": "eslint test/ --ext .ts --fix", "apidocs": "run-s api-extractor:local api-documenter", "api-extractor": "node generate-reports.js", "api-extractor:local": "npm run build && node generate-reports.js --local", diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts index 3ef99bacea..79a72431ac 100644 --- a/src/data-connect/data-connect-api-client-internal.ts +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -38,9 +38,17 @@ const FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT = const EXECUTE_GRAPH_QL_ENDPOINT = 'executeGraphql'; const EXECUTE_GRAPH_QL_READ_ENDPOINT = 'executeGraphqlRead'; -const DATA_CONNECT_CONFIG_HEADERS = { - 'X-Firebase-Client': `fire-admin-node/${utils.getSdkVersion()}` -}; + +function getHeaders(isUsingGen: boolean): { [key: string]: string } { + const headerValue = { + 'X-Firebase-Client': `fire-admin-node/${utils.getSdkVersion()}`, + 'X-Goog-Api-Client': utils.getMetricsHeader(), + }; + if (isUsingGen) { + headerValue['X-Goog-Api-Client'] += ' admin-js/gen'; + } + return headerValue; +} /** * Class that facilitates sending requests to the Firebase Data Connect backend API. @@ -50,6 +58,7 @@ const DATA_CONNECT_CONFIG_HEADERS = { export class DataConnectApiClient { private readonly httpClient: HttpClient; private projectId?: string; + private isUsingGen = false; constructor(private readonly connectorConfig: ConnectorConfig, private readonly app: App) { if (!validator.isNonNullObject(app) || !('options' in app)) { @@ -59,6 +68,14 @@ export class DataConnectApiClient { } this.httpClient = new DataConnectHttpClient(app as FirebaseApp); } + + /** + * Update whether the SDK is using a generated one or not. + * @param isUsingGen + */ + setIsUsingGen(isUsingGen: boolean): void { + this.isUsingGen = isUsingGen; + } /** * Execute arbitrary GraphQL, including both read and write queries @@ -117,7 +134,7 @@ export class DataConnectApiClient { const request: HttpRequestConfig = { method: 'POST', url, - headers: DATA_CONNECT_CONFIG_HEADERS, + headers: getHeaders(this.isUsingGen), data, }; const resp = await this.httpClient.send(request); diff --git a/src/data-connect/data-connect.ts b/src/data-connect/data-connect.ts index a689423257..366b756327 100644 --- a/src/data-connect/data-connect.ts +++ b/src/data-connect/data-connect.ts @@ -72,6 +72,14 @@ export class DataConnect { this.client = new DataConnectApiClient(connectorConfig, app); } + /** + * @param isUsingGen + * @internal + */ + useGen(isUsingGen: boolean): void { + this.client.setIsUsingGen(isUsingGen); + } + /** * Execute an arbitrary GraphQL query or mutation * diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index 3e5aa754d8..6e95619e6d 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -1092,7 +1092,9 @@ export class AuthorizedHttpClient extends HttpClient { requestCopy.httpAgent = this.app.options.httpAgent; } - requestCopy.headers['X-Goog-Api-Client'] = getMetricsHeader() + if (!requestCopy.headers['X-Goog-Api-Client']) { + requestCopy.headers['X-Goog-Api-Client'] = getMetricsHeader() + } return super.send(requestCopy); }); @@ -1126,7 +1128,9 @@ export class AuthorizedHttp2Client extends Http2Client { requestCopy.headers['x-goog-user-project'] = quotaProjectId; } - requestCopy.headers['X-Goog-Api-Client'] = getMetricsHeader() + if (!requestCopy.headers['X-Goog-Api-Client']) { + requestCopy.headers['X-Goog-Api-Client'] = getMetricsHeader() + } return super.send(requestCopy); }); diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index 8086802861..67c1541cd6 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -46,6 +46,12 @@ describe('DataConnectApiClient', () => { 'X-Goog-Api-Client': getMetricsHeader(), }; + const EXPECTED_HEADERS_WITH_GEN = { + 'Authorization': 'Bearer mock-token', + 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, + 'X-Goog-Api-Client': getMetricsHeader() + ' admin-js/gen', + }; + const EMULATOR_EXPECTED_HEADERS = { 'Authorization': 'Bearer owner', 'X-Firebase-Client': `fire-admin-node/${getSdkVersion()}`, @@ -229,6 +235,35 @@ describe('DataConnectApiClient', () => { }); }); }); + it('should use gen headers if set on success', () => { + interface UsersResponse { + users: [ + user: { + id: string; + name: string; + address: string; + } + ]; + } + apiClient.setIsUsingGen(true); + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + return apiClient.executeGraphql('query', {}) + .then((resp) => { + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `https://firebasedataconnect.googleapis.com/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, + headers: EXPECTED_HEADERS_WITH_GEN, + data: { query: 'query' } + }); + apiClient.setIsUsingGen(false); + }); + }); }); }); From 8c9895e87485f5aa686f809b80fd0fb854d25035 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 18:13:52 +0000 Subject: [PATCH 272/323] build(deps): bump axios in /.github/actions/send-email (#2983) --- .github/actions/send-email/package-lock.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 2b2d9b2449..11a686e946 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -57,13 +57,13 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, From 175ca9e073ddd5d4350f7224a7651b6b2abd4b54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 20:19:20 +0000 Subject: [PATCH 273/323] build(deps-dev): bump @firebase/api-documenter from 0.4.0 to 0.5.0 (#3000) --- package-lock.json | 102 +++++++++++++++++++++++++++++++++++----------- package.json | 2 +- 2 files changed, 79 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d6cea5157..bea64ae6d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.4.0", + "version": "13.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.4.0", + "version": "13.5.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -22,7 +22,7 @@ "uuid": "^11.0.2" }, "devDependencies": { - "@firebase/api-documenter": "^0.4.0", + "@firebase/api-documenter": "^0.5.0", "@firebase/app-compat": "^0.2.1", "@firebase/auth-compat": "^0.6.0", "@firebase/auth-types": "^0.13.0", @@ -510,15 +510,15 @@ "license": "MIT" }, "node_modules/@firebase/api-documenter": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/api-documenter/-/api-documenter-0.4.0.tgz", - "integrity": "sha512-UUPxxj1wIAGkXBCF9UL1dhfyzM4Lcd/gMSCoJqy8o75rLqQVGB2GSBaU7I4JmQsQhIIk/nKKLiy4HM/70kEfZA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/api-documenter/-/api-documenter-0.5.0.tgz", + "integrity": "sha512-7fMC0sVInXsatjWMJG45W6ZQBtRcHh5D4oVpLXzKWBe/0TbRyBSE/ApecH9mn48XZGSs8/8Y0k7mKrLsXPLprA==", "dev": true, "license": "Apache-2.0", "dependencies": { "@microsoft/tsdoc": "0.12.24", - "@rushstack/node-core-library": "3.59.7", - "@rushstack/ts-command-line": "4.15.2", + "@rushstack/node-core-library": "3.66.1", + "@rushstack/ts-command-line": "4.23.3", "api-extractor-model-me": "0.1.1", "colors": "~1.4.0", "js-yaml": "4.1.0", @@ -527,6 +527,9 @@ }, "bin": { "api-documenter-fire": "dist/start.js" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@firebase/app": { @@ -1753,9 +1756,9 @@ "optional": true }, "node_modules/@rushstack/node-core-library": { - "version": "3.59.7", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.59.7.tgz", - "integrity": "sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==", + "version": "3.66.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.66.1.tgz", + "integrity": "sha512-ker69cVKAoar7MMtDFZC4CzcDxjwqIhFzqEnYI5NRN/8M3om6saWCVx/A7vL2t/jFCJsnzQplRDqA7c78pytng==", "dev": true, "license": "MIT", "dependencies": { @@ -1897,26 +1900,77 @@ } }, "node_modules/@rushstack/ts-command-line": { - "version": "4.15.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.15.2.tgz", - "integrity": "sha512-5+C2uoJY8b+odcZD6coEe2XNC4ZjGB4vCMESbqW/8DHRWC/qIHfANdmN9F1wz/lAgxz72i7xRoVtPY2j7e4gpQ==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.23.3.tgz", + "integrity": "sha512-HazKL8fv4HMQMzrKJCrOrhyBPPdzk7iajUXgsASwjQ8ROo1cmgyqxt/k9+SdmrNLGE1zATgRqMUH3s/6smbRMA==", "dev": true, "license": "MIT", "dependencies": { + "@rushstack/terminal": "0.14.5", "@types/argparse": "1.0.38", "argparse": "~1.0.9", - "colors": "~1.2.1", "string-argv": "~0.3.1" } }, - "node_modules/@rushstack/ts-command-line/node_modules/colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "node_modules/@rushstack/ts-command-line/node_modules/@rushstack/node-core-library": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.10.2.tgz", + "integrity": "sha512-xOF/2gVJZTfjTxbo4BDj9RtQq/HFnrrKdtem4JkyRLnwsRz2UDTg8gA1/et10fBx5RxmZD9bYVGST69W8ME5OQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.1.90" + "dependencies": { + "ajv": "~8.13.0", + "ajv-draft-04": "~1.0.0", + "ajv-formats": "~3.0.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.22.1", + "semver": "~7.5.4" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/ts-command-line/node_modules/@rushstack/terminal": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.14.5.tgz", + "integrity": "sha512-TEOpNwwmsZVrkp0omnuTUTGZRJKTr6n6m4OITiNjkqzLAkcazVpwR1SOtBg6uzpkIBLgrcNHETqI8rbw3uiUfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rushstack/node-core-library": "5.10.2", + "supports-color": "~8.1.1" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/ts-command-line/node_modules/ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/@sinonjs/commons": { @@ -12001,9 +12055,9 @@ } }, "node_modules/validator": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", - "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "version": "13.15.20", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.20.tgz", + "integrity": "sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index bf0126d792..de6e640c84 100644 --- a/package.json +++ b/package.json @@ -223,7 +223,7 @@ "@google-cloud/storage": "^7.14.0" }, "devDependencies": { - "@firebase/api-documenter": "^0.4.0", + "@firebase/api-documenter": "^0.5.0", "@firebase/app-compat": "^0.2.1", "@firebase/auth-compat": "^0.6.0", "@firebase/auth-types": "^0.13.0", From 27c682a5080ba2080d9b6e73a5b34a6a3ad8a1a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Oct 2025 20:23:40 +0000 Subject: [PATCH 274/323] build(deps): bump @fastify/busboy from 3.1.1 to 3.2.0 (#2998) --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bea64ae6d6..f2229fb9be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -504,9 +504,9 @@ } }, "node_modules/@fastify/busboy": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz", - "integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.2.0.tgz", + "integrity": "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==", "license": "MIT" }, "node_modules/@firebase/api-documenter": { From c9a3ee39e04669a8ed7089a2af6fe331b07136c7 Mon Sep 17 00:00:00 2001 From: Stephen Rosa <84193009+stephenarosaj@users.noreply.github.com> Date: Mon, 3 Nov 2025 11:03:29 -0800 Subject: [PATCH 275/323] feat(dc): Add executeQuery and executeMutation APIs to Data Connect (#2979) # API Changes - Added `executeQuery()` and `executeMutation()` to `src/data-connect/data-connect.ts`. These allow users to call deployed operations with impersonated auth credentials. # Testing - New unit tests added which match the coverage of existing `executeGraphql*` APIs - New integration tests added which more than match the coverage of existing `executeGraphql*` APIs # Commits: * add in changes from stephenarosaj/fdc-impersonate * finish adding in changes from stephenarosaj/fdc-impersonate * update Google Inc. to Google LLC, run npm install; npm run build * run npm apidocs * remove public execute apis * convert executeOperation api to OperationRef(...).execute() api * remove internal client from operation refs * cleanup javadocs to address workflow failures * npm run apidocs * spread GraphqlOptions arguments in OperationRefs and executeOperation functions * convert unit tests to use spread args * convert integration tests to use spread args * add executeQuery test cases which do not provide impersonation options, bypassing auth policies * add executeMutation test cases which do not provide impersonation options, bypassing auth policies * run npm apidocs * address try/catch comment * address await and reject grouping comment * address getUrl comments * address insecureReason comment * convert autopush resources to prod * add RefOptions, [Operation,Query,Mutation]Ref, [Operation,Query,Mutation]Result to exported api * revert OperationRef.execute() API to executeOperation API * revert OperationRef.execute() API to executeOperation API * revert tests to use DataConnect.executeOperation() API instead of OperationRef.execute() API * revert package version * update executeOperation API to return executeOperationResponse * update comments * add invalidateAdminArgs to handle variadic JS executeOperation arguments * npm run apidocs for validateAdminArgs * update validateAdminArgs documentation * address validateAdminArgs and some test comments * update validate-admin-args and add tests, address existing test comments, revert package changes * update tests * update tests * address mutation test comments * address prod url comments * finally fixed unit tests * REALLY fixed unit tests * address comments, add DataConnect.executeQuery() and DataConnect.executeMutation() unit tests * make validateAdminArgs internal * address comments * address documentation comment * undo integration test changes * remove empty checks * remove length checks * remove foreach checks * address test comments * revert package version * revert package version to master * revert package version to master * update comments --- etc/firebase-admin.data-connect.api.md | 15 + .../data-connect-api-client-internal.ts | 294 +++++- src/data-connect/data-connect-api.ts | 34 +- src/data-connect/data-connect.ts | 96 +- src/data-connect/index.ts | 23 +- src/data-connect/validate-admin-args.ts | 91 ++ test/integration/data-connect.spec.ts | 947 ++++++++++++++---- .../dataconnect/my-connector/mutations.gql | 11 +- .../dataconnect/my-connector/queries.gql | 5 +- .../data-connect-api-client-internal.spec.ts | 477 +++++++-- test/unit/data-connect/data-connect.spec.ts | 226 +++++ .../data-connect/validate-admin-args.spec.ts | 271 +++++ test/unit/index.spec.ts | 2 + 13 files changed, 2142 insertions(+), 350 deletions(-) create mode 100644 src/data-connect/validate-admin-args.ts create mode 100644 test/unit/data-connect/data-connect.spec.ts create mode 100644 test/unit/data-connect/validate-admin-args.spec.ts diff --git a/etc/firebase-admin.data-connect.api.md b/etc/firebase-admin.data-connect.api.md index 8a1e7a042c..4ac9e170cd 100644 --- a/etc/firebase-admin.data-connect.api.md +++ b/etc/firebase-admin.data-connect.api.md @@ -13,6 +13,7 @@ export type AuthClaims = Partial; // @public export interface ConnectorConfig { + connector?: string; location: string; serviceId: string; } @@ -27,6 +28,10 @@ export class DataConnect { readonly connectorConfig: ConnectorConfig; executeGraphql(query: string, options?: GraphqlOptions): Promise>; executeGraphqlRead(query: string, options?: GraphqlOptions): Promise>; + executeMutation(name: string, options?: OperationOptions): Promise>; + executeMutation(name: string, variables: Variables, options?: OperationOptions): Promise>; + executeQuery(name: string, options?: OperationOptions): Promise>; + executeQuery(name: string, variables: Variables, options?: OperationOptions): Promise>; insert(tableName: string, variables: Variables): Promise>; insertMany>(tableName: string, variables: Variables): Promise>; upsert(tableName: string, variables: Variables): Promise>; @@ -38,6 +43,11 @@ export interface ExecuteGraphqlResponse { data: GraphqlResponse; } +// @public +export interface ExecuteOperationResponse { + data: GraphqlResponse; +} + // @public export function getDataConnect(connectorConfig: ConnectorConfig, app?: App): DataConnect; @@ -60,4 +70,9 @@ export interface ImpersonateUnauthenticated { unauthenticated: true; } +// @public +export interface OperationOptions { + impersonate?: ImpersonateAuthenticated | ImpersonateUnauthenticated; +} + ``` diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts index 79a72431ac..28284db6a4 100644 --- a/src/data-connect/data-connect-api-client-internal.ts +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -23,21 +23,44 @@ import { import { PrefixedFirebaseError } from '../utils/error'; import * as utils from '../utils/index'; import * as validator from '../utils/validator'; -import { ConnectorConfig, ExecuteGraphqlResponse, GraphqlOptions } from './data-connect-api'; +import { ConnectorConfig, ExecuteGraphqlResponse, GraphqlOptions, OperationOptions } from './data-connect-api'; const API_VERSION = 'v1'; - -/** The Firebase Data Connect backend base URL format. */ -const FIREBASE_DATA_CONNECT_BASE_URL_FORMAT = - 'https://firebasedataconnect.googleapis.com/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}:{endpointId}'; - -/** Firebase Data Connect base URl format when using the Data Connect emultor. */ -const FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT = +const FIREBASE_DATA_CONNECT_PROD_URL = 'https://firebasedataconnect.googleapis.com'; + +/** The Firebase Data Connect backend service URL format. */ +const FIREBASE_DATA_CONNECT_SERVICES_URL_FORMAT = + FIREBASE_DATA_CONNECT_PROD_URL + + '/{version}' + + '/projects/{projectId}' + + '/locations/{locationId}' + + '/services/{serviceId}' + + ':{endpointId}'; + +/** The Firebase Data Connect backend connector URL format. */ +const FIREBASE_DATA_CONNECT_CONNECTORS_URL_FORMAT = + FIREBASE_DATA_CONNECT_PROD_URL + + '/{version}' + + '/projects/{projectId}' + + '/locations/{locationId}' + + '/services/{serviceId}' + + '/connectors/{connectorId}' + + ':{endpointId}'; + +/** Firebase Data Connect service URL format when using the Data Connect emulator. */ +const FIREBASE_DATA_CONNECT_EMULATOR_SERVICES_URL_FORMAT = 'http://{host}/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}:{endpointId}'; +/** Firebase Data Connect connector URL format when using the Data Connect emulator. */ +const FIREBASE_DATA_CONNECT_EMULATOR_CONNECTORS_URL_FORMAT = + 'http://{host}/{version}/projects/{projectId}/locations/{locationId}/services/{serviceId}/connectors/{connectorId}:{endpointId}'; + const EXECUTE_GRAPH_QL_ENDPOINT = 'executeGraphql'; const EXECUTE_GRAPH_QL_READ_ENDPOINT = 'executeGraphqlRead'; +const IMPERSONATE_QUERY_ENDPOINT = 'impersonateQuery'; +const IMPERSONATE_MUTATION_ENDPOINT = 'impersonateMutation'; + function getHeaders(isUsingGen: boolean): { [key: string]: string } { const headerValue = { @@ -50,6 +73,27 @@ function getHeaders(isUsingGen: boolean): { [key: string]: string } { return headerValue; } +/** + * URL params for requests to an endpoint under services: + * .../services/{serviceId}:endpoint + */ +interface ServicesUrlParams { + version: string; + projectId: string; + locationId: string; + serviceId: string; + endpointId: string; + host?: string; // Present only when using the emulator +} + +/** + * URL params for requests to an endpoint under connectors: + * .../services/{serviceId}/connectors/{connectorId}:endpoint + */ +interface ConnectorsUrlParams extends ServicesUrlParams { + connectorId: string; +} + /** * Class that facilitates sending requests to the Firebase Data Connect backend API. * @@ -106,6 +150,15 @@ export class DataConnectApiClient { return this.executeGraphqlHelper(query, EXECUTE_GRAPH_QL_READ_ENDPOINT, options); } + + /** + * A helper function to execute GraphQL queries. + * + * @param query - The arbitrary GraphQL query to execute. + * @param endpoint - The endpoint to call. + * @param options - The GraphQL options. + * @returns A promise that fulfills with the GraphQL response, or throws an error. + */ private async executeGraphqlHelper( query: string, endpoint: string, @@ -129,52 +182,163 @@ export class DataConnectApiClient { ...(options?.operationName && { operationName: options?.operationName }), ...(options?.impersonate && { extensions: { impersonate: options?.impersonate } }), }; - return this.getUrl(API_VERSION, this.connectorConfig.location, this.connectorConfig.serviceId, endpoint) - .then(async (url) => { - const request: HttpRequestConfig = { - method: 'POST', - url, - headers: getHeaders(this.isUsingGen), - data, - }; - const resp = await this.httpClient.send(request); - if (resp.data.errors && validator.isNonEmptyArray(resp.data.errors)) { - const allMessages = resp.data.errors.map((error: { message: any; }) => error.message).join(' '); - throw new FirebaseDataConnectError( - DATA_CONNECT_ERROR_CODE_MAPPING.QUERY_ERROR, allMessages); - } - return Promise.resolve({ - data: resp.data.data as GraphqlResponse, - }); - }) - .then((resp) => { - return resp; - }) - .catch((err) => { - throw this.toFirebaseError(err); - }); + const url = await this.getServicesUrl( + API_VERSION, + this.connectorConfig.location, + this.connectorConfig.serviceId, + endpoint + ); + try { + const resp = await this.makeGqlRequest(url, data); + return resp; + } catch (err: any) { + throw this.toFirebaseError(err); + } } - private async getUrl(version: string, locationId: string, serviceId: string, endpointId: string): Promise { - return this.getProjectId() - .then((projectId) => { - const urlParams = { - version, - projectId, - locationId, - serviceId, - endpointId - }; - let urlFormat: string; - if (useEmulator()) { - urlFormat = utils.formatString(FIREBASE_DATA_CONNECT_EMULATOR_BASE_URL_FORMAT, { - host: emulatorHost() - }); - } else { - urlFormat = FIREBASE_DATA_CONNECT_BASE_URL_FORMAT; - } - return utils.formatString(urlFormat, urlParams); - }); + /** + * Executes a GraphQL query with impersonation. + * + * @param options - The GraphQL options. Must include impersonation details. + * @returns A promise that fulfills with the GraphQL response. + */ + public async executeQuery( + name: string, + variables: Variables, + options?: OperationOptions + ): Promise> { + return this.executeOperationHelper(IMPERSONATE_QUERY_ENDPOINT, name, variables, options); + } + + /** + * Executes a GraphQL mutation with impersonation. + * + * @param options - The GraphQL options. Must include impersonation details. + * @returns A promise that fulfills with the GraphQL response. + */ + public async executeMutation( + name: string, + variables: Variables, + options?: OperationOptions + ): Promise> { + return this.executeOperationHelper(IMPERSONATE_MUTATION_ENDPOINT, name, variables, options); + } + + /** + * A helper function to execute operations by making requests to FDC's impersonate + * operations endpoints. + * + * @param endpoint - The endpoint to call. + * @param options - The GraphQL options, including impersonation details. + * @returns A promise that fulfills with the GraphQL response. + */ + private async executeOperationHelper( + endpoint: string, + name: string, + variables: Variables, + options?: OperationOptions + ): Promise> { + if ( + typeof name === 'undefined' || + !validator.isNonEmptyString(name) + ) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + '`name` must be a non-empty string.' + ); + } + + if (this.connectorConfig.connector === undefined || this.connectorConfig.connector === '') { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + `The 'connectorConfig.connector' field used to instantiate your Data Connect + instance must be a non-empty string (the connectorId) when calling executeQuery or executeMutation.`); + } + + const data = { + ...(variables && { variables: variables }), + operationName: name, + extensions: { impersonate: options?.impersonate }, + }; + const url = await this.getConnectorsUrl( + API_VERSION, + this.connectorConfig.location, + this.connectorConfig.serviceId, + this.connectorConfig.connector, + endpoint, + ); + try { + const resp = await this.makeGqlRequest(url, data); + return resp; + } catch (err: any) { + throw this.toFirebaseError(err); + } + } + + /** + * Constructs the URL for a Data Connect request to a service endpoint. + * + * @param version - The API version. + * @param locationId - The location of the Data Connect service. + * @param serviceId - The ID of the Data Connect service. + * @param endpointId - The endpoint to call. + * @returns A promise which resolves to the formatted URL string. + */ + private async getServicesUrl( + version: string, + locationId: string, + serviceId: string, + endpointId: string, + ): Promise { + const projectId = await this.getProjectId(); + const params: ServicesUrlParams = { + version, + projectId, + locationId, + serviceId, + endpointId, + }; + let urlFormat = FIREBASE_DATA_CONNECT_SERVICES_URL_FORMAT; + if (useEmulator()) { + urlFormat = FIREBASE_DATA_CONNECT_EMULATOR_SERVICES_URL_FORMAT; + params.host = emulatorHost(); + } + return utils.formatString(urlFormat, params); + } + + /** + * Constructs the URL for a Data Connect request to a connector endpoint. + * + * @param version - The API version. + * @param locationId - The location of the Data Connect service. + * @param serviceId - The ID of the Data Connect service. + * @param connectorId - The ID of the Connector. + * @param endpointId - The endpoint to call. + * @returns A promise which resolves to the formatted URL string. + + */ + private async getConnectorsUrl( + version: string, + locationId: string, + serviceId: string, + connectorId: string, + endpointId: string, + ): Promise { + const projectId = await this.getProjectId(); + const params: ConnectorsUrlParams = { + version, + projectId, + locationId, + serviceId, + connectorId, + endpointId, + }; + let urlFormat = FIREBASE_DATA_CONNECT_CONNECTORS_URL_FORMAT; + if (useEmulator()) { + urlFormat = FIREBASE_DATA_CONNECT_EMULATOR_CONNECTORS_URL_FORMAT; + params.host = emulatorHost(); + } + return utils.formatString(urlFormat, params); } private getProjectId(): Promise { @@ -195,6 +359,32 @@ export class DataConnectApiClient { }); } + /** + * Makes a GraphQL request to the specified url. + * + * @param url - The URL to send the request to. + * @param data - The GraphQL request payload. + * @returns A promise that fulfills with the GraphQL response, or throws an error. + */ + private async makeGqlRequest(url: string, data: object): + Promise> { + const request: HttpRequestConfig = { + method: 'POST', + url, + headers: getHeaders(this.isUsingGen), + data, + }; + const resp = await this.httpClient.send(request); + if (resp.data.errors && validator.isNonEmptyArray(resp.data.errors)) { + const allMessages = resp.data.errors.map((error: { message: any; }) => error.message).join(' '); + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.QUERY_ERROR, allMessages); + } + return Promise.resolve({ + data: resp.data.data as GraphqlResponse, + }); + } + private toFirebaseError(err: RequestResponseError): PrefixedFirebaseError { if (err instanceof PrefixedFirebaseError) { return err; diff --git a/src/data-connect/data-connect-api.ts b/src/data-connect/data-connect-api.ts index c60ef5a2eb..bd25d493b2 100644 --- a/src/data-connect/data-connect-api.ts +++ b/src/data-connect/data-connect-api.ts @@ -30,10 +30,15 @@ export interface ConnectorConfig { * Service ID of the Data Connect service. */ serviceId: string; + + /** + * Name of the Data Connect connector. + */ + connector?: string; } /** - * Interface representing GraphQL response. + * Interface representing ExecuteGraphQL response. */ export interface ExecuteGraphqlResponse { /** @@ -43,7 +48,17 @@ export interface ExecuteGraphqlResponse { } /** - * Interface representing GraphQL options. + * Interface representing ExecuteOperation response. + */ +export interface ExecuteOperationResponse { + /** + * Data payload of the GraphQL response. + */ + data: GraphqlResponse; +} + +/** + * Interface representing GraphQL options for executing arbitrary GraphQL operations. */ export interface GraphqlOptions { /** @@ -52,7 +67,9 @@ export interface GraphqlOptions { variables?: Variables; /** - * The name of the GraphQL operation. Required only if `query` contains multiple operations. + * The name of the GraphQL operation. + * Required for operations that interact with services, such as executeGraphql, if + * `query` contains multiple operations. */ operationName?: string; @@ -63,6 +80,17 @@ export interface GraphqlOptions { impersonate?: ImpersonateAuthenticated | ImpersonateUnauthenticated; } +/** + * Interface representing options for executing defined operations. + */ +export interface OperationOptions { + /** + * If set, impersonate a request with given Firebase Auth context and evaluate the auth + * policies on the operation. If omitted, bypass any defined auth policies. + */ + impersonate?: ImpersonateAuthenticated | ImpersonateUnauthenticated; +} + /** * Type representing the partial claims of a Firebase Auth token used to evaluate the * Data Connect auth policy. diff --git a/src/data-connect/data-connect.ts b/src/data-connect/data-connect.ts index 366b756327..c48e3d1c78 100644 --- a/src/data-connect/data-connect.ts +++ b/src/data-connect/data-connect.ts @@ -21,7 +21,9 @@ import { DataConnectApiClient } from './data-connect-api-client-internal'; import { ConnectorConfig, ExecuteGraphqlResponse, + ExecuteOperationResponse, GraphqlOptions, + OperationOptions, } from './data-connect-api'; export class DataConnectService { @@ -96,13 +98,13 @@ export class DataConnect { } /** - * Execute an arbitrary read-only GraphQL query - * - * @param query - The GraphQL read-only query. - * @param options - Optional {@link GraphqlOptions} when executing a read-only GraphQL query. - * - * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. - */ + * Execute an arbitrary read-only GraphQL query + * + * @param query - The GraphQL read-only query. + * @param options - Optional {@link GraphqlOptions} when executing a read-only GraphQL query. + * + * @returns A promise that fulfills with a `ExecuteGraphqlResponse`. + */ public executeGraphqlRead( query: string, options?: GraphqlOptions, @@ -165,4 +167,84 @@ export class DataConnect { ): Promise> { return this.client.upsertMany(tableName, variables); } + + /** + * Executes a GraphQL query. The query must be defined in your Data Connect GraphQL files. + * Optionally, you can provide auth impersonation details. If you don't + * specify a value for this option, the query will run with admin privileges + * and will ignore all auth directives. + * + * @param name - The name of the defined query to execute. + * @param options - The GraphQL options, must include operationName and impersonation details. + * @returns A promise that fulfills with the GraphQL response. + */ + public executeQuery( + name: string, + options?: OperationOptions + ): Promise>; + + /** + * Executes a GraphQL query. The query must be defined in your Data Connect GraphQL files. + * Optionally, you can provide auth impersonation details. If you don't + * specify a value for this option, the query will run with admin privileges + * and will ignore all auth directives. + * + * @param name - The name of the defined query to execute. + * @param variables - The variables for the query. May be optional if the query's variables are optional. + * @param options - The GraphQL options, must include operationName and impersonation details. + * @returns A promise that fulfills with the GraphQL response. + */ + public executeQuery( + name: string, + variables: Variables, + options?: OperationOptions + ): Promise>; + + public executeQuery( + name: string, + variables: Variables, + options?: OperationOptions + ): Promise> { + return this.client.executeQuery(name, variables, options); + } + + /** + * Executes a GraphQL mutation. The mutation must be defined in your Data Connect GraphQL files. + * Optionally, you can provide auth impersonation details. If you don't + * specify a value for this option, the query will run with admin privileges + * and will ignore all auth directives. + * + * @param name - The name of the defined mutation to execute. + * @param options - The GraphQL options, must include operationName and impersonation details. + * @returns A promise that fulfills with the GraphQL response. + */ + public executeMutation( + name: string, + options?: OperationOptions + ): Promise>; + + /** + * Executes a GraphQL mutation. The mutation must be defined in your Data Connect GraphQL files. + * Optionally, you can provide auth impersonation details. If you don't + * specify a value for this option, the query will run with admin privileges + * and will ignore all auth directives. + * + * @param name - The name of the defined mutation to execute. + * @param variables - The variables for the mutation. May be optional if the mutation's variables are optional. + * @param options - The GraphQL options, must include operationName and impersonation details. + * @returns A promise that fulfills with the GraphQL response. + */ + public executeMutation( + name: string, + variables: Variables, + options?: OperationOptions + ): Promise>; + + public executeMutation( + name: string, + variables: Variables, + options?: OperationOptions + ): Promise> { + return this.client.executeMutation(name, variables, options); + } } diff --git a/src/data-connect/index.ts b/src/data-connect/index.ts index 43ca313c90..95d9f26da2 100644 --- a/src/data-connect/index.ts +++ b/src/data-connect/index.ts @@ -1,3 +1,9 @@ +/** + * Firebase Data Connect service. + * + * @packageDocumentation + */ + /*! * @license * Copyright 2024 Google LLC @@ -15,12 +21,7 @@ * limitations under the License. */ -/** - * Firebase Data Connect service. - * - * @packageDocumentation - */ - +import { _validateAdminArgs } from './validate-admin-args'; import { App, getApp } from '../app'; import { FirebaseApp } from '../app/firebase-app'; import { DataConnect, DataConnectService } from './data-connect'; @@ -29,10 +30,12 @@ import { ConnectorConfig } from './data-connect-api'; export { GraphqlOptions, ExecuteGraphqlResponse, + ExecuteOperationResponse, ConnectorConfig, ImpersonateAuthenticated, ImpersonateUnauthenticated, - AuthClaims + AuthClaims, + OperationOptions, } from './data-connect-api' export { DataConnect, @@ -51,6 +54,7 @@ export { * const connectorConfig: ConnectorConfig = { * location: 'us-west2', * serviceId: 'my-service', + * connectorName: 'my-connector', * }; * * // Get the `DataConnect` service for the default app @@ -80,3 +84,8 @@ export function getDataConnect(connectorConfig: ConnectorConfig, app?: App): Dat const dataConnectService = firebaseApp.getOrInitService('dataConnect', (app) => new DataConnectService(app)); return dataConnectService.getDataConnect(connectorConfig); } + +/** + * @internal + */ +export const validateAdminArgs = _validateAdminArgs; diff --git a/src/data-connect/validate-admin-args.ts b/src/data-connect/validate-admin-args.ts new file mode 100644 index 0000000000..f4332b5ddd --- /dev/null +++ b/src/data-connect/validate-admin-args.ts @@ -0,0 +1,91 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getDataConnect } from './index'; +import { DataConnect } from './data-connect'; +import { ConnectorConfig, OperationOptions } from './data-connect-api'; +import { + DATA_CONNECT_ERROR_CODE_MAPPING, + FirebaseDataConnectError, +} from './data-connect-api-client-internal'; + +/** + * @internal + * + * The generated Admin SDK will allow the user to pass in variables, a Data Connect + * instance, or operation options. The only required argument is the variables, + * which are only required when the operation has at least one required variable. + * Otherwise, all arguments are optional. + * + * This function validates the variables and returns back the DataConnect instance, + * variables, and options based on the arguments passed in. It always returns a + * DataConnect instance, using the connectorConfig to grab one if not provided. + * + * For this function to work properly, if the operation has variables (optional + * are required), you must pass hasVars: true (if there are no variables, it is + * not required, since undefined is false-y). + * + * Usage examples can be found in test files. + * + * @param connectorConfig - DataConnect connector config + * @param dcOrVarsOrOptions - the first argument provided to a generated admin function + * @param varsOrOptions - the second argument provided to a generated admin function + * @param options - the third argument provided to a generated admin function + * @param hasVars - boolean parameter indicating whether the operation has variables + * @param validateVars - boolean parameter indicating whether we should expect to find a value for realVars + * @returns parsed DataConnect, Variables, and Options for the operation + */ +export function _validateAdminArgs( + connectorConfig: ConnectorConfig, + dcOrVarsOrOptions?: DataConnect | Variables | OperationOptions, + varsOrOptions?: Variables | OperationOptions, + options?: OperationOptions, + hasVars?: boolean, + validateVars?: boolean +): { dc: DataConnect; vars: Variables; options: OperationOptions; } { + let dcInstance: DataConnect; + let realVars: Variables; + let realOptions: OperationOptions; + + if (dcOrVarsOrOptions && 'connectorConfig' in dcOrVarsOrOptions) { + dcInstance = dcOrVarsOrOptions as DataConnect; + if (hasVars) { + realVars = varsOrOptions as Variables; + realOptions = options as OperationOptions; + } else { + realVars = undefined as unknown as Variables; + realOptions = varsOrOptions as OperationOptions; + } + } else { + dcInstance = getDataConnect(connectorConfig); + if (hasVars) { + realVars = dcOrVarsOrOptions as Variables; + realOptions = varsOrOptions as OperationOptions; + } else { + realVars = undefined as unknown as Variables; + realOptions = dcOrVarsOrOptions as OperationOptions; + } + } + + if (!dcInstance || (!realVars && validateVars)) { + throw new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'Variables required.' + ); + } + return { dc: dcInstance, vars: realVars, options: realOptions }; +} diff --git a/test/integration/data-connect.spec.ts b/test/integration/data-connect.spec.ts index 4cf74549cf..78da027fb4 100644 --- a/test/integration/data-connect.spec.ts +++ b/test/integration/data-connect.spec.ts @@ -16,9 +16,10 @@ import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { getDataConnect, ConnectorConfig, GraphqlOptions } from '../../lib/data-connect/index'; +import { getDataConnect, ConnectorConfig } from '../../lib/data-connect/index'; import firebase from '@firebase/app-compat'; import { apiKey, projectId } from './setup'; +import { OperationOptions } from '../../lib/data-connect/data-connect-api'; chai.should(); chai.use(chaiAsPromised); @@ -44,11 +45,11 @@ type User = { /** * // Schema * type Email @table { - * id: String! - * subject: String! - * date: Date! - * text: String! - * from: User! + * id: String! + * subject: String! + * date: Date! + * text: String! + * from: User! * } */ type Email = { @@ -59,10 +60,24 @@ type Email = { id: string; }; +interface GetUserVariables { + id: { id: string; }; +} + interface GetUserResponse { user: User; } +interface InsertUserVariables { + id: string; + name: string; + address: string; +} + +interface InsertUserResponse { + user_insert: { id: string; }; +} + interface ListUsersResponse { users: User[]; } @@ -75,16 +90,32 @@ interface UserUpdateResponse { user_update: { id: string; }; } +interface GetEmailVariables { + id: string +} + +interface GetEmailResponse { + email: Email; +} + interface EmailUpsertResponse { email_upsert: { id: string; }; } -interface ListEmailsResponse { - emails: Email[]; +interface InsertEmailVariables { + id: string; } -interface GetUserVariables { - id: { id: string; }; +interface InsertEmailResponse { + email_insert: { id: string; }; +} + +interface InsertEmailResponse { + email_insert: { id: string; }; +} + +interface ListEmailsResponse { + emails: Email[]; } interface DeleteResponse { @@ -95,6 +126,7 @@ interface DeleteResponse { const connectorConfig: ConnectorConfig = { location: 'us-west2', serviceId: 'my-service', + connector: 'my-connector' }; const fredUser = { id: 'fred_id', address: '32 Elm St.', name: 'Fred' } @@ -152,6 +184,9 @@ describe('getDataConnect()', () => { /** @auth(level: NO_ACCESS) */ const queryListEmails = 'query ListEmails @auth(level: NO_ACCESS) { emails { id subject text date from { id } } }'; + /** @auth(level: NO_ACCESS) */ + const queryGetEmail = + 'query GetEmail($id: String!) @auth(level: NO_ACCESS) { email(id: $id) { id subject text date from { id } } }'; /** no @auth specified - default permissions */ const queryGetUserById = 'query GetUser($id: User_Key!) { user(key: $id) { id name address } }'; @@ -204,223 +239,767 @@ describe('getDataConnect()', () => { user_deleteMany(all: true) }` - describe('executeGraphql()', () => { - it('executeGraphql() successfully executes a GraphQL mutation', async () => { - const fredResponse = await getDataConnect(connectorConfig).executeGraphql( - upsertFredUser - ); - //{ data: { user_insert: { id: 'fred_id' } } } - expect(fredResponse.data.user_upsert.id).to.be.not.empty; - expect(fredResponse.data.user_upsert.id).equals(fredUser.id); - - const jeffResponse = await getDataConnect(connectorConfig).executeGraphql( - upsertJeffUser - ); - //{ data: { user_insert: { id: 'jeff_id' } } } - expect(jeffResponse.data.user_upsert.id).to.be.not.empty; - expect(jeffResponse.data.user_upsert.id).equals(jeffUser.id); - - const emailResponse = await getDataConnect(connectorConfig).executeGraphql( - upsertFredEmail - ); - //{ data: { email_upsert: { id: 'email_id' } } } - expect(emailResponse.data.email_upsert.id).to.be.not.empty; - - const deleteResponse = await getDataConnect(connectorConfig).executeGraphql(deleteAll); - expect(deleteResponse.data.email_deleteMany).to.be.greaterThan(0); - expect(deleteResponse.data.user_deleteMany).to.be.greaterThan(0); - }); + const optsUnauthorizedClaims: OperationOptions = { + impersonate: { + unauthenticated: true + } + }; + + const optsAuthorizedFredAnonClaims: OperationOptions = { + impersonate: { + authClaims: { + sub: fredUser.id, + firebase: { + identities: { who: 'me' }, + sign_in_provider: 'anonymous' + } + } + } + }; - it('executeGraphql() successfully executes a GraphQL query', async () => { - const resp = await getDataConnect(connectorConfig) - .executeGraphql(queryListUsers); - expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.equal(initialState.users.length); - resp.data.users.forEach((user) => { - expect(initialState.users).to.deep.include(user); + const optsAuthorizedFredClaims: OperationOptions = { + impersonate: { + authClaims: { + sub: fredUser.id, + } + } + }; + + const optsAuthorizedFredEmailVerifiedClaims: OperationOptions = { + impersonate: { + authClaims: { + sub: fredUser.id, + email_verified: true + } + } + }; + + const optsNonExistingClaims: OperationOptions = { + impersonate: { + authClaims: { + sub: 'non-exisiting-id', + email_verified: true + } + } + }; + + + describe('executeGraphql* API', () => { + describe('executeGraphql()', () => { + it('executeGraphql() successfully executes a GraphQL mutation', async () => { + const fredResponse = await getDataConnect(connectorConfig).executeGraphql( + upsertFredUser + ); + //{ data: { user_insert: { id: 'fred_id' } } } + expect(fredResponse.data.user_upsert.id).equals(fredUser.id); + + const jeffResponse = await getDataConnect(connectorConfig).executeGraphql( + upsertJeffUser + ); + //{ data: { user_insert: { id: 'jeff_id' } } } + expect(jeffResponse.data.user_upsert.id).equals(jeffUser.id); + + const upsertEmailResponse = await getDataConnect(connectorConfig).executeGraphql( + upsertFredEmail + ); + //{ data: { email_upsert: { id: 'email_id' } } } + expect(upsertEmailResponse.data.email_upsert.id).to.not.be.empty; + const queryGetEmailResponse = + await getDataConnect(connectorConfig).executeGraphql( + queryGetEmail, { variables: { id: upsertEmailResponse.data.email_upsert.id } } + ); + expect(queryGetEmailResponse.data.email).to.deep.equal(fredEmail); + + const deleteResponse = await getDataConnect(connectorConfig).executeGraphql(deleteAll); + expect(deleteResponse.data.email_deleteMany).to.equal(1); + expect(deleteResponse.data.user_deleteMany).to.equal(2); }); - }); - it('executeGraphql() use the operationName when multiple queries are provided', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - multipleQueries, - { operationName: 'ListEmails' } - ); - expect(resp.data.emails).to.not.be.empty; - expect(resp.data.emails).to.deep.equal(initialState.emails); - }); + it('executeGraphql() successfully executes a GraphQL query', async () => { + const resp = await getDataConnect(connectorConfig) + .executeGraphql(queryListUsers); + expect(resp.data.users).to.deep.equal(initialState.users); + }); - it('executeGraphql() should throw for a query error when no variables are provided', async () => { - return getDataConnect(connectorConfig).executeGraphql(queryGetUserById) - .should.eventually.be.rejected.and.have.property('code', 'data-connect/query-error'); - }); + it('executeGraphql() use the operationName when multiple queries are provided', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + multipleQueries, + { operationName: 'ListEmails' } + ); + expect(resp.data.emails).to.deep.equal(initialState.emails); + }); - it('executeGraphql() successfully executes a GraphQL query with variables', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - queryGetUserById, - { variables: { id: { id: initialState.users[0].id } } } - ); - expect(resp.data.user).to.deep.equal(initialState.users[0]); - }); - }); + it('executeGraphql() should throw for a query error when no variables are provided', async () => { + return getDataConnect(connectorConfig).executeGraphql(queryGetUserById) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/query-error'); + }); - describe('executeGraphqlRead()', () => { - it('executeGraphqlRead() successfully executes a read-only GraphQL', async () => { - const resp = await getDataConnect(connectorConfig) - .executeGraphqlRead(queryListUsers); - expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.equal(initialState.users.length); - resp.data.users.forEach((user) => { - expect(initialState.users).to.deep.include(user); + it('executeGraphql() successfully executes a GraphQL query with variables', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryGetUserById, + { variables: { id: { id: initialState.users[0].id } } } + ); + expect(resp.data.user).to.deep.equal(initialState.users[0]); }); }); - it('executeGraphqlRead() should throw for a GraphQL mutation', async () => { - return getDataConnect(connectorConfig).executeGraphqlRead(upsertFredUser) - .should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); - }); - }); + describe('executeGraphqlRead()', () => { + it('executeGraphqlRead() successfully executes a read-only GraphQL', async () => { + const resp = await getDataConnect(connectorConfig) + .executeGraphqlRead(queryListUsers); + expect(resp.data.users).to.deep.equal(initialState.users); + }); - describe('Impersonation', () => { - const optsAuthorizedFredClaims: GraphqlOptions = { - impersonate: { - authClaims: { - sub: fredUser.id, - email_verified: true - } - } - }; + it('executeGraphqlRead() should throw for a GraphQL mutation', async () => { + return getDataConnect(connectorConfig).executeGraphqlRead(upsertFredUser) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + }); - const optsNonExistingClaims: GraphqlOptions = { - impersonate: { - authClaims: { - sub: 'non-exisiting-id', - email_verified: true - } - } - }; + describe('executeGraphql* impersonation', () => { + describe('USER Auth Policy', () => { + it('executeGraphqlRead() successfully executes an impersonated query with authenticated claims', async () => { + const resp = + await getDataConnect(connectorConfig).executeGraphqlRead( + queryListUsersImpersonation, optsAuthorizedFredClaims); + expect(resp.data.users.length).equals(1); + expect(resp.data.users[0]).to.deep.equal(fredUser); + }); - const optsUnauthorizedClaims: GraphqlOptions = { - impersonate: { - unauthenticated: true - } - }; + it('executeGraphqlRead() should throw for impersonated query with unauthenticated claims', async () => { + return getDataConnect(connectorConfig).executeGraphqlRead( + queryListUsersImpersonation, + optsUnauthorizedClaims + ) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); - describe('USER Auth Policy', () => { - it('executeGraphqlRead() successfully executes an impersonated query with authenticated claims', async () => { - const resp = - await getDataConnect(connectorConfig).executeGraphqlRead( + it('executeGraphql() successfully executes an impersonated query with authenticated claims', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( queryListUsersImpersonation, optsAuthorizedFredClaims); - expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).equals(1); - expect(resp.data.users[0]).to.deep.equal(fredUser); + expect(resp.data.users.length).equals(1); + expect(resp.data.users[0]).to.deep.equal(fredUser); + }); + + it('executeGraphql() should throw for impersonated query with unauthenticated claims', async () => { + return getDataConnect(connectorConfig).executeGraphql(queryListUsersImpersonation, optsUnauthorizedClaims) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('executeGraphql() should return an empty list for an impersonated query with non-existing authenticated ' + + 'claims', + async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsersImpersonation, optsNonExistingClaims); + // Should find no data + expect(resp.data.users).to.be.empty; + }); + + it('executeGraphql() successfully executes an impersonated mutation with authenticated claims', + async () => { + const updateResp = await getDataConnect(connectorConfig).executeGraphql( + updateFredrickUserImpersonated, optsAuthorizedFredClaims); + // Fred -> Fredrick + expect(updateResp.data.user_update.id).equals(fredUser.id); + const queryResp = await getDataConnect(connectorConfig).executeGraphql( + queryGetUserById, { variables: { id: { id: fredUser.id } } }); + expect(queryResp.data.user).to.deep.equal(fredrickUser); + }); + + it('executeGraphql() should throw for impersonated mutation with unauthenticated claims', async () => { + return getDataConnect(connectorConfig).executeGraphql(updateFredrickUserImpersonated, optsUnauthorizedClaims) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('executeGraphql() should return null for an impersonated mutation with non-existing authenticated claims', + async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + updateFredrickUserImpersonated, optsNonExistingClaims); + // Should mutate no data + expect(resp.data.user_update).to.be.null; + }); + }); + + describe('PUBLIC Auth Policy', () => { + it('executeGraphql() successfully executes an impersonated query with authenticated claims', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsers, optsAuthorizedFredClaims); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('executeGraphql() successfully executes an impersonated query with unauthenticated claims', async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsers, optsUnauthorizedClaims); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('executeGraphql() successfully executes an impersonated query with non-existing authenticated claims', + async () => { + const resp = await getDataConnect(connectorConfig).executeGraphql( + queryListUsers, optsNonExistingClaims); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + }); + + describe('NO_ACCESS Auth Policy', () => { + it('executeGraphql() should throw for an impersonated query with authenticated claims', async () => { + return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsAuthorizedFredClaims) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + + it('executeGraphql() should throw for an impersonated query with unauthenticated claims', async () => { + return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsUnauthorizedClaims) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + + it('executeGraphql() should throw for an impersonated query with non-existing authenticated claims', + async () => { + return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsNonExistingClaims) + .should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); }); + }); + }); - it('executeGraphqlRead() should throw for impersonated query with unauthenticated claims', async () => { - return getDataConnect(connectorConfig).executeGraphqlRead( - queryListUsersImpersonation, + describe('executeQuery|Mutation API', () => { + describe('executeQuery()', () => { + it("should fail when executing a query which doesn't exist", async () => { + return getDataConnect(connectorConfig).executeQuery( + 'DOES_NOT_EXIST!!!', + undefined, optsUnauthorizedClaims - ) - .should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/not-found'); + }); + + it('should execute a query with variables', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'GetUser', + { id: { id: fredUser.id } }, + ); + expect(resp.data.user).to.deep.equal(fredUser); }); - it('executeGraphql() successfully executes an impersonated query with authenticated claims', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - queryListUsersImpersonation, optsAuthorizedFredClaims); - expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).equals(1); - expect(resp.data.users[0]).to.deep.equal(fredUser); + describe('with unauthenticated impersonation', () => { + it('should successfully execute a query with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersPublic', + undefined, + optsUnauthorizedClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should fail to execute a query with @auth(level: USER_ANON)', () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserAnon', undefined, optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a query with @auth(level: USER)', async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersUser', undefined, optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a query with @auth(level: USER_EMAIL_VERIFIED)', () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserEmailVerified', undefined, optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a query with @auth(level: NO_ACCESS)', async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersNoAccess', undefined, optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); }); - it('executeGraphql() should throw for impersonated query with unauthenticated claims', async () => { - return getDataConnect(connectorConfig).executeGraphql(queryListUsersImpersonation, optsUnauthorizedClaims) - .should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated'); + describe('with authenticated anonymous impersonation', () => { + it('should successfully execute a query with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersPublic', undefined, optsAuthorizedFredAnonClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER_ANON)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserAnon', undefined, optsAuthorizedFredAnonClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should fail to execute a query with @auth(level: USER)', async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersUser', undefined, optsAuthorizedFredAnonClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a query with @auth(level: USER_EMAIL_VERIFIED)', async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserEmailVerified', undefined, optsAuthorizedFredAnonClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a query with @auth(level: NO_ACCESS)', async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersNoAccess', undefined, optsAuthorizedFredAnonClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + + it("should use the impersonated user's auth.uid", async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersImpersonationAnon', undefined, optsAuthorizedFredAnonClaims + ); + expect(resp.data.users.length).equals(1); + expect(resp.data.users[0]).to.deep.equal(fredUser); + }); }); - it('executeGraphql() should return an empty list for an impersonated query with non-existing authenticated ' + - 'claims', - async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - queryListUsersImpersonation, optsNonExistingClaims); - // Should find no data - expect(resp.data.users).to.be.empty; + describe('with authenticated user impersonation', () => { + it('should successfully execute a query with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersPublic', undefined, optsAuthorizedFredClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER_ANON)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserAnon', undefined, optsAuthorizedFredClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUser', undefined, optsAuthorizedFredClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should fail to execute a query with @auth(level: USER_EMAIL_VERIFIED)', async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserEmailVerified', undefined, optsAuthorizedFredClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a query with @auth(level: NO_ACCESS)', async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersNoAccess', undefined, optsAuthorizedFredClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + + it("should use the impersonated user's auth.uid", async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersImpersonationAnon', undefined, optsAuthorizedFredClaims + ); + expect(resp.data.users.length).equals(1); + expect(resp.data.users[0]).to.deep.equal(fredUser); + }); }); - it('executeGraphql() successfully executes an impersonated mutation with authenticated claims', - async () => { - const updateResp = await getDataConnect(connectorConfig).executeGraphql( - updateFredrickUserImpersonated, optsAuthorizedFredClaims); - // Fred -> Fredrick - expect(updateResp.data.user_update.id).equals(fredUser.id); - const queryResp = await getDataConnect(connectorConfig).executeGraphql( - queryGetUserById, { variables: { id: { id: fredUser.id } } }); - expect(queryResp.data.user).to.not.be.empty; - expect(queryResp.data.user).to.deep.equal(fredrickUser); - }); - - it('executeGraphql() should throw for impersonated mutation with unauthenticated claims', async () => { - return getDataConnect(connectorConfig).executeGraphql(updateFredrickUserImpersonated, optsUnauthorizedClaims) - .should.eventually.be.rejected.and.has.property('code', 'data-connect/unauthenticated'); + describe('with authenticated email verified user impersonation', () => { + it('should successfully execute a query with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersPublic', undefined, optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER_ANON)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserAnon', undefined, optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUser', undefined, optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserEmailVerified', undefined, optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should fail to execute a query with @auth(level: NO_ACCESS)', async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersNoAccess', undefined, optsAuthorizedFredEmailVerifiedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + + it("should use the impersonated user's auth.uid", async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersImpersonationAnon', undefined, optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.users.length).equals(1); + expect(resp.data.users[0]).to.deep.equal(fredUser); + }); }); - it('executeGraphql() should return null for an impersonated mutation with non-existing authenticated claims', - async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - updateFredrickUserImpersonated, optsNonExistingClaims); - // Should mutate no data - expect(resp.data.user_update).to.be.null; + describe('with no impersonation, bypassing auth policies', () => { + it('should successfully execute a query with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersPublic' + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER_ANON)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserAnon' + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUser' + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: USER_EMAIL_VERIFIED)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersUserEmailVerified' + ); + expect(resp.data.users).to.deep.equal(initialState.users); + }); + + it('should successfully execute a query with @auth(level: NO_ACCESS)', async () => { + const resp = await getDataConnect(connectorConfig).executeQuery( + 'ListUsersNoAccess' + ); + expect(resp.data.users).to.deep.equal(initialState.users); }); + + it("should fail to execute a query using the impersonated user's auth.uid", async () => { + return getDataConnect(connectorConfig).executeQuery( + 'ListUsersImpersonationAnon' + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/query-error'); + }); + }); }); - describe('PUBLIC Auth Policy', () => { - it('executeGraphql() successfully executes an impersonated query with authenticated claims', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - queryListUsers, optsAuthorizedFredClaims); - expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.equal(initialState.users.length); - resp.data.users.forEach((user) => { - expect(initialState.users).to.deep.include(user); + describe('executeMutation()', () => { + function generateEmailId(): string { + return `email_id_${Math.random() * 1000}`; + } + + it("should fail when executing a mutation which doesn't exist", async () => { + return getDataConnect(connectorConfig).executeMutation( + 'DOES_NOT_EXIST!!!', optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/not-found'); + }); + + it('should execute a mutation with variables', async () => { + const user = { id: 'USER_ID', name: 'USER_NAME', address: 'USER_ADDRESS' }; + const insertResp = await getDataConnect(connectorConfig) + .executeMutation('InsertUser', user); + expect(insertResp.data.user_insert).to.deep.equal({ id: user.id }); + + const getResp = await getDataConnect(connectorConfig).executeQuery( + 'GetUser', + { id: { id: user.id } }, + ); + expect(getResp.data.user).to.deep.equal(user); + }) + + describe('with unauthenticated impersonation', () => { + it('should successfully execute a mutation with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailPublic', + { id: generateEmailId() }, + optsUnauthorizedClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should fail to execute a mutation with @auth(level: USER_ANON)', () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailUserAnon', + { id: generateEmailId() }, + optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a mutation with @auth(level: USER)', async () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailUser', + { id: generateEmailId() }, + optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a mutation with @auth(level: USER_EMAIL_VERIFIED)', () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailUserEmailVerified', + { id: generateEmailId() }, + optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a mutation with @auth(level: NO_ACCESS)', async () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailNoAccess', + { id: generateEmailId() }, + optsUnauthorizedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); }); }); - it('executeGraphql() successfully executes an impersonated query with unauthenticated claims', async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - queryListUsers, optsUnauthorizedClaims); - expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.equal(initialState.users.length); - resp.data.users.forEach((user) => { - expect(initialState.users).to.deep.include(user); + describe('with authenticated anonymous impersonation', () => { + it('should successfully execute a mutation with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailPublic', + { id: generateEmailId() }, + optsAuthorizedFredAnonClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: USER_ANON)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUserAnon', + { id: generateEmailId() }, + optsAuthorizedFredAnonClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should fail to execute a mutation with @auth(level: USER)', async () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailUser', + { id: generateEmailId() }, + optsAuthorizedFredAnonClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a mutation with @auth(level: USER_EMAIL_VERIFIED)', () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailUserEmailVerified', + { id: generateEmailId() }, + optsAuthorizedFredAnonClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a mutation with @auth(level: NO_ACCESS)', async () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailNoAccess', + { id: generateEmailId() }, + optsAuthorizedFredAnonClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + + it("should use the impersonated user's auth.uid", async () => { + const insertResp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailImpersonation', + { id: generateEmailId() }, + optsAuthorizedFredAnonClaims + ); + expect(insertResp.data.email_insert.id).to.not.be.undefined; + const queryResp = await getDataConnect(connectorConfig).executeQuery( + 'GetEmail', + { id: insertResp.data.email_insert.id }, + optsAuthorizedFredAnonClaims + ); + expect(queryResp.data.email.from.id).to.equal(fredUser.id); }); }); - it('executeGraphql() successfully executes an impersonated query with non-existing authenticated claims', - async () => { - const resp = await getDataConnect(connectorConfig).executeGraphql( - queryListUsers, optsNonExistingClaims); - expect(resp.data.users).to.be.not.empty; - expect(resp.data.users.length).to.equal(initialState.users.length); - resp.data.users.forEach((user) => { - expect(initialState.users).to.deep.include(user); - }); + describe('with authenticated user impersonation', () => { + it('should successfully execute a mutation with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailPublic', + { id: generateEmailId() }, + optsAuthorizedFredClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should fail to execute a mutation with @auth(level: USER_ANON)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUserAnon', + { id: generateEmailId() }, + optsAuthorizedFredClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: USER)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUser', + { id: generateEmailId() }, + optsAuthorizedFredClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should fail to execute a mutation with @auth(level: USER_EMAIL_VERIFIED)', () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailUserEmailVerified', + { id: generateEmailId() }, + optsAuthorizedFredClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/unauthenticated'); + }); + + it('should fail to execute a mutation with @auth(level: NO_ACCESS)', async () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailNoAccess', + { id: generateEmailId() }, + optsAuthorizedFredClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); }); - }); - describe('NO_ACCESS Auth Policy', () => { - it('executeGraphql() should throw for an impersonated query with authenticated claims', async () => { - return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsAuthorizedFredClaims) - .should.eventually.be.rejected.and.has.property('code', 'data-connect/permission-denied'); + it("should use the impersonated user's auth.uid", async () => { + const insertResp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailImpersonation', + { id: generateEmailId() }, + optsAuthorizedFredClaims + ); + expect(insertResp.data.email_insert.id).to.not.be.undefined; + const queryResp = await getDataConnect(connectorConfig).executeQuery( + 'GetEmail', + { id: insertResp.data.email_insert.id }, + optsAuthorizedFredClaims + ); + expect(queryResp.data.email.from.id).to.equal(fredUser.id); + }); }); - it('executeGraphql() should throw for an impersonated query with unauthenticated claims', async () => { - return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsUnauthorizedClaims) - .should.eventually.be.rejected.and.has.property('code', 'data-connect/permission-denied'); + describe('with authenticated email verified user impersonation', () => { + it('should successfully execute a mutation with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailPublic', + { id: generateEmailId() }, + optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: USER_ANON)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUserAnon', + { id: generateEmailId() }, + optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: USER)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUser', + { id: generateEmailId() }, + optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: USER_EMAIL_VERIFIED)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUserEmailVerified', + { id: generateEmailId() }, + optsAuthorizedFredEmailVerifiedClaims + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should fail to execute a mutation with @auth(level: NO_ACCESS)', async () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailNoAccess', + { id: generateEmailId() }, + optsAuthorizedFredEmailVerifiedClaims + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/permission-denied'); + }); + + it("should use the impersonated user's auth.uid", async () => { + const insertResp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailImpersonation', + { id: generateEmailId() }, + optsAuthorizedFredEmailVerifiedClaims + ); + expect(insertResp.data.email_insert.id).to.not.be.undefined; + const queryResp = await getDataConnect(connectorConfig).executeQuery( + 'GetEmail', + { id: insertResp.data.email_insert.id }, + optsAuthorizedFredEmailVerifiedClaims + ); + expect(queryResp.data.email.from.id).to.equal(fredUser.id); + }); }); - it('executeGraphql() should throw for an impersonated query with non-existing authenticated claims', - async () => { - return await getDataConnect(connectorConfig).executeGraphql(queryListEmails, optsNonExistingClaims) - .should.eventually.be.rejected.and.has.property('code', 'data-connect/permission-denied'); + describe('with no impersonation, bypassing auth policies', () => { + it('should successfully execute a mutation with @auth(level: PUBLIC)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailPublic', + { id: generateEmailId() } + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: USER_ANON)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUserAnon', + { id: generateEmailId() } + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: USER)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUser', + { id: generateEmailId() } + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: USER_EMAIL_VERIFIED)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailUserEmailVerified', + { id: generateEmailId() } + ); + expect(resp.data.email_insert.id).to.not.be.undefined; + }); + + it('should successfully execute a mutation with @auth(level: NO_ACCESS)', async () => { + const resp = await getDataConnect(connectorConfig) + .executeMutation( + 'InsertEmailNoAccess', + { id: generateEmailId() } + ); + expect(resp.data.email_insert.id).to.not.be.undefined; }); + + it("should fail to execute a mutation using the impersonated user's auth.uid", async () => { + return getDataConnect(connectorConfig).executeMutation( + 'InsertEmailImpersonation', + { id: generateEmailId() }, + ).should.eventually.be.rejected.and.have.property('code', 'data-connect/query-error'); + }); + }); }); }); }); diff --git a/test/integration/dataconnect/dataconnect/my-connector/mutations.gql b/test/integration/dataconnect/dataconnect/my-connector/mutations.gql index 10a870880e..f3bfbeeb89 100644 --- a/test/integration/dataconnect/dataconnect/my-connector/mutations.gql +++ b/test/integration/dataconnect/dataconnect/my-connector/mutations.gql @@ -1,7 +1,8 @@ mutation upsertFredUser @auth(level: NO_ACCESS) { user_upsert(data: { id: "fred_id", address: "32 Elm St.", name: "Fred" }) } -mutation updateFredrickUserImpersonation @auth(level: USER) { +mutation updateFredrickUserImpersonation +@auth(level: USER, insecureReason: "test") { user_update( key: { id_expr: "auth.uid" } data: { address: "64 Elm St. North", name: "Fredrick" } @@ -23,6 +24,11 @@ mutation upsertJeffEmail @auth(level: NO_ACCESS) { ) } +mutation InsertUser($id: String!, $name: String!, $address: String!) +@auth(level: PUBLIC, insecureReason: "test") { + user_insert(data: { id: $id, name: $name, address: $address }) +} + mutation InsertEmailPublic($id: String!) @auth(level: PUBLIC, insecureReason: "test") { email_insert( @@ -82,7 +88,8 @@ mutation InsertEmailNoAccess($id: String!) @auth(level: NO_ACCESS) { } ) } -mutation InsertEmailImpersonation($id: String!) @auth(level: NO_ACCESS) { +mutation InsertEmailImpersonation($id: String!) +@auth(level: USER_ANON, insecureReason: "test") { email_insert( data: { id: $id diff --git a/test/integration/dataconnect/dataconnect/my-connector/queries.gql b/test/integration/dataconnect/dataconnect/my-connector/queries.gql index b93da41828..b4c3c92213 100644 --- a/test/integration/dataconnect/dataconnect/my-connector/queries.gql +++ b/test/integration/dataconnect/dataconnect/my-connector/queries.gql @@ -41,10 +41,11 @@ query ListUsersImpersonationAnon @auth(level: USER_ANON) { address } } -query GetUser($id: User_Key!) @auth(level: NO_ACCESS) { +query GetUser($id: User_Key!) @auth(level: PUBLIC, insecureReason: "test") { user(key: $id) { id name + address } } @@ -59,7 +60,7 @@ query ListEmails @auth(level: NO_ACCESS) { } } } -query GetEmail($id: String!) @auth(level: NO_ACCESS) { +query GetEmail($id: String!) @auth(level: USER_ANON, insecureReason: "test") { email(id: $id) { id subject diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index 67c1541cd6..628608a9e9 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -29,6 +29,7 @@ import { DATA_CONNECT_ERROR_CODE_MAPPING, DataConnectApiClient, FirebaseDataConn import { FirebaseApp } from '../../../src/app/firebase-app'; import { ConnectorConfig } from '../../../src/data-connect'; import { getMetricsHeader, getSdkVersion } from '../../../src/utils'; +import { OperationOptions } from '../../../src/data-connect/data-connect-api'; describe('DataConnectApiClient', () => { @@ -75,6 +76,7 @@ describe('DataConnectApiClient', () => { const connectorConfig: ConnectorConfig = { location: 'us-west2', serviceId: 'my-service', + connector: 'my-connector', }; const clientWithoutProjectId = new DataConnectApiClient( @@ -119,48 +121,307 @@ describe('DataConnectApiClient', () => { }); describe('executeGraphql', () => { - it('should reject when project id is not available', () => { - return clientWithoutProjectId.executeGraphql('query', {}) - .should.eventually.be.rejectedWith(noProjectId); + describe('should reject with an appropriate error response on failure', () => { + it('should reject when project id is not available', () => { + return clientWithoutProjectId.executeGraphql('query', {}) + .should.eventually.be.rejectedWith(noProjectId); + }); + + it('should throw an error if query is not a non-empty string', async () => { + await expect(apiClient.executeGraphql('')).to.be.rejectedWith( + FirebaseDataConnectError, + '`query` must be a non-empty string.' + ); + await expect(apiClient.executeGraphql(undefined as any)).to.be.rejectedWith( + FirebaseDataConnectError, + '`query` must be a non-empty string.' + ); + }); + + const invalidQueries = [null, NaN, 0, 1, true, false, [], {}, { a: 1 }, _.noop]; + invalidQueries.forEach((invalidQuery) => { + it('should throw given a non-string query: ' + JSON.stringify(invalidQuery), async () => { + await expect(apiClient.executeGraphql(invalidQuery as any)).to.be.rejectedWith( + FirebaseDataConnectError, + '`query` must be a non-empty string.' + ); + }); + }); + + const invalidOptions = [null, NaN, 0, 1, true, false, [], _.noop]; + invalidOptions.forEach((invalidOption) => { + it('should throw given an invalid options object: ' + JSON.stringify(invalidOption), async () => { + await expect(apiClient.executeGraphql('query', invalidOption as any)).to.be.rejectedWith( + FirebaseDataConnectError, + 'GraphqlOptions must be a non-null object' + ); + }); + }); + + it('should reject when a full platform error response is received', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom(ERROR_RESPONSE, 404)); + const expected = new FirebaseDataConnectError('not-found', 'Requested entity not found'); + return apiClient.executeGraphql('query', {}) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject with unknown-error when error code is not present', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom({}, 404)); + const expected = new FirebaseDataConnectError('unknown-error', 'Unknown server error: {}'); + return apiClient.executeGraphql('query', {}) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject with unknown-error for non-json response', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom('not json', 404)); + const expected = new FirebaseDataConnectError( + 'unknown-error', 'Unexpected response with status: 404 and body: not json'); + return apiClient.executeGraphql('query', {}) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject when rejected with a FirebaseDataConnectError', () => { + const expected = new FirebaseDataConnectError('internal-error', 'socket hang up'); + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(expected); + return apiClient.executeGraphql('query', {}) + .should.eventually.be.rejected.and.deep.include(expected); + }); }); - it('should throw an error if query is not a non-empty string', async () => { - await expect(apiClient.executeGraphql('')).to.be.rejectedWith( - FirebaseDataConnectError, - '`query` must be a non-empty string.' - ); - await expect(apiClient.executeGraphql(undefined as any)).to.be.rejectedWith( - FirebaseDataConnectError, - '`query` must be a non-empty string.' - ); + it('should resolve with the GraphQL response on success', async () => { + interface UsersResponse { + users: [ + user: { + id: string; + name: string; + address: string; + } + ]; + } + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + const resp = await apiClient.executeGraphql('query', {}); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `https://firebasedataconnect.googleapis.com/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, + headers: EXPECTED_HEADERS, + data: { query: 'query' } + }); }); - const invalidQueries = [null, NaN, 0, 1, true, false, [], {}, { a: 1 }, _.noop]; - invalidQueries.forEach((invalidQuery) => { - it('should throw given a non-string query: ' + JSON.stringify(invalidQuery), async () => { - await expect(apiClient.executeGraphql(invalidQuery as any)).to.be.rejectedWith( - FirebaseDataConnectError, - '`query` must be a non-empty string.' + it('should use DATA_CONNECT_EMULATOR_HOST if set', async () => { + process.env.DATA_CONNECT_EMULATOR_HOST = 'localhost:9399'; + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + await apiClient.executeGraphql('query', {}); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `http://localhost:9399/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, + headers: EMULATOR_EXPECTED_HEADERS, + data: { query: 'query' } + }); + }); + }); + + describe('executeQuery', () => { + const unauthenticatedOptions: OperationOptions = { impersonate: { unauthenticated: true } }; + const authenticatedOptions: OperationOptions = { impersonate: { authClaims: { sub: 'authenticated-UUID' } } }; + + describe('should reject with an appropriate error response on failure', () => { + it('should reject when no operationName is provided', () => { + apiClient.executeQuery( '', undefined, unauthenticatedOptions) + .should.eventually.be.rejectedWith('`name` must be a non-empty string.'); + apiClient.executeQuery(undefined as unknown as string, undefined, unauthenticatedOptions) + .should.eventually.be.rejectedWith('`name` must be a non-empty string.'); + }); + + it('should reject when project id is not available', () => { + clientWithoutProjectId.executeQuery( + 'unauthenticated query', + undefined, + unauthenticatedOptions + ).should.eventually.be.rejectedWith(noProjectId); + }); + + it('should reject when no connectorId is provided', () => { + apiClient = new DataConnectApiClient( + { location: connectorConfig.location, serviceId: connectorConfig.serviceId }, + app ); + apiClient.executeQuery('unauthenticated query', undefined, unauthenticatedOptions) + .should.eventually.be.rejectedWith( + `The 'connectorConfig.connector' field used to instantiate your Data Connect + instance must be a non-empty string (the connectorId) when calling executeQuery or executeMutation.`); + }); + + it('should reject when a full platform error response is received', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom(ERROR_RESPONSE, 404)); + const expected = new FirebaseDataConnectError('not-found', 'Requested entity not found'); + return apiClient.executeQuery('unauthenticated query', undefined, unauthenticatedOptions) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject with unknown-error when error code is not present', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom({}, 404)); + const expected = new FirebaseDataConnectError('unknown-error', 'Unknown server error: {}'); + return apiClient.executeQuery('unauthenticated query', undefined, unauthenticatedOptions) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject with unknown-error for non-json response', () => { + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(utils.errorFrom('not json', 404)); + const expected = new FirebaseDataConnectError( + 'unknown-error', 'Unexpected response with status: 404 and body: not json'); + return apiClient.executeQuery('unauthenticated query', undefined, unauthenticatedOptions) + .should.eventually.be.rejected.and.deep.include(expected); + }); + + it('should reject when rejected with a FirebaseDataConnectError', () => { + const expected = new FirebaseDataConnectError('internal-error', 'socket hang up'); + sandbox + .stub(HttpClient.prototype, 'send') + .rejects(expected); + return apiClient.executeQuery('unauthenticated query', undefined, unauthenticatedOptions) + .should.eventually.be.rejected.and.deep.include(expected); }); }); - const invalidOptions = [null, NaN, 0, 1, true, false, [], _.noop]; - invalidOptions.forEach((invalidOption) => { - it('should throw given an invalid options object: ' + JSON.stringify(invalidOption), async () => { - await expect(apiClient.executeGraphql('query', invalidOption as any)).to.be.rejectedWith( - FirebaseDataConnectError, - 'GraphqlOptions must be a non-null object' + describe('should resolve with the GraphQL response on success', () => { + interface UsersResponse { + users: [ + user: { + id: string; + name: string; + address: string; + } + ]; + } + it('for an unauthenticated request', async () => { + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + const resp = await apiClient.executeQuery( + 'unauthenticated query', + undefined, + unauthenticatedOptions + ); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `https://firebasedataconnect.googleapis.com/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}/connectors/${connectorConfig.connector}:impersonateQuery`, + headers: EXPECTED_HEADERS, + data: { + operationName: 'unauthenticated query', + extensions: unauthenticatedOptions + } + }); + }); + + it('for an authenticated request', async () => { + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + const resp = await apiClient.executeQuery( + 'authenticated query', + undefined, + authenticatedOptions ); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `https://firebasedataconnect.googleapis.com/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}/connectors/${connectorConfig.connector}:impersonateQuery`, + headers: EXPECTED_HEADERS, + data: { + operationName: 'authenticated query', + extensions: { impersonate: authenticatedOptions.impersonate } + } + }); + }); + }); + + it('should use DATA_CONNECT_EMULATOR_HOST if set', async () => { + process.env.DATA_CONNECT_EMULATOR_HOST = 'localhost:9399'; + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + await apiClient.executeQuery( + 'unauthenticated query', + undefined, + unauthenticatedOptions + ); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `http://localhost:9399/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}/connectors/${connectorConfig.connector}:impersonateQuery`, + headers: EMULATOR_EXPECTED_HEADERS, + data: { + operationName: 'unauthenticated query', + extensions: unauthenticatedOptions + } }); }); + }); + + const unauthenticatedOptions: OperationOptions = + { impersonate: { unauthenticated: true } }; + const authenticatedOptions: OperationOptions = + { impersonate: { authClaims: { sub: 'authenticated-UUID' } } }; + + describe('executeMutation', () => { + it('should reject when no operationName is provided', () => { + apiClient.executeMutation('', undefined, unauthenticatedOptions) + .should.eventually.be.rejectedWith('`name` must be a non-empty string.'); + apiClient.executeMutation(undefined as unknown as string, undefined, unauthenticatedOptions) + .should.eventually.be.rejectedWith('`name` must be a non-empty string.'); + }); + + it('should reject when project id is not available', () => { + clientWithoutProjectId.executeMutation('unauthenticated mutation', undefined, unauthenticatedOptions) + .should.eventually.be.rejectedWith(noProjectId); + }); + + it('should reject when no connectorId is provided', () => { + apiClient = new DataConnectApiClient( + { location: connectorConfig.location, serviceId: connectorConfig.serviceId }, + app + ); + apiClient.executeMutation('unauthenticated mutation', undefined, unauthenticatedOptions) + .should.eventually.be.rejectedWith( + `The 'connectorConfig.connector' field used to instantiate your Data Connect + instance must be a non-empty string (the connectorId) when calling executeQuery or executeMutation.`); + }); it('should reject when a full platform error response is received', () => { sandbox .stub(HttpClient.prototype, 'send') .rejects(utils.errorFrom(ERROR_RESPONSE, 404)); const expected = new FirebaseDataConnectError('not-found', 'Requested entity not found'); - return apiClient.executeGraphql('query', {}) + return apiClient.executeMutation('unauthenticated mutation', undefined, unauthenticatedOptions) .should.eventually.be.rejected.and.deep.include(expected); }); @@ -169,7 +430,7 @@ describe('DataConnectApiClient', () => { .stub(HttpClient.prototype, 'send') .rejects(utils.errorFrom({}, 404)); const expected = new FirebaseDataConnectError('unknown-error', 'Unknown server error: {}'); - return apiClient.executeGraphql('query', {}) + return apiClient.executeMutation('unauthenticated mutation', undefined, unauthenticatedOptions) .should.eventually.be.rejected.and.deep.include(expected); }); @@ -179,7 +440,7 @@ describe('DataConnectApiClient', () => { .rejects(utils.errorFrom('not json', 404)); const expected = new FirebaseDataConnectError( 'unknown-error', 'Unexpected response with status: 404 and body: not json'); - return apiClient.executeGraphql('query', {}) + return apiClient.executeMutation('unauthenticated mutation', undefined, unauthenticatedOptions) .should.eventually.be.rejected.and.deep.include(expected); }); @@ -188,11 +449,11 @@ describe('DataConnectApiClient', () => { sandbox .stub(HttpClient.prototype, 'send') .rejects(expected); - return apiClient.executeGraphql('query', {}) + return apiClient.executeMutation('unauthenticated mutation', undefined, unauthenticatedOptions) .should.eventually.be.rejected.and.deep.include(expected); }); - it('should resolve with the GraphQL response on success', () => { + describe('should resolve with the GraphQL response on success', () => { interface UsersResponse { users: [ user: { @@ -202,38 +463,67 @@ describe('DataConnectApiClient', () => { } ]; } - const stub = sandbox - .stub(HttpClient.prototype, 'send') - .resolves(utils.responseFrom(TEST_RESPONSE, 200)); - return apiClient.executeGraphql('query', {}) - .then((resp) => { - expect(resp.data.users).to.be.not.empty; - expect(resp.data.users[0].name).to.be.not.undefined; - expect(resp.data.users[0].address).to.be.not.undefined; - expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); - expect(stub).to.have.been.calledOnce.and.calledWith({ - method: 'POST', - url: `https://firebasedataconnect.googleapis.com/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, - headers: EXPECTED_HEADERS, - data: { query: 'query' } - }); + + it('for an unauthenticated request', async () => { + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + const resp = await apiClient.executeMutation( + 'unauthenticated mutation', undefined, unauthenticatedOptions + ) + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `https://firebasedataconnect.googleapis.com/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}/connectors/${connectorConfig.connector}:impersonateMutation`, + headers: EXPECTED_HEADERS, + data: { + operationName: 'unauthenticated mutation', + extensions: unauthenticatedOptions + } + }); + }); + + it('for an authenticated request', async () => { + const stub = sandbox + .stub(HttpClient.prototype, 'send') + .resolves(utils.responseFrom(TEST_RESPONSE, 200)); + const resp = await apiClient.executeMutation( + 'authenticated mutation', undefined, authenticatedOptions + ); + expect(resp.data.users).to.be.not.empty; + expect(resp.data.users[0].name).to.be.not.undefined; + expect(resp.data.users[0].address).to.be.not.undefined; + expect(resp.data.users).to.deep.equal(TEST_RESPONSE.data.users); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `https://firebasedataconnect.googleapis.com/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}/connectors/${connectorConfig.connector}:impersonateMutation`, + headers: EXPECTED_HEADERS, + data: { + operationName: 'authenticated mutation', + extensions: authenticatedOptions + } }); + }); }); - it('should use DATA_CONNECT_EMULATOR_HOST if set', () => { + it('should use DATA_CONNECT_EMULATOR_HOST if set', async () => { process.env.DATA_CONNECT_EMULATOR_HOST = 'localhost:9399'; const stub = sandbox .stub(HttpClient.prototype, 'send') .resolves(utils.responseFrom(TEST_RESPONSE, 200)); - return apiClient.executeGraphql('query', {}) - .then(() => { - expect(stub).to.have.been.calledOnce.and.calledWith({ - method: 'POST', - url: `http://localhost:9399/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}:executeGraphql`, - headers: EMULATOR_EXPECTED_HEADERS, - data: { query: 'query' } - }); - }); + await apiClient.executeMutation('unauthenticated mutation', undefined, unauthenticatedOptions); + expect(stub).to.have.been.calledOnce.and.calledWith({ + method: 'POST', + url: `http://localhost:9399/v1/projects/test-project/locations/${connectorConfig.location}/services/${connectorConfig.serviceId}/connectors/${connectorConfig.connector}:impersonateMutation`, + headers: EMULATOR_EXPECTED_HEADERS, + data: { + operationName: 'unauthenticated mutation', + extensions: unauthenticatedOptions + } + }); }); it('should use gen headers if set on success', () => { interface UsersResponse { @@ -276,6 +566,7 @@ describe('DataConnectApiClient CRUD helpers', () => { const connectorConfig: ConnectorConfig = { location: 'us-west1', serviceId: 'my-crud-service', + connector: 'my-crud-connector', }; const mockOptions = { @@ -349,9 +640,9 @@ describe('DataConnectApiClient CRUD helpers', () => { const expectedMutation = ` mutation { ${formatedTableName}_insert(data: { - name: "test", - value: 123 - }) + name: "test", + value: 123 + }) }`; await apiClient.insert(tableName, simpleData); expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); @@ -362,9 +653,9 @@ describe('DataConnectApiClient CRUD helpers', () => { const expectedMutation = ` mutation { ${formatedTableName}_insert(data: { - id: "abc", active: true, scores: [10, 20], - info: { nested: "yes/no \\"quote\\" \\\\slash\\\\" } - }) + id: "abc", active: true, scores: [10, 20], + info: { nested: "yes/no \\"quote\\" \\\\slash\\\\" } + }) }`; await apiClient.insert(tableName, complexData); expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); @@ -374,12 +665,12 @@ describe('DataConnectApiClient CRUD helpers', () => { const expectedMutation = ` mutation { ${formatedTableName}_insert(data: { - genre: "Action", - title: "Die Hard", - ratings: null, - director: {}, - extras: [1, null, "hello", null, { a: 1 }] - }) + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] + }) }`; await apiClient.insert(tableName, dataWithUndefined); expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); @@ -435,7 +726,7 @@ describe('DataConnectApiClient CRUD helpers', () => { mutation { ${formatedTableName}_insertMany(data: [{ id: "a", active: true, info: { nested: "n1 \\"quote\\"" } }, { id: "b", scores: [1, 2], - info: { nested: "n2/\\\\" } }]) }`; + info: { nested: "n2/\\\\" } }]) }`; await apiClient.insertMany(tableName, complexDataArray); expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); }); @@ -448,18 +739,18 @@ describe('DataConnectApiClient CRUD helpers', () => { const expectedMutation = ` mutation { ${formatedTableName}_insertMany(data: [{ - genre: "Action", - title: "Die Hard", - ratings: null, - director: {}, - extras: [1, null, "hello", null, { a: 1 }] + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] }, { - genre: "Action", - title: "Die Hard", - ratings: null, - director: {}, - extras: [1, null, "hello", null, { a: 1 }] + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] }]) }`; await apiClient.insertMany(tableName, dataArray); @@ -523,12 +814,12 @@ describe('DataConnectApiClient CRUD helpers', () => { const expectedMutation = ` mutation { ${formatedTableName}_upsert(data: { - genre: "Action", - title: "Die Hard", - ratings: null, - director: {}, - extras: [1, null, "hello", null, { a: 1 }] - }) + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] + }) }`; await apiClient.upsert(tableName, dataWithUndefined); expect(executeGraphqlStub).to.have.been.calledOnceWithExactly(normalizeGraphQLString(expectedMutation)); @@ -594,18 +885,18 @@ describe('DataConnectApiClient CRUD helpers', () => { const expectedMutation = ` mutation { ${formatedTableName}_upsertMany(data: [{ - genre: "Action", - title: "Die Hard", - ratings: null, - director: {}, - extras: [1, null, "hello", null, { a: 1 }] + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] }, { - genre: "Action", - title: "Die Hard", - ratings: null, - director: {}, - extras: [1, null, "hello", null, { a: 1 }] + genre: "Action", + title: "Die Hard", + ratings: null, + director: {}, + extras: [1, null, "hello", null, { a: 1 }] }]) }`; await apiClient.upsertMany(tableName, dataArray); diff --git a/test/unit/data-connect/data-connect.spec.ts b/test/unit/data-connect/data-connect.spec.ts new file mode 100644 index 0000000000..992d1c3861 --- /dev/null +++ b/test/unit/data-connect/data-connect.spec.ts @@ -0,0 +1,226 @@ +import * as sinon from 'sinon'; +import * as mocks from '../../resources/mocks'; +import { ConnectorConfig, DataConnect, getDataConnect, OperationOptions } from '../../../src/data-connect'; +import { expect } from 'chai'; +import { DataConnectApiClient } from '../../../src/data-connect/data-connect-api-client-internal'; +import { FirebaseApp } from '../../../src/app/firebase-app'; +import * as appIndex from '../../../src/app/lifecycle'; + +describe('DataConnect', () => { + const mockOptions = { + credential: new mocks.MockCredential(), + projectId: 'test-project', + }; + const connectorConfig: ConnectorConfig = { + location: 'us-west2', + serviceId: 'my-service', + connector: 'my-connector', + }; + let mockApp: FirebaseApp; + let dc: DataConnect; + + interface RequiredVariables { + limit: number; + } + + type OptionalVariables = Partial | undefined; + + interface Data { + data: number; + } + + const operationName = 'operation'; + const requiredVariables: RequiredVariables = { limit: 1 }; + const optionalVariables: OptionalVariables = { limit: 2 }; + const options: OperationOptions = { impersonate: { unauthenticated: true } }; + const data: Data = { data: 99 }; + + let executeQueryStub: sinon.SinonStub; + let executeMutationStub: sinon.SinonStub; + let getAppStub: sinon.SinonStub; + + beforeEach(() => { + mockApp = mocks.appWithOptions(mockOptions); + getAppStub = sinon.stub(appIndex, 'getApp').returns(mockApp); + executeQueryStub = sinon + .stub(DataConnectApiClient.prototype, 'executeQuery') + .resolves(data); + executeMutationStub = sinon + .stub(DataConnectApiClient.prototype, 'executeMutation') + .resolves(data); + dc = getDataConnect(connectorConfig); + }); + + afterEach(() => { + executeQueryStub.restore(); + executeMutationStub.restore(); + getAppStub.restore(); + return mockApp.delete(); + }); + + describe('executeQuery()', () => { + describe('should handle method and argument overload correctly', async () => { + describe('with required variables', () => { + describe('with a Variable type parameter provided', () => { + describe('with variables provided', () => { + it('with options provided', async () => { + await dc.executeQuery(operationName, requiredVariables, options); + expect(executeQueryStub.calledOnceWithExactly(operationName, requiredVariables, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeQuery(operationName, requiredVariables); + expect(executeQueryStub.calledOnceWithExactly(operationName, requiredVariables, undefined)).to.be.true; + }); + }); + }); + + describe('WITHOUT a Variable type parameter provided', () => { + describe('with variables provided', () => { + it('with options provided', async () => { + await dc.executeQuery(operationName, requiredVariables, options); + expect(executeQueryStub.calledOnceWithExactly(operationName, requiredVariables, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeQuery(operationName, requiredVariables); + expect(executeQueryStub.calledOnceWithExactly(operationName, requiredVariables, undefined)).to.be.true; + }); + }); + }); + }); + + describe('with optional variables', () => { + describe('with a Variable type parameter provided', () => { + describe('with variables provided', () => { + it('with options provided', async () => { + await dc.executeQuery(operationName, optionalVariables, options); + expect(executeQueryStub.calledOnceWithExactly(operationName, optionalVariables, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeQuery(operationName, optionalVariables); + expect(executeQueryStub.calledOnceWithExactly(operationName, optionalVariables, undefined)).to.be.true; + }); + }); + + describe('WITHOUT variables provided', () => { + it('with options provided', async () => { + await dc.executeQuery(operationName, undefined, options); + expect(executeQueryStub.calledOnceWithExactly(operationName, undefined, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeQuery(operationName, undefined); + expect(executeQueryStub.calledOnceWithExactly(operationName, undefined, undefined)).to.be.true; + }); + }); + }); + + describe('WITHOUT a Variable type parameter provided', () => { + describe('with variables provided', async () => { + it('with options provided', async () => { + await dc.executeQuery(operationName, optionalVariables, options); + expect(executeQueryStub.calledOnceWithExactly(operationName, optionalVariables, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeQuery(operationName, optionalVariables); + expect(executeQueryStub.calledOnceWithExactly(operationName, optionalVariables, undefined)).to.be.true; + }); + }); + + describe('WITHOUT variables provided', async () => { + it('WITHOUT options provided', async () => { + await dc.executeQuery(operationName); + expect(executeQueryStub.calledOnceWithExactly(operationName, undefined, undefined)).to.be.true; + }); + }); + }); + }); + }); + }); + + describe('executeMutation()', () => { + describe('should handle method and argument overload correctly', async () => { + describe('with required variables', () => { + describe('with a Variable type parameter provided', () => { + describe('with variables provided', () => { + it('with options provided', async () => { + await dc.executeMutation(operationName, requiredVariables, options); + expect(executeMutationStub.calledOnceWithExactly(operationName, requiredVariables, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeMutation(operationName, requiredVariables); + expect(executeMutationStub.calledOnceWithExactly(operationName, requiredVariables, undefined)).to.be.true; + }); + }); + }); + + describe('WITHOUT a Variable type parameter provided', () => { + describe('with variables provided', () => { + it('with options provided', async () => { + await dc.executeMutation(operationName, requiredVariables, options); + expect(executeMutationStub.calledOnceWithExactly(operationName, requiredVariables, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeMutation(operationName, requiredVariables); + expect(executeMutationStub.calledOnceWithExactly(operationName, requiredVariables, undefined)).to.be.true; + }); + }); + }); + }); + + describe('with optional variables', () => { + describe('with a Variable type parameter provided', () => { + describe('with variables provided', () => { + it('with options provided', async () => { + await dc.executeMutation(operationName, optionalVariables, options); + expect(executeMutationStub.calledOnceWithExactly(operationName, optionalVariables, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeMutation(operationName, optionalVariables); + expect(executeMutationStub.calledOnceWithExactly(operationName, optionalVariables, undefined)).to.be.true; + }); + }); + + describe('WITHOUT variables provided', () => { + it('with options provided', async () => { + await dc.executeMutation(operationName, undefined, options); + expect(executeMutationStub.calledOnceWithExactly(operationName, undefined, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeMutation(operationName, undefined); + expect(executeMutationStub.calledOnceWithExactly(operationName, undefined, undefined)).to.be.true; + }); + }); + }); + + describe('WITHOUT a Variable type parameter provided', () => { + describe('with variables provided', async () => { + it('with options provided', async () => { + await dc.executeMutation(operationName, optionalVariables, options); + expect(executeMutationStub.calledOnceWithExactly(operationName, optionalVariables, options)).to.be.true; + }); + + it('WITHOUT options provided', async () => { + await dc.executeMutation(operationName, optionalVariables); + expect(executeMutationStub.calledOnceWithExactly(operationName, optionalVariables, undefined)).to.be.true; + }); + }); + + describe('WITHOUT variables provided', async () => { + it('WITHOUT options provided', async () => { + await dc.executeMutation(operationName); + expect(executeMutationStub.calledOnceWithExactly(operationName, undefined, undefined)).to.be.true; + }); + }); + }); + }); + }); + }); +}); diff --git a/test/unit/data-connect/validate-admin-args.spec.ts b/test/unit/data-connect/validate-admin-args.spec.ts new file mode 100644 index 0000000000..0d940d5144 --- /dev/null +++ b/test/unit/data-connect/validate-admin-args.spec.ts @@ -0,0 +1,271 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import { ConnectorConfig, validateAdminArgs } from '../../../src/data-connect'; +import { DataConnect } from '../../../src/data-connect/data-connect'; +import { OperationOptions } from '../../../src/data-connect'; +import { + DATA_CONNECT_ERROR_CODE_MAPPING, + FirebaseDataConnectError +} from '../../../src/data-connect/data-connect-api-client-internal'; +import * as dataConnectIndex from '../../../src/data-connect/index'; + +interface IdVars { + id: string +} + +describe('validateAdminArgs()', () => { + let getDataConnectStub: sinon.SinonStub; + + const connectorConfig: ConnectorConfig = { + location: 'us-west2', + serviceId: 'my-service', + connector: 'my-connector', + }; + + const providedDcInstance = { connectorConfig: connectorConfig, source: 'PROVIDED' } as unknown as DataConnect; + const variables: IdVars = { id: 'stephenarosaj' }; + const options: OperationOptions = { impersonate: { unauthenticated: true } }; + + const invalidVariablesError = new FirebaseDataConnectError( + DATA_CONNECT_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'Variables required.' + ); + + const stubDcInstance = { connectorConfig: connectorConfig, source: 'STUB' } as unknown as DataConnect; + beforeEach(() => { + getDataConnectStub = sinon.stub(dataConnectIndex, 'getDataConnect').returns(stubDcInstance); + }); + + afterEach(() => { + getDataConnectStub.restore(); + }); + + describe('with no variadic args', () => { + it('should call getDataConnect to generate a DataConnect instance', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs(connectorConfig); + expect(getDataConnectStub.calledOnce).to.be.true; + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.be.undefined; + }); + }); + + describe('with one variadic arg', () => { + it('should successfully parse the provided DataConnect', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.be.undefined; + }); + + it('should successfully parse the provided options', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, options + ); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.deep.equal(options); + }); + }); + + describe('with two variadic args', () => { + it('should successfully parse the provided DataConnect instance and options', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance, options + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.deep.equal(options); + }); + }); + + describe('with four variadic args and hasVars = true', () => { + describe('and the first argument is a DataConnect instance', () => { + it('and variables and options are undefined', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance, undefined, undefined, true + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.be.undefined; + }); + + it('and variables are provided, options undefined', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance, variables, undefined, true + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; + }); + + it('and options are provided, variables undefined', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance, undefined, options, true + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.deep.be.undefined; + expect(inputOpts).to.deep.equal(options); + }); + + it('and variables and options are provided', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance, variables, options, true + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.deep.equal(options); + }); + }); + + describe('and the first argument is variables', () => { + it('and variables and options are undefined', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, undefined, undefined, undefined, true + ); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.be.undefined; + }); + + it('and variables are provided, options undefined', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, variables, undefined, undefined, true + ); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; + }); + + it('and options are provided, variables undefined', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, undefined, options, undefined, true + ); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.deep.be.undefined; + expect(inputOpts).to.deep.equal(options); + }); + + it('and variables and options are provided', () => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, variables, options, undefined, true + ); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.deep.equal(options); + }); + }); + }); + + describe('with five variadic args', () => { + describe('and validateVars = true', () => { + describe('should succeed if vars WERE provided', () => { + it('and the first argument is a DataConnect instance', () => { + expect(() => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance, variables, undefined, true, true + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; + }).to.not.throw(invalidVariablesError); + }); + + it('and the first argument is variables instance', () => { + expect(() => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, variables, undefined, undefined, true, true + ); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; + }).to.not.throw(invalidVariablesError); + }); + }); + + describe('should throw if vars were NOT provided', () => { + it('and the first argument is a DataConnect instance', () => { + expect(() => { + validateAdminArgs(connectorConfig, providedDcInstance, undefined, undefined, true, true); + }).to.throw().and.have.property('code', invalidVariablesError.code); + }); + + it('and the first argument is undefined variables', () => { + expect(() => { + validateAdminArgs(connectorConfig, undefined, undefined, undefined, true, true); + }).to.throw().and.have.property('code', invalidVariablesError.code); + }); + }); + }); + + describe('and validateVars = false', () => { + describe('should succeed if vars WERE provided', () => { + it('and the first argument is a DataConnect instance', () => { + expect(() => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance, variables, undefined, true, false + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.be.undefined; + }).to.not.throw(invalidVariablesError); + }); + + it('and the first argument is variables instance', () => { + expect(() => { + validateAdminArgs(connectorConfig, variables, undefined, undefined, true, false); + }).to.not.throw(invalidVariablesError); + + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, variables, undefined, undefined, true, false + ); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; + }); + }); + + describe('should succeed if vars were NOT provided', () => { + it('and the first argument is a DataConnect instance', () => { + expect(() => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, providedDcInstance, undefined, undefined, true, false + ); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; + }).to.not.throw(invalidVariablesError); + }); + + it('and the first argument is undefined variables', () => { + expect(() => { + const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + connectorConfig, undefined, undefined, undefined, true, false + ); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.be.undefined; + }).to.not.throw(invalidVariablesError); + }); + }); + }); + }); +}); diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index c75bf0dc8b..39ae51fd9f 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -121,3 +121,5 @@ import './extensions/extensions-api-client-internal.spec'; // Data Connect import './data-connect/index.spec'; import './data-connect/data-connect-api-client-internal.spec'; +import './data-connect/data-connect.spec'; +import './data-connect/validate-admin-args.spec'; From 48c8ca6552efeb636a9eef9ca91e8ab3c50229e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 09:57:43 -0500 Subject: [PATCH 276/323] build(deps): bump @firebase/database-compat from 2.0.6 to 2.1.0 (#3002) Bumps [@firebase/database-compat](https://github.com/firebase/firebase-js-sdk/tree/HEAD/packages/database-compat) from 2.0.6 to 2.1.0. - [Release notes](https://github.com/firebase/firebase-js-sdk/releases) - [Changelog](https://github.com/firebase/firebase-js-sdk/blob/main/packages/database-compat/CHANGELOG.md) - [Commits](https://github.com/firebase/firebase-js-sdk/commits/@firebase/database-compat@2.1.0/packages/database-compat) --- updated-dependencies: - dependency-name: "@firebase/database-compat" dependency-version: 2.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 104 ++++++++++++++-------------------------------- 1 file changed, 31 insertions(+), 73 deletions(-) diff --git a/package-lock.json b/package-lock.json index f2229fb9be..dd5838d0ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -708,7 +708,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", - "dev": true, "dependencies": { "@firebase/util": "1.13.0", "tslib": "^2.1.0" @@ -718,119 +717,79 @@ } }, "node_modules/@firebase/database": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.15.tgz", - "integrity": "sha512-xmeTqKoIB2u1AXvLc1jq3Val0QAHUr49YycAr6feoDD7zM9dCjSk8rq9s1ESTv+tbbqS2BRoTpjIvxwXRTKhQQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.0.tgz", + "integrity": "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.6.14", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.11.1", + "@firebase/component": "0.7.0", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", "faye-websocket": "0.11.4", "tslib": "^2.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@firebase/database-compat": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.6.tgz", - "integrity": "sha512-vv15b1E59sLwoVdjGKvJ75ok9Qu1VRJC/7KXAQGnXvURAL199Ndy1YEw6/GA9twoFlLCYnd2ltxxB2pPiL1Vqw==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/component": "0.6.14", - "@firebase/database": "1.0.15", - "@firebase/database-types": "1.0.11", - "@firebase/logger": "0.4.4", - "@firebase/util": "1.11.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database-compat/node_modules/@firebase/component": { - "version": "0.6.14", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.14.tgz", - "integrity": "sha512-kf/zAT8GQJ9nYoHuj0mv7twp1QzifKYrO+GsmsVHHM+Hi9KkmI7E3B3J0CtihHpb34vinl4gbJrYJ2p2wfvc9A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.0.tgz", + "integrity": "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==", "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.11.1", + "@firebase/component": "0.7.0", + "@firebase/database": "1.1.0", + "@firebase/database-types": "1.0.16", + "@firebase/logger": "0.5.0", + "@firebase/util": "1.13.0", "tslib": "^2.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, - "node_modules/@firebase/database-compat/node_modules/@firebase/util": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.1.tgz", - "integrity": "sha512-RXg4WE8C2LUrvoV/TMGRTu223zZf9Dq9MR8yHZio9nF9TpLnpCPURw9VWWB2WATDl6HfIdWfl2x2SJYtHkN4hw==", - "hasInstallScript": true, + "node_modules/@firebase/database-compat/node_modules/@firebase/logger": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", + "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@firebase/database-types": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.11.tgz", - "integrity": "sha512-LBZG/nT6GbntbIdGxBNvu9PBtj4xUEE9wX8AFF6njFK/MufYBESiKqT+jhDwmbcM4zAha9U0Pcca8FvJ1z1bYw==", + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.16.tgz", + "integrity": "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==", "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.3", - "@firebase/util": "1.11.1" - } - }, - "node_modules/@firebase/database-types/node_modules/@firebase/util": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.1.tgz", - "integrity": "sha512-RXg4WE8C2LUrvoV/TMGRTu223zZf9Dq9MR8yHZio9nF9TpLnpCPURw9VWWB2WATDl6HfIdWfl2x2SJYtHkN4hw==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@firebase/database/node_modules/@firebase/component": { - "version": "0.6.14", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.14.tgz", - "integrity": "sha512-kf/zAT8GQJ9nYoHuj0mv7twp1QzifKYrO+GsmsVHHM+Hi9KkmI7E3B3J0CtihHpb34vinl4gbJrYJ2p2wfvc9A==", - "license": "Apache-2.0", - "dependencies": { - "@firebase/util": "1.11.1", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" + "@firebase/util": "1.13.0" } }, - "node_modules/@firebase/database/node_modules/@firebase/util": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.1.tgz", - "integrity": "sha512-RXg4WE8C2LUrvoV/TMGRTu223zZf9Dq9MR8yHZio9nF9TpLnpCPURw9VWWB2WATDl6HfIdWfl2x2SJYtHkN4hw==", - "hasInstallScript": true, + "node_modules/@firebase/database/node_modules/@firebase/logger": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", + "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@firebase/logger": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "dev": true, "dependencies": { "tslib": "^2.1.0" }, @@ -842,7 +801,6 @@ "version": "1.13.0", "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", - "dev": true, "hasInstallScript": true, "dependencies": { "tslib": "^2.1.0" From ad7a4f3efced00de5ee1f81556467b35324e8c1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 15:02:28 +0000 Subject: [PATCH 277/323] build(deps-dev): bump gulp from 5.0.0 to 5.0.1 (#3001) --- package-lock.json | 130 +++++++++++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd5838d0ba..3826e45eb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3209,6 +3209,21 @@ "dev": true, "license": "MIT" }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, "node_modules/bach": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", @@ -3232,12 +3247,19 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", - "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.1.tgz", + "integrity": "sha512-oxSAxTS1hRfnyit2CL5QpAOS5ixfBjj6ex3yTNvXyY/kE719jQ/IjuESJBK2w5v4wwQRAHGseVJXx9QBYOtFGQ==", "dev": true, "license": "Apache-2.0", - "optional": true + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } }, "node_modules/base64-js": { "version": "1.5.1", @@ -4767,6 +4789,16 @@ "node": ">=6" } }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -5651,9 +5683,9 @@ } }, "node_modules/glob-stream": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", - "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.3.tgz", + "integrity": "sha512-fqZVj22LtFJkHODT+M4N1RJQ3TjnnQhfE9GwZI8qXscYarnhpip70poMldRnP8ipQ/w0B621kOhfc53/J9bd/A==", "dev": true, "license": "MIT", "dependencies": { @@ -5912,16 +5944,16 @@ } }, "node_modules/gulp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz", - "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.1.tgz", + "integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==", "dev": true, "license": "MIT", "dependencies": { "glob-watcher": "^6.0.0", - "gulp-cli": "^3.0.0", + "gulp-cli": "^3.1.0", "undertaker": "^2.0.0", - "vinyl-fs": "^4.0.0" + "vinyl-fs": "^4.0.2" }, "bin": { "gulp": "bin/gulp.js" @@ -5931,9 +5963,9 @@ } }, "node_modules/gulp-cli": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", - "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.1.0.tgz", + "integrity": "sha512-zZzwlmEsTfXcxRKiCHsdyjZZnFvXWM4v1NqBJSYbuApkvVKivjcmOS2qruAJ+PkEHLFavcDKH40DPc1+t12a9Q==", "dev": true, "license": "MIT", "dependencies": { @@ -5942,7 +5974,7 @@ "copy-props": "^4.0.0", "gulplog": "^2.2.0", "interpret": "^3.1.1", - "liftoff": "^5.0.0", + "liftoff": "^5.0.1", "mute-stdout": "^2.0.0", "replace-homedir": "^2.0.0", "semver-greatest-satisfied-range": "^2.0.0", @@ -7893,9 +7925,9 @@ } }, "node_modules/liftoff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", - "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.1.tgz", + "integrity": "sha512-wwLXMbuxSF8gMvubFcFRp56lkFV69twvbU5vDPbaw+Q+/rF8j0HKjGbIdlSi+LuJm9jf7k9PB+nTxnsLMPcv2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -9896,13 +9928,6 @@ ], "license": "MIT" }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true, - "license": "MIT" - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -11065,18 +11090,15 @@ } }, "node_modules/streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", "dev": true, "license": "MIT", "dependencies": { + "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" } }, "node_modules/string_decoder": { @@ -11430,11 +11452,14 @@ } }, "node_modules/text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } }, "node_modules/text-table": { "version": "0.2.0", @@ -12090,14 +12115,13 @@ } }, "node_modules/vinyl-contents/node_modules/vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", + "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", "dev": true, "license": "MIT", "dependencies": { "clone": "^2.1.2", - "clone-stats": "^1.0.0", "remove-trailing-separator": "^1.1.0", "replace-ext": "^2.0.0", "teex": "^1.0.1" @@ -12107,14 +12131,14 @@ } }, "node_modules/vinyl-fs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", - "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.2.tgz", + "integrity": "sha512-XRFwBLLTl8lRAOYiBqxY279wY46tVxLaRhSwo3GzKEuLz1giffsOquWWboD/haGf5lx+JyTigCFfe7DWHoARIA==", "dev": true, "license": "MIT", "dependencies": { "fs-mkdirp-stream": "^2.0.1", - "glob-stream": "^8.0.0", + "glob-stream": "^8.0.3", "graceful-fs": "^4.2.11", "iconv-lite": "^0.6.3", "is-valid-glob": "^1.0.0", @@ -12125,7 +12149,7 @@ "streamx": "^2.14.0", "to-through": "^3.0.0", "value-or-function": "^4.0.0", - "vinyl": "^3.0.0", + "vinyl": "^3.0.1", "vinyl-sourcemap": "^2.0.0" }, "engines": { @@ -12143,14 +12167,13 @@ } }, "node_modules/vinyl-fs/node_modules/vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", + "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", "dev": true, "license": "MIT", "dependencies": { "clone": "^2.1.2", - "clone-stats": "^1.0.0", "remove-trailing-separator": "^1.1.0", "replace-ext": "^2.0.0", "teex": "^1.0.1" @@ -12195,14 +12218,13 @@ } }, "node_modules/vinyl-sourcemap/node_modules/vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", + "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", "dev": true, "license": "MIT", "dependencies": { "clone": "^2.1.2", - "clone-stats": "^1.0.0", "remove-trailing-separator": "^1.1.0", "replace-ext": "^2.0.0", "teex": "^1.0.1" From 2e2b36a84ba28679bcb7aecdacabfec0bded2d48 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 5 Nov 2025 09:59:05 -0500 Subject: [PATCH 278/323] [chore] Release 13.6.0 (#3006) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de6e640c84..721ff00c9f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.5.0", + "version": "13.6.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From a92b67702926fa0912583bb2b7d6beca1b825648 Mon Sep 17 00:00:00 2001 From: Stephen Rosa <84193009+stephenarosaj@users.noreply.github.com> Date: Tue, 11 Nov 2025 09:53:48 -0800 Subject: [PATCH 279/323] fix validate unit tests (#3009) - no behavior changes, just fixing some bad testing patterns --- .../data-connect/validate-admin-args.spec.ts | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/test/unit/data-connect/validate-admin-args.spec.ts b/test/unit/data-connect/validate-admin-args.spec.ts index 0d940d5144..7c60718838 100644 --- a/test/unit/data-connect/validate-admin-args.spec.ts +++ b/test/unit/data-connect/validate-admin-args.spec.ts @@ -179,25 +179,33 @@ describe('validateAdminArgs()', () => { describe('and validateVars = true', () => { describe('should succeed if vars WERE provided', () => { it('and the first argument is a DataConnect instance', () => { + let dcInstance, inputVars, inputOpts; expect(() => { - const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + const parsedArgs = validateAdminArgs( connectorConfig, providedDcInstance, variables, undefined, true, true ); - expect(dcInstance).to.deep.equal(providedDcInstance); - expect(inputVars).to.deep.equal(variables); - expect(inputOpts).to.be.undefined; - }).to.not.throw(invalidVariablesError); + dcInstance = parsedArgs.dc; + inputVars = parsedArgs.vars; + inputOpts = parsedArgs.options; + }).to.not.throw(invalidVariablesError); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; }); it('and the first argument is variables instance', () => { + let dcInstance, inputVars, inputOpts; expect(() => { - const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + const parsedArgs = validateAdminArgs( connectorConfig, variables, undefined, undefined, true, true ); - expect(dcInstance).to.deep.equal(stubDcInstance); - expect(inputVars).to.deep.equal(variables); - expect(inputOpts).to.be.undefined; + dcInstance = parsedArgs.dc; + inputVars = parsedArgs.vars; + inputOpts = parsedArgs.options; }).to.not.throw(invalidVariablesError); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; }); }); @@ -219,14 +227,18 @@ describe('validateAdminArgs()', () => { describe('and validateVars = false', () => { describe('should succeed if vars WERE provided', () => { it('and the first argument is a DataConnect instance', () => { + let dcInstance, inputVars, inputOpts; expect(() => { - const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + const parsedArgs = validateAdminArgs( connectorConfig, providedDcInstance, variables, undefined, true, false ); - expect(dcInstance).to.deep.equal(providedDcInstance); - expect(inputVars).to.be.undefined; - expect(inputOpts).to.be.undefined; + dcInstance = parsedArgs.dc; + inputVars = parsedArgs.vars; + inputOpts = parsedArgs.options; }).to.not.throw(invalidVariablesError); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.deep.equal(variables); + expect(inputOpts).to.be.undefined; }); it('and the first argument is variables instance', () => { @@ -245,25 +257,33 @@ describe('validateAdminArgs()', () => { describe('should succeed if vars were NOT provided', () => { it('and the first argument is a DataConnect instance', () => { + let dcInstance, inputVars, inputOpts; expect(() => { - const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + const parsedArgs = validateAdminArgs( connectorConfig, providedDcInstance, undefined, undefined, true, false ); - expect(dcInstance).to.deep.equal(providedDcInstance); - expect(inputVars).to.deep.equal(variables); - expect(inputOpts).to.be.undefined; + dcInstance = parsedArgs.dc; + inputVars = parsedArgs.vars; + inputOpts = parsedArgs.options; }).to.not.throw(invalidVariablesError); + expect(dcInstance).to.deep.equal(providedDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.be.undefined; }); it('and the first argument is undefined variables', () => { + let dcInstance, inputVars, inputOpts; expect(() => { - const { dc: dcInstance, vars: inputVars, options: inputOpts } = validateAdminArgs( + const parsedArgs = validateAdminArgs( connectorConfig, undefined, undefined, undefined, true, false ); - expect(dcInstance).to.deep.equal(stubDcInstance); - expect(inputVars).to.be.undefined; - expect(inputOpts).to.be.undefined; + dcInstance = parsedArgs.dc; + inputVars = parsedArgs.vars; + inputOpts = parsedArgs.options; }).to.not.throw(invalidVariablesError); + expect(dcInstance).to.deep.equal(stubDcInstance); + expect(inputVars).to.be.undefined; + expect(inputOpts).to.be.undefined; }); }); }); From ce9de63d6e5f211d10781e26decc8f331cd61742 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:10:41 +0000 Subject: [PATCH 280/323] build(deps-dev): bump bcrypt and @types/bcrypt (#3015) --- package-lock.json | 311 +++++----------------------------------------- package.json | 4 +- 2 files changed, 36 insertions(+), 279 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3826e45eb1..1c7ecd4f9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.5.0", + "version": "13.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.5.0", + "version": "13.6.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -27,7 +27,7 @@ "@firebase/auth-compat": "^0.6.0", "@firebase/auth-types": "^0.13.0", "@microsoft/api-extractor": "^7.11.2", - "@types/bcrypt": "^5.0.0", + "@types/bcrypt": "^6.0.0", "@types/chai": "^4.0.0", "@types/chai-as-promised": "^7.1.0", "@types/firebase-token-generator": "^2.0.28", @@ -43,7 +43,7 @@ "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", - "bcrypt": "^5.0.0", + "bcrypt": "^6.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.0.0", "chai-exclude": "^2.1.0", @@ -1280,27 +1280,6 @@ "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, "node_modules/@microsoft/api-extractor": { "version": "7.52.10", "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.10.tgz", @@ -2026,9 +2005,9 @@ "license": "MIT" }, "node_modules/@types/bcrypt": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", - "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-6.0.0.tgz", + "integrity": "sha512-/oJGukuH3D2+D+3H4JWLaAsJ/ji86dhRidzZ/Od7H/i8g+aCmvkeCc6Ni/f9uxGLSQVCRZkX2/lqEFG2BvWtlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2529,13 +2508,6 @@ "dev": true, "license": "ISC" }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "license": "ISC" - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -2589,8 +2561,8 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "devOptional": true, "license": "MIT", + "optional": true, "dependencies": { "debug": "4" }, @@ -2925,13 +2897,6 @@ "node": ">=8" } }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true, - "license": "ISC" - }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -2939,21 +2904,6 @@ "dev": true, "license": "MIT" }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -3282,18 +3232,18 @@ "license": "MIT" }, "node_modules/bcrypt": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", - "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz", + "integrity": "sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.11", - "node-addon-api": "^5.0.0" + "node-addon-api": "^8.3.0", + "node-gyp-build": "^4.8.4" }, "engines": { - "node": ">= 10.0.0" + "node": ">= 18" } }, "node_modules/bcrypt-pbkdf": { @@ -3727,16 +3677,6 @@ "node": ">= 6" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -3971,13 +3911,6 @@ "source-map": "^0.6.1" } }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true, - "license": "ISC" - }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -4223,13 +4156,6 @@ "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true, - "license": "MIT" - }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -4240,16 +4166,6 @@ "node": ">=0.10.0" } }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", @@ -5331,39 +5247,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/fs-mkdirp-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", @@ -5446,28 +5329,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/gaxios": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", @@ -6546,13 +6407,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true, - "license": "ISC" - }, "node_modules/hasha": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", @@ -6708,8 +6562,8 @@ "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==", - "devOptional": true, "license": "MIT", + "optional": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -8343,53 +8197,6 @@ "node": ">=8" } }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/mocha": { "version": "11.7.1", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.1.tgz", @@ -8596,11 +8403,14 @@ } }, "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz", + "integrity": "sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "^18 || ^20 || >= 21" + } }, "node_modules/node-fetch": { "version": "2.7.0", @@ -8631,6 +8441,18 @@ "node": ">= 6.13.0" } }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -8661,22 +8483,6 @@ "node": ">=6.0.0" } }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -8887,20 +8693,6 @@ "node": ">=4" } }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "deprecated": "This package is no longer supported.", - "dev": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, "node_modules/nyc": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", @@ -11335,31 +11127,6 @@ "semver": "bin/semver.js" } }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/teeny-request": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", @@ -12329,16 +12096,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/package.json b/package.json index 721ff00c9f..a17a1e291f 100644 --- a/package.json +++ b/package.json @@ -228,7 +228,7 @@ "@firebase/auth-compat": "^0.6.0", "@firebase/auth-types": "^0.13.0", "@microsoft/api-extractor": "^7.11.2", - "@types/bcrypt": "^5.0.0", + "@types/bcrypt": "^6.0.0", "@types/chai": "^4.0.0", "@types/chai-as-promised": "^7.1.0", "@types/firebase-token-generator": "^2.0.28", @@ -244,7 +244,7 @@ "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", - "bcrypt": "^5.0.0", + "bcrypt": "^6.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.0.0", "chai-exclude": "^2.1.0", From e4dbb05255d632ab93989df9887d33b265fba423 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:38:46 -0500 Subject: [PATCH 281/323] build(deps): bump glob from 10.4.5 to 10.5.0 (#3019) Bumps [glob](https://github.com/isaacs/node-glob) from 10.4.5 to 10.5.0. - [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md) - [Commits](https://github.com/isaacs/node-glob/compare/v10.4.5...v10.5.0) --- updated-dependencies: - dependency-name: glob dependency-version: 10.5.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c7ecd4f9e..47396eb2ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5511,10 +5511,11 @@ } }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", From 179dab70b7ccc89185fc90e5c7a48ffecef60102 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 16:55:01 +0000 Subject: [PATCH 282/323] build(deps): bump node-forge from 1.3.1 to 1.3.2 (#3024) --- package-lock.json | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 47396eb2ae..e6ee94fbd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,6 +126,7 @@ "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", @@ -603,7 +604,8 @@ "node_modules/@firebase/app-types": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "peer": true }, "node_modules/@firebase/app/node_modules/@firebase/component": { "version": "0.6.13", @@ -802,6 +804,7 @@ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", "hasInstallScript": true, + "peer": true, "dependencies": { "tslib": "^2.1.0" }, @@ -2166,6 +2169,7 @@ "version": "22.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "peer": true, "dependencies": { "undici-types": "~6.20.0" } @@ -2309,6 +2313,7 @@ "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", @@ -2527,6 +2532,7 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3373,6 +3379,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -3545,6 +3552,7 @@ "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -4469,6 +4477,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5811,6 +5820,7 @@ "integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "glob-watcher": "^6.0.0", "gulp-cli": "^3.1.0", @@ -8434,9 +8444,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz", + "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -11620,6 +11630,7 @@ "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" From 255851bfd80684e5b75e1fa5e362ac8e19c6cb2c Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Fri, 12 Dec 2025 09:49:05 -0500 Subject: [PATCH 283/323] chore: Rename default branch to (#3033) --- .github/scripts/publish_preflight_check.sh | 4 ++-- .github/workflows/release.yml | 7 ++++--- CONTRIBUTING.md | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/scripts/publish_preflight_check.sh b/.github/scripts/publish_preflight_check.sh index d52b49a531..3aabd70b58 100755 --- a/.github/scripts/publish_preflight_check.sh +++ b/.github/scripts/publish_preflight_check.sh @@ -146,8 +146,8 @@ echo_info "Generating changelog" echo_info "--------------------------------------------" echo_info "" -echo_info "---< git fetch origin master --prune --unshallow >---" -git fetch origin master --prune --unshallow +echo_info "---< git fetch origin main --prune --unshallow >---" +git fetch origin main --prune --unshallow echo "" echo_info "Generating changelog from history..." diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0589a5f669..f961ff4a07 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -92,11 +92,12 @@ jobs: # Check whether the release should be published. We publish only when the trigger PR is # 1. merged - # 2. to the master branch + # 2. to the main branch # 3. with the label 'release:publish', and # 4. the title prefix '[chore] Release '. - if: github.event.pull_request.merged && - github.ref == 'refs/heads/master' && + if: | + github.event.pull_request.merged && + github.ref == 'refs/heads/main' && contains(github.event.pull_request.labels.*.name, 'release:publish') && startsWith(github.event.pull_request.title, '[chore] Release ') diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4a7df3f715..8f9d80ec69 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,7 +47,7 @@ Great, we love hearing how we can improve our products! Share you idea through o ## Want to submit a pull request? Sweet, we'd love to accept your contribution! -[Open a new pull request](https://github.com/firebase/firebase-admin-node/pull/new/master) and fill +[Open a new pull request](https://github.com/firebase/firebase-admin-node/pull/new/main) and fill out the provided template. **If you want to implement a new feature, please open an issue with a proposal first so that we can From e2e5f0dc23c2bd138ac5bae0a36ac4a7ce4dc87d Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Tue, 13 Jan 2026 15:32:43 -0500 Subject: [PATCH 284/323] chore: Update github actions workflows and integration test resources (#3052) * chore: Pinned github actions to a full-length commit SHA * Trigger integration tests * chore: Added environment lable to release action * chore: Update integration test resource --- .../resources/integ-service-account.json.gpg | Bin 1762 -> 1756 bytes .github/workflows/ci.yml | 4 ++-- .github/workflows/nightly.yml | 6 +++--- .github/workflows/release.yml | 13 +++++++------ 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/resources/integ-service-account.json.gpg b/.github/resources/integ-service-account.json.gpg index 7740dccd8bdada2eecc181f75c552c00e912e5c2..5a52805c9a854fdea91101dfa1822cdd5e79c874 100644 GIT binary patch literal 1756 zcmV<21|#{54Fm}T3b4{&ennUfga6X%0rw}><=tSBuPhv7FQy8=I?3Lmw%%fwb*z*z z=6KA27D5iuBgx~x$Nyfl&GpjP(Qv$$D`=U2l?uxu35Sn`=|kyz<8?VA+jsyF+7=2@ z<@|}U!==V573LAFo)Fk!&)W@2^oQ_BI8xVK1@Fz@nY52OgWsOxEWs4?ws$bNy2VpekV}20eGu8>0Z((IN{nq@79Jv z>qJM3@B0X3ROSPK`6JTc9rmfZp<%iCo=L%D$)96DgP`ezf<5a55_+{><$|JWn2{6- zu8|~zd^P6mDHo4^^s;zYo=gn$v3_|-6h#Q*v>YB4FwzzYxJ$OFI2qsh-<}WE`UP0o zvNc^F5c1`|u5^Lo6gM(449xUT0J_lPfT`o-Rv3YXMm45zU)xYv%V8E`t!^%3W2T@d zME7SXe{`62EFI}_gg}|*iwSRjWZ)dX-wOf2SENE#%c{=78oej87A$)iafd`bW8SH6 zJ-kB6gL(_ov>A`sM?z99l_M;#(lNwfS+_jn-)(p+mR%!(X&i-aQ;uoOep`8uJh{NU z`;X((7+wEarUlyb_5_u^GXdq zaHU$=fZ8&|fJOjb;?BfCUET*97w=(u`g8iTDN%`zGy@e26Rze|?C=eo-{bX~^~{(OslofH)*vmX`q?uh;mD5YR6@E1U1-|M>X0?* znFf7wQOrblD2(asM#I1dWRAPl@zh(QD z3XsUb(1C36YvZSlmD6!_%N!na+}IMOU|^m>_N`mzbT zZz&Ee7(3&M^=M8Xx_;F26O2}mG$#jR3sA&;ot)ktfCj624V{@9&f|P1`hLMTpnf^v zyhk%W;T7PT7K8gpz*`iIN{Id&dQVMOU|K%KwbY*8!(h}Mh1@VUgaWc{)H1_HNj{KH zq!~m9Ks6xb#27@Jch`+}Rsh!qa(SViGg&w78YzoJc~jys?pKii|FV@TzhUOuk}*;X z4UM8Nu9^|{7&XbCsEJX@rHSaw)%Fuy4-8YCUH<)teY{M^oANVK%EBx4h~)y7RP!u+ zG4q4$%cl%;>0k?v&6UdW=S7~lH-VQ%rOiDIg!tzMdLHwerG6__b|UZ{+x*``6FM_x z9Q%*J0L1Bea||NK+{ND-NlRa5UL%ezMBxFUxC1VlSB|DLWU6iI+7OPXmC?gb}g23VDc?X&{)zPJ~y802E;k33pZuLifi1$Fy+IgceC8QUX(c8vuYUjQKL zPLpo*M3{Hm$;qSSe&l)rR9` zt9n!#Tg#AJ^E292w0{@6@OsPYQ6>R0#1H-qumS64GunHce~@%Y9h397pn53owR5DC zt*{lGzs20XTi%=eqw1~J<2TYgq7Y{bA?-e8DSjCROK>ezwNru{_CUNLu@-pZpX7y~ z;J^s(GiVC9k!jG$m?zZX8w$6!$XoIBdUL|re!W6X_8{PtSQ38mbE@D8(%y$_zcNI6 zQOb{GR=s*=H?m`D`{_yr@g0Jr`3B&P>JtuTtoLNZgc9|vz>at=Wdh*Zk?DLam2X-i zvOz~E+b``WR>({bK{cqmo9hPH%#g(%I1-u!fh6lSWv!AmZ6+;`&jUAf%zUT!Y_d3L ye!cL($Ue&aX9i7=EYc2_I+(Y=Ru;Ur6L%VZx+|5b-zMEMj_Xxk_VrmJgD2Lh0c>#q literal 1762 zcmV<81|9i~4Fm}T0)n*iur~xoxnP%@af)-$RhZ&7)3w(?>+$-b1cw>C)uo%^A>P*=<*0iel03 za}Fsg1`ruYzno_!>aY;)OsTkc%h&&pe{$nZw5?@UjcH^%VjHu)VgwEnKQUK4HJk0= zyZ5gIrQ>xo>l)_!-wlcQad@p8gshGgv1xcg_Yjj!nW#U|n*LMBm3Wlbk?i_CZ5Ume zal+1184AaJ?*V#JRCa=MTz1K6B-nEb*&W)}8_{YN|7UTh+U!ds%WR1v?9Hbxk@ z+EogP!glp>+*yB=n_Y5O!Q;p67Vmj%K0Z&IQHoSQT$5HK`B~z1yiX&eY#WwU=~;7S z*R}F3&c9V&rDM=B?(>!Z9}?HjEfYzeD!pR<0+x@F>TU9zk7}`hv#*;%+wZyrU0HEofh5VjbOiejUW3pY z12D!+Wf#4>(VKPmD}rZ71T zja(Co^VJ`de?Q=DM7vMvigtGHs?54vGS7;%Hh%Kgpcm|%^7?KEi%S69Cr3HH;P{#2 zQKW(H3{(*{l=~Bf7Rl-tT)anXQbTFgdpURPL%zy_*wvVIb#5uC(O*IiG}XiMGUA%y z{hDOjK*5$4CjH6|s5_9ya=cleH7`i?@E_&%aD!Azwfl->_ z*G%8=hHUxvc;-w-8SZhmd?W7x5Q>Gdn&TWCqCer@&YB71xG=dZ z)$Q#4CnyByk9+}lQNhr0X%Yl^Z@x^E{?CS9l0qFDy5|%MRx3RMp&FRUbXi#z!svt^ z$1+LBRDKak{r8lR!uG7M$3y`i=mM%I6C;mOE*azp=yC&EjEO@hZAV~%vb<>vw*Tx}<@1-F%E1MJ z&Kx%>OC=ss;A2c#Xs*e!O^%Y!Dj=VPAc>{~z^9u8{@H%2A-4|8w>siL6sFHXXGAGp z6u#;-ci&~<6YWll-R0BZ(9=FJ*d=Z^1zpP&loXySLaK2LILSvW!Dc?^#B&6$r*#Z0VQL=xlo$_b_5MO*>kW6!}M4b=rO4;kC? z7>1#k9x6oenqHJ=>|?M)^;{lP0reAV^DsBc!yt{hJ=)44ze!{NMcolK=)E*z3xPIFQ}^9xIoZ8E2fWR@#G|3UOCwegz@y^#$8?WWnJ zs2>$dD-U!>e@QG8RfQO0o(=0E;V|(Wz7kVeam0oZT7r|6xiFJ zNd8hqdzqJ0-`fL-a@okskU*`zWMi=%n1PPxq!&m!cL|J#l~QZ}A3JebK?T zy$sIEE!|IkVGk9;6HzHA)9Y-IXTCA)$QGOVqdT1OhM%`yYT53qvYtc=4KjLTfqCH9 zgC*H0Jk^%P@UH!391-ApSu$Z{4D#3;W{vq*kO zsL+qpghA`Jm|4{gJrTOb%(>>3vR5{Am*n3SBI9H-+h-WW$}kgTg9MyYUUi*K+#nml Ero6&wRR910 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba8a5896b2..36bf48432f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,9 +12,9 @@ jobs: node-version: [18.x, 20.x, 22.x, 24.x] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: ${{ matrix.node-version }} - name: Install and build diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 277f1449e4..8f4e36bbfb 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -29,12 +29,12 @@ jobs: steps: - name: Checkout source for staging - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: ref: ${{ github.event.client_payload.ref || github.ref }} - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 18.x @@ -72,7 +72,7 @@ jobs: # Attach the packaged artifacts to the workflow output. These can be manually # downloaded for later inspection if necessary. - name: Archive artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: dist path: dist diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f961ff4a07..6a93e1edbf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,12 +40,12 @@ jobs: # via the 'ref' client parameter. steps: - name: Checkout source for staging - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: ref: ${{ github.event.client_payload.ref || github.ref }} - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 18.x @@ -77,7 +77,7 @@ jobs: # Attach the packaged artifacts to the workflow output. These can be manually # downloaded for later inspection if necessary. - name: Archive artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: dist path: dist @@ -102,23 +102,24 @@ jobs: startsWith(github.event.pull_request.title, '[chore] Release ') runs-on: ubuntu-latest + environment: Release permissions: contents: write steps: - name: Checkout source for publish - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 # Download the artifacts created by the stage_release job. - name: Download release candidates - uses: actions/download-artifact@v4.1.7 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: dist path: dist # Node.js and NPM are needed to complete the publish. - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 18.x From 801727d94dd5a3794dfaf0c6581ea2e836f1f0f6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 14:08:37 -0800 Subject: [PATCH 285/323] fix(data-connect): correctly serialize strings with special characters (#3056) Replaces manual string escaping with JSON.stringify in DataConnect API client to properly handle newlines and other control characters in mutation arguments. Adds a regression test for verifying newline escaping. Fixes #3043 --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Yuchen Shi --- .../data-connect-api-client-internal.ts | 5 +- .../data-connect-api-client-internal.spec.ts | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/data-connect/data-connect-api-client-internal.ts b/src/data-connect/data-connect-api-client-internal.ts index 28284db6a4..6292d023aa 100644 --- a/src/data-connect/data-connect-api-client-internal.ts +++ b/src/data-connect/data-connect-api-client-internal.ts @@ -413,10 +413,7 @@ export class DataConnectApiClient { */ private objectToString(data: unknown): string { if (typeof data === 'string') { - const escapedString = data - .replace(/\\/g, '\\\\') // Replace \ with \\ - .replace(/"/g, '\\"'); // Replace " with \" - return `"${escapedString}"`; + return JSON.stringify(data); } if (typeof data === 'number' || typeof data === 'boolean' || data === null) { return String(data); diff --git a/test/unit/data-connect/data-connect-api-client-internal.spec.ts b/test/unit/data-connect/data-connect-api-client-internal.spec.ts index 628608a9e9..7dc20080b1 100644 --- a/test/unit/data-connect/data-connect-api-client-internal.spec.ts +++ b/test/unit/data-connect/data-connect-api-client-internal.spec.ts @@ -928,4 +928,61 @@ describe('DataConnectApiClient CRUD helpers', () => { .to.be.rejectedWith(FirebaseDataConnectError, `${serverErrorString}. ${additionalErrorMessageForBulkImport}`); }); }); + + describe('String serialization', () => { + it('should correctly escape special characters in strings during insert', async () => { + const data = { + content: 'Line 1\nLine 2', + }; + + await apiClient.insert(tableName, data); + const callArgs = executeGraphqlStub.firstCall.args[0]; + + expect(callArgs).to.include(String.raw`content: "Line 1\nLine 2"`); + }); + + it('should correctly escape backslash', async () => { + const data = { + content: 'Backslash \\', + }; + + await apiClient.insert(tableName, data); + const callArgs = executeGraphqlStub.firstCall.args[0]; + + expect(callArgs).to.include(String.raw`content: "Backslash \\"`); + }); + + it('should correctly escape double quotes', async () => { + const data = { + content: 'Quote "test"', + }; + + await apiClient.insert(tableName, data); + const callArgs = executeGraphqlStub.firstCall.args[0]; + + expect(callArgs).to.include(String.raw`content: "Quote \"test\""`); + }); + + it('should correctly escape tab character', async () => { + const data = { + content: 'Tab\tCharacter', + }; + + await apiClient.insert(tableName, data); + const callArgs = executeGraphqlStub.firstCall.args[0]; + + expect(callArgs).to.include(String.raw`content: "Tab\tCharacter"`); + }); + + it('should correctly handle emojis', async () => { + const data = { + content: 'Emoji 😊', + }; + + await apiClient.insert(tableName, data); + const callArgs = executeGraphqlStub.firstCall.args[0]; + + expect(callArgs).to.include('content: "Emoji 😊"'); + }); + }); }); From 1bf436d40ab86709456c81d6f01211449df1ed23 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 4 Feb 2026 12:16:14 -0500 Subject: [PATCH 286/323] fix: Refactor `isURL()` to use Built-in `URL` Constructor (#3061) * fix: Potential ReDos vulnerability in url validator * restore pathname validations --- src/utils/validator.ts | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/utils/validator.ts b/src/utils/validator.ts index fb738904e1..15b2f53e68 100644 --- a/src/utils/validator.ts +++ b/src/utils/validator.ts @@ -15,8 +15,6 @@ * limitations under the License. */ -import url = require('url'); - /** * Validates that a value is a byte buffer. * @@ -234,33 +232,38 @@ export function isURL(urlStr: any): boolean { return false; } try { - const uri = url.parse(urlStr); + const uri = new URL(urlStr); const scheme = uri.protocol; - const slashes = uri.slashes; - const hostname = uri.hostname; - const pathname = uri.pathname; - if ((scheme !== 'http:' && scheme !== 'https:') || !slashes) { + if (scheme !== 'http:' && scheme !== 'https:') { return false; } - // Validate hostname: Can contain letters, numbers, underscore and dashes separated by a dot. - // Each zone must not start with a hyphen or underscore. - if (!hostname || !/^[a-zA-Z0-9]+[\w-]*([.]?[a-zA-Z0-9]+[\w-]*)*$/.test(hostname)) { - return false; + const hostname = uri.hostname; + // Validate hostname strictly to match previous behavior and prevent weak/invalid domains. + // Must be alphanumeric with optional dashes/underscores, separated by dots. + // Cannot start/end with dot or dash (mostly). + // This regex is safe (no nested quantifiers with overlap). + if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/.test(hostname)) { + // Check for IPv6 literals which are valid but behave differently. + // Node 'new URL' keeps brackets for IPv6: [::1] -> [::1] + // Check for IPv6 address (simple check for brackets) + if (!/^\[[a-fA-F0-9:.]+\]$/.test(hostname)) { + return false; + } } - // Allow for pathnames: (/chars+)*/? + // Restore strict pathname validation: (/chars+)*/? // Where chars can be a combination of: a-z A-Z 0-9 - _ . ~ ! $ & ' ( ) * + , ; = : @ % const pathnameRe = /^(\/[\w\-.~!$'()*+,;=:@%]+)*\/?$/; // Validate pathname. + const pathname = uri.pathname; if (pathname && - pathname !== '/' && - !pathnameRe.test(pathname)) { + pathname !== '/' && + !pathnameRe.test(pathname)) { return false; } - // Allow any query string and hash as long as no invalid character is used. + return true; } catch (e) { return false; } - return true; } From e8120c280bccf4af90e967837f1d0fa880f3133f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 12:27:50 -0500 Subject: [PATCH 287/323] build(deps-dev): bump mocha from 11.7.1 to 11.7.5 (#3012) Bumps [mocha](https://github.com/mochajs/mocha) from 11.7.1 to 11.7.5. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/v11.7.5/CHANGELOG.md) - [Commits](https://github.com/mochajs/mocha/compare/v11.7.1...v11.7.5) --- updated-dependencies: - dependency-name: mocha dependency-version: 11.7.5 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- package-lock.json | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index e6ee94fbd0..00caa122e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,7 +126,6 @@ "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", @@ -604,8 +603,7 @@ "node_modules/@firebase/app-types": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", - "peer": true + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" }, "node_modules/@firebase/app/node_modules/@firebase/component": { "version": "0.6.13", @@ -804,7 +802,6 @@ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", "hasInstallScript": true, - "peer": true, "dependencies": { "tslib": "^2.1.0" }, @@ -2169,7 +2166,6 @@ "version": "22.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", - "peer": true, "dependencies": { "undici-types": "~6.20.0" } @@ -2313,7 +2309,6 @@ "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "7.18.0", "@typescript-eslint/types": "7.18.0", @@ -2532,7 +2527,6 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3379,7 +3373,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -3552,7 +3545,6 @@ "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -4477,7 +4469,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5820,7 +5811,6 @@ "integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "glob-watcher": "^6.0.0", "gulp-cli": "^3.1.0", @@ -8209,10 +8199,11 @@ } }, "node_modules/mocha": { - "version": "11.7.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.1.tgz", - "integrity": "sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A==", + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", "dev": true, + "license": "MIT", "dependencies": { "browser-stdout": "^1.3.1", "chokidar": "^4.0.1", @@ -8222,6 +8213,7 @@ "find-up": "^5.0.0", "glob": "^10.4.5", "he": "^1.2.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", "minimatch": "^9.0.5", @@ -11630,7 +11622,6 @@ "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" From bcc76f5304af4f73ec27543d2d4a04088690f7d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 12:33:58 -0500 Subject: [PATCH 288/323] build(deps-dev): bump lodash from 4.17.21 to 4.17.23 (#3057) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 00caa122e1..1b121c861a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7846,9 +7846,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" }, From 43bda4c77833091d85b1e13da8ff7f13f891b8e2 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:05:54 -0500 Subject: [PATCH 289/323] chore: Update release workflows for push triggers (#3062) * chore: Update release workflows for push triggers * chore: Update release instructions and fix tag creation --- .github/workflows/release.yml | 61 ++++++++++++++--------------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6a93e1edbf..88bf8a28ba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,10 +15,18 @@ name: Release Candidate on: - # Only run the workflow when a PR is updated or when a developer explicitly requests - # a build by sending a 'firebase_build' event. + # Run the workflow when: + # 1. A PR is created or updated (staging checks). + # 2. A commit is pushed to main (release publication). + # 3. A developer explicitly requests a build via 'firebase_build' event. pull_request: - types: [opened, synchronize, closed] + types: [opened, synchronize] + + push: + branches: + - main + paths: + - 'package.json' repository_dispatch: types: @@ -26,23 +34,19 @@ on: jobs: stage_release: - # To publish a release, merge the release PR with the label 'release:publish'. + # To publish a release, merge a PR with the title prefix '[chore] Release ' to main + # and ensure the squashed commit message also has the prefix. # To stage a release without publishing it, send a 'firebase_build' event or apply # the 'release:stage' label to a PR. if: github.event.action == 'firebase_build' || contains(github.event.pull_request.labels.*.name, 'release:stage') || - (github.event.pull_request.merged && - contains(github.event.pull_request.labels.*.name, 'release:publish')) + (github.event_name == 'push' && startsWith(github.event.head_commit.message, '[chore] Release ')) runs-on: ubuntu-latest - # When manually triggering the build, the requester can specify a target branch or a tag - # via the 'ref' client parameter. steps: - name: Checkout source for staging uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - with: - ref: ${{ github.event.client_payload.ref || github.ref }} - name: Set up Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 @@ -90,16 +94,13 @@ jobs: publish_release: needs: stage_release - # Check whether the release should be published. We publish only when the trigger PR is - # 1. merged + # Check whether the release should be published. We publish only when the trigger is + # 1. a push (merge) # 2. to the main branch - # 3. with the label 'release:publish', and - # 4. the title prefix '[chore] Release '. - if: | - github.event.pull_request.merged && + # 3. and the commit message has the title prefix '[chore] Release '. + if: github.event_name == 'push' && github.ref == 'refs/heads/main' && - contains(github.event.pull_request.labels.*.name, 'release:publish') && - startsWith(github.event.pull_request.title, '[chore] Release ') + startsWith(github.event.head_commit.message, '[chore] Release ') runs-on: ubuntu-latest environment: Release @@ -131,27 +132,15 @@ jobs: - name: Create release tag env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh release create ${{ steps.preflight.outputs.version }} - --title "Firebase Admin Node.js SDK ${{ steps.preflight.outputs.version }}" - --notes '${{ steps.preflight.outputs.changelog }}' + RELEASE_VER: ${{ steps.preflight.outputs.version }} + RELEASE_BODY: ${{ steps.preflight.outputs.changelog }} + run: | + gh release create "$RELEASE_VER" \ + --title "Firebase Admin Node.js SDK $RELEASE_VER" \ + --notes "$RELEASE_BODY" - name: Publish to NPM run: ./.github/scripts/publish_package.sh env: NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} VERSION: ${{ steps.preflight.outputs.version }} - - # Post to Twitter if explicitly opted-in by adding the label 'release:tweet'. - - name: Post to Twitter - if: success() && - contains(github.event.pull_request.labels.*.name, 'release:tweet') - uses: ./.github/actions/send-tweet - with: - status: > - ${{ steps.preflight.outputs.version }} of @Firebase Admin Node.js SDK is available. - https://github.com/firebase/firebase-admin-node/releases/tag/${{ steps.preflight.outputs.version }} - consumer-key: ${{ secrets.TWITTER_CONSUMER_KEY }} - consumer-secret: ${{ secrets.TWITTER_CONSUMER_SECRET }} - access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }} - access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }} - continue-on-error: true From 2ea1cecdc783ab338038780834c8ab7d3bafc917 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:36:11 -0500 Subject: [PATCH 290/323] build(deps): bump jws (#3029) Bumps and [jws](https://github.com/brianloveswords/node-jws). These dependencies needed to be updated together. Updates `jws` from 4.0.0 to 4.0.1 - [Release notes](https://github.com/brianloveswords/node-jws/releases) - [Changelog](https://github.com/auth0/node-jws/blob/master/CHANGELOG.md) - [Commits](https://github.com/brianloveswords/node-jws/compare/v4.0.0...v4.0.1) Updates `jws` from 3.2.2 to 3.2.3 - [Release notes](https://github.com/brianloveswords/node-jws/releases) - [Changelog](https://github.com/auth0/node-jws/blob/master/CHANGELOG.md) - [Commits](https://github.com/brianloveswords/node-jws/compare/v4.0.0...v4.0.1) --- updated-dependencies: - dependency-name: jws dependency-version: 4.0.1 dependency-type: indirect - dependency-name: jws dependency-version: 3.2.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- package-lock.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1b121c861a..d8d60d1505 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7589,23 +7589,23 @@ } }, "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz", + "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==", "license": "MIT", "dependencies": { - "jwa": "^1.4.1", + "jwa": "^1.4.2", "safe-buffer": "^5.0.1" } }, @@ -7633,12 +7633,12 @@ "license": "MIT" }, "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } @@ -7670,12 +7670,12 @@ } }, "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", "license": "MIT", "dependencies": { - "jwa": "^2.0.0", + "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, From 4d4426dbb4ef022d86bbf09bfd55bbabcdcd8087 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 4 Feb 2026 14:28:41 -0500 Subject: [PATCH 291/323] [chore] Release 13.6.1 (#3063) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d8d60d1505..b7b1f0ff1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.6.0", + "version": "13.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.6.0", + "version": "13.6.1", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", diff --git a/package.json b/package.json index a17a1e291f..cef227703a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.6.0", + "version": "13.6.1", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From efa02dee1ad3d97d3c7ee5a04c8278cac6d60532 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:06:11 -0500 Subject: [PATCH 292/323] build(deps): bump axios in /.github/actions/send-email (#3070) Bumps [axios](https://github.com/axios/axios) from 1.12.2 to 1.13.5. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.12.2...v1.13.5) --- updated-dependencies: - dependency-name: axios dependency-version: 1.13.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/send-email/package-lock.json | 30 ++++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 11a686e946..f20d2d3ad6 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -54,16 +54,17 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", - "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -89,6 +90,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -100,6 +102,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -164,15 +167,16 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -183,9 +187,9 @@ } }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -321,6 +325,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -329,6 +334,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, From d25b0361624de0fc1e89976791148eaadb89827d Mon Sep 17 00:00:00 2001 From: Ashish Kothari Date: Thu, 19 Feb 2026 10:45:30 +0530 Subject: [PATCH 293/323] feat(rc): Support Rollout, Personalization, and Experiment values (#3046) Support Rollout, Personalization, and Experiment values in Remote Config Added new Remote Config parameter value types (Rollout, Personalization, Experiment) to the SDK. Updated `RemoteConfigParameterValue` union type and added corresponding interfaces. Updated unit tests to verify the new types in Remote Config templates. --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- etc/firebase-admin.api.md | 18 +++ etc/firebase-admin.remote-config.api.md | 52 ++++++- src/remote-config/index.ts | 9 ++ src/remote-config/remote-config-api.ts | 136 +++++++++++++++++- src/remote-config/remote-config-namespace.ts | 54 +++++++ src/remote-config/remote-config.ts | 5 +- test/unit/remote-config/remote-config.spec.ts | 116 +++++++++++++++ 7 files changed, 387 insertions(+), 3 deletions(-) diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index e9d4bb0e49..e4675c2009 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -434,6 +434,16 @@ export function remoteConfig(app?: App): remoteConfig.RemoteConfig; // @public (undocumented) export namespace remoteConfig { + // Warning: (ae-forgotten-export) The symbol "ExperimentParameterValue" needs to be exported by the entry point default-namespace.d.ts + export type ExperimentParameterValue = ExperimentParameterValue; + // Warning: (ae-forgotten-export) The symbol "ExperimentValue" needs to be exported by the entry point default-namespace.d.ts + export type ExperimentValue = ExperimentValue; + // Warning: (ae-forgotten-export) The symbol "ExperimentVariantExplicitValue" needs to be exported by the entry point default-namespace.d.ts + export type ExperimentVariantExplicitValue = ExperimentVariantExplicitValue; + // Warning: (ae-forgotten-export) The symbol "ExperimentVariantNoChange" needs to be exported by the entry point default-namespace.d.ts + export type ExperimentVariantNoChange = ExperimentVariantNoChange; + // Warning: (ae-forgotten-export) The symbol "ExperimentVariantValue" needs to be exported by the entry point default-namespace.d.ts + export type ExperimentVariantValue = ExperimentVariantValue; // Warning: (ae-forgotten-export) The symbol "ExplicitParameterValue" needs to be exported by the entry point default-namespace.d.ts export type ExplicitParameterValue = ExplicitParameterValue; // Warning: (ae-forgotten-export) The symbol "InAppDefaultValue" needs to be exported by the entry point default-namespace.d.ts @@ -444,6 +454,10 @@ export namespace remoteConfig { export type ListVersionsResult = ListVersionsResult; // Warning: (ae-forgotten-export) The symbol "ParameterValueType" needs to be exported by the entry point default-namespace.d.ts export type ParameterValueType = ParameterValueType; + // Warning: (ae-forgotten-export) The symbol "PersonalizationParameterValue" needs to be exported by the entry point default-namespace.d.ts + export type PersonalizationParameterValue = PersonalizationParameterValue; + // Warning: (ae-forgotten-export) The symbol "PersonalizationValue" needs to be exported by the entry point default-namespace.d.ts + export type PersonalizationValue = PersonalizationValue; // Warning: (ae-forgotten-export) The symbol "RemoteConfig" needs to be exported by the entry point default-namespace.d.ts export type RemoteConfig = RemoteConfig; // Warning: (ae-forgotten-export) The symbol "RemoteConfigCondition" needs to be exported by the entry point default-namespace.d.ts @@ -458,6 +472,10 @@ export namespace remoteConfig { export type RemoteConfigTemplate = RemoteConfigTemplate; // Warning: (ae-forgotten-export) The symbol "RemoteConfigUser" needs to be exported by the entry point default-namespace.d.ts export type RemoteConfigUser = RemoteConfigUser; + // Warning: (ae-forgotten-export) The symbol "RolloutParameterValue" needs to be exported by the entry point default-namespace.d.ts + export type RolloutParameterValue = RolloutParameterValue; + // Warning: (ae-forgotten-export) The symbol "RolloutValue" needs to be exported by the entry point default-namespace.d.ts + export type RolloutValue = RolloutValue; // Warning: (ae-forgotten-export) The symbol "TagColor" needs to be exported by the entry point default-namespace.d.ts export type TagColor = TagColor; // Warning: (ae-forgotten-export) The symbol "Version" needs to be exported by the entry point default-namespace.d.ts diff --git a/etc/firebase-admin.remote-config.api.md b/etc/firebase-admin.remote-config.api.md index cf7eb32b93..1a19d1bb6c 100644 --- a/etc/firebase-admin.remote-config.api.md +++ b/etc/firebase-admin.remote-config.api.md @@ -47,6 +47,34 @@ export type DefaultConfig = { // @public export type EvaluationContext = UserProvidedSignals & PredefinedSignals; +// @public +export interface ExperimentParameterValue { + experimentValue: ExperimentValue; +} + +// @public +export interface ExperimentValue { + experimentId: string; + variantValue: ExperimentVariantValue[]; +} + +// @public +export interface ExperimentVariantExplicitValue { + noChange?: never; + value: string; + variantId: string; +} + +// @public +export interface ExperimentVariantNoChange { + noChange: true; + value?: never; + variantId: string; +} + +// @public +export type ExperimentVariantValue = ExperimentVariantExplicitValue | ExperimentVariantNoChange; + // @public export interface ExplicitParameterValue { value: string; @@ -142,6 +170,16 @@ export enum PercentConditionOperator { UNKNOWN = "UNKNOWN" } +// @public +export interface PersonalizationParameterValue { + personalizationValue: PersonalizationValue; +} + +// @public +export interface PersonalizationValue { + personalizationId: string; +} + // @public export type PredefinedSignals = { randomizationId?: string; @@ -197,7 +235,7 @@ export interface RemoteConfigParameterGroup { } // @public -export type RemoteConfigParameterValue = ExplicitParameterValue | InAppDefaultValue; +export type RemoteConfigParameterValue = ExplicitParameterValue | InAppDefaultValue | RolloutParameterValue | PersonalizationParameterValue | ExperimentParameterValue; // @public export interface RemoteConfigTemplate { @@ -219,6 +257,18 @@ export interface RemoteConfigUser { name?: string; } +// @public +export interface RolloutParameterValue { + rolloutValue: RolloutValue; +} + +// @public +export interface RolloutValue { + percent: number; + rolloutId: string; + value: string; +} + // @public export interface ServerConfig { getAll(): { diff --git a/src/remote-config/index.ts b/src/remote-config/index.ts index 790568735e..e44606f193 100644 --- a/src/remote-config/index.ts +++ b/src/remote-config/index.ts @@ -47,6 +47,15 @@ export { PredefinedSignals, RemoteConfigCondition, RemoteConfigParameter, + ExperimentParameterValue, + ExperimentValue, + ExperimentVariantExplicitValue, + ExperimentVariantNoChange, + ExperimentVariantValue, + PersonalizationParameterValue, + PersonalizationValue, + RolloutParameterValue, + RolloutValue, RemoteConfigParameterGroup, RemoteConfigParameterValue, RemoteConfigTemplate, diff --git a/src/remote-config/remote-config-api.ts b/src/remote-config/remote-config-api.ts index ed7da05496..6566fe231e 100644 --- a/src/remote-config/remote-config-api.ts +++ b/src/remote-config/remote-config-api.ts @@ -354,12 +354,146 @@ export interface InAppDefaultValue { useInAppDefault: boolean; } +/** + * Interface representing a value that is linked to a Rollout. + */ +export interface RolloutValue { + /** + * The ID of the Rollout to which the value is linked. + */ + rolloutId: string; + + /** + * The value that is being rolled out. + */ + value: string; + + /** + * The rollout percentage representing the exposure of the rollout value in + * the target audience. + */ + percent: number; // Numeric value between 1-100 +} + +/** + * Interface representing a value returned by Personalization. + */ +export interface PersonalizationValue { + /** + * The ID of the Personalization to which the value is linked. + */ + personalizationId: string; +} + +/** + * Interface representing a specific variant value within an Experiment. + */ +export interface ExperimentVariantExplicitValue { + /** + * ID of the variant value within an Experiment. + */ + variantId: string; + + /** + * Value of the variant within an Experiment. + */ + value: string; + + /** + * Represents an unset `noChange` value. To set `noChange`, use + * `ExperimentVariantNoChange` instead. + */ + noChange?: never; +} + +/** + * Represents a no-change variant value within an Experiment. + */ +export interface ExperimentVariantNoChange { + /** + * ID of the variant value within an Experiment. + */ + variantId: string; + + /** + * Represents an unset value as only one of `noChange` or `value` can be set. + * To set a variant value, use `ExperimentVariantExplicitValue` instead. + */ + value?: never; + + /** + * Represents a no-change variant value within an Experiment. If `true`, + * the variant served to the client is equal to the value against the + * next condition in the evaluation order (or the default value if no + * conditions are applicable). + */ + noChange: true; +} + +/** + * Type representing an Experiment variant value. + * An `ExperimentVariantValue` could be either an + * `ExperimentVariantExplicitValue` or an `ExperimentVariantNoChange`. + */ +export type ExperimentVariantValue = ExperimentVariantExplicitValue | ExperimentVariantNoChange; + +/** + * Represents an Experiment value. + */ +export interface ExperimentValue { + /** + * ID of the Experiment to which the value is linked. + */ + experimentId: string; + + /** + * Collection of `ExperimentVariantValue`s that represents the variants + * served by the Experiment. + */ + variantValue: ExperimentVariantValue[]; +} + +/** + * Interface representing a parameter value linked to a Rollout. + */ +export interface RolloutParameterValue { + /** + * The value returned by a Rollout. + */ + rolloutValue: RolloutValue; +} + +/** + * Interface representing a parameter value linked to a Personalization. + */ +export interface PersonalizationParameterValue { + /** + * The value returned by a Personalization. + */ + personalizationValue: PersonalizationValue; +} + +/** + * Interface representing a parameter value linked to an Experiment. + */ +export interface ExperimentParameterValue { + /** + * The value returned by an Experiment. + */ + experimentValue: ExperimentValue; +} + /** * Type representing a Remote Config parameter value. * A `RemoteConfigParameterValue` could be either an `ExplicitParameterValue` or * an `InAppDefaultValue`. */ -export type RemoteConfigParameterValue = ExplicitParameterValue | InAppDefaultValue; +export type RemoteConfigParameterValue = + | ExplicitParameterValue + | InAppDefaultValue + | RolloutParameterValue + | PersonalizationParameterValue + | ExperimentParameterValue; /** * Interface representing a Remote Config parameter. diff --git a/src/remote-config/remote-config-namespace.ts b/src/remote-config/remote-config-namespace.ts index 159204d316..abc315b150 100644 --- a/src/remote-config/remote-config-namespace.ts +++ b/src/remote-config/remote-config-namespace.ts @@ -18,6 +18,15 @@ import { App } from '../app'; import { ExplicitParameterValue as TExplicitParameterValue, InAppDefaultValue as TInAppDefaultValue, + RolloutValue as TRolloutValue, + PersonalizationValue as TPersonalizationValue, + ExperimentVariantExplicitValue as TExperimentVariantExplicitValue, + ExperimentVariantNoChange as TExperimentVariantNoChange, + ExperimentVariantValue as TExperimentVariantValue, + ExperimentValue as TExperimentValue, + RolloutParameterValue as TRolloutParameterValue, + PersonalizationParameterValue as TPersonalizationParameterValue, + ExperimentParameterValue as TExperimentParameterValue, ListVersionsOptions as TListVersionsOptions, ListVersionsResult as TListVersionsResult, ParameterValueType as TParameterValueType, @@ -73,6 +82,51 @@ export namespace remoteConfig { */ export type InAppDefaultValue = TInAppDefaultValue; + /** + * Type alias to {@link firebase-admin.remote-config#RolloutValue}. + */ + export type RolloutValue = TRolloutValue; + + /** + * Type alias to {@link firebase-admin.remote-config#PersonalizationValue}. + */ + export type PersonalizationValue = TPersonalizationValue; + + /** + * Type alias to {@link firebase-admin.remote-config#ExperimentVariantExplicitValue}. + */ + export type ExperimentVariantExplicitValue = TExperimentVariantExplicitValue; + + /** + * Type alias to {@link firebase-admin.remote-config#ExperimentVariantNoChange}. + */ + export type ExperimentVariantNoChange = TExperimentVariantNoChange; + + /** + * Type alias to {@link firebase-admin.remote-config#ExperimentVariantValue}. + */ + export type ExperimentVariantValue = TExperimentVariantValue; + + /** + * Type alias to {@link firebase-admin.remote-config#ExperimentValue}. + */ + export type ExperimentValue = TExperimentValue; + + /** + * Type alias to {@link firebase-admin.remote-config#RolloutParameterValue}. + */ + export type RolloutParameterValue = TRolloutParameterValue; + + /** + * Type alias to {@link firebase-admin.remote-config#PersonalizationParameterValue}. + */ + export type PersonalizationParameterValue = TPersonalizationParameterValue; + + /** + * Type alias to {@link firebase-admin.remote-config#ExperimentParameterValue}. + */ + export type ExperimentParameterValue = TExperimentParameterValue; + /** * Type alias to {@link firebase-admin.remote-config#ListVersionsOptions}. */ diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index 91eebfa0cb..6ae44c4064 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -382,6 +382,7 @@ class ServerTemplateImpl implements ServerTemplate { // Iterates in order over condition list. If there is a value associated // with a condition, this checks if the condition is true. for (const [conditionName, conditionEvaluation] of evaluatedConditions) { + if (normalizedConditionalValues[conditionName] && conditionEvaluation) { parameterValueWrapper = normalizedConditionalValues[conditionName]; break; @@ -395,7 +396,9 @@ class ServerTemplateImpl implements ServerTemplate { if (parameterValueWrapper) { const parameterValue = (parameterValueWrapper as ExplicitParameterValue).value; - configValues[key] = new ValueImpl('remote', parameterValue); + if (parameterValue !== undefined) { + configValues[key] = new ValueImpl('remote', parameterValue); + } continue; } diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index e7e4f84e57..74d277290e 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -27,6 +27,9 @@ import { TagColor, ListVersionsResult, RemoteConfigFetchResponse, + RolloutParameterValue, + PersonalizationParameterValue, + ExperimentParameterValue, } from '../../../src/remote-config/index'; import { FirebaseApp } from '../../../src/app/firebase-app'; import * as mocks from '../../resources/mocks'; @@ -96,6 +99,48 @@ describe('RemoteConfig', () => { description: 'this is a promo', valueType: 'BOOLEAN', }, + new_ui_enabled: { + defaultValue: { value: 'false' }, + conditionalValues: { + ios: { + rolloutValue: { + rolloutId: 'rollout_1', + value: 'true', + percent: 50, + } + } + }, + description: 'New UI Rollout', + valueType: 'BOOLEAN', + }, + personalized_welcome_message: { + defaultValue: { value: 'Welcome!' }, + conditionalValues: { + ios: { + personalizationValue: { + personalizationId: 'personalization_1', + } + } + }, + description: 'Personalized Welcome Message', + valueType: 'STRING', + }, + experiment_enabled: { + defaultValue: { value: 'false' }, + conditionalValues: { + ios: { + experimentValue: { + experimentId: 'experiment_1', + variantValue: [ + { variantId: 'variant_A', value: 'true' }, + { variantId: 'variant_B', noChange: true } + ] + } + } + }, + description: 'Experiment Enabled', + valueType: 'BOOLEAN', + } }, parameterGroups: PARAMETER_GROUPS, etag: 'etag-123456789012-5', @@ -153,6 +198,48 @@ describe('RemoteConfig', () => { description: 'this is a promo', valueType: 'BOOLEAN', }, + new_ui_enabled: { + defaultValue: { value: 'false' }, + conditionalValues: { + ios: { + rolloutValue: { + rolloutId: 'rollout_1', + value: 'true', + percent: 50, + } + } + }, + description: 'New UI Rollout', + valueType: 'BOOLEAN', + }, + personalized_welcome_message: { + defaultValue: { value: 'Welcome!' }, + conditionalValues: { + ios: { + personalizationValue: { + personalizationId: 'personalization_1', + } + } + }, + description: 'Personalized Welcome Message', + valueType: 'STRING', + }, + experiment_enabled: { + defaultValue: { value: 'false' }, + conditionalValues: { + ios: { + experimentValue: { + experimentId: 'experiment_1', + variantValue: [ + { variantId: 'variant_A', value: 'true' }, + { variantId: 'variant_B', noChange: true } + ] + } + } + }, + description: 'Experiment Enabled', + valueType: 'BOOLEAN', + } }, parameterGroups: PARAMETER_GROUPS, etag: 'etag-123456789012-6', @@ -542,6 +629,35 @@ describe('RemoteConfig', () => { expect(p1.description).equals('this is a promo'); expect(p1.valueType).equals('BOOLEAN'); + const p2 = newTemplate.parameters['new_ui_enabled']; + expect(p2.defaultValue).deep.equals({ value: 'false' }); + expect(p2.conditionalValues).to.not.be.undefined; + const rolloutParam = p2.conditionalValues!['ios'] as RolloutParameterValue; + expect(rolloutParam.rolloutValue.rolloutId).to.equal('rollout_1'); + expect(rolloutParam.rolloutValue.value).to.equal('true'); + expect(rolloutParam.rolloutValue.percent).to.equal(50); + expect(p2.description).equals('New UI Rollout'); + expect(p2.valueType).equals('BOOLEAN'); + + const p3 = newTemplate.parameters['personalized_welcome_message']; + expect(p3.defaultValue).deep.equals({ value: 'Welcome!' }); + expect(p3.conditionalValues).to.not.be.undefined; + const personalizationParam = p3.conditionalValues!['ios'] as PersonalizationParameterValue; + expect(personalizationParam.personalizationValue.personalizationId).to.equal('personalization_1'); + expect(p3.description).equals('Personalized Welcome Message'); + expect(p3.valueType).equals('STRING'); + + const p4 = newTemplate.parameters['experiment_enabled']; + expect(p4.defaultValue).deep.equals({ value: 'false' }); + expect(p4.conditionalValues).to.not.be.undefined; + const experimentParam = p4.conditionalValues!['ios'] as ExperimentParameterValue; + expect(experimentParam.experimentValue.experimentId).to.equal('experiment_1'); + expect(experimentParam.experimentValue.variantValue.length).to.equal(2); + expect(experimentParam.experimentValue.variantValue[0]).to.deep.equal({ variantId: 'variant_A', value: 'true' }); + expect(experimentParam.experimentValue.variantValue[1]).to.deep.equal({ variantId: 'variant_B', noChange: true }); + expect(p4.description).equals('Experiment Enabled'); + expect(p4.valueType).equals('BOOLEAN'); + expect(newTemplate.parameterGroups).deep.equals(PARAMETER_GROUPS); const c = newTemplate.conditions.find((c) => c.name === 'ios'); From 4ce0f8b5b63d1cb099154c74c0bc74189d29bf5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Feb 2026 09:05:13 -0500 Subject: [PATCH 294/323] build(deps-dev): bump @microsoft/api-extractor from 7.52.10 to 7.56.2 (#3066) Bumps [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor) from 7.52.10 to 7.56.2. - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.56.2/apps/api-extractor) --- updated-dependencies: - dependency-name: "@microsoft/api-extractor" dependency-version: 7.56.2 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- package-lock.json | 190 ++++++++++++++++++++++++++-------------------- 1 file changed, 109 insertions(+), 81 deletions(-) diff --git a/package-lock.json b/package-lock.json index b7b1f0ff1a..01427abc50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1001,9 +1001,9 @@ } }, "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", + "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1281,21 +1281,22 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.52.10", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.10.tgz", - "integrity": "sha512-LhKytJM5ZJkbHQVfW/3o747rZUNs/MGg6j/wt/9qwwqEOfvUDTYXXxIBuMgrRXhJ528p41iyz4zjBVHZU74Odg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@microsoft/api-extractor-model": "7.30.7", - "@microsoft/tsdoc": "~0.15.1", - "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.14.0", - "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.15.4", - "@rushstack/ts-command-line": "5.0.2", - "lodash": "~4.17.15", - "minimatch": "10.0.3", + "version": "7.56.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.56.3.tgz", + "integrity": "sha512-fRqok4aRNq5GpgGBv2fKlSSKbirPKTJ75vQefthB5x9dwt4Zz+AezUzdc1p/AG4wUBIgmhjcEwn/Rj+N4Wh4Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@microsoft/api-extractor-model": "7.32.2", + "@microsoft/tsdoc": "~0.16.0", + "@microsoft/tsdoc-config": "~0.18.0", + "@rushstack/node-core-library": "5.19.1", + "@rushstack/rig-package": "0.6.0", + "@rushstack/terminal": "0.21.0", + "@rushstack/ts-command-line": "5.2.0", + "diff": "~8.0.2", + "lodash": "~4.17.23", + "minimatch": "10.1.2", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", @@ -1306,28 +1307,28 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.30.7", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.7.tgz", - "integrity": "sha512-TBbmSI2/BHpfR9YhQA7nH0nqVmGgJ0xH0Ex4D99/qBDAUpnhA2oikGmdXanbw9AWWY/ExBYIpkmY8dBHdla3YQ==", + "version": "7.32.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.32.2.tgz", + "integrity": "sha512-Ussc25rAalc+4JJs9HNQE7TuO9y6jpYQX9nWD1DhqUzYPBr3Lr7O9intf+ZY8kD5HnIqeIRJX7ccCT0QyBy2Ww==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/tsdoc": "~0.15.1", - "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.14.0" + "@microsoft/tsdoc": "~0.16.0", + "@microsoft/tsdoc-config": "~0.18.0", + "@rushstack/node-core-library": "5.19.1" } }, "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", - "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz", + "integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==", "dev": true, "license": "MIT" }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.14.0.tgz", - "integrity": "sha512-eRong84/rwQUlATGFW3TMTYVyqL1vfW9Lf10PH+mVGfIb9HzU3h5AASNIw+axnBLjnD0n3rT5uQBwu9fvzATrg==", + "version": "5.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.19.1.tgz", + "integrity": "sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==", "dev": true, "license": "MIT", "dependencies": { @@ -1367,9 +1368,9 @@ } }, "node_modules/@microsoft/api-extractor-model/node_modules/fs-extra": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", - "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", "dev": true, "license": "MIT", "dependencies": { @@ -1382,9 +1383,9 @@ } }, "node_modules/@microsoft/api-extractor-model/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { @@ -1405,15 +1406,16 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@microsoft/tsdoc": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", - "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", - "dev": true + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz", + "integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==", + "dev": true, + "license": "MIT" }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.14.0.tgz", - "integrity": "sha512-eRong84/rwQUlATGFW3TMTYVyqL1vfW9Lf10PH+mVGfIb9HzU3h5AASNIw+axnBLjnD0n3rT5uQBwu9fvzATrg==", + "version": "5.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.19.1.tgz", + "integrity": "sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==", "dev": true, "license": "MIT", "dependencies": { @@ -1436,13 +1438,13 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.0.2.tgz", - "integrity": "sha512-+AkJDbu1GFMPIU8Sb7TLVXDv/Q7Mkvx+wAjEl8XiXVVq+p1FmWW6M3LYpJMmoHNckSofeMecgWg5lfMwNAAsEQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.2.0.tgz", + "integrity": "sha512-lYxCX0nDdkDtCkVpvF0m25ymf66SaMWuppbD6b7MdkIzvGXKBXNIVZlwBH/C0YfkanrupnICWf2n4z3AKSfaHw==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.15.4", + "@rushstack/terminal": "0.21.0", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1465,10 +1467,20 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@microsoft/api-extractor/node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/@microsoft/api-extractor/node_modules/fs-extra": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", - "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", "dev": true, "license": "MIT", "dependencies": { @@ -1481,9 +1493,9 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { @@ -1494,13 +1506,13 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", + "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "@isaacs/brace-expansion": "^5.0.1" }, "engines": { "node": "20 || >=22" @@ -1541,22 +1553,22 @@ "license": "MIT" }, "node_modules/@microsoft/tsdoc-config": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz", - "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.18.0.tgz", + "integrity": "sha512-8N/vClYyfOH+l4fLkkr9+myAoR6M7akc8ntBJ4DJdWH2b09uVfr71+LTMpNyG19fNqWDg8KEDZhx5wxuqHyGjw==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/tsdoc": "0.15.1", + "@microsoft/tsdoc": "0.16.0", "ajv": "~8.12.0", "jju": "~1.4.0", "resolve": "~1.22.2" } }, "node_modules/@microsoft/tsdoc-config/node_modules/@microsoft/tsdoc": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", - "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz", + "integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==", "dev": true, "license": "MIT" }, @@ -1726,10 +1738,25 @@ "node": ">=0.1.90" } }, + "node_modules/@rushstack/problem-matcher": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@rushstack/problem-matcher/-/problem-matcher-0.1.1.tgz", + "integrity": "sha512-Fm5XtS7+G8HLcJHCWpES5VmeMyjAKaWeyZU5qPzZC+22mPlJzAsOxymHiWIfuirtPckX3aptWws+K2d0BzniJA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/@rushstack/rig-package": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", - "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.6.0.tgz", + "integrity": "sha512-ZQmfzsLE2+Y91GF15c65L/slMRVhF6Hycq04D4TwtdGaUAbIXXg9c5pKA5KFU7M4QMaihoobp9JJYpYcaY3zOw==", "dev": true, "license": "MIT", "dependencies": { @@ -1738,13 +1765,14 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.4.tgz", - "integrity": "sha512-OQSThV0itlwVNHV6thoXiAYZlQh4Fgvie2CzxFABsbO2MWQsI4zOh3LRNigYSTrmS+ba2j0B3EObakPzf/x6Zg==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.21.0.tgz", + "integrity": "sha512-cLaI4HwCNYmknM5ns4G+drqdEB6q3dCPV423+d3TZeBusYSSm09+nR7CnhzJMjJqeRcdMAaLnrA4M/3xDz4R3w==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.14.0", + "@rushstack/node-core-library": "5.19.1", + "@rushstack/problem-matcher": "0.1.1", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -1757,9 +1785,9 @@ } }, "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.14.0.tgz", - "integrity": "sha512-eRong84/rwQUlATGFW3TMTYVyqL1vfW9Lf10PH+mVGfIb9HzU3h5AASNIw+axnBLjnD0n3rT5uQBwu9fvzATrg==", + "version": "5.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.19.1.tgz", + "integrity": "sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==", "dev": true, "license": "MIT", "dependencies": { @@ -1799,9 +1827,9 @@ } }, "node_modules/@rushstack/terminal/node_modules/fs-extra": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", - "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", "dev": true, "license": "MIT", "dependencies": { @@ -1814,9 +1842,9 @@ } }, "node_modules/@rushstack/terminal/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { From a1d99ead39a37376b809d4a69ae9799cacbdc611 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 24 Feb 2026 10:59:46 -0500 Subject: [PATCH 295/323] fix: upgrade @google-cloud/storage@7.19.0 (#3071) * fix: upgrade @google-cloud/storage@7.19.0 to address a vilnarability in fast-xml-parser * refactor: use type guard for headers in api-request * chore: upgrade typescript-eslint to fix version mismatch warning --- .eslintrc.js | 11 +- package-lock.json | 389 +++++++++++++++++++++++++-------------- package.json | 8 +- src/utils/api-request.ts | 10 +- 4 files changed, 273 insertions(+), 145 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c462e7c05a..1d4c74bd43 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -33,6 +33,8 @@ module.exports = { '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/no-use-before-define': 0, '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-require-imports': 0, + '@typescript-eslint/no-unused-expressions': 0, // Required checks 'indent': ['error', 2], @@ -54,7 +56,14 @@ module.exports = { } ], 'no-unused-vars': 'off', // Must be disabled to enable the next rule - '@typescript-eslint/no-unused-vars': ['error'], + '@typescript-eslint/no-unused-vars': [ + 'error', + { + 'varsIgnorePattern': '^_', + 'argsIgnorePattern': '^_', + 'caughtErrors': 'none' + } + ], 'quotes': ['error', 'single', {'avoidEscape': true}], '@typescript-eslint/naming-convention': [ 'error', diff --git a/package-lock.json b/package-lock.json index 01427abc50..cc0ff68fb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,8 +41,8 @@ "@types/sinon": "^17.0.2", "@types/sinon-chai": "^3.0.0", "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^7.16.1", - "@typescript-eslint/parser": "^7.16.1", + "@typescript-eslint/eslint-plugin": "^8.56.0", + "@typescript-eslint/parser": "^8.56.0", "bcrypt": "^6.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.0.0", @@ -70,7 +70,7 @@ "sinon": "^18.0.0", "sinon-chai": "^3.0.0", "ts-node": "^10.2.0", - "typescript": "5.5.4", + "typescript": "^5.7.3", "yargs": "^17.0.1" }, "engines": { @@ -78,7 +78,7 @@ }, "optionalDependencies": { "@google-cloud/firestore": "^7.11.0", - "@google-cloud/storage": "^7.14.0" + "@google-cloud/storage": "^7.19.0" } }, "node_modules/@ampproject/remapping": { @@ -404,9 +404,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -423,9 +423,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -860,19 +860,19 @@ } }, "node_modules/@google-cloud/storage": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.14.0.tgz", - "integrity": "sha512-H41bPL2cMfSi4EEnFzKvg7XSb7T67ocSXrmF7MPjfgFB0L6CKGzfIYJheAZi1iqXjz6XaCT1OBf6HCG5vDBTOQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.19.0.tgz", + "integrity": "sha512-n2FjE7NAOYyshogdc7KQOl/VZb4sneqPjWouSyia9CMDdMhRX5+RIbqalNmC7LOLzuLAN89VlF2HvG8na9G+zQ==", "license": "Apache-2.0", "optional": true, "dependencies": { "@google-cloud/paginator": "^5.0.0", "@google-cloud/projectify": "^4.0.0", - "@google-cloud/promisify": "^4.0.0", + "@google-cloud/promisify": "<4.1.0", "abort-controller": "^3.0.0", "async-retry": "^1.3.3", "duplexify": "^4.1.3", - "fast-xml-parser": "^4.4.1", + "fast-xml-parser": "^5.3.4", "gaxios": "^6.0.2", "google-auth-library": "^9.6.3", "html-entities": "^2.5.2", @@ -2298,122 +2298,159 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", - "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", + "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/type-utils": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/type-utils": "8.56.0", + "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.56.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", + "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", + "debug": "^4.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", + "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.56.0", + "@typescript-eslint/types": "^8.56.0", + "debug": "^4.4.3" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", + "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", - "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", + "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2421,52 +2458,64 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz", + "integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -2476,9 +2525,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -2489,46 +2538,60 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -4053,9 +4116,9 @@ } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -4869,23 +4932,19 @@ "license": "MIT" }, "node_modules/fast-xml-parser": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", - "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.5.tgz", + "integrity": "sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" } ], "license": "MIT", "optional": true, "dependencies": { - "strnum": "^1.0.5" + "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" @@ -11095,9 +11154,15 @@ } }, "node_modules/strnum": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", - "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT", "optional": true }, @@ -11361,6 +11426,54 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/to-absolute-glob": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", @@ -11422,16 +11535,16 @@ "license": "MIT" }, "node_modules/ts-api-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", - "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "dev": true, "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-node": { @@ -11645,9 +11758,9 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index cef227703a..7e7c494da7 100644 --- a/package.json +++ b/package.json @@ -220,7 +220,7 @@ }, "optionalDependencies": { "@google-cloud/firestore": "^7.11.0", - "@google-cloud/storage": "^7.14.0" + "@google-cloud/storage": "^7.19.0" }, "devDependencies": { "@firebase/api-documenter": "^0.5.0", @@ -242,8 +242,8 @@ "@types/sinon": "^17.0.2", "@types/sinon-chai": "^3.0.0", "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^7.16.1", - "@typescript-eslint/parser": "^7.16.1", + "@typescript-eslint/eslint-plugin": "^8.56.0", + "@typescript-eslint/parser": "^8.56.0", "bcrypt": "^6.0.0", "chai": "^4.2.0", "chai-as-promised": "^7.0.0", @@ -271,7 +271,7 @@ "sinon": "^18.0.0", "sinon-chai": "^3.0.0", "ts-node": "^10.2.0", - "typescript": "5.5.4", + "typescript": "^5.7.3", "yargs": "^17.0.1" } } diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index 6e95619e6d..a6a578b81c 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -730,7 +730,10 @@ class AsyncHttpCall extends AsyncRequestCall { try { this.httpConfigImpl = httpConfigImpl; this.options = this.httpConfigImpl.buildRequestOptions(); - this.entity = this.httpConfigImpl.buildEntity(this.options.headers!); + if (!validator.isNonNullObject(this.options.headers)) { + this.options.headers = {}; + } + this.entity = this.httpConfigImpl.buildEntity(this.options.headers); this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; @@ -828,7 +831,10 @@ class AsyncHttp2Call extends AsyncRequestCall { try { this.http2ConfigImpl = http2ConfigImpl; this.options = this.http2ConfigImpl.buildRequestOptions(); - this.entity = this.http2ConfigImpl.buildEntity(this.options.headers!); + if (!validator.isNonNullObject(this.options.headers)) { + this.options.headers = {}; + } + this.entity = this.http2ConfigImpl.buildEntity(this.options.headers); this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; From 24e52ebdf9e87dd2bfd35efe8a58e5a9402e6c4e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 14:27:35 -0500 Subject: [PATCH 296/323] build(deps): bump fast-xml-parser from 5.3.5 to 5.3.7 (#3077) Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.3.5 to 5.3.7. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.5...v5.3.7) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.3.7 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index cc0ff68fb0..c9b8131167 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4932,9 +4932,9 @@ "license": "MIT" }, "node_modules/fast-xml-parser": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.5.tgz", - "integrity": "sha512-JeaA2Vm9ffQKp9VjvfzObuMCjUYAp5WDYhRYL5LrBPY/jUDlUtOvDfot0vKSkB9tuX885BDHjtw4fZadD95wnA==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.7.tgz", + "integrity": "sha512-JzVLro9NQv92pOM/jTCR6mHlJh2FGwtomH8ZQjhFj/R29P2Fnj38OgPJVtcvYw6SuKClhgYuwUZf5b3rd8u2mA==", "funding": [ { "type": "github", From 9327311f710ec248638151527936eba109325d70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 16:38:43 -0500 Subject: [PATCH 297/323] build(deps): bump ajv in /.github/actions/send-tweet (#3074) Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.12.6 to 6.14.0. - [Release notes](https://github.com/ajv-validator/ajv/releases) - [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v6.14.0) --- updated-dependencies: - dependency-name: ajv dependency-version: 6.14.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- .github/actions/send-tweet/package-lock.json | 306 +++++++++++++------ 1 file changed, 206 insertions(+), 100 deletions(-) diff --git a/.github/actions/send-tweet/package-lock.json b/.github/actions/send-tweet/package-lock.json index fc0d99cbe2..98aa84d768 100644 --- a/.github/actions/send-tweet/package-lock.json +++ b/.github/actions/send-tweet/package-lock.json @@ -1,282 +1,361 @@ { "name": "send-tweet", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@actions/core": { + "packages": { + "": { + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "@actions/core": "^1.9.1", + "twitter": "^1.7.1" + }, + "devDependencies": { + "@zeit/ncc": "^0.21.1" + } + }, + "node_modules/@actions/core": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", - "requires": { + "dependencies": { "@actions/http-client": "^2.0.1", "uuid": "^8.3.2" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - } } }, - "@actions/http-client": { + "node_modules/@actions/core/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@actions/http-client": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz", "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==", - "requires": { + "dependencies": { "tunnel": "^0.0.6" } }, - "@zeit/ncc": { + "node_modules/@zeit/ncc": { "version": "0.21.1", "resolved": "https://registry.npmjs.org/@zeit/ncc/-/ncc-0.21.1.tgz", "integrity": "sha512-M9WzgquSOt2nsjRkYM9LRylBLmmlwNCwYbm3Up3PDEshfvdmIfqpFNSK8EJvR18NwZjGHE5z2avlDtYQx2JQnw==", - "dev": true + "deprecated": "@zeit/ncc is no longer maintained. Please use @vercel/ncc instead.", + "dev": true, + "bin": { + "ncc": "dist/ncc/cli.js" + } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "license": "MIT", + "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "asn1": { + "node_modules/asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { + "dependencies": { "safer-buffer": "~2.1.0" } }, - "assert-plus": { + "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } }, - "asynckit": { + "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "aws-sign2": { + "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "engines": { + "node": "*" + } }, - "aws4": { + "node_modules/aws4": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" }, - "bcrypt-pbkdf": { + "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { + "dependencies": { "tweetnacl": "^0.14.3" } }, - "caseless": { + "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "combined-stream": { + "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { + "dependencies": { "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "core-util-is": { + "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "dashdash": { + "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { + "dependencies": { "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" } }, - "deep-extend": { + "node_modules/deep-extend": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==" + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } }, - "delayed-stream": { + "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } }, - "ecc-jsbn": { + "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { + "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, - "extend": { + "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "extsprintf": { + "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ] }, - "fast-deep-equal": { + "node_modules/fast-deep-equal": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" }, - "fast-json-stable-stringify": { + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "forever-agent": { + "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "engines": { + "node": "*" + } }, - "form-data": { + "node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { + "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" } }, - "getpass": { + "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { + "dependencies": { "assert-plus": "^1.0.0" } }, - "har-schema": { + "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "engines": { + "node": ">=4" + } }, - "har-validator": { + "node_modules/har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { + "deprecated": "this library is no longer supported", + "dependencies": { "ajv": "^6.5.5", "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "http-signature": { + "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { + "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "is-typedarray": { + "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, - "isstream": { + "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, - "jsbn": { + "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, - "json-schema": { + "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, - "json-schema-traverse": { + "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, - "json-stringify-safe": { + "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, - "jsprim": { + "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "requires": { + "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.4.0", "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, - "mime-db": { + "node_modules/mime-db": { "version": "1.43.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/mime-types": { "version": "2.1.26", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", - "requires": { + "dependencies": { "mime-db": "1.43.0" + }, + "engines": { + "node": ">= 0.6" } }, - "oauth-sign": { + "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } }, - "performance-now": { + "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, - "psl": { + "node_modules/psl": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" }, - "punycode": { + "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } }, - "qs": { + "node_modules/qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } }, - "request": { + "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", "caseless": "~0.12.0", @@ -297,23 +376,26 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" } }, - "safe-buffer": { + "node_modules/safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, - "safer-buffer": { + "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sshpk": { + "node_modules/sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { + "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", @@ -323,62 +405,86 @@ "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" } }, - "tough-cookie": { + "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==", - "requires": { + "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" } }, - "tunnel": { + "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } }, - "tunnel-agent": { + "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { + "dependencies": { "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" } }, - "tweetnacl": { + "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, - "twitter": { + "node_modules/twitter": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/twitter/-/twitter-1.7.1.tgz", "integrity": "sha1-B2I3jx3BwFDkj2ZqypBOJLGpYvQ=", - "requires": { + "dependencies": { "deep-extend": "^0.5.0", "request": "^2.72.0" } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { + "dependencies": { "punycode": "^2.1.0" } }, - "uuid": { + "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } }, - "verror": { + "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { + "engines": [ + "node >=0.6.0" + ], + "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" From ccddfe1f137f049c38f44aa6ead0823f95a3eefc Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 25 Feb 2026 11:31:30 -0500 Subject: [PATCH 298/323] chore: upgrade @types/node to v25.2.0 and fix type compatibility (#3078) * chore: upgrade @types/node to v25.2.0 and fix type compatibility * clean up * more cleanup --- package-lock.json | 18 ++++++++++-------- package.json | 2 +- src/utils/api-request.ts | 8 ++++---- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index c9b8131167..72ebb2149e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,6 @@ "@fastify/busboy": "^3.0.0", "@firebase/database-compat": "^2.0.0", "@firebase/database-types": "^1.0.6", - "@types/node": "^22.8.7", "farmhash-modern": "^1.1.0", "fast-deep-equal": "^3.1.1", "google-auth-library": "^9.14.2", @@ -36,6 +35,7 @@ "@types/minimist": "^1.2.2", "@types/mocha": "^10.0.0", "@types/nock": "^11.1.0", + "@types/node": "^25.2.0", "@types/request": "^2.47.0", "@types/request-promise": "^4.1.41", "@types/sinon": "^17.0.2", @@ -2191,11 +2191,12 @@ } }, "node_modules/@types/node": { - "version": "22.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", - "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "version": "25.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", + "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "license": "MIT", "dependencies": { - "undici-types": "~6.20.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/qs": { @@ -11834,9 +11835,10 @@ } }, "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" }, "node_modules/unique-stream": { "version": "2.3.1", diff --git a/package.json b/package.json index 7e7c494da7..c580a508e1 100644 --- a/package.json +++ b/package.json @@ -209,7 +209,6 @@ "@fastify/busboy": "^3.0.0", "@firebase/database-compat": "^2.0.0", "@firebase/database-types": "^1.0.6", - "@types/node": "^22.8.7", "farmhash-modern": "^1.1.0", "fast-deep-equal": "^3.1.1", "google-auth-library": "^9.14.2", @@ -237,6 +236,7 @@ "@types/minimist": "^1.2.2", "@types/mocha": "^10.0.0", "@types/nock": "^11.1.0", + "@types/node": "^25.2.0", "@types/request": "^2.47.0", "@types/request-promise": "^4.1.41", "@types/sinon": "^17.0.2", diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index a6a578b81c..9616b7a39f 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -733,7 +733,7 @@ class AsyncHttpCall extends AsyncRequestCall { if (!validator.isNonNullObject(this.options.headers)) { this.options.headers = {}; } - this.entity = this.httpConfigImpl.buildEntity(this.options.headers); + this.entity = this.httpConfigImpl.buildEntity(this.options.headers as http.OutgoingHttpHeaders); this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; @@ -834,7 +834,7 @@ class AsyncHttp2Call extends AsyncRequestCall { if (!validator.isNonNullObject(this.options.headers)) { this.options.headers = {}; } - this.entity = this.http2ConfigImpl.buildEntity(this.options.headers); + this.entity = this.http2ConfigImpl.buildEntity(this.options.headers as http.OutgoingHttpHeaders); this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; @@ -1354,11 +1354,11 @@ export class Http2SessionHandler { )); }) - http2Session.on('error', (error) => { + http2Session.on('error', (error: any) => { let errorMessage: any; if (error.name == 'AggregateError' && error.errors) { errorMessage = `Session error while making requests: ${error.code} - ${error.name}: ` + - `[${error.errors.map((error: any) => error.message).join(', ')}]` + `[${error.errors.map((e: any) => e.message).join(', ')}]` } else { errorMessage = `Session error while making requests: ${error.code} - ${error.message} ` } From 0f291137587a03fe7fc6c571c7a3c6da3318039b Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 25 Feb 2026 15:29:18 -0500 Subject: [PATCH 299/323] chore: Deprecate Node.js 18 support (#3079) * chore: Deprecate Node.js 18 support * Update README.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ebe57eab4..8c695d8c89 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,8 @@ requests, code review feedback, and also pull requests. ## Supported Environments -We support Node.js 18 and higher. +We currently support Node.js 18 and higher, but its support is deprecated. We strongly encourage +you to use Node.js 20 or higher as we will drop support for Node.js 18 in the next major version. Please also note that the Admin SDK should only be used in server-side/back-end environments controlled by the app developer. From 9c4261e210446c457122ff64752de1504fefcd68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:44:30 -0500 Subject: [PATCH 300/323] build(deps): bump @types/node from 22.10.2 to 25.2.0 (#3064) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.10.2 to 25.2.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.2.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72ebb2149e..e08b6b3377 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2191,12 +2191,12 @@ } }, "node_modules/@types/node": { - "version": "25.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", - "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", + "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/qs": { @@ -11835,9 +11835,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "license": "MIT" }, "node_modules/unique-stream": { From 189f0ee5e52e27d698c769b8462a491ce04cdfad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:09:56 -0500 Subject: [PATCH 301/323] build(deps): bump google-auth-library from 9.15.1 to 10.6.1 (#3084) Bumps [google-auth-library](https://github.com/googleapis/google-cloud-node-core/tree/HEAD/packages/google-auth-library-nodejs) from 9.15.1 to 10.6.1. - [Release notes](https://github.com/googleapis/google-cloud-node-core/releases) - [Changelog](https://github.com/googleapis/google-cloud-node-core/blob/main/packages/google-auth-library-nodejs/CHANGELOG.md) - [Commits](https://github.com/googleapis/google-cloud-node-core/commits/google-auth-library-v10.6.1/packages/google-auth-library-nodejs) --- updated-dependencies: - dependency-name: google-auth-library dependency-version: 10.6.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 401 +++++++++++++++++++++++++++++++++++++++------- package.json | 2 +- 2 files changed, 342 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index e08b6b3377..ff3c73f903 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@firebase/database-types": "^1.0.6", "farmhash-modern": "^1.1.0", "fast-deep-equal": "^3.1.1", - "google-auth-library": "^9.14.2", + "google-auth-library": "^10.6.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", "node-forge": "^1.3.1", @@ -886,6 +886,49 @@ "node": ">=14" } }, + "node_modules/@google-cloud/storage/node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/google-auth-library": { + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@google-cloud/storage/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -1017,7 +1060,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -1034,7 +1076,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "engines": { "node": ">=12" }, @@ -1046,7 +1087,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, "engines": { "node": ">=12" }, @@ -1057,14 +1097,12 @@ "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1081,7 +1119,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1096,7 +1133,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -1624,7 +1660,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "optional": true, "engines": { "node": ">=14" @@ -2779,7 +2814,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -2789,7 +2823,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3285,7 +3318,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/bare-events": { @@ -3349,9 +3381,9 @@ } }, "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", "license": "MIT", "engines": { "node": "*" @@ -3870,7 +3902,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -3883,7 +3914,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true, "license": "MIT" }, "node_modules/color-support": { @@ -4062,6 +4092,15 @@ "node": ">=0.10" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/data-view-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", @@ -4339,8 +4378,7 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/ecc-jsbn": { "version": "0.1.2", @@ -4373,7 +4411,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true, "license": "MIT" }, "node_modules/end-of-stream": { @@ -4990,6 +5027,29 @@ "dev": true, "license": "MIT" }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -5214,7 +5274,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", @@ -5231,7 +5290,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -5246,7 +5304,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -5259,7 +5316,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -5299,6 +5355,18 @@ "node": ">= 0.12" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", @@ -5422,6 +5490,7 @@ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", "license": "Apache-2.0", + "optional": true, "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", @@ -5438,6 +5507,7 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "license": "MIT", + "optional": true, "dependencies": { "debug": "^4.3.4" }, @@ -5450,6 +5520,7 @@ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "license": "MIT", + "optional": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -5467,21 +5538,93 @@ "https://github.com/sponsors/ctavan" ], "license": "MIT", + "optional": true, "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", "license": "Apache-2.0", "dependencies": { - "gaxios": "^6.0.0", + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", "json-bigint": "^1.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" + } + }, + "node_modules/gcp-metadata/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/gcp-metadata/node_modules/gaxios": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gcp-metadata/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/gcp-metadata/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/gcp-metadata/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/gensync": { @@ -5602,7 +5745,6 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -5670,7 +5812,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -5679,7 +5820,6 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5694,7 +5834,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -5799,20 +5938,90 @@ } }, "node_modules/google-auth-library": { - "version": "9.15.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", - "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.1.tgz", + "integrity": "sha512-5awwuLrzNol+pFDmKJd0dKtZ0fPLAtoA5p7YO4ODsDu6ONJUVqbYwvv8y2ZBO5MBNp9TJXigB19710kYpBPdtA==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^6.1.1", - "gcp-metadata": "^6.1.0", - "gtoken": "^7.0.0", + "gaxios": "7.1.3", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", "jws": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" + } + }, + "node_modules/google-auth-library/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/google-auth-library/node_modules/gaxios": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-auth-library/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/google-auth-library/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/google-auth-library/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/google-gax": { @@ -5839,6 +6048,49 @@ "node": ">=14" } }, + "node_modules/google-gax/node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/google-auth-library": { + "version": "9.15.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", + "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/google-gax/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -5853,6 +6105,15 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -5885,6 +6146,7 @@ "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", "license": "MIT", + "optional": true, "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" @@ -6999,7 +7261,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -7157,6 +7418,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -7297,7 +7559,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/isobject": { @@ -7506,7 +7767,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -8280,7 +8540,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, "license": "ISC", "engines": { "node": ">=8" @@ -8503,11 +8762,32 @@ "node": "^18 || ^20 || >= 21" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", + "optional": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -9260,8 +9540,7 @@ "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -9356,7 +9635,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9396,7 +9674,6 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -9411,8 +9688,7 @@ "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, "node_modules/path-to-regexp": { "version": "8.2.0", @@ -10588,7 +10864,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -10601,7 +10876,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11008,7 +11282,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "devOptional": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -11024,7 +11297,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11109,7 +11381,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -11123,7 +11394,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11533,7 +11803,8 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/ts-api-utils": { "version": "2.4.0", @@ -12146,11 +12417,21 @@ "node": ">=10.13.0" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "optional": true }, "node_modules/websocket-driver": { "version": "0.7.4", @@ -12180,6 +12461,7 @@ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", + "optional": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -12281,7 +12563,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", diff --git a/package.json b/package.json index c580a508e1..232790dde8 100644 --- a/package.json +++ b/package.json @@ -211,7 +211,7 @@ "@firebase/database-types": "^1.0.6", "farmhash-modern": "^1.1.0", "fast-deep-equal": "^3.1.1", - "google-auth-library": "^9.14.2", + "google-auth-library": "^10.6.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", "node-forge": "^1.3.1", From ca0a2d277327e58b32ee728da28a3be707a362be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:21:33 -0500 Subject: [PATCH 302/323] build(deps): bump node-forge from 1.3.2 to 1.3.3 (#3085) Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.2 to 1.3.3. - [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md) - [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.2...v1.3.3) --- updated-dependencies: - dependency-name: node-forge dependency-version: 1.3.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ff3c73f903..f4575b1070 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8804,9 +8804,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz", - "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", + "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" From 64b7755876066c78961f315e59640b71a90e2db1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 08:36:06 -0500 Subject: [PATCH 303/323] build(deps-dev): bump @typescript-eslint/eslint-plugin (#3086) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.56.0 to 8.56.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.56.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.56.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 120 +++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/package-lock.json b/package-lock.json index f4575b1070..35ebdfc404 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2334,17 +2334,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", - "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/type-utils": "8.56.0", - "@typescript-eslint/utils": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -2357,7 +2357,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.56.0", + "@typescript-eslint/parser": "^8.56.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -2373,16 +2373,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", - "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "engines": { @@ -2398,14 +2398,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", - "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.0", - "@typescript-eslint/types": "^8.56.0", + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "engines": { @@ -2420,14 +2420,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", - "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2438,9 +2438,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", - "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, "license": "MIT", "engines": { @@ -2455,15 +2455,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", - "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -2480,9 +2480,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", - "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, "license": "MIT", "engines": { @@ -2494,18 +2494,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", - "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.56.0", - "@typescript-eslint/tsconfig-utils": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -2545,16 +2545,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz", - "integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2574,16 +2574,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", - "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2598,13 +2598,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", - "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/types": "8.56.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { From 0da27afb05506fd45127340f8020238425a0c640 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:28:52 -0500 Subject: [PATCH 304/323] build(deps-dev): bump @types/lodash from 4.17.18 to 4.17.24 (#3083) Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.18 to 4.17.24. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-version: 4.17.24 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 35ebdfc404..0b8a7b9669 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2175,9 +2175,9 @@ } }, "node_modules/@types/lodash": { - "version": "4.17.18", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.18.tgz", - "integrity": "sha512-KJ65INaxqxmU6EoCiJmRPZC9H9RVWCRd349tXM2M3O5NA7cY6YL7c0bHAHQ93NOfTObEQ004kd2QVHs/r0+m4g==", + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", + "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", "dev": true, "license": "MIT" }, From 2279070bcea42f380b44b58acc576cbd63ebd0ee Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 26 Feb 2026 12:10:21 -0500 Subject: [PATCH 305/323] [chore] Release 13.7.0 (#3081) --- package-lock.json | 18 +++++++++++++++--- package.json | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0b8a7b9669..6038d7ae77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.6.1", + "version": "13.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.6.1", + "version": "13.7.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -126,6 +126,7 @@ "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", @@ -603,7 +604,8 @@ "node_modules/@firebase/app-types": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "peer": true }, "node_modules/@firebase/app/node_modules/@firebase/component": { "version": "0.6.13", @@ -802,6 +804,7 @@ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", "hasInstallScript": true, + "peer": true, "dependencies": { "tslib": "^2.1.0" }, @@ -2230,6 +2233,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.18.0" } @@ -2378,6 +2382,7 @@ "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", @@ -2654,6 +2659,7 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3497,6 +3503,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -3669,6 +3676,7 @@ "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -4598,6 +4606,7 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6161,6 +6170,7 @@ "integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "glob-watcher": "^6.0.0", "gulp-cli": "^3.1.0", @@ -11738,6 +11748,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -12035,6 +12046,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 232790dde8..1844240d0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.6.1", + "version": "13.7.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From 1773f030df17f5877accc48922901b6c3035687e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 28 Feb 2026 20:25:22 -0500 Subject: [PATCH 306/323] build(deps): bump fast-xml-parser from 5.3.7 to 5.4.1 (#3087) Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.3.7 to 5.4.1. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.3.7...v5.4.1) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.4.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6038d7ae77..dea8d29887 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,7 +126,6 @@ "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", @@ -604,8 +603,7 @@ "node_modules/@firebase/app-types": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", - "peer": true + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" }, "node_modules/@firebase/app/node_modules/@firebase/component": { "version": "0.6.13", @@ -804,7 +802,6 @@ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", "hasInstallScript": true, - "peer": true, "dependencies": { "tslib": "^2.1.0" }, @@ -2233,7 +2230,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.18.0" } @@ -2382,7 +2378,6 @@ "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", @@ -2659,7 +2654,6 @@ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3503,7 +3497,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", @@ -3676,7 +3669,6 @@ "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -4606,7 +4598,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4978,10 +4969,23 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-xml-builder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", + "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true + }, "node_modules/fast-xml-parser": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.7.tgz", - "integrity": "sha512-JzVLro9NQv92pOM/jTCR6mHlJh2FGwtomH8ZQjhFj/R29P2Fnj38OgPJVtcvYw6SuKClhgYuwUZf5b3rd8u2mA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", + "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", "funding": [ { "type": "github", @@ -4991,6 +4995,7 @@ "license": "MIT", "optional": true, "dependencies": { + "fast-xml-builder": "^1.0.0", "strnum": "^2.1.2" }, "bin": { @@ -6170,7 +6175,6 @@ "integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "glob-watcher": "^6.0.0", "gulp-cli": "^3.1.0", @@ -11748,7 +11752,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -12046,7 +12049,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" From 7cbc3141658caeaa1a2bbce91be0c901452c7d0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 10:51:02 -0400 Subject: [PATCH 307/323] build(deps): bump fast-xml-parser from 5.4.1 to 5.5.6 (#3093) Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.4.1 to 5.5.6. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.4.1...v5.5.6) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.5.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index dea8d29887..0c73da8982 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4970,9 +4970,9 @@ "license": "MIT" }, "node_modules/fast-xml-builder": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", - "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", + "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", "funding": [ { "type": "github", @@ -4980,12 +4980,15 @@ } ], "license": "MIT", - "optional": true + "optional": true, + "dependencies": { + "path-expression-matcher": "^1.1.3" + } }, "node_modules/fast-xml-parser": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", - "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.6.tgz", + "integrity": "sha512-3+fdZyBRVg29n4rXP0joHthhcHdPUHaIC16cuyyd1iLsuaO6Vea36MPrxgAzbZna8lhvZeRL8Bc9GP56/J9xEw==", "funding": [ { "type": "github", @@ -4995,7 +4998,8 @@ "license": "MIT", "optional": true, "dependencies": { - "fast-xml-builder": "^1.0.0", + "fast-xml-builder": "^1.1.4", + "path-expression-matcher": "^1.1.3", "strnum": "^2.1.2" }, "bin": { @@ -9635,6 +9639,22 @@ "node": ">=8" } }, + "node_modules/path-expression-matcher": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.1.3.tgz", + "integrity": "sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", From 7fbad72eb4a453ababd971c6345f44283479d7fe Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 23 Mar 2026 16:48:43 -0400 Subject: [PATCH 308/323] feat(fcm): Add bandwidthConstrainedOk and restrictedSatelliteOk (#2994) * feat(messaging): Add bandwidthConstrainedOk and restrictedSatelliteOk to AndroidConfig Adds two new optional boolean properties, `bandwidthConstrainedOk` and `restrictedSatelliteOk`, to the `AndroidConfig` type in the messaging API. This change includes: - Updating the `AndroidConfig` interface in `src/messaging/messaging-api.ts`. - Adding the corresponding property mappings in `src/messaging/messaging-internal.ts`. - Updating unit tests in `test/unit/messaging/messaging.spec.ts` to cover the new properties. * feat(messaging): Add bandwidthConstrainedOk and restrictedSatelliteOk to AndroidConfig Adds two new optional boolean properties, `bandwidthConstrainedOk` and `restrictedSatelliteOk`, to the `AndroidConfig` type in the messaging API. This change includes: - Updating the `AndroidConfig` interface in `src/messaging/messaging-api.ts`. - Adding the corresponding property mappings in `src/messaging/messaging-internal.ts`. - Updating unit tests in `test/unit/messaging/messaging.spec.ts` to cover the new properties. - Updating the public API documentation. * fix docstrings --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- etc/firebase-admin.messaging.api.md | 2 ++ src/messaging/messaging-api.ts | 12 ++++++++++++ src/messaging/messaging-internal.ts | 2 ++ test/unit/messaging/messaging.spec.ts | 8 ++++++++ 4 files changed, 24 insertions(+) diff --git a/etc/firebase-admin.messaging.api.md b/etc/firebase-admin.messaging.api.md index 1ad50f85f6..b93ba7e58e 100644 --- a/etc/firebase-admin.messaging.api.md +++ b/etc/firebase-admin.messaging.api.md @@ -8,6 +8,7 @@ import { Agent } from 'http'; // @public export interface AndroidConfig { + bandwidthConstrainedOk?: boolean; collapseKey?: string; data?: { [key: string]: string; @@ -17,6 +18,7 @@ export interface AndroidConfig { notification?: AndroidNotification; priority?: ('high' | 'normal'); restrictedPackageName?: string; + restrictedSatelliteOk?: boolean; ttl?: number; } diff --git a/src/messaging/messaging-api.ts b/src/messaging/messaging-api.ts index a305ec68b3..516c07bb44 100644 --- a/src/messaging/messaging-api.ts +++ b/src/messaging/messaging-api.ts @@ -428,6 +428,18 @@ export interface AndroidConfig { * the app while the device is in direct boot mode. */ directBootOk?: boolean; + + /** + * A boolean indicating whether messages will be allowed to be delivered to + * the app while the device is on a bandwidth constrained network. + */ + bandwidthConstrainedOk?: boolean; + + /** + * A boolean indicating whether messages will be allowed to be delivered to + * the app while the device is on a restricted satellite network. + */ + restrictedSatelliteOk?: boolean; } /** diff --git a/src/messaging/messaging-internal.ts b/src/messaging/messaging-internal.ts index 311d2af4be..6427b98e0a 100644 --- a/src/messaging/messaging-internal.ts +++ b/src/messaging/messaging-internal.ts @@ -422,6 +422,8 @@ function validateAndroidConfig(config: AndroidConfig | undefined): void { collapseKey: 'collapse_key', restrictedPackageName: 'restricted_package_name', directBootOk: 'direct_boot_ok', + bandwidthConstrainedOk: 'bandwidth_constrained_ok', + restrictedSatelliteOk: 'restricted_satellite_ok', }; renameProperties(config, propertyMappings); } diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index d51c186c48..af4dad1d4d 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -1899,6 +1899,8 @@ describe('Messaging', () => { collapseKey: 'test.key', restrictedPackageName: 'test.package', directBootOk: true, + bandwidthConstrainedOk: true, + restrictedSatelliteOk: true, notification: { clickAction: 'test.click.action', titleLocKey: 'title.loc.key', @@ -1927,6 +1929,8 @@ describe('Messaging', () => { collapse_key: 'test.key', restricted_package_name: 'test.package', direct_boot_ok: true, + bandwidth_constrained_ok: true, + restricted_satellite_ok: true, notification: { click_action: 'test.click.action', title_loc_key: 'title.loc.key', @@ -1983,6 +1987,8 @@ describe('Messaging', () => { collapseKey: 'test.key', restrictedPackageName: 'test.package', directBootOk: true, + bandwidthConstrainedOk: true, + restrictedSatelliteOk: true, ttl: 5, data: { k1: 'v1', @@ -2031,6 +2037,8 @@ describe('Messaging', () => { collapse_key: 'test.key', restricted_package_name: 'test.package', direct_boot_ok: true, + bandwidth_constrained_ok: true, + restricted_satellite_ok: true, ttl: '0.005000000s', // 5 ms = 5,000,000 ns data: { k1: 'v1', From a3faacf7c35723b0a4f44ff1be960d01ba90119a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 12:22:07 -0400 Subject: [PATCH 309/323] build(deps): bump fast-xml-parser from 5.5.6 to 5.5.7 (#3095) Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.5.6 to 5.5.7. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.5.6...v5.5.7) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.5.7 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0c73da8982..faeca3f0a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4986,9 +4986,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "5.5.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.6.tgz", - "integrity": "sha512-3+fdZyBRVg29n4rXP0joHthhcHdPUHaIC16cuyyd1iLsuaO6Vea36MPrxgAzbZna8lhvZeRL8Bc9GP56/J9xEw==", + "version": "5.5.7", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.7.tgz", + "integrity": "sha512-LteOsISQ2GEiDHZch6L9hB0+MLoYVLToR7xotrzU0opCICBkxOPgHAy1HxAvtxfJNXDJpgAsQN30mkrfpO2Prg==", "funding": [ { "type": "github", @@ -5000,7 +5000,7 @@ "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.1.3", - "strnum": "^2.1.2" + "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" @@ -11459,9 +11459,9 @@ } }, "node_modules/strnum": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", - "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz", + "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==", "funding": [ { "type": "github", From c8de86dda584775496b813f5e24ccbfb9ccac597 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 8 Apr 2026 16:10:03 -0400 Subject: [PATCH 310/323] feat(pnv): Add support for Phone Number Verification (#3101) * feat(auth): Add support for FPNV (#3030) * feat: add basic fpnv * chore: resolve comments * fix: remove unused interface * chore: update export * chore: linting * chore: update export * feat: add apidocs * chore: resolve commnets * chore: linting * chore: add unit test * chore: change test description * chore: remove extra line * chore: add unit test * chore: add unit test * chore: fix minor comments * chore: add unit test * chore: add unot test * chore: update api.md * chore: update sdk * feat: update fpnv * chore: update jwt spec * chore: resolve comments * chore: test cover Fpnv index * chore: update test coverage * feat: add namespace support * fix(fpnv): validate JWT audience using project ID and improve safety checks * rename FPNV to PhoneNumberVerification and replace getPhoneNumber() with property * remove namspaces and ensure naming consistency * fix api extractor * fix tests * address PR feedback * PR comments PR comments --------- Co-authored-by: boikoa-gl --- entrypoints.json | 4 + ...ase-admin.phone-number-verification.api.md | 33 + package-lock.json | 3296 ++++++++++------- package.json | 8 + src/phone-number-verification/index.ts | 66 + ...number-verification-api-client-internal.ts | 72 + .../phone-number-verification-api.ts | 86 + .../phone-number-verification.ts | 65 + .../token-verifier.ts | 213 ++ src/utils/jwt.ts | 4 +- test/unit/index.spec.ts | 7 + .../phone-number-verification/index.spec.ts | 77 + ...r-verification-api-client-internal.spec.ts | 86 + .../phone-number-verification.spec.ts | 102 + .../token-verifier.spec.ts | 326 ++ test/unit/utils/jwt.spec.ts | 16 +- 16 files changed, 3068 insertions(+), 1393 deletions(-) create mode 100644 etc/firebase-admin.phone-number-verification.api.md create mode 100644 src/phone-number-verification/index.ts create mode 100644 src/phone-number-verification/phone-number-verification-api-client-internal.ts create mode 100644 src/phone-number-verification/phone-number-verification-api.ts create mode 100644 src/phone-number-verification/phone-number-verification.ts create mode 100644 src/phone-number-verification/token-verifier.ts create mode 100644 test/unit/phone-number-verification/index.spec.ts create mode 100644 test/unit/phone-number-verification/phone-number-verification-api-client-internal.spec.ts create mode 100644 test/unit/phone-number-verification/phone-number-verification.spec.ts create mode 100644 test/unit/phone-number-verification/token-verifier.spec.ts diff --git a/entrypoints.json b/entrypoints.json index caa92a7604..27906c2fa8 100644 --- a/entrypoints.json +++ b/entrypoints.json @@ -16,6 +16,10 @@ "typings": "./lib/auth/index.d.ts", "dist": "./lib/auth/index.js" }, + "firebase-admin/phone-number-verification": { + "typings": "./lib/phone-number-verification/index.d.ts", + "dist": "./lib/phone-number-verification/index.js" + }, "firebase-admin/database": { "typings": "./lib/database/index.d.ts", "dist": "./lib/database/index.js" diff --git a/etc/firebase-admin.phone-number-verification.api.md b/etc/firebase-admin.phone-number-verification.api.md new file mode 100644 index 0000000000..90b118a661 --- /dev/null +++ b/etc/firebase-admin.phone-number-verification.api.md @@ -0,0 +1,33 @@ +## API Report File for "firebase-admin.phone-number-verification" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Agent } from 'http'; + +// Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts +// +// @public +export function getPhoneNumberVerification(app?: App): PhoneNumberVerification; + +// @public +export class PhoneNumberVerification { + get app(): App; + verifyToken(jwt: string): Promise; +} + +// @public +export interface PhoneNumberVerificationToken { + [key: string]: any; + aud: string[]; + exp: number; + iat: number; + iss: string; + jti: string; + nonce: string; + phoneNumber: string; + sub: string; +} + +``` diff --git a/package-lock.json b/package-lock.json index faeca3f0a2..0a561dc40b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,39 +81,25 @@ "@google-cloud/storage": "^7.19.0" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", - "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -121,22 +107,22 @@ } }, "node_modules/@babel/core": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", - "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.0", - "@babel/generator": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.0", - "@babel/parser": "^7.26.0", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.26.0", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -169,16 +155,16 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", - "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.2", - "@babel/types": "^7.26.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { @@ -186,14 +172,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", - "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -229,30 +215,40 @@ "dev": true, "license": "ISC" }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -262,9 +258,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -272,9 +268,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -282,9 +278,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", "engines": { @@ -292,27 +288,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", - "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.0" + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -322,58 +318,48 @@ } }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -457,9 +443,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -473,6 +459,34 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -481,9 +495,9 @@ "license": "MIT" }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -533,9 +547,9 @@ } }, "node_modules/@firebase/app": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.11.2.tgz", - "integrity": "sha512-bFee0hPJZBzNtiizRxdgsu8C9DW3mn1y0OJJ4zHQsccjDYzGOfvN0G3CMGyBIiwNctsFpQa8orbp2IKywoUeqA==", + "version": "0.11.5", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.11.5.tgz", + "integrity": "sha512-uNp8/Rv12GrrM/dfyqzZCftA2i/5X9axmiEtUDmyQw+0S17EV5s9gudOgdIIGr849LmbAk3At2CBZMqiQJVwNw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -556,13 +570,13 @@ "license": "Apache-2.0" }, "node_modules/@firebase/app-compat": { - "version": "0.2.51", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.51.tgz", - "integrity": "sha512-pxF1+coABt+ugqNI0YXDlmkKv4kh3pjI5BqIJJ1VXBo42OZbKMsQbFeos14YBrWwiqqSjUvQ70FBNsv5E2wuxg==", + "version": "0.2.54", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.54.tgz", + "integrity": "sha512-Vwf29tV/5bHEnp+VPgNWOFMbFG+RSur2ntmzZ19Plp5dJOtoo2nQS817COALLaHlebG/Xf/P5PVHyeQNcSVCqQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@firebase/app": "0.11.2", + "@firebase/app": "0.11.5", "@firebase/component": "0.6.13", "@firebase/logger": "0.4.4", "@firebase/util": "1.11.0", @@ -572,20 +586,6 @@ "node": ">=18.0.0" } }, - "node_modules/@firebase/app-compat/node_modules/@firebase/component": { - "version": "0.6.13", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.13.tgz", - "integrity": "sha512-I/Eg1NpAtZ8AAfq8mpdfXnuUpcLxIDdCDtTzWSh+FXnp/9eCKJ3SNbOCKrUCyhLzNa2SiPJYruei0sxVjaOTeg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@firebase/util": "1.11.0", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@firebase/app-compat/node_modules/@firebase/util": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.0.tgz", @@ -603,21 +603,8 @@ "node_modules/@firebase/app-types": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", - "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==" - }, - "node_modules/@firebase/app/node_modules/@firebase/component": { - "version": "0.6.13", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.13.tgz", - "integrity": "sha512-I/Eg1NpAtZ8AAfq8mpdfXnuUpcLxIDdCDtTzWSh+FXnp/9eCKJ3SNbOCKrUCyhLzNa2SiPJYruei0sxVjaOTeg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@firebase/util": "1.11.0", - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=18.0.0" - } + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" }, "node_modules/@firebase/app/node_modules/@firebase/util": { "version": "1.11.0", @@ -634,14 +621,15 @@ } }, "node_modules/@firebase/auth": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.11.0.tgz", - "integrity": "sha512-5j7+ua93X+IRcJ1oMDTClTo85l7Xe40WSkoJ+shzPrX7OISlVWLdE1mKC57PSD+/LfAbdhJmvKixINBw2ESK6w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.12.2.tgz", + "integrity": "sha512-CZJL8V10Vzibs+pDTXdQF+hot1IigIoqF4a4lA/qr5Deo1srcefiyIfgg28B67Lk7IxZhwfJMuI+1bu2xBmV0A==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.7.0", + "@firebase/component": "0.7.2", "@firebase/logger": "0.5.0", - "@firebase/util": "1.13.0", + "@firebase/util": "1.15.0", "tslib": "^2.1.0" }, "engines": { @@ -649,7 +637,7 @@ }, "peerDependencies": { "@firebase/app": "0.x", - "@react-native-async-storage/async-storage": "^1.18.1" + "@react-native-async-storage/async-storage": "^2.2.0" }, "peerDependenciesMeta": { "@react-native-async-storage/async-storage": { @@ -658,15 +646,16 @@ } }, "node_modules/@firebase/auth-compat": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.6.0.tgz", - "integrity": "sha512-J0lGSxXlG/lYVi45wbpPhcWiWUMXevY4fvLZsN1GHh+po7TZVng+figdHBVhFheaiipU8HZyc7ljw1jNojM2nw==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.6.4.tgz", + "integrity": "sha512-2pj8m/hnqXvMLfC0Mk+fORVTM5DQPkS6l8JpMgtoAWGVgCmYnoWdFMaNWtKbmCxBEyvMA3FlnCJyzrUSMWTfuA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@firebase/auth": "1.11.0", + "@firebase/auth": "1.12.2", "@firebase/auth-types": "0.13.0", - "@firebase/component": "0.7.0", - "@firebase/util": "1.13.0", + "@firebase/component": "0.7.2", + "@firebase/util": "1.15.0", "tslib": "^2.1.0" }, "engines": { @@ -676,6 +665,20 @@ "@firebase/app-compat": "0.x" } }, + "node_modules/@firebase/auth-compat/node_modules/@firebase/component": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.2.tgz", + "integrity": "sha512-iyVDGc6Vjx7Rm0cAdccLH/NG6fADsgJak/XW9IA2lPf8AjIlsemOpFGKczYyPHxm4rnKdR8z6sK4+KEC7NwmEg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.15.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@firebase/auth-interop-types": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", @@ -687,16 +690,32 @@ "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.13.0.tgz", "integrity": "sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==", "dev": true, + "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", "@firebase/util": "1.x" } }, + "node_modules/@firebase/auth/node_modules/@firebase/component": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.2.tgz", + "integrity": "sha512-iyVDGc6Vjx7Rm0cAdccLH/NG6fADsgJak/XW9IA2lPf8AjIlsemOpFGKczYyPHxm4rnKdR8z6sK4+KEC7NwmEg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.15.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@firebase/auth/node_modules/@firebase/logger": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.5.0.tgz", "integrity": "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" }, @@ -705,28 +724,44 @@ } }, "node_modules/@firebase/component": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.0.tgz", - "integrity": "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==", + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.13.tgz", + "integrity": "sha512-I/Eg1NpAtZ8AAfq8mpdfXnuUpcLxIDdCDtTzWSh+FXnp/9eCKJ3SNbOCKrUCyhLzNa2SiPJYruei0sxVjaOTeg==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.13.0", + "@firebase/util": "1.11.0", "tslib": "^2.1.0" }, "engines": { - "node": ">=20.0.0" + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/component/node_modules/@firebase/util": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.11.0.tgz", + "integrity": "sha512-PzSrhIr++KI6y4P6C/IdgBNMkEx0Ex6554/cYd0Hm+ovyFSJtJXqb/3OSIdnBoa2cpwZT1/GW56EmRc5qEc5fQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@firebase/database": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.0.tgz", - "integrity": "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.1.2.tgz", + "integrity": "sha512-lP96CMjMPy/+d1d9qaaHjHHdzdwvEOuyyLq9ehX89e2XMKwS1jHNzYBO+42bdSumuj5ukPbmnFtViZu8YOMT+w==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", "@firebase/auth-interop-types": "0.2.4", - "@firebase/component": "0.7.0", + "@firebase/component": "0.7.2", "@firebase/logger": "0.5.0", - "@firebase/util": "1.13.0", + "@firebase/util": "1.15.0", "faye-websocket": "0.11.4", "tslib": "^2.1.0" }, @@ -735,16 +770,29 @@ } }, "node_modules/@firebase/database-compat": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.0.tgz", - "integrity": "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.1.2.tgz", + "integrity": "sha512-j4A6IhVZbgxAzT6gJJC2PfOxYCK9SrDrUO7nTM4EscTYtKkAkzsbKoCnDdjFapQfnsncvPWjqVTr/0PffUwg3g==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.7.0", - "@firebase/database": "1.1.0", - "@firebase/database-types": "1.0.16", + "@firebase/component": "0.7.2", + "@firebase/database": "1.1.2", + "@firebase/database-types": "1.0.18", "@firebase/logger": "0.5.0", - "@firebase/util": "1.13.0", + "@firebase/util": "1.15.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@firebase/database-compat/node_modules/@firebase/component": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.2.tgz", + "integrity": "sha512-iyVDGc6Vjx7Rm0cAdccLH/NG6fADsgJak/XW9IA2lPf8AjIlsemOpFGKczYyPHxm4rnKdR8z6sK4+KEC7NwmEg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.15.0", "tslib": "^2.1.0" }, "engines": { @@ -764,13 +812,26 @@ } }, "node_modules/@firebase/database-types": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.16.tgz", - "integrity": "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==", + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.18.tgz", + "integrity": "sha512-yOY8IC2go9lfbVDMiy2ATun4EB2AFwocPaQADwMN/RHRUAZSM4rlAV7PGbWPSG/YhkJ2A9xQAiAENgSua9G5Fg==", "license": "Apache-2.0", "dependencies": { "@firebase/app-types": "0.9.3", - "@firebase/util": "1.13.0" + "@firebase/util": "1.15.0" + } + }, + "node_modules/@firebase/database/node_modules/@firebase/component": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.7.2.tgz", + "integrity": "sha512-iyVDGc6Vjx7Rm0cAdccLH/NG6fADsgJak/XW9IA2lPf8AjIlsemOpFGKczYyPHxm4rnKdR8z6sK4+KEC7NwmEg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.15.0", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@firebase/database/node_modules/@firebase/logger": { @@ -790,6 +851,7 @@ "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" }, @@ -798,10 +860,11 @@ } }, "node_modules/@firebase/util": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.13.0.tgz", - "integrity": "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.15.0.tgz", + "integrity": "sha512-AmWf3cHAOMbrCPG4xdPKQaj5iHnyYfyLKZxwz+Xf55bqKbpAmcYifB4jQinT2W9XhDRHISOoPyBOariJpCG6FA==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" }, @@ -810,9 +873,10 @@ } }, "node_modules/@google-cloud/firestore": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.0.tgz", - "integrity": "sha512-88uZ+jLsp1aVMj7gh3EKYH1aulTAMFAp8sH/v5a9w8q8iqSG27RiWLoxSAFr/XocZ9hGiWH1kEnBw+zl3xAgNA==", + "version": "7.11.6", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.6.tgz", + "integrity": "sha512-EW/O8ktzwLfyWBOsNuhRoMi8lrC3clHM5LVFhGvO1HCsLozCOOXRAlHrYBoE6HL42Sc8yYMuCb2XqcnJ4OOEpw==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@opentelemetry/api": "^1.3.0", @@ -940,23 +1004,42 @@ } }, "node_modules/@grpc/grpc-js": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.2.tgz", - "integrity": "sha512-bgxdZmgTrJZX50OjyVwz3+mNEnCTNkh3cIqGPWVNeW9jX6bn1ZkU80uPd+67/ZpIJIjRQ9qaHCjhavyoWYxumg==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", + "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", "license": "Apache-2.0", "optional": true, "dependencies": { - "@grpc/proto-loader": "^0.7.13", + "@grpc/proto-loader": "^0.8.0", "@js-sdsl/ordered-map": "^4.4.2" }, "engines": { "node": ">=12.10.0" } }, + "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", + "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.5.3", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@grpc/proto-loader": { - "version": "0.7.13", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", - "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -1011,6 +1094,37 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -1033,33 +1147,12 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", - "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -1073,9 +1166,11 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -1083,26 +1178,19 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -1116,11 +1204,13 @@ } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -1129,22 +1219,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1177,9 +1251,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -1253,34 +1327,31 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6.0.0" + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { @@ -1288,16 +1359,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -1317,22 +1388,22 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.56.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.56.3.tgz", - "integrity": "sha512-fRqok4aRNq5GpgGBv2fKlSSKbirPKTJ75vQefthB5x9dwt4Zz+AezUzdc1p/AG4wUBIgmhjcEwn/Rj+N4Wh4Mw==", + "version": "7.57.7", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.57.7.tgz", + "integrity": "sha512-kmnmVs32MFWbV5X6BInC1/TfCs7y1ugwxv1xHsAIj/DyUfoe7vtO0alRUgbQa57+yRGHBBjlNcEk33SCAt5/dA==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.32.2", + "@microsoft/api-extractor-model": "7.33.4", "@microsoft/tsdoc": "~0.16.0", - "@microsoft/tsdoc-config": "~0.18.0", - "@rushstack/node-core-library": "5.19.1", - "@rushstack/rig-package": "0.6.0", - "@rushstack/terminal": "0.21.0", - "@rushstack/ts-command-line": "5.2.0", + "@microsoft/tsdoc-config": "~0.18.1", + "@rushstack/node-core-library": "5.20.3", + "@rushstack/rig-package": "0.7.2", + "@rushstack/terminal": "0.22.3", + "@rushstack/ts-command-line": "5.3.3", "diff": "~8.0.2", "lodash": "~4.17.23", - "minimatch": "10.1.2", + "minimatch": "10.2.3", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", @@ -1343,15 +1414,15 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.32.2", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.32.2.tgz", - "integrity": "sha512-Ussc25rAalc+4JJs9HNQE7TuO9y6jpYQX9nWD1DhqUzYPBr3Lr7O9intf+ZY8kD5HnIqeIRJX7ccCT0QyBy2Ww==", + "version": "7.33.4", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.33.4.tgz", + "integrity": "sha512-u1LTaNTikZAQ9uK6KG1Ms7nvNedsnODnspq/gH2dcyETWvH4hVNGNDvRAEutH66kAmxA4/necElqGNs1FggC8w==", "dev": true, "license": "MIT", "dependencies": { "@microsoft/tsdoc": "~0.16.0", - "@microsoft/tsdoc-config": "~0.18.0", - "@rushstack/node-core-library": "5.19.1" + "@microsoft/tsdoc-config": "~0.18.1", + "@rushstack/node-core-library": "5.20.3" } }, "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { @@ -1362,13 +1433,13 @@ "license": "MIT" }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "5.19.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.19.1.tgz", - "integrity": "sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==", + "version": "5.20.3", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.20.3.tgz", + "integrity": "sha512-95JgEPq2k7tHxhF9/OJnnyHDXfC9cLhhta0An/6MlkDsX2A6dTzDrTUG18vx4vjc280V0fi0xDH9iQczpSuWsw==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "~8.13.0", + "ajv": "~8.18.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", "fs-extra": "~11.3.0", @@ -1378,35 +1449,18 @@ "semver": "~7.5.4" }, "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@microsoft/api-extractor-model/node_modules/ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "@types/node": "*" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/@microsoft/api-extractor-model/node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "dependencies": { @@ -1449,13 +1503,13 @@ "license": "MIT" }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "5.19.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.19.1.tgz", - "integrity": "sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==", + "version": "5.20.3", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.20.3.tgz", + "integrity": "sha512-95JgEPq2k7tHxhF9/OJnnyHDXfC9cLhhta0An/6MlkDsX2A6dTzDrTUG18vx4vjc280V0fi0xDH9iQczpSuWsw==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "~8.13.0", + "ajv": "~8.18.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", "fs-extra": "~11.3.0", @@ -1474,49 +1528,22 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.2.0.tgz", - "integrity": "sha512-lYxCX0nDdkDtCkVpvF0m25ymf66SaMWuppbD6b7MdkIzvGXKBXNIVZlwBH/C0YfkanrupnICWf2n4z3AKSfaHw==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.3.3.tgz", + "integrity": "sha512-c+ltdcvC7ym+10lhwR/vWiOhsrm/bP3By2VsFcs5qTKv+6tTmxgbVrtJ5NdNjANiV5TcmOZgUN+5KYQ4llsvEw==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.21.0", + "@rushstack/terminal": "0.22.3", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" } }, - "node_modules/@microsoft/api-extractor/node_modules/ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@microsoft/api-extractor/node_modules/diff": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", - "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/@microsoft/api-extractor/node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "dependencies": { @@ -1541,22 +1568,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/@microsoft/api-extractor/node_modules/minimatch": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", - "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { "version": "5.8.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", @@ -1589,14 +1600,14 @@ "license": "MIT" }, "node_modules/@microsoft/tsdoc-config": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.18.0.tgz", - "integrity": "sha512-8N/vClYyfOH+l4fLkkr9+myAoR6M7akc8ntBJ4DJdWH2b09uVfr71+LTMpNyG19fNqWDg8KEDZhx5wxuqHyGjw==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.18.1.tgz", + "integrity": "sha512-9brPoVdfN9k9g0dcWkFeA7IH9bbcttzDJlXvkf8b2OBzd5MueR1V2wkKBL0abn0otvmkHJC6aapBOTJDDeMCZg==", "dev": true, "license": "MIT", "dependencies": { "@microsoft/tsdoc": "0.16.0", - "ajv": "~8.12.0", + "ajv": "~8.18.0", "jju": "~1.4.0", "resolve": "~1.22.2" } @@ -1647,9 +1658,9 @@ } }, "node_modules/@opentelemetry/api": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", "license": "Apache-2.0", "optional": true, "engines": { @@ -1660,6 +1671,8 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=14" @@ -1774,9 +1787,9 @@ } }, "node_modules/@rushstack/problem-matcher": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@rushstack/problem-matcher/-/problem-matcher-0.1.1.tgz", - "integrity": "sha512-Fm5XtS7+G8HLcJHCWpES5VmeMyjAKaWeyZU5qPzZC+22mPlJzAsOxymHiWIfuirtPckX3aptWws+K2d0BzniJA==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@rushstack/problem-matcher/-/problem-matcher-0.2.1.tgz", + "integrity": "sha512-gulfhBs6n+I5b7DvjKRfhMGyUejtSgOHTclF/eONr8hcgF1APEDjhxIsfdUYYMzC3rvLwGluqLjbwCFZ8nxrog==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1789,9 +1802,9 @@ } }, "node_modules/@rushstack/rig-package": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.6.0.tgz", - "integrity": "sha512-ZQmfzsLE2+Y91GF15c65L/slMRVhF6Hycq04D4TwtdGaUAbIXXg9c5pKA5KFU7M4QMaihoobp9JJYpYcaY3zOw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.7.2.tgz", + "integrity": "sha512-9XbFWuqMYcHUso4mnETfhGVUSaADBRj6HUAAEYk50nMPn8WRICmBuCphycQGNB3duIR6EEZX3Xj3SYc2XiP+9A==", "dev": true, "license": "MIT", "dependencies": { @@ -1800,14 +1813,14 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.21.0.tgz", - "integrity": "sha512-cLaI4HwCNYmknM5ns4G+drqdEB6q3dCPV423+d3TZeBusYSSm09+nR7CnhzJMjJqeRcdMAaLnrA4M/3xDz4R3w==", + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.22.3.tgz", + "integrity": "sha512-gHC9pIMrUPzAbBiI4VZMU7Q+rsCzb8hJl36lFIulIzoceKotyKL3Rd76AZ2CryCTKEg+0bnTj406HE5YY5OQvw==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.19.1", - "@rushstack/problem-matcher": "0.1.1", + "@rushstack/node-core-library": "5.20.3", + "@rushstack/problem-matcher": "0.2.1", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -1820,13 +1833,13 @@ } }, "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "5.19.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.19.1.tgz", - "integrity": "sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==", + "version": "5.20.3", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.20.3.tgz", + "integrity": "sha512-95JgEPq2k7tHxhF9/OJnnyHDXfC9cLhhta0An/6MlkDsX2A6dTzDrTUG18vx4vjc280V0fi0xDH9iQczpSuWsw==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "~8.13.0", + "ajv": "~8.18.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", "fs-extra": "~11.3.0", @@ -1844,27 +1857,10 @@ } } }, - "node_modules/@rushstack/terminal/node_modules/ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@rushstack/terminal/node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "dev": true, "license": "MIT", "dependencies": { @@ -2004,24 +2000,16 @@ } }, "node_modules/@sinonjs/samsam": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", - "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.3.tgz", + "integrity": "sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", - "lodash.get": "^4.4.2", "type-detect": "^4.1.0" } }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", - "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", - "dev": true, - "license": "(Unlicense OR Apache-2.0)" - }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -2033,9 +2021,9 @@ } }, "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", "dev": true, "license": "MIT" }, @@ -2084,16 +2072,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, "node_modules/@types/caseless": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", @@ -2118,39 +2096,6 @@ "@types/chai": "*" } }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "node_modules/@types/firebase-token-generator": { "version": "2.0.33", "resolved": "https://registry.npmjs.org/@types/firebase-token-generator/-/firebase-token-generator-2.0.33.tgz", @@ -2158,12 +2103,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "license": "MIT" - }, "node_modules/@types/jsonwebtoken": { "version": "8.5.1", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", @@ -2188,12 +2127,6 @@ "license": "MIT", "optional": true }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -2212,7 +2145,14 @@ "version": "10.0.10", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" }, "node_modules/@types/nock": { "version": "11.1.0", @@ -2226,26 +2166,14 @@ } }, "node_modules/@types/node": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", - "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "license": "MIT", "dependencies": { "undici-types": "~7.18.0" } }, - "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, "node_modules/@types/request": { "version": "2.48.13", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.13.tgz", @@ -2270,31 +2198,10 @@ "@types/request": "*" } }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, "node_modules/@types/sinon": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", - "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "version": "17.0.4", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz", + "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==", "dev": true, "license": "MIT", "dependencies": { @@ -2313,9 +2220,9 @@ } }, "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", - "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-15.0.1.tgz", + "integrity": "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==", "dev": true, "license": "MIT" }, @@ -2334,17 +2241,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", - "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", + "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/type-utils": "8.56.1", - "@typescript-eslint/utils": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -2357,32 +2264,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.56.1", + "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", - "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", + "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "engines": { @@ -2398,14 +2295,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", - "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.1", - "@typescript-eslint/types": "^8.56.1", + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "engines": { @@ -2420,14 +2317,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", - "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1" + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2438,9 +2335,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", - "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", "dev": true, "license": "MIT", "engines": { @@ -2455,15 +2352,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", - "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", + "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1", - "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -2480,9 +2377,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", - "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", "dev": true, "license": "MIT", "engines": { @@ -2494,16 +2391,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", - "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.56.1", - "@typescript-eslint/tsconfig-utils": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/visitor-keys": "8.56.1", + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -2521,45 +2418,6 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", @@ -2574,16 +2432,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", - "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.1", - "@typescript-eslint/types": "8.56.1", - "@typescript-eslint/typescript-estree": "8.56.1" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2598,13 +2456,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", - "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -2629,9 +2487,9 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "dev": true, "license": "ISC" }, @@ -2649,9 +2507,9 @@ } }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "bin": { @@ -2672,9 +2530,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", "dev": true, "license": "MIT", "dependencies": { @@ -2685,16 +2543,12 @@ } }, "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==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", - "optional": true, - "dependencies": { - "debug": "4" - }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/aggregate-error": { @@ -2712,16 +2566,16 @@ } }, "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -2814,6 +2668,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -2823,6 +2678,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "devOptional": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3077,14 +2933,14 @@ } }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -3134,20 +2990,19 @@ } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -3221,6 +3076,16 @@ "node": ">= 10.13.0" } }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/async-retry": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", @@ -3285,9 +3150,9 @@ "license": "MIT" }, "node_modules/b4a": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", - "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", + "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -3315,15 +3180,19 @@ } }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/bare-events": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.1.tgz", - "integrity": "sha512-oxSAxTS1hRfnyit2CL5QpAOS5ixfBjj6ex3yTNvXyY/kE719jQ/IjuESJBK2w5v4wwQRAHGseVJXx9QBYOtFGQ==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -3355,6 +3224,19 @@ ], "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz", + "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/bcrypt": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-6.0.0.tgz", @@ -3447,14 +3329,16 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/braces": { @@ -3478,9 +3362,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -3498,10 +3382,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -3565,17 +3450,16 @@ } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "set-function-length": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -3636,9 +3520,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001677", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", - "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", + "version": "1.0.30001782", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001782.tgz", + "integrity": "sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==", "dev": true, "funding": [ { @@ -3826,6 +3710,24 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", @@ -3902,6 +3804,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -3914,6 +3817,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "devOptional": true, "license": "MIT" }, "node_modules/color-support": { @@ -4102,15 +4006,15 @@ } }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4120,31 +4024,31 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -4298,9 +4202,9 @@ } }, "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz", + "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -4378,7 +4282,9 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" }, "node_modules/ecc-jsbn": { "version": "0.1.2", @@ -4401,9 +4307,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.51", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.51.tgz", - "integrity": "sha512-kKeWV57KSS8jH4alKt/jKnvHPmJgBxXzGUSbMd4eQF+iOsVPl7bz2KUmu6eo80eMP8wVioTfTyTzdMgM15WXNg==", + "version": "1.5.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", "dev": true, "license": "ISC" }, @@ -4411,12 +4317,13 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "devOptional": true, "license": "MIT" }, "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -4424,9 +4331,9 @@ } }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4434,58 +4341,66 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", "dev": true, "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", + "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -4544,15 +4459,15 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -4679,9 +4594,9 @@ } }, "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -4695,10 +4610,28 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -4710,6 +4643,16 @@ "node": ">= 8" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4718,9 +4661,9 @@ "license": "MIT" }, "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -4779,9 +4722,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -4926,9 +4869,9 @@ "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { @@ -4936,7 +4879,7 @@ "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -4969,6 +4912,23 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fast-xml-builder": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", @@ -4986,9 +4946,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "5.5.7", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.7.tgz", - "integrity": "sha512-LteOsISQ2GEiDHZch6L9hB0+MLoYVLToR7xotrzU0opCICBkxOPgHAy1HxAvtxfJNXDJpgAsQN30mkrfpO2Prg==", + "version": "5.5.9", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.9.tgz", + "integrity": "sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g==", "funding": [ { "type": "github", @@ -4999,8 +4959,8 @@ "optional": true, "dependencies": { "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.1.3", - "strnum": "^2.2.0" + "path-expression-matcher": "^1.2.0", + "strnum": "^2.2.2" }, "bin": { "fxparser": "src/cli/cli.js" @@ -5017,9 +4977,9 @@ } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, "license": "ISC", "dependencies": { @@ -5205,9 +5165,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -5256,13 +5216,19 @@ } }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/for-in": { @@ -5289,12 +5255,13 @@ } }, "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -5305,9 +5272,10 @@ } }, "node_modules/foreground-child/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -5318,22 +5286,11 @@ "node": ">= 8" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/foreground-child/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -5468,16 +5425,18 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -5520,33 +5479,6 @@ "node": ">=14" } }, - "node_modules/gaxios/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "license": "MIT", - "optional": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/gaxios/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "license": "MIT", - "optional": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/gaxios/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -5575,43 +5507,20 @@ "node": ">=18" } }, - "node_modules/gcp-metadata/node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, "node_modules/gcp-metadata/node_modules/gaxios": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", - "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", + "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2", - "rimraf": "^5.0.1" + "node-fetch": "^3.3.2" }, "engines": { "node": ">=18" } }, - "node_modules/gcp-metadata/node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/gcp-metadata/node_modules/node-fetch": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", @@ -5630,19 +5539,14 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/gcp-metadata/node_modules/rimraf": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, "node_modules/gensync": { @@ -5732,15 +5636,15 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -5763,6 +5667,8 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -5826,20 +5732,31 @@ "node": ">= 10.13.0" } }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5848,14 +5765,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob/node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -5942,6 +5851,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/glogg": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", @@ -5956,14 +5875,14 @@ } }, "node_modules/google-auth-library": { - "version": "10.6.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.1.tgz", - "integrity": "sha512-5awwuLrzNol+pFDmKJd0dKtZ0fPLAtoA5p7YO4ODsDu6ONJUVqbYwvv8y2ZBO5MBNp9TJXigB19710kYpBPdtA==", + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz", + "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "7.1.3", + "gaxios": "^7.1.4", "gcp-metadata": "8.1.2", "google-logging-utils": "1.1.3", "jws": "^4.0.0" @@ -5972,43 +5891,20 @@ "node": ">=18" } }, - "node_modules/google-auth-library/node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, "node_modules/google-auth-library/node_modules/gaxios": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", - "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", + "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2", - "rimraf": "^5.0.1" + "node-fetch": "^3.3.2" }, "engines": { "node": ">=18" } }, - "node_modules/google-auth-library/node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/google-auth-library/node_modules/node-fetch": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", @@ -6027,25 +5923,10 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/google-auth-library/node_modules/rimraf": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/google-gax": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", - "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.6.1.tgz", + "integrity": "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -6231,6 +6112,24 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/gulp-cli/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/gulp-cli/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -6250,6 +6149,16 @@ "node": ">=10" } }, + "node_modules/gulp-cli/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/gulp-filter": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-7.0.0.tgz", @@ -6278,16 +6187,16 @@ } }, "node_modules/gulp-header": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-2.0.9.tgz", - "integrity": "sha512-LMGiBx+qH8giwrOuuZXSGvswcIUh0OiioNkUpLhNyvaC6/Ga8X6cfAeme2L5PqsbXMhL8o8b/OmVqIQdxprhcQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-2.0.12.tgz", + "integrity": "sha512-7PFW56tRISOroZ3N5R+f1Bn4wvdtE5LZXfZqz4ubEAXLEsLS7kSifgsk/lF26hSqnYO786GniQCxCuLxQZ0SoA==", "dev": true, "license": "MIT", "dependencies": { "concat-with-sourcemaps": "^1.1.0", - "lodash.template": "^4.5.0", - "map-stream": "0.0.7", - "through2": "^2.0.0" + "lodash": "^4.17.21", + "map-stream": "^0.0.7", + "through2": "^4.0.2" } }, "node_modules/gulp-typescript": { @@ -6311,6 +6220,24 @@ "typescript": "~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev" } }, + "node_modules/gulp-typescript/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/gulp-typescript/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", @@ -6340,7 +6267,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -6418,9 +6345,9 @@ } }, "node_modules/gulp-typescript/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -6493,13 +6420,13 @@ "license": "MIT" }, "node_modules/gulp-typescript/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "dev": true, "license": "BSD-3-Clause", "engines": { - "node": ">= 8" + "node": ">= 12" } }, "node_modules/gulp-typescript/node_modules/string_decoder": { @@ -6655,9 +6582,9 @@ } }, "node_modules/har-validator/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -6702,11 +6629,14 @@ } }, "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6735,11 +6665,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -6847,9 +6780,9 @@ "license": "ISC" }, "node_modules/html-entities": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", - "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", + "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", "funding": [ { "type": "github", @@ -6911,6 +6844,19 @@ "node": ">= 6" } }, + "node_modules/http-proxy-agent/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==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -6928,17 +6874,16 @@ } }, "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==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", - "optional": true, "dependencies": { - "agent-base": "6", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/iconv-lite": { @@ -6983,9 +6928,9 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "license": "MIT", "engines": { @@ -6993,9 +6938,9 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7105,14 +7050,15 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -7128,14 +7074,37 @@ "dev": true, "license": "MIT" }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7155,14 +7124,14 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7192,9 +7161,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { @@ -7208,12 +7177,14 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "license": "MIT", "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -7224,13 +7195,14 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7275,15 +7247,52 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -7297,6 +7306,19 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", @@ -7331,13 +7353,14 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7387,14 +7410,16 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -7416,14 +7441,27 @@ "node": ">=0.10.0" } }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -7446,13 +7484,14 @@ } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -7462,13 +7501,15 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -7478,13 +7519,13 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -7543,14 +7584,47 @@ "node": ">=0.10.0" } }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7577,6 +7651,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, "license": "ISC" }, "node_modules/isobject": { @@ -7655,9 +7730,9 @@ } }, "node_modules/istanbul-lib-processinfo/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -7768,9 +7843,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -7785,6 +7860,8 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -7846,9 +7923,9 @@ "license": "MIT" }, "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", "bin": { @@ -7933,12 +8010,12 @@ } }, "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", "license": "MIT", "dependencies": { - "jws": "^3.2.2", + "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", @@ -7954,27 +8031,6 @@ "npm": ">=6" } }, - "node_modules/jsonwebtoken/node_modules/jwa": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jsonwebtoken/node_modules/jws": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz", - "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.2", - "safe-buffer": "^5.0.1" - } - }, "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -8010,12 +8066,11 @@ } }, "node_modules/jwks-rsa": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", - "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.2.tgz", + "integrity": "sha512-BqTyEDV+lS8F2trk3A+qJnxV5Q9EqKCBJOPti3W97r7qTympCZjb7h2X6f2kc+0K3rsSTY1/6YG2eaXKoj497w==", "license": "MIT", "dependencies": { - "@types/express": "^4.17.20", "@types/jsonwebtoken": "^9.0.4", "debug": "^4.3.4", "jose": "^4.15.4", @@ -8027,11 +8082,12 @@ } }, "node_modules/jwks-rsa/node_modules/@types/jsonwebtoken": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", - "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", + "version": "9.0.10", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", + "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", "license": "MIT", "dependencies": { + "@types/ms": "*", "@types/node": "*" } }, @@ -8218,13 +8274,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -8249,6 +8298,7 @@ "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", "dev": true, "license": "MIT" }, @@ -8268,6 +8318,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", "dev": true, "license": "MIT" }, @@ -8308,27 +8359,6 @@ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", "license": "MIT" }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -8347,9 +8377,9 @@ } }, "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "license": "Apache-2.0", "optional": true }, @@ -8532,16 +8562,19 @@ } }, "node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", + "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "*" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -8555,12 +8588,13 @@ } }, "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "license": "ISC", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/mocha": { @@ -8600,11 +8634,19 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/mocha/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -8614,6 +8656,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, + "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, @@ -8629,17 +8672,19 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/mocha/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -8653,6 +8698,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14.18.0" }, @@ -8661,15 +8707,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -8696,6 +8733,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/multimatch/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/multimatch/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/multimatch/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/mute-stdout": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", @@ -8733,23 +8801,22 @@ "license": "MIT" }, "node_modules/nise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", - "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.4.tgz", + "integrity": "sha512-vSA4IpRHRWZkmotu61SvF45Jirq4CTLT3KKOWJPsPMtxtOBOlxcAlXfv/OrWxkzAJiCBrvdfWvGQjHT7r7+Qqg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^13.0.1", - "@sinonjs/text-encoding": "^0.7.3", + "@sinonjs/fake-timers": "^15.1.1", "just-extend": "^6.2.0", - "path-to-regexp": "^8.1.0" + "path-to-regexp": "^8.3.0" } }, "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", + "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -8761,6 +8828,7 @@ "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.6.tgz", "integrity": "sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.1.0", "json-stringify-safe": "^5.0.1", @@ -8771,9 +8839,9 @@ } }, "node_modules/node-addon-api": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.5.0.tgz", - "integrity": "sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.7.0.tgz", + "integrity": "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==", "dev": true, "license": "MIT", "engines": { @@ -8822,9 +8890,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -8856,9 +8924,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "dev": true, "license": "MIT" }, @@ -8957,6 +9025,24 @@ "node": ">=4" } }, + "node_modules/npm-run-all/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/npm-run-all/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/npm-run-all/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -8990,9 +9076,9 @@ "license": "MIT" }, "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "license": "MIT", "dependencies": { @@ -9026,6 +9112,19 @@ "node": ">=4" } }, + "node_modules/npm-run-all/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/npm-run-all/node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", @@ -9124,6 +9223,24 @@ "node": ">=18" } }, + "node_modules/nyc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nyc/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/nyc/node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -9154,7 +9271,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -9186,9 +9303,9 @@ } }, "node_modules/nyc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -9250,6 +9367,13 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/nyc/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -9363,15 +9487,17 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -9481,6 +9607,24 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -9558,7 +9702,9 @@ "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { "version": "1.0.1", @@ -9640,9 +9786,9 @@ } }, "node_modules/path-expression-matcher": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.1.3.tgz", - "integrity": "sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz", + "integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==", "funding": [ { "type": "github", @@ -9669,6 +9815,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9708,6 +9855,8 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -9722,16 +9871,19 @@ "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" }, "node_modules/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", + "integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==", "dev": true, "license": "MIT", - "engines": { - "node": ">=16" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/path-type": { @@ -9769,9 +9921,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -9903,9 +10055,9 @@ } }, "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { @@ -9930,9 +10082,9 @@ "license": "MIT" }, "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.1.0.tgz", + "integrity": "sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==", "dev": true, "license": "MIT", "dependencies": { @@ -9973,9 +10125,9 @@ } }, "node_modules/protobufjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", - "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", "hasInstallScript": true, "license": "BSD-3-Clause", "optional": true, @@ -10005,11 +10157,17 @@ "license": "ISC" }, "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } }, "node_modules/pump": { "version": "2.0.1", @@ -10091,9 +10249,9 @@ } }, "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz", + "integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -10200,16 +10358,41 @@ "node": ">= 10.13.0" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "set-function-name": "^2.0.2" }, "engines": { @@ -10261,6 +10444,50 @@ "node": ">= 0.10" } }, + "node_modules/remove-bom-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/remove-bom-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/remove-bom-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/remove-bom-stream/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -10411,19 +10638,22 @@ "license": "ISC" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10491,9 +10721,9 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -10518,11 +10748,29 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/rimraf/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -10541,9 +10789,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -10727,15 +10975,16 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -10772,16 +11021,40 @@ ], "license": "MIT" }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -10894,10 +11167,26 @@ "node": ">= 0.4" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -10910,17 +11199,21 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11002,11 +11295,17 @@ } }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "ISC" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/sinon": { "version": "18.0.1", @@ -11038,6 +11337,16 @@ "sinon": ">=4.0.0" } }, + "node_modules/sinon/node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/sinon/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11100,9 +11409,9 @@ } }, "node_modules/spawn-wrap/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -11128,6 +11437,13 @@ "node": ">=8.0.0" } }, + "node_modules/spawn-wrap/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/spawn-wrap/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -11174,9 +11490,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", "dev": true, "license": "CC0-1.0" }, @@ -11220,7 +11536,21 @@ "dev": true, "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": ">=0.10.0" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/stream-buffers": { @@ -11281,9 +11611,9 @@ } }, "node_modules/streamx": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", - "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz", + "integrity": "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==", "dev": true, "license": "MIT", "dependencies": { @@ -11316,6 +11646,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "devOptional": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -11331,6 +11662,8 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -11360,16 +11693,19 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -11379,16 +11715,20 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11415,6 +11755,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "devOptional": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -11428,6 +11769,8 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -11459,9 +11802,9 @@ } }, "node_modules/strnum": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz", - "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz", + "integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==", "funding": [ { "type": "github", @@ -11545,6 +11888,33 @@ "node": ">=14" } }, + "node_modules/teeny-request/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==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/teeny-request/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==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/teeny-request/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -11584,11 +11954,29 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/test-exclude/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -11607,9 +11995,9 @@ } }, "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -11620,9 +12008,9 @@ } }, "node_modules/text-decoder": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", + "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -11660,14 +12048,13 @@ } }, "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "license": "MIT", "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "readable-stream": "3" } }, "node_modules/through2-filter": { @@ -11681,7 +12068,7 @@ "xtend": "~4.0.0" } }, - "node_modules/through2/node_modules/readable-stream": { + "node_modules/through2-filter/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", @@ -11697,14 +12084,14 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/through2/node_modules/safe-buffer": { + "node_modules/through2-filter/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "license": "MIT" }, - "node_modules/through2/node_modules/string_decoder": { + "node_modules/through2-filter/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", @@ -11714,6 +12101,17 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/through2-filter/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, "node_modules/time-stamp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", @@ -11767,9 +12165,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", "engines": { @@ -11841,9 +12239,9 @@ "optional": true }, "node_modules/ts-api-utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", - "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -11898,9 +12296,9 @@ } }, "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -11970,32 +12368,32 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -12005,18 +12403,19 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -12026,18 +12425,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-proto": "^1.0.3", "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" }, "engines": { "node": ">= 0.4" @@ -12078,16 +12477,19 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12146,14 +12548,14 @@ "license": "MIT" }, "node_modules/unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.4.0.tgz", + "integrity": "sha512-V6QarSfeSgDipGA9EZdoIzu03ZDlOFkk+FbEP5cwgrZXN3iIkYR91IjU2EnM6rB835kGQsqHX8qncObTXV+6KA==", "dev": true, "license": "MIT", "dependencies": { "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" + "through2-filter": "3.0.0" } }, "node_modules/universalify": { @@ -12167,9 +12569,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -12188,7 +12590,7 @@ "license": "MIT", "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -12256,9 +12658,9 @@ } }, "node_modules/validator": { - "version": "13.15.20", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.20.tgz", - "integrity": "sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==", + "version": "13.15.26", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.26.tgz", + "integrity": "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==", "dev": true, "license": "MIT", "engines": { @@ -12515,17 +12917,74 @@ } }, "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which-collection": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", "dev": true, "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12539,16 +12998,18 @@ "license": "ISC" }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -12569,24 +13030,25 @@ } }, "node_modules/workerpool": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.3.tgz", - "integrity": "sha512-slxCaKbYjEdFT/o2rH9xS1hf4uRDch1w7Uo+apxhZ+sf/1d9e0ZVkn42kPNGP2dgjIx6YFvSevj0zHvbWe2jdw==", - "dev": true + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "devOptional": true, + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -12597,6 +13059,8 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -12609,6 +13073,73 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -12629,6 +13160,13 @@ "typedarray-to-buffer": "^3.1.5" } }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -12676,13 +13214,13 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "devOptional": true, "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-unparser": { @@ -12727,16 +13265,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "devOptional": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index 1844240d0d..ee14d9d52b 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,9 @@ "auth": [ "lib/auth" ], + "phone-number-verification": [ + "lib/phone-number-verification" + ], "eventarc": [ "lib/eventarc" ], @@ -134,6 +137,11 @@ "require": "./lib/auth/index.js", "import": "./lib/esm/auth/index.js" }, + "./phone-number-verification": { + "types": "./lib/phone-number-verification/index.d.ts", + "require": "./lib/phone-number-verification/index.js", + "import": "./lib/esm/phone-number-verification/index.js" + }, "./database": { "types": "./lib/database/index.d.ts", "require": "./lib/database/index.js", diff --git a/src/phone-number-verification/index.ts b/src/phone-number-verification/index.ts new file mode 100644 index 0000000000..2d2de73f8a --- /dev/null +++ b/src/phone-number-verification/index.ts @@ -0,0 +1,66 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Firebase Phone Number Verification. + * + * @packageDocumentation + */ + +import { App, getApp } from '../app'; +import { FirebaseApp } from '../app/firebase-app'; +import { PhoneNumberVerification } from './phone-number-verification'; + +export { + PhoneNumberVerification +} from './phone-number-verification'; + +export { + PhoneNumberVerificationToken, +} from './phone-number-verification-api' + +/** + * Gets the {@link PhoneNumberVerification} service for the default app or a + * given app. + * + * `getPhoneNumberVerification()` can be called with no arguments to access the default app's + * {@link PhoneNumberVerification} service or as `getPhoneNumberVerification(app)` to access the + * {@link PhoneNumberVerification} service associated with a specific app. + * + * @example + * ```javascript + * // Get the PhoneNumberVerification service for the default app + * const defaultPnv = getPhoneNumberVerification(); + * ``` + * + * @example + * ```javascript + * // Get the PhoneNumberVerification service for a given app + * const otherPnv = getPhoneNumberVerification(otherApp); + * ``` + * + * @returns The {@link PhoneNumberVerification} service associated with the provided app. + * + */ +export function getPhoneNumberVerification(app?: App): PhoneNumberVerification { + if (typeof app === 'undefined') { + app = getApp(); + } + + const firebaseApp: FirebaseApp = app as FirebaseApp; + return firebaseApp.getOrInitService('phone-number-verification', (app) => new PhoneNumberVerification(app)); +} diff --git a/src/phone-number-verification/phone-number-verification-api-client-internal.ts b/src/phone-number-verification/phone-number-verification-api-client-internal.ts new file mode 100644 index 0000000000..be0a372f33 --- /dev/null +++ b/src/phone-number-verification/phone-number-verification-api-client-internal.ts @@ -0,0 +1,72 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PrefixedFirebaseError } from '../utils/error'; + +export interface FirebasePhoneNumberTokenInfo { + /** Documentation URL. */ + url: string; + /** verify API name. */ + verifyApiName: string; + /** The JWT full name. */ + jwtName: string; + /** The JWT short name. */ + shortName: string; + /** The JWT typ (Type) */ + typ: string; +} + +export const JWKS_URL = 'https://fpnv.googleapis.com/v1beta/jwks'; + +export const FPNV_TOKEN_INFO: FirebasePhoneNumberTokenInfo = { + url: 'https://firebase.google.com/docs/phone-number-verification', + verifyApiName: 'verifyToken()', + jwtName: 'Firebase Phone Verification token', + shortName: 'FPNV token', + typ: 'JWT', +}; + +export const FPNV_ERROR_CODE_MAPPING = { + INVALID_ARGUMENT: 'invalid-argument', + INVALID_TOKEN: 'invalid-token', + EXPIRED_TOKEN: 'expired-token', +} satisfies Record; + +export type PhoneNumberVerificationErrorCode = + | 'invalid-argument' + | 'invalid-token' + | 'expired-token' + +/** + * Firebase Phone Number Verification error code structure. This extends `PrefixedFirebaseError`. + * + * @param code - The error code. + * @param message - The error message. + * @constructor + */ +export class FirebasePhoneNumberVerificationError extends PrefixedFirebaseError { + constructor(code: PhoneNumberVerificationErrorCode, message: string) { + super('phone-number-verification', code, message); + + /* tslint:disable:max-line-length */ + // Set the prototype explicitly. See the following link for more details: + // https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work + /* tslint:enable:max-line-length */ + (this as any).__proto__ = FirebasePhoneNumberVerificationError.prototype; + } +} + diff --git a/src/phone-number-verification/phone-number-verification-api.ts b/src/phone-number-verification/phone-number-verification-api.ts new file mode 100644 index 0000000000..e3c937b728 --- /dev/null +++ b/src/phone-number-verification/phone-number-verification-api.ts @@ -0,0 +1,86 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/** + * Interface representing a PhoneNumberVerification token. + */ +export interface PhoneNumberVerificationToken { + /** + * The issuer identifier for the issuer of the response. + * This value is a URL with the format + * `https://fpnv.googleapis.com/projects/`, where `` is the + * project number of your Firebase project, and the + * same project number specified in the {@link PhoneNumberVerificationToken.aud} property. + */ + iss: string; + + /** + * The audience for which this token is intended. + * This value is a JSON array of two strings, the first is the project number of your + * Firebase project, and the second is the project ID of the same project. + */ + aud: string[]; + + /** + * The PhoneNumber Verification token's expiration time, in seconds since the Unix epoch. That is, the + * time at which this PhoneNumber Verification token expires and should no longer be considered valid. + */ + exp: number; + + /** + * The PhoneNumber Verification token's issued-at time, in seconds since the Unix epoch. That is, the + * time at which this PhoneNumber Verification token was issued and should start to be considered + * valid. + */ + iat: number; + + /** + * The phone number corresponding to this token. + * As a convenience, this value is copied over to the + * {@link PhoneNumberVerificationToken.phoneNumber | phoneNumber} property. + */ + sub: string; + + /** + * A case-sensitive string that uniquely identifies a specific JWT instance + */ + jti: string; + + /** + * A unique, single-use "number used once" value. + */ + nonce: string; + + /** + * The corresponding user's phone number. + * This value is not actually one of the JWT token claims. It is added as a + * convenience, and is set as the value of the {@link PhoneNumberVerificationToken.sub} property. + */ + phoneNumber: string; + + /** + * Other arbitrary claims included in the token. + */ + [key: string]: any; +} + +export { + PhoneNumberVerificationErrorCode, + FirebasePhoneNumberVerificationError, +} from './phone-number-verification-api-client-internal'; + diff --git a/src/phone-number-verification/phone-number-verification.ts b/src/phone-number-verification/phone-number-verification.ts new file mode 100644 index 0000000000..06e1818a68 --- /dev/null +++ b/src/phone-number-verification/phone-number-verification.ts @@ -0,0 +1,65 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { App } from '../app'; +import { PhoneNumberVerificationToken } from './phone-number-verification-api'; +import { PhoneNumberTokenVerifier } from './token-verifier'; +import { JWKS_URL, FPNV_TOKEN_INFO } from './phone-number-verification-api-client-internal'; + +/** + * PhoneNumberVerification service bound to the provided app. + */ +export class PhoneNumberVerification { + private readonly appInternal: App; + private readonly phoneNumberVerificationVerifier: PhoneNumberTokenVerifier; + + /** + * @param app - The app for this `PhoneNumberVerification` service. + * @constructor + * @internal + */ + constructor(app: App) { + + this.appInternal = app; + this.phoneNumberVerificationVerifier = new PhoneNumberTokenVerifier( + JWKS_URL, + 'https://fpnv.googleapis.com/projects/', + FPNV_TOKEN_INFO, + app + ); + } + + /** + * Returns the app associated with this `PhoneNumberVerification` instance. + * + * @returns The app associated with this `PhoneNumberVerification` instance. + */ + get app(): App { + return this.appInternal; + } + + /** + * Verifies a Firebase Phone Number Verification token. + * + * @param jwt - A string containing the Firebase Phone Number Verification JWT. + * @returns A promise that resolves with the decoded token. + */ + public verifyToken(jwt: string): Promise { + return this.phoneNumberVerificationVerifier.verifyJWT(jwt); + } +} + diff --git a/src/phone-number-verification/token-verifier.ts b/src/phone-number-verification/token-verifier.ts new file mode 100644 index 0000000000..706a99d68c --- /dev/null +++ b/src/phone-number-verification/token-verifier.ts @@ -0,0 +1,213 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { App } from '../app'; +import { FirebasePhoneNumberVerificationError, PhoneNumberVerificationToken } from './phone-number-verification-api'; +import * as util from '../utils/index'; +import * as validator from '../utils/validator'; +import { + DecodedToken, decodeJwt, JwtError, JwtErrorCode, + PublicKeySignatureVerifier, ALGORITHM_ES256, SignatureVerifier, +} from '../utils/jwt'; +import { FirebasePhoneNumberTokenInfo, FPNV_ERROR_CODE_MAPPING } from './phone-number-verification-api-client-internal'; + +export class PhoneNumberTokenVerifier { + private readonly shortNameArticle: string; + private readonly signatureVerifier: SignatureVerifier; + + constructor( + jwksUrl: string, + private readonly issuer: string, + private readonly tokenInfo: FirebasePhoneNumberTokenInfo, + private readonly app: App + ) { + + if (!validator.isURL(jwksUrl)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'The provided public client certificate URL is an invalid URL.', + ); + } else if (!validator.isURL(issuer)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'The provided JWT issuer is an invalid URL.', + ); + } else if (!validator.isNonNullObject(tokenInfo)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'The provided JWT information is not an object or null.', + ); + } else if (!validator.isURL(tokenInfo.url)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'The provided JWT verification documentation URL is invalid.', + ); + } else if (!validator.isNonEmptyString(tokenInfo.verifyApiName)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'The JWT verify API name must be a non-empty string.', + ); + } else if (!validator.isNonEmptyString(tokenInfo.jwtName)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'The JWT public full name must be a non-empty string.', + ); + } else if (!validator.isNonEmptyString(tokenInfo.shortName)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'The JWT public short name must be a non-empty string.', + ); + } + + this.shortNameArticle = tokenInfo.shortName.charAt(0).match(/[aeiou]/i) ? 'an' : 'a'; + + this.signatureVerifier = PublicKeySignatureVerifier.withJwksUrl(jwksUrl, app.options.httpAgent); + + // Project ID is validated in the verification call. + } + + public async verifyJWT(jwtToken: string): Promise { + if (!validator.isString(jwtToken)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_TOKEN, + `First argument to ${this.tokenInfo.verifyApiName} must be a string.`, + ); + } + + const projectId = await this.ensureProjectId(); + const decoded = await this.decodeAndVerify(jwtToken, projectId); + const decodedIdToken = decoded.payload as PhoneNumberVerificationToken; + decodedIdToken.phoneNumber = decodedIdToken.sub; + return decodedIdToken; + } + + + private async ensureProjectId(): Promise { + const projectId = await util.findProjectId(this.app); + if (!validator.isNonEmptyString(projectId)) { + throw new FirebasePhoneNumberVerificationError( + FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + 'Must initialize app with a cert credential or set your Firebase project ID as the ' + + `GOOGLE_CLOUD_PROJECT environment variable to call ${this.tokenInfo.verifyApiName}.`); + } + + return projectId; + } + + private async decodeAndVerify( + token: string, + projectId: string + ): Promise { + const decodedToken = await this.safeDecode(token); + this.verifyContent(decodedToken, projectId); + await this.verifySignature(token); + return decodedToken; + } + + private async safeDecode(jwtToken: string): Promise { + try { + return await decodeJwt(jwtToken); + } catch (err) { + if (err.code === JwtErrorCode.INVALID_ARGUMENT) { + const verifyJwtTokenDocsMessage = ` See ${this.tokenInfo.url} ` + + `for details on how to retrieve ${this.shortNameArticle} ${this.tokenInfo.shortName}.`; + const errorMessage = `Decoding ${this.tokenInfo.jwtName} failed. Make sure you passed ` + + `the entire string JWT which represents ${this.shortNameArticle} ` + + `${this.tokenInfo.shortName}.` + verifyJwtTokenDocsMessage; + throw new FirebasePhoneNumberVerificationError(FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, + errorMessage); + } + throw new FirebasePhoneNumberVerificationError(FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, err.message); + + } + } + + private verifyContent( + fullDecodedToken: DecodedToken, + projectId: string + ): void { + const header = fullDecodedToken && fullDecodedToken.header; + const payload = fullDecodedToken && fullDecodedToken.payload; + + const projectIdMatchMessage = ` Make sure the ${this.tokenInfo.shortName} comes from the same ` + + 'Firebase project as the service account used to authenticate this SDK.'; + const verifyJwtTokenDocsMessage = ` See ${this.tokenInfo.url} ` + + `for details on how to retrieve ${this.shortNameArticle} ${this.tokenInfo.shortName}.`; + const scopedProjectId = `${this.issuer}${projectId}`; + + let errorMessage: string | undefined; + + // JWT Header + if (!header || typeof header.kid === 'undefined') { + errorMessage = `${this.tokenInfo.jwtName} has no "kid" claim.`; + errorMessage += verifyJwtTokenDocsMessage; + } else if (header.alg !== ALGORITHM_ES256) { + errorMessage = `${this.tokenInfo.jwtName} has incorrect algorithm. Expected ` + + `"${ALGORITHM_ES256}" but got "${header.alg}". ${verifyJwtTokenDocsMessage}`; + } else if (header.typ !== this.tokenInfo.typ) { + errorMessage = `${this.tokenInfo.jwtName} has incorrect typ. Expected "${this.tokenInfo.typ}" but got ` + + `"${header.typ}". ${verifyJwtTokenDocsMessage}`; + } + // FPNV Token + else if (!payload) { + errorMessage = `${this.tokenInfo.jwtName} has no payload. ${verifyJwtTokenDocsMessage}`; + } else if (typeof payload.iss !== 'string' || !payload.iss.startsWith(this.issuer)) { + errorMessage = `${this.tokenInfo.jwtName} has incorrect "iss" (issuer) claim. Expected ` + + `an issuer starting with "${this.issuer}" but got "${payload.iss}".` + + ` ${projectIdMatchMessage} ${verifyJwtTokenDocsMessage}`; + } else if (!validator.isNonEmptyArray(payload.aud) || !payload.aud.includes(scopedProjectId)) { + errorMessage = `${this.tokenInfo.jwtName} has incorrect "aud" (audience) claim. Expected ` + + `"${scopedProjectId}" to be one of "${payload.aud}". ${projectIdMatchMessage} ${verifyJwtTokenDocsMessage}`; + } else if (typeof payload.sub !== 'string') { + errorMessage = `${this.tokenInfo.jwtName} has no "sub" (subject) claim. ${verifyJwtTokenDocsMessage}`; + } else if (payload.sub === '') { + errorMessage = `${this.tokenInfo.jwtName} has an empty "sub" (subject) claim. ${verifyJwtTokenDocsMessage}`; + } + + if (errorMessage) { + throw new FirebasePhoneNumberVerificationError(FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, errorMessage); + } + } + + private async verifySignature(jwtToken: string): Promise { + try { + return await this.signatureVerifier.verify(jwtToken); + } catch (error) { + throw this.mapJwtErrorToAuthError(error); + } + } + + private mapJwtErrorToAuthError(error: JwtError): Error { + const verifyJwtTokenDocsMessage = ` See ${this.tokenInfo.url} ` + + `for details on how to retrieve ${this.shortNameArticle} ${this.tokenInfo.shortName}.`; + if (error.code === JwtErrorCode.TOKEN_EXPIRED) { + const errorMessage = `${this.tokenInfo.jwtName} has expired. Get a fresh ${this.tokenInfo.shortName}` + + ` from your client app and try again. ${verifyJwtTokenDocsMessage}`; + return new FirebasePhoneNumberVerificationError(FPNV_ERROR_CODE_MAPPING.EXPIRED_TOKEN, errorMessage); + } else if (error.code === JwtErrorCode.INVALID_SIGNATURE) { + const errorMessage = `${this.tokenInfo.jwtName} has invalid signature. ${verifyJwtTokenDocsMessage}`; + return new FirebasePhoneNumberVerificationError(FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, errorMessage); + } else if (error.code === JwtErrorCode.NO_MATCHING_KID) { + const errorMessage = `${this.tokenInfo.jwtName} has "kid" claim which does not ` + + `correspond to a known public key. Most likely the ${this.tokenInfo.shortName} ` + + 'is expired, so get a fresh token from your client app and try again.'; + return new FirebasePhoneNumberVerificationError(FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, errorMessage); + } + return new FirebasePhoneNumberVerificationError(FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT, error.message); + } + +} diff --git a/src/utils/jwt.ts b/src/utils/jwt.ts index 9a66494482..41433c4f06 100644 --- a/src/utils/jwt.ts +++ b/src/utils/jwt.ts @@ -21,6 +21,7 @@ import { HttpClient, HttpRequestConfig, RequestResponseError } from '../utils/ap import { Agent } from 'http'; export const ALGORITHM_RS256: jwt.Algorithm = 'RS256' as const; +export const ALGORITHM_ES256: jwt.Algorithm = 'ES256' as const; // `jsonwebtoken` converts errors from the `getKey` callback to its own `JsonWebTokenError` type // and prefixes the error message with the following. Use the prefix to identify errors thrown @@ -201,7 +202,8 @@ export class PublicKeySignatureVerifier implements SignatureVerifier { 'The provided token must be a string.')); } - return verifyJwtSignature(token, getKeyCallback(this.keyFetcher), { algorithms: [ALGORITHM_RS256] }) + return verifyJwtSignature(token, getKeyCallback(this.keyFetcher), + { algorithms: [ALGORITHM_RS256, ALGORITHM_ES256] }) .catch((error: JwtError) => { if (error.code === JwtErrorCode.NO_KID_IN_HEADER) { // No kid in JWT header. Try with all the public keys. diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index 39ae51fd9f..9f2fecc1a1 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -123,3 +123,10 @@ import './data-connect/index.spec'; import './data-connect/data-connect-api-client-internal.spec'; import './data-connect/data-connect.spec'; import './data-connect/validate-admin-args.spec'; + +// Phone Number Verification +import './phone-number-verification/index.spec'; +import './phone-number-verification/phone-number-verification-api-client-internal.spec'; +import './phone-number-verification/phone-number-verification.spec'; +import './phone-number-verification/token-verifier.spec' + diff --git a/test/unit/phone-number-verification/index.spec.ts b/test/unit/phone-number-verification/index.spec.ts new file mode 100644 index 0000000000..357d37b028 --- /dev/null +++ b/test/unit/phone-number-verification/index.spec.ts @@ -0,0 +1,77 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import * as chai from 'chai'; +import * as sinonChai from 'sinon-chai'; +import * as chaiAsPromised from 'chai-as-promised'; + +import * as mocks from '../../resources/mocks'; +import { App } from '../../../src/app/index'; +import { getPhoneNumberVerification, PhoneNumberVerification } from '../../../src/phone-number-verification/index'; +import * as pnvIndex from '../../../src/phone-number-verification/index'; + +chai.should(); +chai.use(sinonChai); +chai.use(chaiAsPromised); + +const expect = chai.expect; + +describe('Module export', () => { + it('should export PhoneNumberVerification class', () => { + expect(pnvIndex.PhoneNumberVerification).to.exist; + expect(pnvIndex.getPhoneNumberVerification).to.be.a('function'); + }); +}); + +describe('PhoneNumberVerification', () => { + let mockApp: App; + let mockCredentialApp: App; + + beforeEach(() => { + mockApp = mocks.app(); + mockCredentialApp = mocks.mockCredentialApp(); + }); + + describe('getPhoneNumberVerification()', () => { + it('should throw when default app is not available', () => { + expect(() => { + return getPhoneNumberVerification(); + }).to.throw('The default Firebase app does not exist.'); + }); + + it('should not throw given a valid app', () => { + expect(() => { + return getPhoneNumberVerification(mockApp); + }).not.to.throw(); + }); + + it('should return the same instance for app instance', () => { + const pnvFirst: PhoneNumberVerification = getPhoneNumberVerification(mockApp); + const pnvSecond: PhoneNumberVerification = getPhoneNumberVerification(mockApp); + expect(pnvFirst).to.equal(pnvSecond); + }); + + it('should not return the same instance when different apps are provided', () => { + const pnvFirst: PhoneNumberVerification = getPhoneNumberVerification(mockApp); + const pnvSecond: PhoneNumberVerification = getPhoneNumberVerification(mockCredentialApp); + expect(pnvFirst).to.not.equal(pnvSecond); + }); + }); +}); + diff --git a/test/unit/phone-number-verification/phone-number-verification-api-client-internal.spec.ts b/test/unit/phone-number-verification/phone-number-verification-api-client-internal.spec.ts new file mode 100644 index 0000000000..126e4c4978 --- /dev/null +++ b/test/unit/phone-number-verification/phone-number-verification-api-client-internal.spec.ts @@ -0,0 +1,86 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import { expect } from 'chai'; +import { + FirebasePhoneNumberVerificationError, + JWKS_URL, + FPNV_TOKEN_INFO, + FPNV_ERROR_CODE_MAPPING +} from '../../../src/phone-number-verification/phone-number-verification-api-client-internal'; +import { PrefixedFirebaseError, FirebaseError } from '../../../src/utils/error'; + +const FPNV_PREFIX = 'phone-number-verification'; + +describe('FPNV Constants and Error Class', () => { + + describe('Constants Integrity', () => { + it('should have the correct CLIENT_CERT_URL', () => { + expect(JWKS_URL).to.equal('https://fpnv.googleapis.com/v1beta/jwks'); + }); + + it('should have the correct structure and values for FPNV_TOKEN_INFO', () => { + expect(FPNV_TOKEN_INFO).to.be.an('object'); + expect(FPNV_TOKEN_INFO).to.have.all.keys('url', 'verifyApiName', 'jwtName', 'shortName', 'typ'); + expect(FPNV_TOKEN_INFO.shortName).to.equal('FPNV token'); + expect(FPNV_TOKEN_INFO.typ).to.equal('JWT'); + }); + + it('should have the correct structure and values for FPNV_ERROR_CODE_MAPPING', () => { + expect(FPNV_ERROR_CODE_MAPPING).to.be.an('object'); + expect(FPNV_ERROR_CODE_MAPPING).to.deep.equal({ + INVALID_ARGUMENT: 'invalid-argument', + INVALID_TOKEN: 'invalid-token', + EXPIRED_TOKEN: 'expired-token', + }); + }); + }); + + describe('FirebasePhoneNumberVerificationError', () => { + const testCode = FPNV_ERROR_CODE_MAPPING.INVALID_TOKEN; + const testMessage = 'The provided token is malformed or invalid.'; + + it('should correctly extend PrefixedFirebaseError', () => { + const error = new FirebasePhoneNumberVerificationError(testCode, testMessage); + + expect(error).to.be.an.instanceOf(FirebasePhoneNumberVerificationError); + expect(error).to.be.an.instanceOf(PrefixedFirebaseError); + expect(error).to.be.an.instanceOf(FirebaseError); + expect(error).to.be.an.instanceOf(Error); + }); + + + it('should have the correct error properties on the instance', () => { + const error = new FirebasePhoneNumberVerificationError(testCode, testMessage); + + expect(error.code).to.equal(`${FPNV_PREFIX}/${testCode}`); + expect(error.message).to.equal(testMessage); + }); + + it('should handle all defined error codes', () => { + const codes = Object.values(FPNV_ERROR_CODE_MAPPING); + + codes.forEach(code => { + const error = new FirebasePhoneNumberVerificationError(code, `Test message for ${code}`); + expect(error.code).to.equal(`${FPNV_PREFIX}/${code}`); + }); + }); + }); + +}); diff --git a/test/unit/phone-number-verification/phone-number-verification.spec.ts b/test/unit/phone-number-verification/phone-number-verification.spec.ts new file mode 100644 index 0000000000..e21ac19627 --- /dev/null +++ b/test/unit/phone-number-verification/phone-number-verification.spec.ts @@ -0,0 +1,102 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import { expect } from 'chai'; +import * as sinon from 'sinon'; + +import { App } from '../../../src/app/index'; +import * as mocks from '../../resources/mocks'; +import { PhoneNumberVerification } from '../../../src/phone-number-verification/phone-number-verification'; +import { PhoneNumberTokenVerifier } from '../../../src/phone-number-verification/token-verifier'; +import { PhoneNumberVerificationToken } from '../../../src/phone-number-verification/phone-number-verification-api'; + +describe('PhoneNumberVerification Service', () => { + let phoneNumberVerificationService: PhoneNumberVerification; + let mockApp: App; + let verifyJwtStub: sinon.SinonStub; + + beforeEach(() => { + mockApp = mocks.app(); + verifyJwtStub = sinon.stub(PhoneNumberTokenVerifier.prototype, 'verifyJWT'); + + phoneNumberVerificationService = new PhoneNumberVerification(mockApp); + }); + + afterEach(() => { + + sinon.restore(); + }); + + describe('Constructor', () => { + it('should be an instance of PhoneNumberVerification', () => { + expect(phoneNumberVerificationService).to.be.instanceOf(PhoneNumberVerification); + }); + }); + + describe('get app()', () => { + it('should return the app instance provided in the constructor', () => { + expect(phoneNumberVerificationService.app).to.equal(mockApp); + }); + }); + + describe('verifyToken()', () => { + const mockTokenString = 'eyJh...mock.jwt...token'; + const mockDecodedToken: PhoneNumberVerificationToken = { + iss: 'https://fpnv.googleapis.com/projects/1234567890', + aud: ['1234567890', 'my-project-id'], + exp: Math.floor(Date.now() / 1000) + 3600, // Expires in 1 hour + iat: Math.floor(Date.now() / 1000), // Issued now + sub: '+15555550100', // Phone number + jti: 'unique-token-id-123', + nonce: 'random-nonce-string', + phoneNumber: '+15555550100', + }; + + it('should call the internal verifier with the provided JWT string', async () => { + verifyJwtStub.resolves(mockDecodedToken); + + await phoneNumberVerificationService.verifyToken(mockTokenString); + + expect(verifyJwtStub.calledOnce).to.be.true; + expect(verifyJwtStub.calledWith(mockTokenString)).to.be.true; + }); + + it('should return the decoded token object on success', async () => { + verifyJwtStub.resolves(mockDecodedToken); + + const result = await phoneNumberVerificationService.verifyToken(mockTokenString); + + expect(result).to.equal(mockDecodedToken); + }); + + it('should bubble up errors if the verifier fails', async () => { + const mockError = new Error('Token expired'); + verifyJwtStub.rejects(mockError); + + try { + await phoneNumberVerificationService.verifyToken(mockTokenString); + // If we reach here, the test failed + expect.fail('Should have thrown an error'); + } catch (error) { + expect(error).to.equal(mockError); + } + }); + }); + +}); diff --git a/test/unit/phone-number-verification/token-verifier.spec.ts b/test/unit/phone-number-verification/token-verifier.spec.ts new file mode 100644 index 0000000000..9cc68935e1 --- /dev/null +++ b/test/unit/phone-number-verification/token-verifier.spec.ts @@ -0,0 +1,326 @@ +/*! + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +import * as chai from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import * as sinon from 'sinon'; + +import { App } from '../../../src/app/index'; +import * as jwt from '../../../src/utils/jwt'; +import * as util from '../../../src/utils/index'; +import { PhoneNumberTokenVerifier } from '../../../src/phone-number-verification/token-verifier'; +import { + FirebasePhoneNumberTokenInfo, + FPNV_ERROR_CODE_MAPPING +} from '../../../src/phone-number-verification/phone-number-verification-api-client-internal'; +import * as mocks from '../../resources/mocks'; + +chai.use(chaiAsPromised); +const expect = chai.expect; + +describe('PhoneNumberTokenVerifier', () => { + let verifier: PhoneNumberTokenVerifier; + let mockApp: App; + + let findProjectIdStub: sinon.SinonStub; + let decodeJwtStub: sinon.SinonStub; + let signatureVerifierStub: { verify: sinon.SinonStub }; + let withJwksUrlStub: sinon.SinonStub; + + const MOCK_CERT_URL = 'https://fpnv.googleapis.com/v1-beta/jwks'; + const MOCK_ISSUER = 'https://fpnv.googleapis.com/projects/'; + const MOCK_PROJECT_NUMBER = '123456789012'; + const MOCK_PROJECT_ID = 'fpnv-team-test'; + const MOCK_FPNV_PREFIX = 'phone-number-verification'; + + + const MOCK_TOKEN_INFO: FirebasePhoneNumberTokenInfo = { + url: 'https://firebase.google.com/docs/phone-number-verification', + verifyApiName: 'verifyToken()', + jwtName: 'Firebase Phone Verification token', + shortName: 'FPNV token', + typ: 'JWT', + }; + + const VALID_HEADER = { + kid: 'mock-key-id', + alg: 'ES256', + typ: 'JWT', // Matches MOCK_TOKEN_INFO.typ + }; + + const VALID_PAYLOAD = { + iss: MOCK_ISSUER + MOCK_PROJECT_NUMBER, + aud: [MOCK_ISSUER + MOCK_PROJECT_NUMBER, MOCK_ISSUER + MOCK_PROJECT_ID], + sub: '+15555550100', + exp: Math.floor(Date.now() / 1000) + 3600, // Expires in 1 hour + iat: Math.floor(Date.now() / 1000), // Issued now + }; + + beforeEach(() => { + mockApp = mocks.app(); + findProjectIdStub = sinon.stub(util, 'findProjectId').resolves(MOCK_PROJECT_ID); + decodeJwtStub = sinon.stub(jwt, 'decodeJwt'); + signatureVerifierStub = { verify: sinon.stub().resolves() }; + withJwksUrlStub = sinon.stub(jwt.PublicKeySignatureVerifier, 'withJwksUrl') + .returns(signatureVerifierStub as any); + }); + + afterEach(() => { + sinon.restore(); + }); + + /** + * Helper to instantiate the verifier with default valid args + */ + function createVerifier(overrides: Partial = {}): PhoneNumberTokenVerifier { + return new PhoneNumberTokenVerifier( + overrides.clientCertUrl || MOCK_CERT_URL, + overrides.issuer || MOCK_ISSUER, + overrides.tokenInfo || MOCK_TOKEN_INFO, + mockApp + ); + } + + describe('Constructor', () => { + it('should instantiate successfully with valid arguments', () => { + const v = createVerifier(); + expect(v).to.be.instanceOf(PhoneNumberTokenVerifier); + expect(withJwksUrlStub.calledOnce).to.be.true; + }); + + it('should throw if clientCertUrl is invalid', () => { + expect(() => createVerifier({ clientCertUrl: 'not-a-url' })) + .to.throw('invalid URL'); + }); + + it('should throw if issuer is invalid', () => { + expect(() => createVerifier({ issuer: 'not-a-url' })) + .to.throw('invalid URL'); + }); + + it('should throw if tokenInfo is null', () => { + expect(() => new PhoneNumberTokenVerifier( + MOCK_CERT_URL, + MOCK_ISSUER, + // @ts-expect-error null for testing + null, + mockApp + )) + .to.throw('The provided JWT information is not an object or null.'); + }); + + it('should throw if tokenInfo is missing URL field', () => { + const invalidInfo = { ...MOCK_TOKEN_INFO, url: '' }; + expect(() => createVerifier({ tokenInfo: invalidInfo })) + .to.throw('The provided JWT verification documentation URL is invalid.'); + }); + + it('should throw if tokenInfo is missing jwtName field', () => { + const invalidInfo = { ...MOCK_TOKEN_INFO, jwtName: '' }; + expect(() => createVerifier({ tokenInfo: invalidInfo })) + .to.throw('The JWT public full name must be a non-empty string.'); + }); + + it('should throw if tokenInfo is missing shortName field', () => { + const invalidInfo = { ...MOCK_TOKEN_INFO, shortName: '' }; + expect(() => createVerifier({ tokenInfo: invalidInfo })) + .to.throw('The JWT public short name must be a non-empty string.'); + }); + + it('should throw if tokenInfo is missing verifyApiName field', () => { + const invalidInfo = { ...MOCK_TOKEN_INFO, verifyApiName: '' }; + expect(() => createVerifier({ tokenInfo: invalidInfo })) + .to.throw('verify API name must be a non-empty string'); + }); + }); + + describe('verifyJWT()', () => { + beforeEach(() => { + verifier = createVerifier(); + }); + + it('should throw if jwtToken is not a string', async () => { + await expect(verifier.verifyJWT(123 as any)) + .to.be.rejectedWith('First argument to verifyToken() must be a string.'); + }); + + it('should throw if project ID cannot be determined', async () => { + findProjectIdStub.resolves(null); + await expect(verifier.verifyJWT('token')) + .to.be.rejectedWith('Must initialize app with a cert credential or set your' + + ' Firebase project ID as the GOOGLE_CLOUD_PROJECT environment variable to call verifyToken().'); + }); + + describe('Token Decoding', () => { + it('should throw if decodeJwt fails with invalid argument', async () => { + const err = new Error('Invalid token'); + (err as any).code = jwt.JwtErrorCode.INVALID_ARGUMENT; + decodeJwtStub.rejects(err); + + await expect(verifier.verifyJWT('bad-token')) + .to.be.rejectedWith(/Decoding Firebase Phone Verification token failed/); + }); + + it('should rethrow unknown errors from decodeJwt', async () => { + decodeJwtStub.rejects(new Error('Unknown error')); + await expect(verifier.verifyJWT('token')) + .to.be.rejectedWith('Unknown error'); + }); + + it('should rethrow unknown errors from decodeJwt', async () => { + const tokenInfo = { ...MOCK_TOKEN_INFO, shortName: 'a-short' }; + const verifier = createVerifier({ tokenInfo }) + + const err = new Error('Invalid argument'); + (err as any).code = jwt.JwtErrorCode.INVALID_ARGUMENT; + decodeJwtStub.rejects(err); + + await expect(verifier.verifyJWT('token')) + .to.be.rejectedWith(/Make sure you passed the entire string JWT which represents an a-short/); + }); + }); + + describe('Content Verification', () => { + // Helper to setup a successful decode + const setupDecode = (headerOverrides = {}, payloadOverrides = {}): void => { + decodeJwtStub.resolves({ + header: { ...VALID_HEADER, ...headerOverrides }, + payload: { ...VALID_PAYLOAD, ...payloadOverrides }, + }); + }; + + it('should throw if "kid" is missing', async () => { + setupDecode({ kid: undefined }); + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('has no "kid" claim'); + }); + + it('should throw if algorithm is not ES256', async () => { + setupDecode({ alg: 'RS256' }); + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('incorrect algorithm'); + }); + + it('should throw if "typ" is incorrect', async () => { + setupDecode({ typ: 'WRONG' }); + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('incorrect typ'); + }); + + it('should throw if "aud" does not contain issuer+projectId', async () => { + setupDecode({}, { aud: ['wrong-audience'] }); + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('incorrect "aud"'); + }); + + it('should throw if "iss" is missing', async () => { + setupDecode({}, { iss: undefined }); + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('has incorrect "iss"'); + }); + + it('should throw if "sub" is missing', async () => { + setupDecode({}, { sub: undefined }); + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('no "sub"'); + }); + + it('should throw if "sub" is empty', async () => { + setupDecode({}, { sub: '' }); + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('empty "sub"'); + }); + + it('should throw if payload is missing', async () => { + decodeJwtStub.resolves({ header: VALID_HEADER, payload: undefined }); + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('has no payload'); + }); + + it('should throw if "aud" does not match the current app projectId', async () => { + findProjectIdStub.resolves('some-other-project-id'); + setupDecode(); // uses VALID_PAYLOAD which has 'fpnv-team-test' + await expect(verifier.verifyJWT('token')).to.be.rejectedWith('has incorrect "aud"'); + }); + }); + + describe('Signature Verification', () => { + beforeEach(() => { + // Assume decoding passes for these tests + decodeJwtStub.resolves({ header: VALID_HEADER, payload: VALID_PAYLOAD }); + }); + + it('should call signatureVerifier.verify with the token', async () => { + const token = 'valid.jwt.string'; + await verifier.verifyJWT(token); + expect(signatureVerifierStub.verify.calledWith(token)).to.be.true; + }); + + it('should throw EXPIRED_TOKEN if signature verifier throws TOKEN_EXPIRED', async () => { + const error = new Error('Expired'); + (error as any).code = jwt.JwtErrorCode.TOKEN_EXPIRED; + signatureVerifierStub.verify.rejects(error); + + await expect(verifier.verifyJWT('token')) + .to.be.rejectedWith(/has expired/) + .and.eventually.have.property('code', `${MOCK_FPNV_PREFIX}/${FPNV_ERROR_CODE_MAPPING.EXPIRED_TOKEN}`); + }); + + it('should throw INVALID_ARGUMENT if signature verifier throws INVALID_SIGNATURE', async () => { + const error = new Error('Bad Sig'); + (error as any).code = jwt.JwtErrorCode.INVALID_SIGNATURE; + signatureVerifierStub.verify.rejects(error); + + await expect(verifier.verifyJWT('token')) + .to.be.rejectedWith(/invalid signature/) + .and.eventually.have.property('code',`${MOCK_FPNV_PREFIX}/${FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT}`); + }); + + it('should throw INVALID_ARGUMENT if signature verifier throws NO_MATCHING_KID', async () => { + const error = new Error('No Key'); + (error as any).code = jwt.JwtErrorCode.NO_MATCHING_KID; + signatureVerifierStub.verify.rejects(error); + + await expect(verifier.verifyJWT('token')) + .to.be.rejectedWith(/does not correspond to a known public key/) + .and.eventually.have.property('code',`${MOCK_FPNV_PREFIX}/${FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT}`); + }); + + it('should throw INVALID_ARGUMENT if signature verifier throws KEY_FETCH_ERROR', async () => { + const error = new Error('No Key'); + (error as any).code = jwt.JwtErrorCode.KEY_FETCH_ERROR; + signatureVerifierStub.verify.rejects(error); + + await expect(verifier.verifyJWT('token')) + .to.be.rejectedWith(/No Key/) + .and.eventually.have.property('code',`${MOCK_FPNV_PREFIX}/${FPNV_ERROR_CODE_MAPPING.INVALID_ARGUMENT}`); + }); + }); + + describe('Success', () => { + it('should return the token with phoneNumber property appended', async () => { + decodeJwtStub.resolves({ header: VALID_HEADER, payload: VALID_PAYLOAD }); + signatureVerifierStub.verify.resolves(); + + const result = await verifier.verifyJWT('valid-token'); + + // Check data integrity + expect(result.sub).to.equal(VALID_PAYLOAD.sub); + expect(result.aud).to.deep.equal(VALID_PAYLOAD.aud); + + // Check the property + expect(result).to.have.property('phoneNumber'); + expect(result.phoneNumber).to.equal(VALID_PAYLOAD.sub); + }); + }); + + }); +}); diff --git a/test/unit/utils/jwt.spec.ts b/test/unit/utils/jwt.spec.ts index 987faf5e47..6660351fcc 100644 --- a/test/unit/utils/jwt.spec.ts +++ b/test/unit/utils/jwt.spec.ts @@ -27,7 +27,7 @@ import * as sinon from 'sinon'; import * as mocks from '../../resources/mocks'; import { - ALGORITHM_RS256, DecodedToken, decodeJwt, EmulatorSignatureVerifier, JwksFetcher, + ALGORITHM_RS256, ALGORITHM_ES256, DecodedToken, decodeJwt, EmulatorSignatureVerifier, JwksFetcher, JwtErrorCode, PublicKeySignatureVerifier, UrlKeyFetcher, verifyJwtSignature } from '../../../src/utils/jwt'; @@ -240,7 +240,7 @@ describe('verifyJwtSignature', () => { const mockIdToken = mocks.generateIdToken(); return verifyJwtSignature(mockIdToken, mocks.keyPairs[0].public, - { algorithms: [ALGORITHM_RS256] }) + { algorithms: [ALGORITHM_RS256, ALGORITHM_ES256] }) .should.eventually.be.fulfilled; }); @@ -259,7 +259,7 @@ describe('verifyJwtSignature', () => { const getKeyCallback = (_: any, callback: any): void => callback(null, mocks.keyPairs[0].public); return verifyJwtSignature(mockIdToken, getKeyCallback, - { algorithms: [ALGORITHM_RS256] }) + { algorithms: [ALGORITHM_RS256, ALGORITHM_ES256] }) .should.eventually.be.fulfilled; }); @@ -279,13 +279,13 @@ describe('verifyJwtSignature', () => { // token should still be valid return verifyJwtSignature(mockIdToken, mocks.keyPairs[0].public, - { algorithms: [ALGORITHM_RS256] }) + { algorithms: [ALGORITHM_RS256, ALGORITHM_ES256] }) .then(() => { clock!.tick(1); // token should now be invalid return verifyJwtSignature(mockIdToken, mocks.keyPairs[0].public, - { algorithms: [ALGORITHM_RS256] }) + { algorithms: [ALGORITHM_RS256, ALGORITHM_ES256] }) .should.eventually.be.rejectedWith( 'The provided token has expired. Get a fresh token from your client app and try again.' ) @@ -299,7 +299,7 @@ describe('verifyJwtSignature', () => { callback(new Error('key fetch failed.')); return verifyJwtSignature(mockIdToken, getKeyCallback, - { algorithms: [ALGORITHM_RS256] }) + { algorithms: [ALGORITHM_RS256, ALGORITHM_ES256] }) .should.eventually.be.rejectedWith('key fetch failed.') .with.property('code', JwtErrorCode.KEY_FETCH_ERROR); }); @@ -310,7 +310,7 @@ describe('verifyJwtSignature', () => { callback(new Error('no-matching-kid-error')); return verifyJwtSignature(mockIdToken, getKeyCallback, - { algorithms: [ALGORITHM_RS256] }) + { algorithms: [ALGORITHM_RS256, ALGORITHM_ES256] }) .should.eventually.be.rejectedWith('no-matching-kid-error') .with.property('code', JwtErrorCode.NO_MATCHING_KID); }); @@ -319,7 +319,7 @@ describe('verifyJwtSignature', () => { const mockIdToken = mocks.generateIdToken(); return verifyJwtSignature(mockIdToken, mocks.keyPairs[1].public, - { algorithms: [ALGORITHM_RS256] }) + { algorithms: [ALGORITHM_RS256, ALGORITHM_ES256] }) .should.eventually.be.rejectedWith('invalid signature') .with.property('code', JwtErrorCode.INVALID_SIGNATURE); }); From db6f5c01545b64f02f71e0aff07d8805d4a668de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:25:18 -0400 Subject: [PATCH 311/323] build(deps-dev): bump lodash and @microsoft/api-extractor (#3106) Bumps [lodash](https://github.com/lodash/lodash) and [@microsoft/api-extractor](https://github.com/microsoft/rushstack/tree/HEAD/apps/api-extractor). These dependencies needed to be updated together. Updates `lodash` from 4.17.23 to 4.18.1 - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.23...4.18.1) Updates `@microsoft/api-extractor` from 7.57.7 to 7.58.1 - [Changelog](https://github.com/microsoft/rushstack/blob/main/apps/api-extractor/CHANGELOG.md) - [Commits](https://github.com/microsoft/rushstack/commits/@microsoft/api-extractor_v7.58.1/apps/api-extractor) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.18.1 dependency-type: direct:development - dependency-name: "@microsoft/api-extractor" dependency-version: 7.58.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 80 +++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a561dc40b..e60cadece1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1388,41 +1388,41 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.57.7", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.57.7.tgz", - "integrity": "sha512-kmnmVs32MFWbV5X6BInC1/TfCs7y1ugwxv1xHsAIj/DyUfoe7vtO0alRUgbQa57+yRGHBBjlNcEk33SCAt5/dA==", + "version": "7.58.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.58.1.tgz", + "integrity": "sha512-kF3GFME4lN22O5zbnXk2RP4y/4PDQdps0xKiYTipMYprkwCmmpsWLZt/N2Fkbil540cSLfJX0BW7LkHzgMVUYg==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.33.4", + "@microsoft/api-extractor-model": "7.33.5", "@microsoft/tsdoc": "~0.16.0", "@microsoft/tsdoc-config": "~0.18.1", - "@rushstack/node-core-library": "5.20.3", + "@rushstack/node-core-library": "5.21.0", "@rushstack/rig-package": "0.7.2", - "@rushstack/terminal": "0.22.3", - "@rushstack/ts-command-line": "5.3.3", + "@rushstack/terminal": "0.22.4", + "@rushstack/ts-command-line": "5.3.4", "diff": "~8.0.2", - "lodash": "~4.17.23", + "lodash": "~4.18.1", "minimatch": "10.2.3", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", - "typescript": "5.8.2" + "typescript": "5.9.3" }, "bin": { "api-extractor": "bin/api-extractor" } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.33.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.33.4.tgz", - "integrity": "sha512-u1LTaNTikZAQ9uK6KG1Ms7nvNedsnODnspq/gH2dcyETWvH4hVNGNDvRAEutH66kAmxA4/necElqGNs1FggC8w==", + "version": "7.33.5", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.33.5.tgz", + "integrity": "sha512-Xh4dXuusndVQqVz4nEN9xOp0DyzsKxeD2FFJkSPg4arAjDSKPcy6cAc7CaeBPA7kF2wV1fuDlo2p/bNMpVr8yg==", "dev": true, "license": "MIT", "dependencies": { "@microsoft/tsdoc": "~0.16.0", "@microsoft/tsdoc-config": "~0.18.1", - "@rushstack/node-core-library": "5.20.3" + "@rushstack/node-core-library": "5.21.0" } }, "node_modules/@microsoft/api-extractor-model/node_modules/@microsoft/tsdoc": { @@ -1433,9 +1433,9 @@ "license": "MIT" }, "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "5.20.3", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.20.3.tgz", - "integrity": "sha512-95JgEPq2k7tHxhF9/OJnnyHDXfC9cLhhta0An/6MlkDsX2A6dTzDrTUG18vx4vjc280V0fi0xDH9iQczpSuWsw==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.21.0.tgz", + "integrity": "sha512-LFzN+1lyWROit/P8Md6yxAth7lLYKn37oCKJHirEE2TQB25NDUM7bALf0ar+JAtwFfRCH+D+DGOA7DAzIi2r+g==", "dev": true, "license": "MIT", "dependencies": { @@ -1503,9 +1503,9 @@ "license": "MIT" }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "5.20.3", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.20.3.tgz", - "integrity": "sha512-95JgEPq2k7tHxhF9/OJnnyHDXfC9cLhhta0An/6MlkDsX2A6dTzDrTUG18vx4vjc280V0fi0xDH9iQczpSuWsw==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.21.0.tgz", + "integrity": "sha512-LFzN+1lyWROit/P8Md6yxAth7lLYKn37oCKJHirEE2TQB25NDUM7bALf0ar+JAtwFfRCH+D+DGOA7DAzIi2r+g==", "dev": true, "license": "MIT", "dependencies": { @@ -1528,13 +1528,13 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.3.3.tgz", - "integrity": "sha512-c+ltdcvC7ym+10lhwR/vWiOhsrm/bP3By2VsFcs5qTKv+6tTmxgbVrtJ5NdNjANiV5TcmOZgUN+5KYQ4llsvEw==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.3.4.tgz", + "integrity": "sha512-MLkVKVEN6/2clKTrjN2B2KqKCuPxRwnNsWY7a+FCAq2EMdkj10cM8YgiBSMeGFfzM0mDMzargpHNnNzaBi9Whg==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.22.3", + "@rushstack/terminal": "0.22.4", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1568,20 +1568,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/@microsoft/api-extractor/node_modules/typescript": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", - "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/@microsoft/api-extractor/node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -1813,13 +1799,13 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.22.3", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.22.3.tgz", - "integrity": "sha512-gHC9pIMrUPzAbBiI4VZMU7Q+rsCzb8hJl36lFIulIzoceKotyKL3Rd76AZ2CryCTKEg+0bnTj406HE5YY5OQvw==", + "version": "0.22.4", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.22.4.tgz", + "integrity": "sha512-fhtLjnXCc/4WleVbVl6aoc7jcWnU6yqjS1S8WoaNREG3ycu/viZ9R/9QM7Y/b4CDvcXoiDyMNIay7JMwBptM3g==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.20.3", + "@rushstack/node-core-library": "5.21.0", "@rushstack/problem-matcher": "0.2.1", "supports-color": "~8.1.1" }, @@ -1833,9 +1819,9 @@ } }, "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "5.20.3", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.20.3.tgz", - "integrity": "sha512-95JgEPq2k7tHxhF9/OJnnyHDXfC9cLhhta0An/6MlkDsX2A6dTzDrTUG18vx4vjc280V0fi0xDH9iQczpSuWsw==", + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.21.0.tgz", + "integrity": "sha512-LFzN+1lyWROit/P8Md6yxAth7lLYKn37oCKJHirEE2TQB25NDUM7bALf0ar+JAtwFfRCH+D+DGOA7DAzIi2r+g==", "dev": true, "license": "MIT", "dependencies": { @@ -8268,9 +8254,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, From 1689659bf7e56990340107247f78cd9ed050c785 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:36:53 -0400 Subject: [PATCH 312/323] build(deps-dev): bump @types/node from 25.3.0 to 25.3.3 (#3090) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.3.0 to 25.3.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.3.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba From bbd3365fd070f4057bde3409f8c120f2ae6cbed6 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 9 Apr 2026 13:09:13 -0400 Subject: [PATCH 313/323] chore(deps): bump node-forge to 1.4.0 (#3108) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e60cadece1..60f5453fbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "google-auth-library": "^10.6.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", - "node-forge": "^1.3.1", + "node-forge": "^1.4.0", "uuid": "^11.0.2" }, "devDependencies": { diff --git a/package.json b/package.json index ee14d9d52b..4a373473dd 100644 --- a/package.json +++ b/package.json @@ -222,7 +222,7 @@ "google-auth-library": "^10.6.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", - "node-forge": "^1.3.1", + "node-forge": "^1.4.0", "uuid": "^11.0.2" }, "optionalDependencies": { From ff4c94df66ebbcca74bac1f8c55685d1ce875604 Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:40:20 -0400 Subject: [PATCH 314/323] [chore] Release 13.8.0 (#3109) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4a373473dd..f375c597e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.7.0", + "version": "13.8.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", From e310a72ee18908e30c8ed8cab73b3a116e047eb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:28:04 -0400 Subject: [PATCH 315/323] build(deps): bump fast-xml-parser from 5.5.9 to 5.7.1 (#3122) Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.5.9 to 5.7.1. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.5.9...v5.7.1) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.7.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 48 ++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 60f5453fbc..f51efaec84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.7.0", + "version": "13.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.7.0", + "version": "13.8.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -1605,6 +1605,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT", + "optional": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4916,9 +4929,9 @@ "license": "BSD-3-Clause" }, "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", + "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", "funding": [ { "type": "github", @@ -4932,9 +4945,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "5.5.9", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.9.tgz", - "integrity": "sha512-jldvxr1MC6rtiZKgrFnDSvT8xuH+eJqxqOBThUVjYrxssYTo1avZLGql5l0a0BAERR01CadYzZ83kVEkbyDg+g==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.1.tgz", + "integrity": "sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==", "funding": [ { "type": "github", @@ -4944,9 +4957,10 @@ "license": "MIT", "optional": true, "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.2.0", - "strnum": "^2.2.2" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" @@ -9772,9 +9786,9 @@ } }, "node_modules/path-expression-matcher": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.2.0.tgz", - "integrity": "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", "funding": [ { "type": "github", @@ -11788,9 +11802,9 @@ } }, "node_modules/strnum": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.2.tgz", - "integrity": "sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", "funding": [ { "type": "github", From 8b9b7a7768a808aac668b4d2d04b18ed97855a9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:43:09 -0400 Subject: [PATCH 316/323] build(deps): bump axios in /.github/actions/send-email (#3123) Bumps [axios](https://github.com/axios/axios) from 1.13.5 to 1.15.2. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.13.5...v1.15.2) --- updated-dependencies: - dependency-name: axios dependency-version: 1.15.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/send-email/package-lock.json | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index f20d2d3ad6..969d6b237d 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -58,14 +58,14 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", + "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "proxy-from-env": "^2.1.0" } }, "node_modules/base-64": { @@ -343,9 +343,13 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/tunnel": { "version": "0.0.6", From 92003fc20fde1dfd747f17034f812dcf6d9767d3 Mon Sep 17 00:00:00 2001 From: Tushar Khandelwal <64364243+tusharkhandelwal8@users.noreply.github.com> Date: Mon, 27 Apr 2026 23:28:07 +0530 Subject: [PATCH 317/323] feat(remote-config): add optional exposurePercent field to ExperimentValue (#3096) * feat(remote-config): add optional exposurePercent field to ExperimentValue * document the expected range for the exposure * correct field ordering in ExperimentValue API report * validate experiment exposure percent range * Validate parameterGroups for exposure --- etc/firebase-admin.remote-config.api.md | 1 + src/remote-config/remote-config-api.ts | 6 ++ src/remote-config/remote-config.ts | 55 ++++++++++++++++ test/unit/remote-config/remote-config.spec.ts | 62 ++++++++++++++++++- 4 files changed, 122 insertions(+), 2 deletions(-) diff --git a/etc/firebase-admin.remote-config.api.md b/etc/firebase-admin.remote-config.api.md index 1a19d1bb6c..675fdf54a3 100644 --- a/etc/firebase-admin.remote-config.api.md +++ b/etc/firebase-admin.remote-config.api.md @@ -55,6 +55,7 @@ export interface ExperimentParameterValue { // @public export interface ExperimentValue { experimentId: string; + exposurePercent?: number; variantValue: ExperimentVariantValue[]; } diff --git a/src/remote-config/remote-config-api.ts b/src/remote-config/remote-config-api.ts index 6566fe231e..0f2648d797 100644 --- a/src/remote-config/remote-config-api.ts +++ b/src/remote-config/remote-config-api.ts @@ -451,6 +451,12 @@ export interface ExperimentValue { * served by the Experiment. */ variantValue: ExperimentVariantValue[]; + + /** + * The percentage of users included in the Experiment, represented as a number + * between 0 and 100. + */ + exposurePercent?: number; } /** diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index 6ae44c4064..983af8b887 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -34,6 +34,7 @@ import { InAppDefaultValue, ServerConfig, RemoteConfigParameterValue, + ExperimentParameterValue, EvaluationContext, ServerTemplateData, NamedCondition, @@ -243,6 +244,8 @@ class RemoteConfigTemplateImpl implements RemoteConfigTemplate { this.parameters = {}; } + validateAllParameterExposures(this.parameters); + if (typeof config.parameterGroups !== 'undefined') { if (!validator.isNonNullObject(config.parameterGroups)) { throw new FirebaseRemoteConfigError( @@ -254,6 +257,12 @@ class RemoteConfigTemplateImpl implements RemoteConfigTemplate { this.parameterGroups = {}; } + for (const group of Object.values(this.parameterGroups)) { + if (validator.isNonNullObject(group) && validator.isNonNullObject(group.parameters)) { + validateAllParameterExposures(group.parameters); + } + } + if (typeof config.conditions !== 'undefined') { if (!validator.isArray(config.conditions)) { throw new FirebaseRemoteConfigError( @@ -448,6 +457,52 @@ class ServerConfigImpl implements ServerConfig { } } +function validateAllParameterExposures( + parameters: { [key: string]: RemoteConfigParameter } +): void { + // Walk each parameter and validate any exposurePercent present in + // conditional values only. Experiment exposure is condition-scoped. + for (const [parameterName, parameter] of Object.entries(parameters)) { + if (!validator.isNonNullObject(parameter)) { + continue; + } + + if (!validator.isNonNullObject(parameter.conditionalValues)) { + continue; + } + + for (const conditionalValue of Object.values(parameter.conditionalValues)) { + validateExperimentExposurePercent(conditionalValue, parameterName); + } + } +} + +function validateExperimentExposurePercent( + parameterValue: RemoteConfigParameterValue | undefined, + parameterName: string, +): void { + // Only experiment-backed values can carry `exposurePercent`. + // For other parameter value types, this validator is a no-op. + if (!validator.isNonNullObject(parameterValue) || + !validator.isNonNullObject((parameterValue as ExperimentParameterValue).experimentValue)) { + return; + } + + const exposurePercent = (parameterValue as ExperimentParameterValue).experimentValue.exposurePercent; + // `exposurePercent` is optional. If absent, leave behavior unchanged. + if (typeof exposurePercent === 'undefined') { + return; + } + + // Enforce public contract: numeric and within [0, 100]. + if (!validator.isNumber(exposurePercent) || !Number.isFinite(exposurePercent) || + exposurePercent < 0 || exposurePercent > 100) { + throw new FirebaseRemoteConfigError( + 'invalid-argument', + `Experiment exposure percent must be between 0 and 100 (${parameterName})`); + } +} + /** * Remote Config dataplane template data implementation. */ diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index 74d277290e..737bb868fa 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -134,7 +134,8 @@ describe('RemoteConfig', () => { variantValue: [ { variantId: 'variant_A', value: 'true' }, { variantId: 'variant_B', noChange: true } - ] + ], + exposurePercent: 25, } } }, @@ -233,7 +234,8 @@ describe('RemoteConfig', () => { variantValue: [ { variantId: 'variant_A', value: 'true' }, { variantId: 'variant_B', noChange: true } - ] + ], + exposurePercent: 25, } } }, @@ -607,6 +609,48 @@ describe('RemoteConfig', () => { }); }); + it('should throw if experiment exposure percent is out of range', () => { + sourceTemplate = deepCopy(REMOTE_CONFIG_RESPONSE); + (sourceTemplate.parameters as any).experiment_enabled + .conditionalValues.ios.experimentValue.exposurePercent = 101; + const jsonString = JSON.stringify(sourceTemplate); + expect(() => remoteConfig.createTemplateFromJSON(jsonString)) + .to.throw('Experiment exposure percent must be between 0 and 100 (experiment_enabled)'); + }); + + it('should accept experiment exposure percent for boundary and middle values', () => { + [0, 52, 100].forEach((validExposurePercent) => { + sourceTemplate = deepCopy(REMOTE_CONFIG_RESPONSE); + (sourceTemplate.parameters as any).experiment_enabled + .conditionalValues.ios.experimentValue.exposurePercent = validExposurePercent; + const jsonString = JSON.stringify(sourceTemplate); + expect(() => remoteConfig.createTemplateFromJSON(jsonString)).to.not.throw(); + }); + }); + + it('should throw if experiment exposure percent in a parameter group is out of range', () => { + sourceTemplate = deepCopy(REMOTE_CONFIG_RESPONSE); + (sourceTemplate.parameterGroups as any).new_menu.parameters.pumpkin_spice_season + .conditionalValues.android_en = { + experimentValue: { experimentId: 'exp_1', exposurePercent: 101, variantValue: [] }, + }; + const jsonString = JSON.stringify(sourceTemplate); + expect(() => remoteConfig.createTemplateFromJSON(jsonString)) + .to.throw('Experiment exposure percent must be between 0 and 100 (pumpkin_spice_season)'); + }); + + it('should accept valid experiment exposure percent in a parameter group', () => { + [0, 50, 100].forEach((validExposurePercent) => { + sourceTemplate = deepCopy(REMOTE_CONFIG_RESPONSE); + (sourceTemplate.parameterGroups as any).new_menu.parameters.pumpkin_spice_season + .conditionalValues.android_en = { + experimentValue: { experimentId: 'exp_1', exposurePercent: validExposurePercent, variantValue: [] }, + }; + const jsonString = JSON.stringify(sourceTemplate); + expect(() => remoteConfig.createTemplateFromJSON(jsonString)).to.not.throw(); + }); + }); + it('should succeed when a valid json string is provided', () => { const jsonString = JSON.stringify(REMOTE_CONFIG_RESPONSE); const newTemplate = remoteConfig.createTemplateFromJSON(jsonString); @@ -652,6 +696,7 @@ describe('RemoteConfig', () => { expect(p4.conditionalValues).to.not.be.undefined; const experimentParam = p4.conditionalValues!['ios'] as ExperimentParameterValue; expect(experimentParam.experimentValue.experimentId).to.equal('experiment_1'); + expect(experimentParam.experimentValue.exposurePercent).to.equal(25); expect(experimentParam.experimentValue.variantValue.length).to.equal(2); expect(experimentParam.experimentValue.variantValue[0]).to.deep.equal({ variantId: 'variant_A', value: 'true' }); expect(experimentParam.experimentValue.variantValue[1]).to.deep.equal({ variantId: 'variant_B', noChange: true }); @@ -1668,6 +1713,19 @@ describe('RemoteConfig', () => { .should.eventually.be.rejected.and.have.property( 'message', 'Remote Config conditions must be an array'); }); + + it('should reject when API response contains invalid experiment exposure percent', () => { + const response = deepCopy(REMOTE_CONFIG_RESPONSE); + (response.parameters as any).experiment_enabled + .conditionalValues.ios.experimentValue.exposurePercent = 101; + const stub = sinon + .stub(RemoteConfigApiClient.prototype, operationName) + .resolves(response); + stubs.push(stub); + return rcOperation() + .should.eventually.be.rejected.and.have.property( + 'message', 'Experiment exposure percent must be between 0 and 100 (experiment_enabled)'); + }); } function runValidResponseTests(rcOperation: () => Promise, From e891a3cacc86c2cff6ab153366536c80aaf0ee23 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:10:45 -0400 Subject: [PATCH 318/323] build(deps): bump uuid and @actions/core in /.github/actions/send-email (#3120) Removes [uuid](https://github.com/uuidjs/uuid). It's no longer used after updating ancestor dependency [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core). These dependencies need to be updated together. Removes `uuid` Updates `@actions/core` from 1.10.1 to 1.11.1 - [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md) - [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core) --- updated-dependencies: - dependency-name: "@actions/core" dependency-version: 1.11.1 dependency-type: direct:production - dependency-name: uuid dependency-version: dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- .github/actions/send-email/package-lock.json | 36 ++++++++++++-------- .github/actions/send-email/package.json | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 969d6b237d..6de017e924 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.1", "license": "Apache-2.0", "dependencies": { - "@actions/core": "^1.10.1", + "@actions/core": "^1.11.1", "mailgun.js": "^10.1.0" }, "devDependencies": { @@ -17,12 +17,22 @@ } }, "node_modules/@actions/core": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.1.tgz", - "integrity": "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", + "integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==", + "license": "MIT", + "dependencies": { + "@actions/exec": "^1.1.1", + "@actions/http-client": "^2.0.1" + } + }, + "node_modules/@actions/exec": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz", + "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==", + "license": "MIT", "dependencies": { - "@actions/http-client": "^2.0.1", - "uuid": "^8.3.2" + "@actions/io": "^1.0.1" } }, "node_modules/@actions/http-client": { @@ -34,6 +44,12 @@ "undici": "^5.25.4" } }, + "node_modules/@actions/io": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz", + "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==", + "license": "MIT" + }, "node_modules/@fastify/busboy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", @@ -375,14 +391,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } } } } diff --git a/.github/actions/send-email/package.json b/.github/actions/send-email/package.json index 69ee369e50..620b357377 100644 --- a/.github/actions/send-email/package.json +++ b/.github/actions/send-email/package.json @@ -14,7 +14,7 @@ "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0", "dependencies": { - "@actions/core": "^1.10.1", + "@actions/core": "^1.11.1", "mailgun.js": "^10.1.0" }, "devDependencies": { From ce3b9e0b0f6871054b1adefb0b6bcade2257a195 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:19:03 -0400 Subject: [PATCH 319/323] build(deps): bump protobufjs from 7.5.4 to 7.5.5 (#3119) Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 7.5.4 to 7.5.5. - [Release notes](https://github.com/protobufjs/protobuf.js/releases) - [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/protobufjs/protobuf.js/compare/protobufjs-v7.5.4...protobufjs-v7.5.5) --- updated-dependencies: - dependency-name: protobufjs dependency-version: 7.5.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f51efaec84..2343e65685 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10125,9 +10125,9 @@ } }, "node_modules/protobufjs": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", - "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.5.tgz", + "integrity": "sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==", "hasInstallScript": true, "license": "BSD-3-Clause", "optional": true, From 5933705cc66043bcf6a563aae9e285584ddf1dfb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:17:18 -0400 Subject: [PATCH 320/323] build(deps): bump follow-redirects in /.github/actions/send-email (#3113) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.11 to 1.16.0. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.11...v1.16.0) --- updated-dependencies: - dependency-name: follow-redirects dependency-version: 1.16.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- .github/actions/send-email/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/send-email/package-lock.json b/.github/actions/send-email/package-lock.json index 6de017e924..84294888cb 100644 --- a/.github/actions/send-email/package-lock.json +++ b/.github/actions/send-email/package-lock.json @@ -183,9 +183,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", From b28b9212a7b314541fac4cb38030f2dbeadcd83f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 16:32:07 -0400 Subject: [PATCH 321/323] build(deps-dev): bump @typescript-eslint/parser from 8.57.2 to 8.59.1 (#3114) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.57.2 to 8.59.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.58.2 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lahiru Maramba --- package-lock.json | 159 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2343e65685..82dc7466a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2269,16 +2269,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", - "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.1.tgz", + "integrity": "sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.57.2", - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/typescript-estree": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2", + "@typescript-eslint/scope-manager": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", "debug": "^4.4.3" }, "engines": { @@ -2290,7 +2290,150 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz", + "integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.1", + "@typescript-eslint/types": "^8.59.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz", + "integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz", + "integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", + "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz", + "integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.1", + "@typescript-eslint/tsconfig-utils": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz", + "integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@typescript-eslint/project-service": { From 363a302d30469a69bfc8016879438e78835d37fa Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 6 May 2026 16:56:42 -0400 Subject: [PATCH 322/323] chore: Deprecate support for Node.js 20 (#3128) * chore: deprecate Node.js 20 * update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f9d80ec69..b1c626c611 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,7 +87,7 @@ information on using pull requests. ### Prerequisites -1. Node.js 16 or higher. +1. Node.js 22 or higher. 2. `npm` 6 or higher. 3. Google Cloud SDK ([`gcloud`](https://cloud.google.com/sdk/downloads) utility). diff --git a/README.md b/README.md index 8c695d8c89..73c5fe9a21 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,8 @@ requests, code review feedback, and also pull requests. ## Supported Environments -We currently support Node.js 18 and higher, but its support is deprecated. We strongly encourage -you to use Node.js 20 or higher as we will drop support for Node.js 18 in the next major version. +We currently support Node.js 18 and higher, but support for Node.js 18 and Node.js 20 is deprecated. We strongly encourage +you to use Node.js 22 or higher as we will drop support for Node.js 18 and Node.js 20 in the next major version. Please also note that the Admin SDK should only be used in server-side/back-end environments controlled by the app developer. From 0efb21f1648c46078e2fd519932def708c8ac6fd Mon Sep 17 00:00:00 2001 From: Jonathan Edey <145066863+jonathanedey@users.noreply.github.com> Date: Thu, 7 May 2026 15:06:12 -0400 Subject: [PATCH 323/323] [chore] Release 13.9.0 (#3129) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 82dc7466a1..9e2865cb66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.8.0", + "version": "13.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.8.0", + "version": "13.9.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", diff --git a/package.json b/package.json index f375c597e6..b88901e6e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "firebase-admin", - "version": "13.8.0", + "version": "13.9.0", "description": "Firebase admin SDK for Node.js", "author": "Firebase (https://firebase.google.com/)", "license": "Apache-2.0",